mirror of
				https://github.com/lingble/twenty.git
				synced 2025-10-30 20:27:55 +00:00 
			
		
		
		
	8172 update the right drawer action menu to open with command o (#8375)
Closes #8172 - Added a shortcut property to the button component - Displays the actions inside a dropdown - The dropdown is toggled either by clicking on the button or with the `command + O` shortcut https://github.com/user-attachments/assets/4c4c88fa-85dc-404e-bb42-f2b0d57c8960
This commit is contained in:
		| @@ -1,56 +0,0 @@ | |||||||
| import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; |  | ||||||
| import { useTheme } from '@emotion/react'; |  | ||||||
| import styled from '@emotion/styled'; |  | ||||||
| import { MOBILE_VIEWPORT, MenuItemAccent } from 'twenty-ui'; |  | ||||||
|  |  | ||||||
| type RecordShowActionMenuBarEntryProps = { |  | ||||||
|   entry: ActionMenuEntry; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| const StyledButton = styled.div<{ accent: MenuItemAccent }>` |  | ||||||
|   border-radius: ${({ theme }) => theme.border.radius.sm}; |  | ||||||
|   color: ${(props) => |  | ||||||
|     props.accent === 'danger' |  | ||||||
|       ? props.theme.color.red |  | ||||||
|       : props.theme.font.color.secondary}; |  | ||||||
|   cursor: pointer; |  | ||||||
|   display: flex; |  | ||||||
|   justify-content: center; |  | ||||||
|  |  | ||||||
|   padding: ${({ theme }) => theme.spacing(2)}; |  | ||||||
|   transition: background 0.1s ease; |  | ||||||
|   user-select: none; |  | ||||||
|  |  | ||||||
|   &:hover { |  | ||||||
|     background: ${({ theme, accent }) => |  | ||||||
|       accent === 'danger' |  | ||||||
|         ? theme.background.danger |  | ||||||
|         : theme.background.transparent.light}; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @media (max-width: ${MOBILE_VIEWPORT}px) { |  | ||||||
|     padding: ${({ theme }) => theme.spacing(1)}; |  | ||||||
|   } |  | ||||||
| `; |  | ||||||
|  |  | ||||||
| const StyledButtonLabel = styled.div` |  | ||||||
|   font-weight: ${({ theme }) => theme.font.weight.medium}; |  | ||||||
|   margin-left: ${({ theme }) => theme.spacing(1)}; |  | ||||||
| `; |  | ||||||
|  |  | ||||||
| // For now, this component is the same as RecordIndexActionMenuBarEntry but they |  | ||||||
| // will probably diverge in the future |  | ||||||
| export const RecordShowActionMenuBarEntry = ({ |  | ||||||
|   entry, |  | ||||||
| }: RecordShowActionMenuBarEntryProps) => { |  | ||||||
|   const theme = useTheme(); |  | ||||||
|   return ( |  | ||||||
|     <StyledButton |  | ||||||
|       accent={entry.accent ?? 'default'} |  | ||||||
|       onClick={() => entry.onClick?.()} |  | ||||||
|     > |  | ||||||
|       {entry.Icon && <entry.Icon size={theme.icon.size.md} />} |  | ||||||
|       <StyledButtonLabel>{entry.label}</StyledButtonLabel> |  | ||||||
|     </StyledButton> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| import { GlobalActionMenuEntriesSetter } from '@/action-menu/actions/global-actions/components/GlobalActionMenuEntriesSetter'; | import { GlobalActionMenuEntriesSetter } from '@/action-menu/actions/global-actions/components/GlobalActionMenuEntriesSetter'; | ||||||
| import { RecordActionMenuEntriesSetter } from '@/action-menu/actions/record-actions/components/RecordActionMenuEntriesSetter'; | import { RecordActionMenuEntriesSetter } from '@/action-menu/actions/record-actions/components/RecordActionMenuEntriesSetter'; | ||||||
| import { ActionMenuConfirmationModals } from '@/action-menu/components/ActionMenuConfirmationModals'; | import { ActionMenuConfirmationModals } from '@/action-menu/components/ActionMenuConfirmationModals'; | ||||||
| import { RecordShowRightDrawerActionMenuBar } from '@/action-menu/components/RecordShowRightDrawerActionMenuBar'; | import { RightDrawerActionMenuDropdown } from '@/action-menu/components/RightDrawerActionMenuDropdown'; | ||||||
| import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; | import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext'; | ||||||
|  |  | ||||||
| import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState'; | import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState'; | ||||||
| @@ -21,7 +21,7 @@ export const RecordShowRightDrawerActionMenu = () => { | |||||||
|             onActionExecutedCallback: () => {}, |             onActionExecutedCallback: () => {}, | ||||||
|           }} |           }} | ||||||
|         > |         > | ||||||
|           <RecordShowRightDrawerActionMenuBar /> |           <RightDrawerActionMenuDropdown /> | ||||||
|           <ActionMenuConfirmationModals /> |           <ActionMenuConfirmationModals /> | ||||||
|           <RecordActionMenuEntriesSetter /> |           <RecordActionMenuEntriesSetter /> | ||||||
|           <GlobalActionMenuEntriesSetter /> |           <GlobalActionMenuEntriesSetter /> | ||||||
|   | |||||||
| @@ -1,21 +0,0 @@ | |||||||
| import { RecordShowActionMenuBarEntry } from '@/action-menu/components/RecordShowActionMenuBarEntry'; |  | ||||||
| import { actionMenuEntriesComponentSelector } from '@/action-menu/states/actionMenuEntriesComponentSelector'; |  | ||||||
| import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; |  | ||||||
|  |  | ||||||
| export const RecordShowRightDrawerActionMenuBar = () => { |  | ||||||
|   const actionMenuEntries = useRecoilComponentValueV2( |  | ||||||
|     actionMenuEntriesComponentSelector, |  | ||||||
|   ); |  | ||||||
|  |  | ||||||
|   const standardActionMenuEntries = actionMenuEntries.filter( |  | ||||||
|     (actionMenuEntry) => actionMenuEntry.type === 'standard', |  | ||||||
|   ); |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <> |  | ||||||
|       {standardActionMenuEntries.map((actionMenuEntry) => ( |  | ||||||
|         <RecordShowActionMenuBarEntry entry={actionMenuEntry} /> |  | ||||||
|       ))} |  | ||||||
|     </> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
| @@ -0,0 +1,87 @@ | |||||||
|  | import { actionMenuEntriesComponentSelector } from '@/action-menu/states/actionMenuEntriesComponentSelector'; | ||||||
|  | import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext'; | ||||||
|  | import { RightDrawerActionMenuDropdownHotkeyScope } from '@/action-menu/types/RightDrawerActionMenuDropdownHotkeyScope'; | ||||||
|  | import { getRightDrawerActionMenuDropdownIdFromActionMenuId } from '@/action-menu/utils/getRightDrawerActionMenuDropdownIdFromActionMenuId'; | ||||||
|  | import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; | ||||||
|  | import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; | ||||||
|  | import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2'; | ||||||
|  | import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope'; | ||||||
|  | import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; | ||||||
|  | import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; | ||||||
|  | import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; | ||||||
|  | import { useTheme } from '@emotion/react'; | ||||||
|  | import { Key } from 'ts-key-enum'; | ||||||
|  | import { Button, MenuItem } from 'twenty-ui'; | ||||||
|  |  | ||||||
|  | export const RightDrawerActionMenuDropdown = () => { | ||||||
|  |   const actionMenuEntries = useRecoilComponentValueV2( | ||||||
|  |     actionMenuEntriesComponentSelector, | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   const actionMenuId = useAvailableComponentInstanceIdOrThrow( | ||||||
|  |     ActionMenuComponentInstanceContext, | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   const { closeDropdown, openDropdown } = useDropdownV2(); | ||||||
|  |  | ||||||
|  |   const theme = useTheme(); | ||||||
|  |  | ||||||
|  |   useScopedHotkeys( | ||||||
|  |     [Key.Escape, 'ctrl+o,meta+o'], | ||||||
|  |     () => { | ||||||
|  |       closeDropdown( | ||||||
|  |         getRightDrawerActionMenuDropdownIdFromActionMenuId(actionMenuId), | ||||||
|  |       ); | ||||||
|  |     }, | ||||||
|  |     RightDrawerActionMenuDropdownHotkeyScope.RightDrawerActionMenuDropdown, | ||||||
|  |     [closeDropdown], | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   useScopedHotkeys( | ||||||
|  |     ['ctrl+o,meta+o'], | ||||||
|  |     () => { | ||||||
|  |       openDropdown( | ||||||
|  |         getRightDrawerActionMenuDropdownIdFromActionMenuId(actionMenuId), | ||||||
|  |       ); | ||||||
|  |     }, | ||||||
|  |     RightDrawerHotkeyScope.RightDrawer, | ||||||
|  |     [openDropdown], | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <Dropdown | ||||||
|  |       dropdownId={getRightDrawerActionMenuDropdownIdFromActionMenuId( | ||||||
|  |         actionMenuId, | ||||||
|  |       )} | ||||||
|  |       dropdownHotkeyScope={{ | ||||||
|  |         scope: | ||||||
|  |           RightDrawerActionMenuDropdownHotkeyScope.RightDrawerActionMenuDropdown, | ||||||
|  |       }} | ||||||
|  |       data-select-disable | ||||||
|  |       clickableComponent={<Button title="Actions" shortcut="⌘O" />} | ||||||
|  |       dropdownPlacement="top-end" | ||||||
|  |       dropdownOffset={{ | ||||||
|  |         y: parseInt(theme.spacing(2)), | ||||||
|  |       }} | ||||||
|  |       dropdownComponents={ | ||||||
|  |         <DropdownMenuItemsContainer> | ||||||
|  |           {actionMenuEntries.map((item, index) => ( | ||||||
|  |             <MenuItem | ||||||
|  |               key={index} | ||||||
|  |               LeftIcon={item.Icon} | ||||||
|  |               onClick={() => { | ||||||
|  |                 closeDropdown( | ||||||
|  |                   getRightDrawerActionMenuDropdownIdFromActionMenuId( | ||||||
|  |                     actionMenuId, | ||||||
|  |                   ), | ||||||
|  |                 ); | ||||||
|  |                 item.onClick?.(); | ||||||
|  |               }} | ||||||
|  |               text={item.label} | ||||||
|  |             /> | ||||||
|  |           ))} | ||||||
|  |         </DropdownMenuItemsContainer> | ||||||
|  |       } | ||||||
|  |     /> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
| @@ -2,7 +2,7 @@ import { expect, jest } from '@storybook/jest'; | |||||||
| import { Meta, StoryObj } from '@storybook/react'; | import { Meta, StoryObj } from '@storybook/react'; | ||||||
| import { RecoilRoot } from 'recoil'; | import { RecoilRoot } from 'recoil'; | ||||||
|  |  | ||||||
| import { RecordShowRightDrawerActionMenuBar } from '@/action-menu/components/RecordShowRightDrawerActionMenuBar'; | import { RightDrawerActionMenuDropdown } from '@/action-menu/components/RightDrawerActionMenuDropdown'; | ||||||
| import { actionMenuEntriesComponentState } from '@/action-menu/states/actionMenuEntriesComponentState'; | import { actionMenuEntriesComponentState } from '@/action-menu/states/actionMenuEntriesComponentState'; | ||||||
| import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext'; | import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext'; | ||||||
| import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; | import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry'; | ||||||
| @@ -21,9 +21,9 @@ const deleteMock = jest.fn(); | |||||||
| const addToFavoritesMock = jest.fn(); | const addToFavoritesMock = jest.fn(); | ||||||
| const exportMock = jest.fn(); | const exportMock = jest.fn(); | ||||||
|  |  | ||||||
| const meta: Meta<typeof RecordShowRightDrawerActionMenuBar> = { | const meta: Meta<typeof RightDrawerActionMenuDropdown> = { | ||||||
|   title: 'Modules/ActionMenu/RecordShowRightDrawerActionMenuBar', |   title: 'Modules/ActionMenu/RightDrawerActionMenuDropdown', | ||||||
|   component: RecordShowRightDrawerActionMenuBar, |   component: RightDrawerActionMenuDropdown, | ||||||
|   decorators: [ |   decorators: [ | ||||||
|     (Story) => ( |     (Story) => ( | ||||||
|       <RecoilRoot |       <RecoilRoot | ||||||
| @@ -98,7 +98,7 @@ const meta: Meta<typeof RecordShowRightDrawerActionMenuBar> = { | |||||||
|  |  | ||||||
| export default meta; | export default meta; | ||||||
|  |  | ||||||
| type Story = StoryObj<typeof RecordShowRightDrawerActionMenuBar>; | type Story = StoryObj<typeof RightDrawerActionMenuDropdown>; | ||||||
|  |  | ||||||
| export const Default: Story = { | export const Default: Story = { | ||||||
|   args: { |   args: { | ||||||
| @@ -113,12 +113,21 @@ export const WithButtonClicks: Story = { | |||||||
|   play: async ({ canvasElement }) => { |   play: async ({ canvasElement }) => { | ||||||
|     const canvas = within(canvasElement); |     const canvas = within(canvasElement); | ||||||
|  |  | ||||||
|  |     let actionButton = await canvas.findByText('Actions'); | ||||||
|  |     await userEvent.click(actionButton); | ||||||
|  |  | ||||||
|     const deleteButton = await canvas.findByText('Delete'); |     const deleteButton = await canvas.findByText('Delete'); | ||||||
|     await userEvent.click(deleteButton); |     await userEvent.click(deleteButton); | ||||||
|  |  | ||||||
|  |     actionButton = await canvas.findByText('Actions'); | ||||||
|  |     await userEvent.click(actionButton); | ||||||
|  |  | ||||||
|     const addToFavoritesButton = await canvas.findByText('Add to favorites'); |     const addToFavoritesButton = await canvas.findByText('Add to favorites'); | ||||||
|     await userEvent.click(addToFavoritesButton); |     await userEvent.click(addToFavoritesButton); | ||||||
|  |  | ||||||
|  |     actionButton = await canvas.findByText('Actions'); | ||||||
|  |     await userEvent.click(actionButton); | ||||||
|  |  | ||||||
|     const exportButton = await canvas.findByText('Export'); |     const exportButton = await canvas.findByText('Export'); | ||||||
|     await userEvent.click(exportButton); |     await userEvent.click(exportButton); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | export enum RightDrawerActionMenuDropdownHotkeyScope { | ||||||
|  |   RightDrawerActionMenuDropdown = 'right-drawer-action-menu-dropdown', | ||||||
|  | } | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | import { getRightDrawerActionMenuDropdownIdFromActionMenuId } from '../getRightDrawerActionMenuDropdownIdFromActionMenuId'; | ||||||
|  |  | ||||||
|  | describe('getRightDrawerActionMenuDropdownIdFromActionMenuId', () => { | ||||||
|  |   it('should return the right drawer action menu dropdown id', () => { | ||||||
|  |     expect( | ||||||
|  |       getRightDrawerActionMenuDropdownIdFromActionMenuId('action-menu-id'), | ||||||
|  |     ).toBe('right-drawer-action-menu-dropdown-action-menu-id'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @@ -0,0 +1,5 @@ | |||||||
|  | export const getRightDrawerActionMenuDropdownIdFromActionMenuId = ( | ||||||
|  |   actionMenuId: string, | ||||||
|  | ) => { | ||||||
|  |   return `right-drawer-action-menu-dropdown-${actionMenuId}`; | ||||||
|  | }; | ||||||
| @@ -350,6 +350,10 @@ export const RichTextEditor = ({ | |||||||
|       editor.focus(); |       editor.focus(); | ||||||
|     }, |     }, | ||||||
|     RightDrawerHotkeyScope.RightDrawer, |     RightDrawerHotkeyScope.RightDrawer, | ||||||
|  |     [], | ||||||
|  |     { | ||||||
|  |       preventDefault: false, | ||||||
|  |     }, | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|   const handleBlockEditorFocus = () => { |   const handleBlockEditorFocus = () => { | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ export type ButtonProps = { | |||||||
|   to?: string; |   to?: string; | ||||||
|   target?: string; |   target?: string; | ||||||
|   dataTestId?: string; |   dataTestId?: string; | ||||||
|  |   shortcut?: string; | ||||||
| } & React.ComponentProps<'button'>; | } & React.ComponentProps<'button'>; | ||||||
|  |  | ||||||
| const StyledButton = styled('button', { | const StyledButton = styled('button', { | ||||||
| @@ -358,6 +359,19 @@ const StyledSoonPill = styled(Pill)` | |||||||
|   margin-left: auto; |   margin-left: auto; | ||||||
| `; | `; | ||||||
|  |  | ||||||
|  | const StyledShortcutLabel = styled.div` | ||||||
|  |   color: ${({ theme }) => theme.font.color.light}; | ||||||
|  |   font-weight: ${({ theme }) => theme.font.weight.medium}; | ||||||
|  | `; | ||||||
|  |  | ||||||
|  | const StyledSeparator = styled.div<{ buttonSize: ButtonSize }>` | ||||||
|  |   background: ${({ theme }) => theme.border.color.light}; | ||||||
|  |   height: ${({ theme, buttonSize }) => | ||||||
|  |     theme.spacing(buttonSize === 'small' ? 3 : 4)}; | ||||||
|  |   margin: 0 ${({ theme }) => theme.spacing(1)}; | ||||||
|  |   width: 1px; | ||||||
|  | `; | ||||||
|  |  | ||||||
| export const Button = ({ | export const Button = ({ | ||||||
|   className, |   className, | ||||||
|   Icon, |   Icon, | ||||||
| @@ -376,6 +390,7 @@ export const Button = ({ | |||||||
|   to, |   to, | ||||||
|   target, |   target, | ||||||
|   dataTestId, |   dataTestId, | ||||||
|  |   shortcut, | ||||||
| }: ButtonProps) => { | }: ButtonProps) => { | ||||||
|   const theme = useTheme(); |   const theme = useTheme(); | ||||||
|  |  | ||||||
| @@ -399,6 +414,12 @@ export const Button = ({ | |||||||
|     > |     > | ||||||
|       {Icon && <Icon size={theme.icon.size.sm} />} |       {Icon && <Icon size={theme.icon.size.sm} />} | ||||||
|       {title} |       {title} | ||||||
|  |       {shortcut && ( | ||||||
|  |         <> | ||||||
|  |           <StyledSeparator buttonSize={size} /> | ||||||
|  |           <StyledShortcutLabel>{shortcut}</StyledShortcutLabel> | ||||||
|  |         </> | ||||||
|  |       )} | ||||||
|       {soon && <StyledSoonPill label="Soon" />} |       {soon && <StyledSoonPill label="Soon" />} | ||||||
|     </StyledButton> |     </StyledButton> | ||||||
|   ); |   ); | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ type Story = StoryObj<typeof Button>; | |||||||
|  |  | ||||||
| export const Default: Story = { | export const Default: Story = { | ||||||
|   argTypes: { |   argTypes: { | ||||||
|  |     shortcut: { control: false }, | ||||||
|     Icon: { control: false }, |     Icon: { control: false }, | ||||||
|   }, |   }, | ||||||
|   args: { |   args: { | ||||||
| @@ -54,6 +55,7 @@ export const Catalog: CatalogStory<Story, typeof Button> = { | |||||||
|     soon: { control: false }, |     soon: { control: false }, | ||||||
|     position: { control: false }, |     position: { control: false }, | ||||||
|     className: { control: false }, |     className: { control: false }, | ||||||
|  |     shortcut: { control: false }, | ||||||
|   }, |   }, | ||||||
|   parameters: { |   parameters: { | ||||||
|     pseudo: { hover: ['.hover'], active: ['.pressed'], focus: ['.focus'] }, |     pseudo: { hover: ['.hover'], active: ['.pressed'], focus: ['.focus'] }, | ||||||
| @@ -126,6 +128,7 @@ export const SoonCatalog: CatalogStory<Story, typeof Button> = { | |||||||
|     soon: { control: false }, |     soon: { control: false }, | ||||||
|     position: { control: false }, |     position: { control: false }, | ||||||
|     className: { control: false }, |     className: { control: false }, | ||||||
|  |     shortcut: { control: false }, | ||||||
|   }, |   }, | ||||||
|   parameters: { |   parameters: { | ||||||
|     pseudo: { hover: ['.hover'], active: ['.pressed'], focus: ['.focus'] }, |     pseudo: { hover: ['.hover'], active: ['.pressed'], focus: ['.focus'] }, | ||||||
| @@ -197,6 +200,7 @@ export const PositionCatalog: CatalogStory<Story, typeof Button> = { | |||||||
|     fullWidth: { control: false }, |     fullWidth: { control: false }, | ||||||
|     soon: { control: false }, |     soon: { control: false }, | ||||||
|     position: { control: false }, |     position: { control: false }, | ||||||
|  |     shortcut: { control: false }, | ||||||
|   }, |   }, | ||||||
|   parameters: { |   parameters: { | ||||||
|     pseudo: { hover: ['.hover'], active: ['.pressed'], focus: ['.focus'] }, |     pseudo: { hover: ['.hover'], active: ['.pressed'], focus: ['.focus'] }, | ||||||
| @@ -262,6 +266,34 @@ export const PositionCatalog: CatalogStory<Story, typeof Button> = { | |||||||
|   decorators: [CatalogDecorator], |   decorators: [CatalogDecorator], | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | export const ShortcutCatalog: CatalogStory<Story, typeof Button> = { | ||||||
|  |   args: { title: 'Actions', shortcut: '⌘O' }, | ||||||
|  |   argTypes: { | ||||||
|  |     size: { control: false }, | ||||||
|  |     variant: { control: false }, | ||||||
|  |     accent: { control: false }, | ||||||
|  |     disabled: { control: false }, | ||||||
|  |     focus: { control: false }, | ||||||
|  |     fullWidth: { control: false }, | ||||||
|  |     soon: { control: false }, | ||||||
|  |     position: { control: false }, | ||||||
|  |     shortcut: { control: false }, | ||||||
|  |   }, | ||||||
|  |   parameters: { | ||||||
|  |     pseudo: { hover: ['.hover'], active: ['.pressed'], focus: ['.focus'] }, | ||||||
|  |     catalog: { | ||||||
|  |       dimensions: [ | ||||||
|  |         { | ||||||
|  |           name: 'sizes', | ||||||
|  |           values: ['small', 'medium'] satisfies ButtonSize[], | ||||||
|  |           props: (size: ButtonSize) => ({ size }), | ||||||
|  |         }, | ||||||
|  |       ], | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   decorators: [CatalogDecorator], | ||||||
|  | }; | ||||||
|  |  | ||||||
| export const FullWidth: Story = { | export const FullWidth: Story = { | ||||||
|   args: { title: 'Filter', Icon: IconSearch, fullWidth: true }, |   args: { title: 'Filter', Icon: IconSearch, fullWidth: true }, | ||||||
|   argTypes: { |   argTypes: { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Raphaël Bosi
					Raphaël Bosi