From d6afbe8e8ec83bdcbedd2b121be20c14f6bd8bb8 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Mon, 24 Jul 2023 16:49:33 -0700 Subject: [PATCH] Introduce accent for chips (#911) * Introduce accent for chips * Add top bar on Mobile on Settings pages * Various fixes * Fix according to peer review --- .../components/CommentThreadTypeDropdown.tsx | 67 +++----- .../__stories__/CompanyChip.stories.tsx | 4 - .../components/CompanyAccountOwnerCell.tsx | 5 +- .../companies/components/CompanyBoardCard.tsx | 3 +- .../companies/components/CompanyChip.tsx | 9 +- .../components/CompanyEditableNameCell.tsx | 1 - .../modules/people/components/PersonChip.tsx | 9 +- .../ui/button/components/DropdownButton.tsx | 144 ------------------ front/src/modules/ui/chip/components/Chip.tsx | 21 ++- .../modules/ui/chip/components/EntityChip.tsx | 15 +- .../components/__stories__/Chip.stories.tsx | 7 +- .../components/SubMenuTopBarContainer.tsx | 17 ++- .../ui/layout/top-bar/components/TopBar.tsx | 5 +- .../modules/ui/link/components/RawLink.tsx | 2 + .../ui/navbar/components/SubMenuNavbar.tsx | 4 +- .../right-drawer/components/RightDrawer.tsx | 2 - .../src/modules/users/components/UserChip.tsx | 19 +++ front/src/pages/people/People.tsx | 5 +- .../src/pages/settings/SettingsExperience.tsx | 3 +- front/src/pages/settings/SettingsProfile.tsx | 7 +- .../src/pages/settings/SettingsWorkspace.tsx | 3 +- .../settings/SettingsWorkspaceMembers.tsx | 4 +- .../ExhaustiveComponentDecorator.tsx | 89 ++++++----- 23 files changed, 166 insertions(+), 279 deletions(-) delete mode 100644 front/src/modules/ui/button/components/DropdownButton.tsx create mode 100644 front/src/modules/users/components/UserChip.tsx diff --git a/front/src/modules/activities/components/CommentThreadTypeDropdown.tsx b/front/src/modules/activities/components/CommentThreadTypeDropdown.tsx index ff8e8604a..eef0771b7 100644 --- a/front/src/modules/activities/components/CommentThreadTypeDropdown.tsx +++ b/front/src/modules/activities/components/CommentThreadTypeDropdown.tsx @@ -1,60 +1,27 @@ +import { useTheme } from '@emotion/react'; + import { - DropdownButton, - DropdownOptionType, -} from '@/ui/button/components/DropdownButton'; -import { IconCheck, IconNotes } from '@/ui/icon'; -import { - ActivityType, - CommentThread, - useUpdateCommentThreadMutation, -} from '~/generated/graphql'; + Chip, + ChipAccent, + ChipSize, + ChipVariant, +} from '@/ui/chip/components/Chip'; +import { IconPhone } from '@/ui/icon'; +import { CommentThread } from '~/generated/graphql'; type OwnProps = { - commentThread: Pick; + commentThread: Pick; }; export function CommentThreadTypeDropdown({ commentThread }: OwnProps) { - const [updateCommentThreadMutation] = useUpdateCommentThreadMutation(); - const options: DropdownOptionType[] = [ - { label: 'Note', key: 'note', icon: }, - { label: 'Task', key: 'task', icon: }, - ]; - - function getSelectedOptionKey() { - if (commentThread.type === ActivityType.Note) { - return 'note'; - } else if (commentThread.type === ActivityType.Task) { - return 'task'; - } else { - return undefined; - } - } - - const convertSelectionOptionKeyToActivityType = (key: string) => { - switch (key) { - case 'note': - return ActivityType.Note; - case 'task': - return ActivityType.Task; - default: - return undefined; - } - }; - - const handleSelect = (selectedOption: DropdownOptionType) => { - updateCommentThreadMutation({ - variables: { - id: commentThread.id, - type: convertSelectionOptionKeyToActivityType(selectedOption.key), - }, - }); - }; - + const theme = useTheme(); return ( - } + size={ChipSize.Large} + accent={ChipAccent.TextSecondary} + variant={ChipVariant.Highlighted} /> ); } diff --git a/front/src/modules/companies/__stories__/CompanyChip.stories.tsx b/front/src/modules/companies/__stories__/CompanyChip.stories.tsx index 83ed41ab3..331c7b894 100644 --- a/front/src/modules/companies/__stories__/CompanyChip.stories.tsx +++ b/front/src/modules/companies/__stories__/CompanyChip.stories.tsx @@ -47,10 +47,6 @@ export const SmallName: Story = { }, }; -export const Clickable: Story = { - args: { ...SmallName.args, clickable: true }, -}; - export const BigName: Story = { args: { id: 'google', diff --git a/front/src/modules/companies/components/CompanyAccountOwnerCell.tsx b/front/src/modules/companies/components/CompanyAccountOwnerCell.tsx index 14e20d540..5fe0c40ec 100644 --- a/front/src/modules/companies/components/CompanyAccountOwnerCell.tsx +++ b/front/src/modules/companies/components/CompanyAccountOwnerCell.tsx @@ -1,9 +1,10 @@ -import { PersonChip } from '@/people/components/PersonChip'; import { RelationPickerHotkeyScope } from '@/ui/relation-picker/types/RelationPickerHotkeyScope'; import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell'; import { useEditableCell } from '@/ui/table/editable-cell/hooks/useEditableCell'; import { Company, User } from '~/generated/graphql'; +import { UserChip } from '../../users/components/UserChip'; + import { CompanyAccountOwnerPicker } from './CompanyAccountOwnerPicker'; export type CompanyAccountOnwer = Pick & { @@ -38,7 +39,7 @@ export function CompanyAccountOwnerCell({ company }: OwnProps) { } nonEditModeContent={ company.accountOwner?.displayName ? ( - ); } diff --git a/front/src/modules/companies/components/CompanyEditableNameCell.tsx b/front/src/modules/companies/components/CompanyEditableNameCell.tsx index 71a760f88..704e647b8 100644 --- a/front/src/modules/companies/components/CompanyEditableNameCell.tsx +++ b/front/src/modules/companies/components/CompanyEditableNameCell.tsx @@ -37,7 +37,6 @@ export function CompanyEditableNameChipCell({ company }: OwnProps) { } diff --git a/front/src/modules/people/components/PersonChip.tsx b/front/src/modules/people/components/PersonChip.tsx index c91c68c3a..6e84cb13c 100644 --- a/front/src/modules/people/components/PersonChip.tsx +++ b/front/src/modules/people/components/PersonChip.tsx @@ -1,25 +1,26 @@ -import { EntityChip } from '@/ui/chip/components/EntityChip'; +import { EntityChip, EntityChipVariant } from '@/ui/chip/components/EntityChip'; export type PersonChipPropsType = { id: string; name: string; pictureUrl?: string; - clickable?: boolean; + variant?: EntityChipVariant; }; export function PersonChip({ id, name, pictureUrl, - clickable = true, + variant, }: PersonChipPropsType) { return ( ); } diff --git a/front/src/modules/ui/button/components/DropdownButton.tsx b/front/src/modules/ui/button/components/DropdownButton.tsx deleted file mode 100644 index 232ff6d82..000000000 --- a/front/src/modules/ui/button/components/DropdownButton.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import styled from '@emotion/styled'; - -import { IconChevronDown } from '@/ui/icon/index'; - -type ButtonProps = React.ComponentProps<'button'>; - -export type DropdownOptionType = { - key: string; - label: string; - icon: React.ReactNode; -}; - -type OwnProps = { - options: DropdownOptionType[]; - selectedOptionKey?: string; - onSelection: (value: DropdownOptionType) => void; -} & ButtonProps; - -const StyledButton = styled.button` - align-items: center; - background: ${({ theme }) => theme.background.tertiary}; - border: 1px solid ${({ theme }) => theme.border.color.medium}; - border-bottom-left-radius: ${({ isOpen, theme }) => - isOpen ? 0 : theme.border.radius.sm}; - border-bottom-right-radius: ${({ isOpen, theme }) => - isOpen ? 0 : theme.border.radius.sm}; - border-top-left-radius: ${({ theme }) => theme.border.radius.sm}; - border-top-right-radius: ${({ theme }) => theme.border.radius.sm}; - color: ${({ theme }) => theme.font.color.secondary}; - cursor: pointer; - display: flex; - gap: ${({ theme }) => theme.spacing(2)}; - padding: ${({ theme }) => theme.spacing(1)} ${({ theme }) => theme.spacing(2)}; - - svg { - align-items: center; - display: flex; - height: 14px; - justify-content: center; - width: 14px; - } -`; - -const StyledDropdownItem = styled.button` - align-items: center; - background: ${({ theme }) => theme.background.tertiary}; - border: 1px solid ${({ theme }) => theme.border.color.medium}; - border-radius: ${({ theme }) => theme.border.radius.sm}; - border-top: none; - border-top-left-radius: 0; - border-top-right-radius: 0; - color: ${({ theme }) => theme.font.color.secondary}; - cursor: pointer; - display: flex; - gap: ${({ theme }) => theme.spacing(2)}; - padding: ${({ theme }) => theme.spacing(1)} ${({ theme }) => theme.spacing(2)}; - - svg { - align-items: center; - display: flex; - height: 14px; - justify-content: center; - width: 14px; - } -`; - -const DropdownContainer = styled.div` - position: relative; -`; - -const DropdownMenu = styled.div` - display: flex; - flex-direction: column; - position: absolute; - width: 100%; -`; - -export function DropdownButton({ - options, - selectedOptionKey, - onSelection, - ...buttonProps -}: OwnProps) { - const [isOpen, setIsOpen] = useState(false); - const [selectedOption, setSelectedOption] = useState< - DropdownOptionType | undefined - >(undefined); - - useEffect(() => { - if (selectedOptionKey) { - const option = options.find((option) => option.key === selectedOptionKey); - setSelectedOption(option); - } else { - setSelectedOption(options[0]); - } - }, [selectedOptionKey, options]); - - if (!options.length) { - throw new Error('You must provide at least one option.'); - } - - const handleSelect = - (option: DropdownOptionType) => - (event: React.MouseEvent) => { - event.preventDefault(); - onSelection(option); - setSelectedOption(option); - setIsOpen(false); - }; - - return ( - <> - {selectedOption && ( - - setIsOpen(!isOpen)} - {...buttonProps} - isOpen={isOpen} - > - {selectedOption.icon} - {selectedOption.label} - {options.length > 1 && } - - {isOpen && ( - - {options - .filter((option) => option.label !== selectedOption.label) - .map((option, index) => ( - - {option.icon} - {option.label} - - ))} - - )} - - )} - - ); -} diff --git a/front/src/modules/ui/chip/components/Chip.tsx b/front/src/modules/ui/chip/components/Chip.tsx index 91971bc20..fca2c3144 100644 --- a/front/src/modules/ui/chip/components/Chip.tsx +++ b/front/src/modules/ui/chip/components/Chip.tsx @@ -8,6 +8,11 @@ export enum ChipSize { Small = 'small', } +export enum ChipAccent { + TextPrimary = 'text-primary', + TextSecondary = 'text-secondary', +} + export enum ChipVariant { Highlighted = 'highlighted', Regular = 'regular', @@ -21,6 +26,7 @@ type OwnProps = { label: string; maxWidth?: string; variant?: ChipVariant; + accent?: ChipAccent; leftComponent?: React.ReactNode; rightComponent?: React.ReactNode; className?: string; @@ -34,14 +40,18 @@ const StyledContainer = styled.div>` ? theme.background.transparent.light : 'transparent'}; border-radius: ${({ theme }) => theme.border.radius.sm}; - color: ${({ theme, disabled }) => - disabled ? theme.font.color.light : theme.font.color.primary}; + color: ${({ theme, disabled, accent }) => + disabled + ? theme.font.color.light + : accent === ChipAccent.TextPrimary + ? theme.font.color.primary + : theme.font.color.secondary}; cursor: ${({ clickable, disabled, variant }) => disabled || variant === ChipVariant.Transparent - ? 'auto' + ? 'inherit' : clickable ? 'pointer' - : 'auto'}; + : 'inherit'}; display: inline-flex; gap: ${({ theme }) => theme.spacing(1)}; @@ -98,6 +108,7 @@ export function Chip({ variant = ChipVariant.Regular, leftComponent, rightComponent, + accent = ChipAccent.TextPrimary, maxWidth, className, }: OwnProps) { @@ -106,9 +117,11 @@ export function Chip({ data-testid="chip" clickable={clickable} variant={variant} + accent={accent} size={size} disabled={disabled} className={className} + maxWidth={maxWidth} > {leftComponent} diff --git a/front/src/modules/ui/chip/components/EntityChip.tsx b/front/src/modules/ui/chip/components/EntityChip.tsx index b6189da73..15fdd66b8 100644 --- a/front/src/modules/ui/chip/components/EntityChip.tsx +++ b/front/src/modules/ui/chip/components/EntityChip.tsx @@ -12,14 +12,21 @@ type OwnProps = { name: string; pictureUrl?: string; avatarType?: AvatarType; + variant?: EntityChipVariant; }; +export enum EntityChipVariant { + Regular = 'regular', + Transparent = 'transparent', +} + export function EntityChip({ linkToEntity, entityId, name, pictureUrl, avatarType = 'rounded', + variant = EntityChipVariant.Regular, }: OwnProps) { const navigate = useNavigate(); @@ -35,7 +42,13 @@ export function EntityChip({
= { title: 'UI/Chip/Chip', @@ -18,13 +18,15 @@ export const Default: Story = { label: 'Chip test', size: ChipSize.Small, variant: ChipVariant.Highlighted, + accent: ChipAccent.TextPrimary, + disabled: false, clickable: true, maxWidth: '200px', }, decorators: [ComponentDecorator], }; -export const All: Story = { +export const Catalog: Story = { args: { size: ChipSize.Large, clickable: true, label: 'Hello' }, argTypes: { size: { control: false }, @@ -42,6 +44,7 @@ export const All: Story = { ChipVariant.Transparent, ], sizes: [ChipSize.Small, ChipSize.Large], + accents: [ChipAccent.TextPrimary, ChipAccent.TextSecondary], states: ['default', 'hover', 'active', 'disabled'], }, decorators: [ExhaustiveComponentDecorator], diff --git a/front/src/modules/ui/layout/components/SubMenuTopBarContainer.tsx b/front/src/modules/ui/layout/components/SubMenuTopBarContainer.tsx index 6056604a0..37ebfb2d5 100644 --- a/front/src/modules/ui/layout/components/SubMenuTopBarContainer.tsx +++ b/front/src/modules/ui/layout/components/SubMenuTopBarContainer.tsx @@ -1,20 +1,29 @@ import styled from '@emotion/styled'; +import { useIsMobile } from '../../hooks/useIsMobile'; +import { TopBar } from '../top-bar/components/TopBar'; + import { RightDrawerContainer } from './RightDrawerContainer'; type OwnProps = { children: JSX.Element | JSX.Element[]; + title: string; + icon: React.ReactNode; }; -const StyledContainer = styled.div` +const StyledContainer = styled.div<{ isMobile: boolean }>` display: flex; - padding-top: ${({ theme }) => theme.spacing(4)}; + flex-direction: column; + padding-top: ${({ theme, isMobile }) => (!isMobile ? theme.spacing(4) : 0)}; width: 100%; `; -export function SubMenuTopBarContainer({ children }: OwnProps) { +export function SubMenuTopBarContainer({ children, title, icon }: OwnProps) { + const isMobile = useIsMobile(); + return ( - + + {isMobile && } {children} ); diff --git a/front/src/modules/ui/layout/top-bar/components/TopBar.tsx b/front/src/modules/ui/layout/top-bar/components/TopBar.tsx index 194b65c45..c5210b4f4 100644 --- a/front/src/modules/ui/layout/top-bar/components/TopBar.tsx +++ b/front/src/modules/ui/layout/top-bar/components/TopBar.tsx @@ -74,11 +74,8 @@ export function TopBar({ const navigate = useNavigate(); const navigateBack = useCallback(() => navigate(-1), [navigate]); - const isMobile = useIsMobile(); const isNavbarOpened = useRecoilValue(isNavbarOpenedState); - const showNavCollapseButton = isMobile || !isNavbarOpened; - const iconSize = useIsMobile() ? navbarIconSize.mobile : navbarIconSize.desktop; @@ -87,7 +84,7 @@ export function TopBar({ <> - {showNavCollapseButton && ( + {!isNavbarOpened && ( diff --git a/front/src/modules/ui/link/components/RawLink.tsx b/front/src/modules/ui/link/components/RawLink.tsx index e9be8d2f9..6d0d7024e 100644 --- a/front/src/modules/ui/link/components/RawLink.tsx +++ b/front/src/modules/ui/link/components/RawLink.tsx @@ -11,6 +11,8 @@ type OwnProps = { const StyledClickable = styled.div` display: flex; + overflow: hidden; + white-space: nowrap; a { color: inherit; diff --git a/front/src/modules/ui/navbar/components/SubMenuNavbar.tsx b/front/src/modules/ui/navbar/components/SubMenuNavbar.tsx index 2e2b14e1c..c556566bd 100644 --- a/front/src/modules/ui/navbar/components/SubMenuNavbar.tsx +++ b/front/src/modules/ui/navbar/components/SubMenuNavbar.tsx @@ -15,8 +15,8 @@ type OwnProps = { const StyledContainer = styled.div` display: flex; flex-direction: column; - padding-top: ${({ theme }) => theme.spacing(2)}; - width: ${({ theme }) => (useIsMobile() ? '100%' : leftNavbarWidth.desktop)}; + padding-top: ${({ theme }) => theme.spacing(9)}; + width: ${() => (useIsMobile() ? '100%' : leftNavbarWidth.desktop)}; `; export default function SubMenuNavbar({ children, backButtonTitle }: OwnProps) { diff --git a/front/src/modules/ui/right-drawer/components/RightDrawer.tsx b/front/src/modules/ui/right-drawer/components/RightDrawer.tsx index d9e4c82c4..ce1bcab50 100644 --- a/front/src/modules/ui/right-drawer/components/RightDrawer.tsx +++ b/front/src/modules/ui/right-drawer/components/RightDrawer.tsx @@ -82,8 +82,6 @@ export function RightDrawer() { : theme.rightDrawerWidth : '0'; - console.log(rightDrawerWidth); - if (!isDefined(rightDrawerPage)) { return <>; } diff --git a/front/src/modules/users/components/UserChip.tsx b/front/src/modules/users/components/UserChip.tsx new file mode 100644 index 000000000..6113619d0 --- /dev/null +++ b/front/src/modules/users/components/UserChip.tsx @@ -0,0 +1,19 @@ +import { EntityChip, EntityChipVariant } from '@/ui/chip/components/EntityChip'; + +export type UserChipPropsType = { + id: string; + name: string; + pictureUrl?: string; + variant?: EntityChipVariant; +}; + +export function UserChip({ id, name, pictureUrl, variant }: UserChipPropsType) { + return ( + + ); +} diff --git a/front/src/pages/people/People.tsx b/front/src/pages/people/People.tsx index 09c1fea7a..2cf805317 100644 --- a/front/src/pages/people/People.tsx +++ b/front/src/pages/people/People.tsx @@ -24,7 +24,10 @@ export function People() { async function handleAddButtonClick() { await insertOnePerson({ variables: { - data: {}, + data: { + firstName: '', + lastName: '', + }, }, refetchQueries: [getOperationName(GET_PEOPLE) ?? ''], }); diff --git a/front/src/pages/settings/SettingsExperience.tsx b/front/src/pages/settings/SettingsExperience.tsx index f58258a57..83b42b0ad 100644 --- a/front/src/pages/settings/SettingsExperience.tsx +++ b/front/src/pages/settings/SettingsExperience.tsx @@ -1,6 +1,7 @@ import styled from '@emotion/styled'; import { ColorSchemePicker } from '@/ui/color-scheme/components/ColorSchemePicker'; +import { IconSettings } from '@/ui/icon'; import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer'; import { useColorScheme } from '@/ui/themes/hooks/useColorScheme'; import { MainSectionTitle } from '@/ui/title/components/MainSectionTitle'; @@ -27,7 +28,7 @@ export function SettingsExperience() { const { colorScheme, setColorScheme } = useColorScheme(); return ( - + } title="Settings">
Experience diff --git a/front/src/pages/settings/SettingsProfile.tsx b/front/src/pages/settings/SettingsProfile.tsx index 8335d450a..f7b351345 100644 --- a/front/src/pages/settings/SettingsProfile.tsx +++ b/front/src/pages/settings/SettingsProfile.tsx @@ -3,6 +3,7 @@ import styled from '@emotion/styled'; import { EmailField } from '@/settings/profile/components/EmailField'; import { NameFields } from '@/settings/profile/components/NameFields'; import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader'; +import { IconSettings } from '@/ui/icon'; import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer'; import { MainSectionTitle } from '@/ui/title/components/MainSectionTitle'; import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle'; @@ -26,8 +27,8 @@ const StyledSectionContainer = styled.div` export function SettingsProfile() { return ( - -
+ } title="Settings"> + <> Profile @@ -49,7 +50,7 @@ export function SettingsProfile() { -
+
); } diff --git a/front/src/pages/settings/SettingsWorkspace.tsx b/front/src/pages/settings/SettingsWorkspace.tsx index ca8c3a995..10c6f6d64 100644 --- a/front/src/pages/settings/SettingsWorkspace.tsx +++ b/front/src/pages/settings/SettingsWorkspace.tsx @@ -2,6 +2,7 @@ import styled from '@emotion/styled'; import { NameField } from '@/settings/workspace/components/NameField'; import { WorkspaceLogoUploader } from '@/settings/workspace/components/WorkspaceLogoUploader'; +import { IconSettings } from '@/ui/icon'; import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer'; import { MainSectionTitle } from '@/ui/title/components/MainSectionTitle'; import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle'; @@ -24,7 +25,7 @@ const StyledSectionContainer = styled.div` export function SettingsWorksapce() { return ( - + } title="Settings">
General diff --git a/front/src/pages/settings/SettingsWorkspaceMembers.tsx b/front/src/pages/settings/SettingsWorkspaceMembers.tsx index 24ac47196..dbb82002a 100644 --- a/front/src/pages/settings/SettingsWorkspaceMembers.tsx +++ b/front/src/pages/settings/SettingsWorkspaceMembers.tsx @@ -4,7 +4,7 @@ import { useRecoilState } from 'recoil'; import { currentUserState } from '@/auth/states/currentUserState'; import { Button } from '@/ui/button/components/Button'; -import { IconTrash } from '@/ui/icon'; +import { IconSettings, IconTrash } from '@/ui/icon'; import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer'; import { MainSectionTitle } from '@/ui/title/components/MainSectionTitle'; import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle'; @@ -75,7 +75,7 @@ export function SettingsWorkspaceMembers() { }; return ( - + } title="Settings"> Members {workspace?.inviteHash && ( diff --git a/front/src/testing/decorators/ExhaustiveComponentDecorator.tsx b/front/src/testing/decorators/ExhaustiveComponentDecorator.tsx index f1dcca195..014daf4ff 100644 --- a/front/src/testing/decorators/ExhaustiveComponentDecorator.tsx +++ b/front/src/testing/decorators/ExhaustiveComponentDecorator.tsx @@ -1,5 +1,5 @@ import styled from '@emotion/styled'; -import { Decorator, StrictArgs } from '@storybook/react'; +import { Decorator } from '@storybook/react'; function stateProps(state: string) { switch (state) { @@ -22,11 +22,20 @@ const StyledSizeTitle = styled.h1` margin: ${({ theme }) => theme.spacing(2)}; `; -const StyledVariantTitle = styled.h1` +const StyledVariantTitle = styled.h2` + color: ${({ theme }) => theme.font.color.secondary}; + font-size: ${({ theme }) => theme.font.size.md}; + font-weight: ${({ theme }) => theme.font.weight.semiBold}; + margin: ${({ theme }) => theme.spacing(2)}; + width: 100px; +`; + +const StyledAccentTitle = styled.h3` color: ${({ theme }) => theme.font.color.tertiary}; font-size: ${({ theme }) => theme.font.size.md}; font-weight: ${({ theme }) => theme.font.weight.semiBold}; margin: ${({ theme }) => theme.spacing(2)}; + width: 100px; `; const StyledStateTitle = styled.span` @@ -49,62 +58,58 @@ const StyledSizeContainer = styled.div` padding: ${({ theme }) => theme.spacing(2)}; `; -const StyledLineContainer = styled.div` +const StyledVariantContainer = styled.div` + display: flex; + flex-direction: column; + gap: ${({ theme }) => theme.spacing(2)}; +`; + +const StyledAccentContainer = styled.div` display: flex; flex: 1; flex-direction: row; gap: ${({ theme }) => theme.spacing(2)}; `; -const StyledComponentContainer = styled.div` +const StyledStateContainer = styled.div` align-items: center; display: flex; flex-direction: column; padding: ${({ theme }) => theme.spacing(2)}; `; -function renderSize( - size: string, - variants: string[], - states: string[], - args: StrictArgs, - Story: React.FC, -) { - return ( - - {size} - {variants.map((variant) => ( -
- {variant} - - {states.map((state) => ( - - {state} - - - ))} - -
- ))} -
- ); -} - export const ExhaustiveComponentDecorator: Decorator = (Story, context) => { const parameters = context.parameters; return ( - {parameters.sizes.map((size: string) => - renderSize( - size, - parameters.variants, - parameters.states, - context.args, - Story, - ), - )} + {parameters.sizes.map((size: string) => ( + + {size} + {parameters.variants.map((variant: string) => ( + + {variant} + {parameters.accents.map((accent: string) => ( + + {accent} + {parameters.states.map((state: string) => ( + + {state} + + + ))} + + ))} + + ))} + + ))} ); };