From 301b0443d64410c14fbeeec4905c09a945f8a2c4 Mon Sep 17 00:00:00 2001 From: Susanna Nevalainen Date: Mon, 4 Aug 2025 09:31:19 +0200 Subject: [PATCH 01/36] feat(components): code component connected in Figma --- packages/components/figma/Code.figma.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 packages/components/figma/Code.figma.tsx diff --git a/packages/components/figma/Code.figma.tsx b/packages/components/figma/Code.figma.tsx new file mode 100644 index 000000000..ec5af4ecd --- /dev/null +++ b/packages/components/figma/Code.figma.tsx @@ -0,0 +1,14 @@ +import figma from '@figma/code-connect'; + +import { Code } from '../src'; + +figma.connect( + Code, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=2308-667', + { + props: { + children: figma.string('Inline text'), + }, + example: ({ children }) => {children}, + }, +); From 792df7d42085b9295709dd3214b9ec83dddb8d73 Mon Sep 17 00:00:00 2001 From: Susanna Nevalainen Date: Mon, 4 Aug 2025 09:49:54 +0200 Subject: [PATCH 02/36] feat(components): code component figma preview in storybook and default state bugfix --- packages/components/src/Code.tsx | 18 ++++++++++-------- packages/components/src/styles/Code.module.css | 6 ++---- packages/components/stories/Button.stories.tsx | 4 ++++ packages/components/stories/Code.stories.tsx | 4 ++++ 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/packages/components/src/Code.tsx b/packages/components/src/Code.tsx index d0a30bb73..2f6c92c3d 100644 --- a/packages/components/src/Code.tsx +++ b/packages/components/src/Code.tsx @@ -3,7 +3,7 @@ import { forwardRef } from 'react'; import styles from './styles/Code.module.css'; -const codeStyles = cva(styles.default, { +const codeStyles = cva(styles.code, { variants: { size: { small: styles.small, @@ -28,13 +28,15 @@ export interface CodeProps extends Omit, 'clas * * For body text, use `Text`. For headings, use `Heading`. For labels, use `Label`. */ -const Code = forwardRef(({ children, size, className, ...props }, ref) => { - return ( - - {children} - - ); -}); +const Code = forwardRef( + ({ children, size = 'small', className, ...props }, ref) => { + return ( + + {children} + + ); + }, +); Code.displayName = 'Code'; diff --git a/packages/components/src/styles/Code.module.css b/packages/components/src/styles/Code.module.css index 7c32c2910..647c49402 100644 --- a/packages/components/src/styles/Code.module.css +++ b/packages/components/src/styles/Code.module.css @@ -5,10 +5,8 @@ color: var(--lp-color-text-code-string); width: fit-content; background-color: var(--lp-color-bg-ui-tertiary); - padding-top: var(--lp-spacing-100); - padding-bottom: var(--lp-spacing-100); - padding-left: var(--lp-spacing-200); - padding-right: var(--lp-spacing-200); + padding: var(--lp-spacing-100) var(--lp-spacing-200); + display: flex; border: none; outline: none; } diff --git a/packages/components/stories/Button.stories.tsx b/packages/components/stories/Button.stories.tsx index 0632d08c9..10942bd1e 100644 --- a/packages/components/stories/Button.stories.tsx +++ b/packages/components/stories/Button.stories.tsx @@ -16,6 +16,10 @@ const meta: Meta = { test: { dangerouslyIgnoreUnhandledErrors: true, }, + design: { + type: 'figma', + url: 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/LaunchPad?node-id=1-27006', + }, }, decorators: [ (Story) => ( diff --git a/packages/components/stories/Code.stories.tsx b/packages/components/stories/Code.stories.tsx index 415abff5c..beee9b442 100644 --- a/packages/components/stories/Code.stories.tsx +++ b/packages/components/stories/Code.stories.tsx @@ -15,6 +15,10 @@ For body text, use [Text](/docs/components-content-text--docs ). For headings, u `, }, }, + design: { + type: 'figma', + url: 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=2308-667', + }, }, argTypes: { children: { From cb2ad205f780f00b5f1948e8806f6f3f6234626f Mon Sep 17 00:00:00 2001 From: Susanna Nevalainen Date: Mon, 4 Aug 2025 10:06:52 +0200 Subject: [PATCH 03/36] feat(componenents): deprecated tagging for legacy stories --- packages/box/stories/Box.stories.tsx | 1 + packages/button/stories/Button.stories.tsx | 1 + packages/button/stories/ButtonGroup.stories.tsx | 1 + packages/button/stories/IconButton.stories.tsx | 1 + packages/button/stories/UploadButton.stories.tsx | 1 + packages/drawer/stories/Drawer.stories.tsx | 1 + packages/dropdown/stories/Dropdown.stories.tsx | 1 + packages/filter/stories/AppliedFilter.stories.tsx | 1 + packages/filter/stories/Filter.stories.tsx | 1 + packages/filter/stories/FilterButton.stories.tsx | 1 + packages/form/stories/Checkbox.stories.tsx | 1 + packages/form/stories/CompactTextField.stories.tsx | 1 + packages/form/stories/FormField.stories.tsx | 1 + packages/form/stories/FormGroup.stories.tsx | 1 + packages/form/stories/IconField.stories.tsx | 1 + packages/form/stories/Label.stories.tsx | 2 +- packages/form/stories/Radio.stories.tsx | 1 + packages/form/stories/RadioGroup.stories.tsx | 1 + packages/form/stories/SelectField.stories.tsx | 1 + packages/form/stories/TextArea.stories.tsx | 1 + packages/form/stories/TextField.stories.tsx | 1 + packages/form/stories/useNumberField.stories.tsx | 1 + packages/icons/stories/StatusIcon.stories.tsx | 1 + packages/menu/stories/Menu.stories.tsx | 1 + packages/modal/stories/Modal.stories.tsx | 1 + packages/navigation/stories/Navigation.stories.tsx | 1 + packages/popover/stories/Popover.stories.tsx | 1 + packages/table/stories/Table.stories.tsx | 1 + packages/tooltip/stories/Tooltip.stories.tsx | 1 + 29 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/box/stories/Box.stories.tsx b/packages/box/stories/Box.stories.tsx index 35f2e1b44..98cce3476 100644 --- a/packages/box/stories/Box.stories.tsx +++ b/packages/box/stories/Box.stories.tsx @@ -6,6 +6,7 @@ import { Box } from '../src'; export default { component: Box, title: 'Legacy/Experimental/Box', + tags: ['deprecated'], description: '', }; diff --git a/packages/button/stories/Button.stories.tsx b/packages/button/stories/Button.stories.tsx index a0cea7f2c..8e4e79858 100644 --- a/packages/button/stories/Button.stories.tsx +++ b/packages/button/stories/Button.stories.tsx @@ -46,6 +46,7 @@ const buttonTemplateWithStates: Decorator = (storyComponent, context) => { export default { component: Button, title: 'Legacy/Button', + tags: ['deprecated'], description: 'Buttons trigger actions based on user interaction.', decorators: [buttonTemplateWithStates], parameters: { diff --git a/packages/button/stories/ButtonGroup.stories.tsx b/packages/button/stories/ButtonGroup.stories.tsx index 6018d7e21..33f5d0121 100644 --- a/packages/button/stories/ButtonGroup.stories.tsx +++ b/packages/button/stories/ButtonGroup.stories.tsx @@ -50,6 +50,7 @@ const buttonTemplateWithStates: Decorator = (storyComponent, context) => { export default { component: ButtonGroup, title: 'Legacy/Button/ButtonGroup', + tags: ['deprecated'], description: 'ButtonGroups group related actions and trigger them based on user interaction.', decorators: [buttonTemplateWithStates], parameters: { diff --git a/packages/button/stories/IconButton.stories.tsx b/packages/button/stories/IconButton.stories.tsx index 711bfed1d..caf10f8eb 100644 --- a/packages/button/stories/IconButton.stories.tsx +++ b/packages/button/stories/IconButton.stories.tsx @@ -48,6 +48,7 @@ const buttonTemplateWithStates: Decorator = (storyComponent, context) => { export default { component: IconButton, title: 'Legacy/Button/IconButton', + tags: ['deprecated'], description: 'Buttons trigger actions based on user interaction.', decorators: [buttonTemplateWithStates], parameters: { diff --git a/packages/button/stories/UploadButton.stories.tsx b/packages/button/stories/UploadButton.stories.tsx index bb04c1189..1579d33e2 100644 --- a/packages/button/stories/UploadButton.stories.tsx +++ b/packages/button/stories/UploadButton.stories.tsx @@ -5,6 +5,7 @@ import { UploadButton } from '../src'; export default { component: UploadButton, title: 'Legacy/Button/UploadButton', + tags: ['deprecated'], description: 'UploadButtons trigger a native file upload experience.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/drawer/stories/Drawer.stories.tsx b/packages/drawer/stories/Drawer.stories.tsx index 7404fcbe3..a94a1e410 100644 --- a/packages/drawer/stories/Drawer.stories.tsx +++ b/packages/drawer/stories/Drawer.stories.tsx @@ -10,6 +10,7 @@ export default { component: Drawer, subcomponents: { DrawerHeader }, title: 'Legacy/Drawer', + tags: ['deprecated'], description: 'A partial overlay that appears from the right side of the screen.', parameters: { docs: { diff --git a/packages/dropdown/stories/Dropdown.stories.tsx b/packages/dropdown/stories/Dropdown.stories.tsx index 970ddad0c..580f392c3 100644 --- a/packages/dropdown/stories/Dropdown.stories.tsx +++ b/packages/dropdown/stories/Dropdown.stories.tsx @@ -8,6 +8,7 @@ export default { component: Dropdown, subcomponents: { DropdownButton }, title: 'Legacy/Dropdown', + tags: ['deprecated'], description: 'Dropdowns display a list of actions or options to a user.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/filter/stories/AppliedFilter.stories.tsx b/packages/filter/stories/AppliedFilter.stories.tsx index bf3ef2a54..39bb1f168 100644 --- a/packages/filter/stories/AppliedFilter.stories.tsx +++ b/packages/filter/stories/AppliedFilter.stories.tsx @@ -5,6 +5,7 @@ import { AppliedFilter } from '../src'; export default { component: AppliedFilter, title: 'Legacy/Filter/AppliedFilter', + tags: ['deprecated'], description: 'We use filters to filter our lists based on search critera.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/filter/stories/Filter.stories.tsx b/packages/filter/stories/Filter.stories.tsx index d7b9c5d8b..f183f86fd 100644 --- a/packages/filter/stories/Filter.stories.tsx +++ b/packages/filter/stories/Filter.stories.tsx @@ -5,6 +5,7 @@ import { Filter } from '../src'; export default { component: Filter, title: 'Legacy/Filter', + tags: ['deprecated'], description: 'We use filters to filter our lists based on search critera.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/filter/stories/FilterButton.stories.tsx b/packages/filter/stories/FilterButton.stories.tsx index 56277bbef..0a1ec50a6 100644 --- a/packages/filter/stories/FilterButton.stories.tsx +++ b/packages/filter/stories/FilterButton.stories.tsx @@ -5,6 +5,7 @@ import { FilterButton } from '../src'; export default { component: FilterButton, title: 'Legacy/Filter/FilterButton', + tags: ['deprecated'], description: "When the Filter component doesn't suffice, construct your own custom filter using the FilterButton.", parameters: { diff --git a/packages/form/stories/Checkbox.stories.tsx b/packages/form/stories/Checkbox.stories.tsx index c40e26a53..315a0e1f8 100644 --- a/packages/form/stories/Checkbox.stories.tsx +++ b/packages/form/stories/Checkbox.stories.tsx @@ -5,6 +5,7 @@ import { Checkbox } from '../src'; export default { component: Checkbox, title: 'Legacy/Form/Checkbox', + tags: ['deprecated'], description: 'A checkbox allows the user to toggle between checked and unchecked states.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/form/stories/CompactTextField.stories.tsx b/packages/form/stories/CompactTextField.stories.tsx index 69b7e691e..862c9d933 100644 --- a/packages/form/stories/CompactTextField.stories.tsx +++ b/packages/form/stories/CompactTextField.stories.tsx @@ -5,6 +5,7 @@ import { CompactTextField } from '../src'; export default { component: CompactTextField, title: 'Legacy/Form/CompactTextField', + tags: ['deprecated'], description: 'A compact text field allows the user to provide values.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/form/stories/FormField.stories.tsx b/packages/form/stories/FormField.stories.tsx index afd5a2f94..8dbcc1ee1 100644 --- a/packages/form/stories/FormField.stories.tsx +++ b/packages/form/stories/FormField.stories.tsx @@ -5,6 +5,7 @@ import { FormField, TextField } from '../src'; export default { component: FormField, title: 'Legacy/Form/FormField', + tags: ['deprecated'], description: 'A FormField is an opinionated way to organize form field components like labels, errors, hints, and the field itself."', parameters: { diff --git a/packages/form/stories/FormGroup.stories.tsx b/packages/form/stories/FormGroup.stories.tsx index ef009c997..45cb1de87 100644 --- a/packages/form/stories/FormGroup.stories.tsx +++ b/packages/form/stories/FormGroup.stories.tsx @@ -5,6 +5,7 @@ import { FormGroup, FormHint, Label, RequiredAsterisk, TextField } from '../src' export default { component: FormGroup, title: 'Legacy/Form/FormGroup', + tags: ['deprecated'], description: 'A group of form fields.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/form/stories/IconField.stories.tsx b/packages/form/stories/IconField.stories.tsx index 9ee0828dd..10f7e1f92 100644 --- a/packages/form/stories/IconField.stories.tsx +++ b/packages/form/stories/IconField.stories.tsx @@ -6,6 +6,7 @@ import { IconField, TextField } from '../src'; export default { component: IconField, title: 'Legacy/Form/IconField', + tags: ['deprecated'], description: 'An IconField renders an icon placed next to a passed field."', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/form/stories/Label.stories.tsx b/packages/form/stories/Label.stories.tsx index 59c06754c..fbc6e7b78 100644 --- a/packages/form/stories/Label.stories.tsx +++ b/packages/form/stories/Label.stories.tsx @@ -5,7 +5,7 @@ import { Label } from '../src'; export default { component: Label, title: 'Legacy/Form/Label', - + tags: ['deprecated'], parameters: { chromatic: { disableSnapshot: true }, docs: { diff --git a/packages/form/stories/Radio.stories.tsx b/packages/form/stories/Radio.stories.tsx index 1d5b331f0..62e311c24 100644 --- a/packages/form/stories/Radio.stories.tsx +++ b/packages/form/stories/Radio.stories.tsx @@ -5,6 +5,7 @@ import { Radio } from '../src'; export default { component: Radio, title: 'Legacy/Form/Radio', + tags: ['deprecated'], description: 'A radio button allows the user to select one of a set of options."', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/form/stories/RadioGroup.stories.tsx b/packages/form/stories/RadioGroup.stories.tsx index 38a7cde5e..334b14c1d 100644 --- a/packages/form/stories/RadioGroup.stories.tsx +++ b/packages/form/stories/RadioGroup.stories.tsx @@ -5,6 +5,7 @@ import { Label, Radio, RadioGroup } from '../src'; export default { component: RadioGroup, title: 'Legacy/Form/RadioGroup', + tags: ['deprecated'], description: 'A radio button group allows the user to select one of a set of options.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/form/stories/SelectField.stories.tsx b/packages/form/stories/SelectField.stories.tsx index ecd99c24d..365be874e 100644 --- a/packages/form/stories/SelectField.stories.tsx +++ b/packages/form/stories/SelectField.stories.tsx @@ -5,6 +5,7 @@ import { SelectField } from '../src'; export default { component: SelectField, title: 'Legacy/Form/SelectField', + tags: ['deprecated'], description: 'A select field allows the user to select a value from a set of options."', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/form/stories/TextArea.stories.tsx b/packages/form/stories/TextArea.stories.tsx index 020eed7c4..e32881a48 100644 --- a/packages/form/stories/TextArea.stories.tsx +++ b/packages/form/stories/TextArea.stories.tsx @@ -39,6 +39,7 @@ const withRestingAndDisabledStates: Decorator = (story, context) => { export default { component: TextArea, title: 'Legacy/Form/TextArea', + tags: ['deprecated'], description: 'A styled form textarea component', decorators: [ createWithClassesDecorator(testingChromaticClassNames, (args, originalStory, context) => { diff --git a/packages/form/stories/TextField.stories.tsx b/packages/form/stories/TextField.stories.tsx index 9dedbb003..b461a09c5 100644 --- a/packages/form/stories/TextField.stories.tsx +++ b/packages/form/stories/TextField.stories.tsx @@ -38,6 +38,7 @@ const withRestingAndDisabledStates: Decorator = (story, context) => { export default { component: TextField, title: 'Legacy/Form/TextField', + tags: ['deprecated'], description: 'A text field allows the user to provide values."', decorators: [ createWithClassesDecorator(chromaticTestStyles, (args, storyFn, context) => { diff --git a/packages/form/stories/useNumberField.stories.tsx b/packages/form/stories/useNumberField.stories.tsx index 4dac75a20..930de514d 100644 --- a/packages/form/stories/useNumberField.stories.tsx +++ b/packages/form/stories/useNumberField.stories.tsx @@ -29,6 +29,7 @@ const Demo = (props: Partial = {}) => { export default { component: Demo, title: 'Legacy/Form/useNumberField', + tags: ['deprecated'], description: 'A text field allows the user to provide numeric values.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/icons/stories/StatusIcon.stories.tsx b/packages/icons/stories/StatusIcon.stories.tsx index df7a10a14..2c3feade9 100644 --- a/packages/icons/stories/StatusIcon.stories.tsx +++ b/packages/icons/stories/StatusIcon.stories.tsx @@ -5,6 +5,7 @@ import { StatusIcon } from '../src'; export default { component: StatusIcon, title: 'Legacy/Icon/StatusIcon', + tags: ['deprecated'], description: 'Flair icons can be used as either square or circular icons with gradient backgrounds.', parameters: { diff --git a/packages/menu/stories/Menu.stories.tsx b/packages/menu/stories/Menu.stories.tsx index 6b240d35e..25b36b8d7 100644 --- a/packages/menu/stories/Menu.stories.tsx +++ b/packages/menu/stories/Menu.stories.tsx @@ -11,6 +11,7 @@ export default { component: Menu, subcomponents: { MenuDivider, MenuItem, MenuSearch }, title: 'Legacy/Menu', + tags: ['deprecated'], description: 'Menus present a list of items a user can choose from.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/modal/stories/Modal.stories.tsx b/packages/modal/stories/Modal.stories.tsx index 7cb490669..560f7af13 100644 --- a/packages/modal/stories/Modal.stories.tsx +++ b/packages/modal/stories/Modal.stories.tsx @@ -13,6 +13,7 @@ import { AbsoluteModalFooter, Modal, ModalBody, ModalFooter, ModalHeader } from export default { component: Modal, title: 'Legacy/Modal', + tags: ['deprecated'], description: 'Modals presents users information and actions over a page.', parameters: { controls: { sort: 'requiredFirst' }, diff --git a/packages/navigation/stories/Navigation.stories.tsx b/packages/navigation/stories/Navigation.stories.tsx index 4ccc19337..a46206e88 100644 --- a/packages/navigation/stories/Navigation.stories.tsx +++ b/packages/navigation/stories/Navigation.stories.tsx @@ -8,6 +8,7 @@ export default { component: Navigation, subcomponents: { NavigationItem }, title: 'Legacy/Navigation', + tags: ['deprecated'], description: 'An element used to provide navigation links to help users move through an app.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/popover/stories/Popover.stories.tsx b/packages/popover/stories/Popover.stories.tsx index 0e75e3a26..f4a0f7cec 100644 --- a/packages/popover/stories/Popover.stories.tsx +++ b/packages/popover/stories/Popover.stories.tsx @@ -8,6 +8,7 @@ import { Popover } from '../src'; export default { component: Popover, title: 'Legacy/Popover', + tags: ['deprecated'], description: 'Popovers display content within a portal triggered by user interactions.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/table/stories/Table.stories.tsx b/packages/table/stories/Table.stories.tsx index 92db06657..2f7794de1 100644 --- a/packages/table/stories/Table.stories.tsx +++ b/packages/table/stories/Table.stories.tsx @@ -6,6 +6,7 @@ export default { component: Table, subcomponents: { TableBody, TableCell, TableHead, TableHeadCell, TableRow }, title: 'Legacy/Table', + tags: ['deprecated'], description: 'An element used to organize and display data to users.', parameters: { chromatic: { disableSnapshot: true }, diff --git a/packages/tooltip/stories/Tooltip.stories.tsx b/packages/tooltip/stories/Tooltip.stories.tsx index d9056be00..f16c4d187 100644 --- a/packages/tooltip/stories/Tooltip.stories.tsx +++ b/packages/tooltip/stories/Tooltip.stories.tsx @@ -8,6 +8,7 @@ import { Tooltip } from '../src'; export default { component: Tooltip, title: 'Legacy/Tooltip', + tags: ['deprecated'], description: 'Tooltips provide additional information on hover or focus.', parameters: { chromatic: { disableSnapshot: true }, From a5e1b378f2dae84c45c119649404a05bbfbaa7d7 Mon Sep 17 00:00:00 2001 From: Susanna Nevalainen Date: Mon, 4 Aug 2025 10:48:46 +0200 Subject: [PATCH 04/36] feat(components): buttongroup figma connect, prop table stories type clean up --- .../components/figma/ButtonGroup.figma.tsx | 23 ++++ .../components/stories/Button.stories.tsx | 66 +++++++++++ .../stories/ButtonGroup.stories.tsx | 105 ++++++++++++------ packages/components/stories/Code.stories.tsx | 2 +- 4 files changed, 160 insertions(+), 36 deletions(-) create mode 100644 packages/components/figma/ButtonGroup.figma.tsx diff --git a/packages/components/figma/ButtonGroup.figma.tsx b/packages/components/figma/ButtonGroup.figma.tsx new file mode 100644 index 000000000..309a34c1b --- /dev/null +++ b/packages/components/figma/ButtonGroup.figma.tsx @@ -0,0 +1,23 @@ +import figma from '@figma/code-connect'; + +import { Button, ButtonGroup } from '../src'; + +figma.connect( + ButtonGroup, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=1-28639', + { + props: { + spacing: figma.enum('Type', { + Basic: 'basic', + Compact: 'compact', + Large: 'large', + }), + }, + example: ({ spacing }) => ( + + + + + ), + }, +); diff --git a/packages/components/stories/Button.stories.tsx b/packages/components/stories/Button.stories.tsx index 10942bd1e..5e8fde063 100644 --- a/packages/components/stories/Button.stories.tsx +++ b/packages/components/stories/Button.stories.tsx @@ -30,6 +30,72 @@ const meta: Meta = { ), ], + argTypes: { + // Hide technical/internal props + ref: { table: { disable: true } }, + children: { control: false }, + + // Button specific props + size: { + control: { type: 'radio' }, + options: ['small', 'medium', 'large'], + }, + variant: { + control: { type: 'radio' }, + options: ['default', 'primary', 'destructive', 'minimal', 'picker'], + }, + + // Boolean props should be checkboxes + isDisabled: { control: { type: 'boolean' } }, + isPending: { control: { type: 'boolean' } }, + isPressed: { control: { type: 'boolean' } }, + autoFocus: { control: { type: 'boolean' } }, + excludeFromTabOrder: { control: { type: 'boolean' } }, + + // String props should be text inputs + type: { control: { type: 'text' } }, + name: { control: { type: 'text' } }, + value: { control: { type: 'text' } }, + form: { control: { type: 'text' } }, + formAction: { control: { type: 'text' } }, + formEncType: { control: { type: 'text' } }, + formMethod: { control: { type: 'text' } }, + formTarget: { control: { type: 'text' } }, + 'aria-label': { control: { type: 'text' } }, + 'aria-labelledby': { control: { type: 'text' } }, + 'aria-describedby': { control: { type: 'text' } }, + 'aria-details': { control: { type: 'text' } }, + className: { control: { type: 'text' } }, + id: { control: { type: 'text' } }, + + // Function props should be disabled + onPress: { control: { disable: true } }, + onClick: { control: { disable: true } }, + onPressStart: { table: { disable: true } }, + onPressEnd: { table: { disable: true } }, + onPressChange: { table: { disable: true } }, + onPressUp: { table: { disable: true } }, + onFocus: { table: { disable: true } }, + onBlur: { table: { disable: true } }, + onFocusChange: { table: { disable: true } }, + onKeyDown: { table: { disable: true } }, + onKeyUp: { table: { disable: true } }, + onHoverStart: { table: { disable: true } }, + onHoverEnd: { table: { disable: true } }, + onHoverChange: { table: { disable: true } }, + 'aria-controls': { table: { disable: true } }, + 'aria-expanded': { table: { disable: true } }, + 'aria-haspopup': { table: { disable: true } }, + 'aria-pressed': { table: { disable: true } }, + 'aria-required': { table: { disable: true } }, + 'aria-roledescription': { table: { disable: true } }, + 'aria-selected': { table: { disable: true } }, + + // Complex props should be disabled + style: { table: { disable: true } }, + UNSAFE_className: { table: { disable: true } }, + UNSAFE_style: { table: { disable: true } }, + }, }; export default meta; diff --git a/packages/components/stories/ButtonGroup.stories.tsx b/packages/components/stories/ButtonGroup.stories.tsx index 5901c63fd..99dafc2d9 100644 --- a/packages/components/stories/ButtonGroup.stories.tsx +++ b/packages/components/stories/ButtonGroup.stories.tsx @@ -10,6 +10,43 @@ import { Popover } from '../src/Popover'; const meta: Meta = { component: ButtonGroup, title: 'Components/Buttons/ButtonGroup', + parameters: { + design: { + type: 'figma', + url: 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=14332-4328&m=dev', + }, + }, + argTypes: { + // Only show LaunchPad-specific props + spacing: { + control: { type: 'radio' }, + options: ['basic', 'compact', 'large'], + }, + orientation: { + control: { type: 'radio' }, + options: ['horizontal', 'vertical'], + }, + children: { control: false }, + + // Keep a few essential accessibility/state props + isDisabled: { control: { type: 'boolean' } }, + 'aria-label': { control: { type: 'text' } }, + + // Hide all other React Aria props systematically + ref: { table: { disable: true } }, + isInvalid: { table: { disable: true } }, + role: { table: { disable: true } }, + 'aria-labelledby': { table: { disable: true } }, + 'aria-describedby': { table: { disable: true } }, + 'aria-details': { table: { disable: true } }, + className: { table: { disable: true } }, + onHoverStart: { table: { disable: true } }, + onHoverEnd: { table: { disable: true } }, + onHoverChange: { table: { disable: true } }, + style: { table: { disable: true } }, + id: { table: { disable: true } }, + slot: { table: { disable: true } }, + }, }; export default meta; @@ -17,13 +54,13 @@ export default meta; type Story = StoryObj; const defaultArgs = { - children: ( - <> - - - - - ), + children: [ + , + , + , + ], }; export const Basic: Story = { @@ -40,40 +77,38 @@ export const Large: Story = { export const SplitButton: Story = { args: { - children: ( - <> - - - - - - Item one - Item two - - - - - ), + children: [ + , + + + + + Item one + Item two + + + , + ], spacing: 'compact', }, }; export const SplitLinkButton: Story = { args: { - children: ( - <> - Split link button - - - - - Item one - Item two - - - - - ), + children: [ + + Split link button + , + + + + + Item one + Item two + + + , + ], spacing: 'compact', }, }; diff --git a/packages/components/stories/Code.stories.tsx b/packages/components/stories/Code.stories.tsx index beee9b442..8dd98a3e4 100644 --- a/packages/components/stories/Code.stories.tsx +++ b/packages/components/stories/Code.stories.tsx @@ -17,7 +17,7 @@ For body text, use [Text](/docs/components-content-text--docs ). For headings, u }, design: { type: 'figma', - url: 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=2308-667', + url: 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=14383-120498&m=dev', }, }, argTypes: { From a05215938cee574d6922e9600f0ef9941fd3bff5 Mon Sep 17 00:00:00 2001 From: Susanna Nevalainen Date: Mon, 4 Aug 2025 12:02:01 +0200 Subject: [PATCH 05/36] feat(components): storybook prop table global config added for better control types --- .storybook/preview.tsx | 196 ++++++++++++++++++ .../components/stories/Button.stories.tsx | 66 ------ .../stories/ButtonGroup.stories.tsx | 31 --- 3 files changed, 196 insertions(+), 97 deletions(-) diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 0d093a2a1..55ab8524b 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -157,6 +157,170 @@ const globalTypes: GlobalTypes = { }, }; +// Auto-enhance argTypes based on prop types +const enhanceArgTypes = (context: any) => { + const { argTypes } = context; + const enhanced: any = {}; + + Object.keys(argTypes || {}).forEach((key) => { + const argType = argTypes[key]; + + // Skip if already has a control defined, is disabled, or is ref + if (argType.control !== undefined || argType.table?.disable) { + return; + } + + // Auto-detect control type based on prop type + if (argType.type) { + const typeName = argType.type.name || ''; + + // Function props → disable completely + if ( + typeName === 'func' || + typeName === 'function' || + key.startsWith('on') || + key === 'ref' || + (key === 'children' && argType.type !== 'string') + ) { + enhanced[key] = { + ...argType, + control: { disable: true }, + }; + } + // Boolean props → toggle + else if (typeName === 'boolean' || (typeName === 'enum' && argType.type.value.length === 2)) { + enhanced[key] = { + ...argType, + control: { type: 'boolean' }, + }; + } + // Check for boolean unions (like boolean | undefined) → checkbox + else if (typeName === 'union' && argType.type.value) { + const hasBoolean = argType.type.value.some((v: any) => v.name === 'boolean'); + + if (hasBoolean) { + enhanced[key] = { + ...argType, + control: { type: 'boolean' }, + }; + } else { + // Component-specific props that should be radio buttons (whitelist approach) + const componentProps = [ + 'size', + 'variant', + 'spacing', + 'orientation', + 'color', + 'appearance', + 'position', + 'placement', + ]; + + if (componentProps.includes(key)) { + const options = argType.type.value + .filter((v: any) => { + if (v.name === 'literal') { + const value = v.value; + return ( + value !== null && + value !== undefined && + value !== 'null' && + value !== 'undefined' && + value !== '' && + typeof value === 'string' + ); + } + return v.name !== 'null' && v.name !== 'undefined' && v.name !== 'void'; + }) + .map((v: any) => v.value || v.name) + .filter(Boolean); + + if (options.length > 0) { + // + if (options.length <= 5) { + enhanced[key] = { + ...argType, + control: { type: 'radio' }, + options, + }; + } else { + enhanced[key] = { + ...argType, + control: { type: 'select' }, + options, + }; + } + } + } else { + // All other string/union props → text input + enhanced[key] = { + ...argType, + control: { type: 'text' }, + }; + } + } + } + // Enum types → radio or select (for whitelisted component props only) + else if (typeName === 'enum' && argType.type.value) { + const componentProps = [ + 'size', + 'variant', + 'spacing', + 'orientation', + 'color', + 'appearance', + 'position', + 'placement', + ]; + + if (componentProps.includes(key)) { + const options = argType.type.value + .filter((v: any) => v !== null && v !== undefined && v !== 'null' && v !== 'undefined') + .map((v: any) => v); + + if (options.length > 0) { + if (options.length <= 5) { + enhanced[key] = { + ...argType, + control: { type: 'radio' }, + options, + }; + } else { + enhanced[key] = { + ...argType, + control: { type: 'select' }, + options, + }; + } + } + } else { + // Non-whitelisted enums → text input + enhanced[key] = { + ...argType, + control: { type: 'text' }, + }; + } + } + // All string props → text input + else if (typeName === 'string') { + enhanced[key] = { + ...argType, + control: { type: 'text' }, + }; + } + // Number props → number input + else if (typeName === 'number') { + enhanced[key] = { + ...argType, + control: { type: 'number' }, + }; + } + } + }); + + return enhanced; +}; + const preview: Preview = { tags: ['autodocs'], parameters, @@ -165,6 +329,38 @@ const preview: Preview = { initialGlobals: { backgrounds: { value: 'default' }, }, + // Auto-enhance argTypes for better controls + argTypesEnhancers: [(context) => enhanceArgTypes(context)], + // Global argTypes that apply to all stories + argTypes: { + // Hide function props globally by default to keep the prop table skimmable + onPressStart: { table: { disable: true } }, + onPressEnd: { table: { disable: true } }, + onPressChange: { table: { disable: true } }, + onPressUp: { table: { disable: true } }, + onFocusChange: { table: { disable: true } }, + onHoverStart: { table: { disable: true } }, + onHoverEnd: { table: { disable: true } }, + preventFocusOnPress: { table: { disable: true } }, + excludeFromTabOrder: { table: { disable: true } }, + + // Hide technical props + style: { table: { disable: true } }, + UNSAFE_className: { table: { disable: true } }, + UNSAFE_style: { table: { disable: true } }, + + // Hide verbose aria props (keep common ones like aria-label visible) + 'aria-controls': { table: { disable: true } }, + 'aria-expanded': { table: { disable: true } }, + 'aria-haspopup': { table: { disable: true } }, + 'aria-pressed': { table: { disable: true } }, + 'aria-required': { table: { disable: true } }, + 'aria-roledescription': { table: { disable: true } }, + 'aria-selected': { table: { disable: true } }, + 'aria-describedby': { table: { disable: true } }, + 'aria-details': { table: { disable: true } }, + 'aria-labelledby': { table: { disable: true } }, + }, }; export default preview; diff --git a/packages/components/stories/Button.stories.tsx b/packages/components/stories/Button.stories.tsx index 5e8fde063..10942bd1e 100644 --- a/packages/components/stories/Button.stories.tsx +++ b/packages/components/stories/Button.stories.tsx @@ -30,72 +30,6 @@ const meta: Meta = { ), ], - argTypes: { - // Hide technical/internal props - ref: { table: { disable: true } }, - children: { control: false }, - - // Button specific props - size: { - control: { type: 'radio' }, - options: ['small', 'medium', 'large'], - }, - variant: { - control: { type: 'radio' }, - options: ['default', 'primary', 'destructive', 'minimal', 'picker'], - }, - - // Boolean props should be checkboxes - isDisabled: { control: { type: 'boolean' } }, - isPending: { control: { type: 'boolean' } }, - isPressed: { control: { type: 'boolean' } }, - autoFocus: { control: { type: 'boolean' } }, - excludeFromTabOrder: { control: { type: 'boolean' } }, - - // String props should be text inputs - type: { control: { type: 'text' } }, - name: { control: { type: 'text' } }, - value: { control: { type: 'text' } }, - form: { control: { type: 'text' } }, - formAction: { control: { type: 'text' } }, - formEncType: { control: { type: 'text' } }, - formMethod: { control: { type: 'text' } }, - formTarget: { control: { type: 'text' } }, - 'aria-label': { control: { type: 'text' } }, - 'aria-labelledby': { control: { type: 'text' } }, - 'aria-describedby': { control: { type: 'text' } }, - 'aria-details': { control: { type: 'text' } }, - className: { control: { type: 'text' } }, - id: { control: { type: 'text' } }, - - // Function props should be disabled - onPress: { control: { disable: true } }, - onClick: { control: { disable: true } }, - onPressStart: { table: { disable: true } }, - onPressEnd: { table: { disable: true } }, - onPressChange: { table: { disable: true } }, - onPressUp: { table: { disable: true } }, - onFocus: { table: { disable: true } }, - onBlur: { table: { disable: true } }, - onFocusChange: { table: { disable: true } }, - onKeyDown: { table: { disable: true } }, - onKeyUp: { table: { disable: true } }, - onHoverStart: { table: { disable: true } }, - onHoverEnd: { table: { disable: true } }, - onHoverChange: { table: { disable: true } }, - 'aria-controls': { table: { disable: true } }, - 'aria-expanded': { table: { disable: true } }, - 'aria-haspopup': { table: { disable: true } }, - 'aria-pressed': { table: { disable: true } }, - 'aria-required': { table: { disable: true } }, - 'aria-roledescription': { table: { disable: true } }, - 'aria-selected': { table: { disable: true } }, - - // Complex props should be disabled - style: { table: { disable: true } }, - UNSAFE_className: { table: { disable: true } }, - UNSAFE_style: { table: { disable: true } }, - }, }; export default meta; diff --git a/packages/components/stories/ButtonGroup.stories.tsx b/packages/components/stories/ButtonGroup.stories.tsx index 99dafc2d9..0b490098a 100644 --- a/packages/components/stories/ButtonGroup.stories.tsx +++ b/packages/components/stories/ButtonGroup.stories.tsx @@ -16,37 +16,6 @@ const meta: Meta = { url: 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=14332-4328&m=dev', }, }, - argTypes: { - // Only show LaunchPad-specific props - spacing: { - control: { type: 'radio' }, - options: ['basic', 'compact', 'large'], - }, - orientation: { - control: { type: 'radio' }, - options: ['horizontal', 'vertical'], - }, - children: { control: false }, - - // Keep a few essential accessibility/state props - isDisabled: { control: { type: 'boolean' } }, - 'aria-label': { control: { type: 'text' } }, - - // Hide all other React Aria props systematically - ref: { table: { disable: true } }, - isInvalid: { table: { disable: true } }, - role: { table: { disable: true } }, - 'aria-labelledby': { table: { disable: true } }, - 'aria-describedby': { table: { disable: true } }, - 'aria-details': { table: { disable: true } }, - className: { table: { disable: true } }, - onHoverStart: { table: { disable: true } }, - onHoverEnd: { table: { disable: true } }, - onHoverChange: { table: { disable: true } }, - style: { table: { disable: true } }, - id: { table: { disable: true } }, - slot: { table: { disable: true } }, - }, }; export default meta; From 821ac37d61954b46230fa5090d854b9ec8fc5227 Mon Sep 17 00:00:00 2001 From: Susanna Nevalainen Date: Mon, 4 Aug 2025 12:37:54 +0200 Subject: [PATCH 06/36] feat(components): file trigger figma connect, more stories for icon button --- .../components/figma/FileTrigger.figma.tsx | 16 +++++++++ .../stories/FileTrigger.stories.tsx | 6 ++++ .../components/stories/IconButton.stories.tsx | 33 ++++++++++++++++--- 3 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 packages/components/figma/FileTrigger.figma.tsx diff --git a/packages/components/figma/FileTrigger.figma.tsx b/packages/components/figma/FileTrigger.figma.tsx new file mode 100644 index 000000000..3dce02d2b --- /dev/null +++ b/packages/components/figma/FileTrigger.figma.tsx @@ -0,0 +1,16 @@ +import figma from '@figma/code-connect'; + +import { Button } from '../src/Button'; +import { FileTrigger } from '../src/FileTrigger'; + +figma.connect( + FileTrigger, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=14350-114160&m=dev', + { + example: () => ( + + + + ), + }, +); diff --git a/packages/components/stories/FileTrigger.stories.tsx b/packages/components/stories/FileTrigger.stories.tsx index 02fbf2032..277a7d973 100644 --- a/packages/components/stories/FileTrigger.stories.tsx +++ b/packages/components/stories/FileTrigger.stories.tsx @@ -6,6 +6,12 @@ import { FileTrigger } from '../src/FileTrigger'; const meta: Meta = { component: FileTrigger, title: 'Components/Buttons/FileTrigger', + parameters: { + design: { + type: 'figma', + url: 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=14350-114160&m=dev', + }, + }, }; export default meta; diff --git a/packages/components/stories/IconButton.stories.tsx b/packages/components/stories/IconButton.stories.tsx index af0266969..97851751b 100644 --- a/packages/components/stories/IconButton.stories.tsx +++ b/packages/components/stories/IconButton.stories.tsx @@ -5,16 +5,41 @@ import { IconButton } from '../src/IconButton'; const meta: Meta = { component: IconButton, title: 'Components/Buttons/IconButton', -}; + tags: ['autodocs'], + parameters: { + design: { + type: 'figma', + url: 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=14355-114625&m=dev', + }, + }, +} satisfies Meta; export default meta; type Story = StoryObj; -export const Example: Story = { +export const Default: Story = { args: { icon: 'add', 'aria-label': 'create' }, }; -export const Small: Story = { - args: { icon: 'add', 'aria-label': 'create', size: 'small' }, +export const Variant: Story = { + render: () => ( +
+ + + + +
+ ), + args: { 'aria-label': 'create' }, +}; + +export const Size: Story = { + render: () => ( +
+ + +
+ ), + args: { 'aria-label': 'create' }, }; From f889b2f3e44fde060150fc3c93ea3c9436baf084 Mon Sep 17 00:00:00 2001 From: Susanna Nevalainen Date: Mon, 4 Aug 2025 12:44:53 +0200 Subject: [PATCH 07/36] feat(components): linter fix --- packages/components/stories/IconButton.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/components/stories/IconButton.stories.tsx b/packages/components/stories/IconButton.stories.tsx index 97851751b..ce082383b 100644 --- a/packages/components/stories/IconButton.stories.tsx +++ b/packages/components/stories/IconButton.stories.tsx @@ -5,7 +5,6 @@ import { IconButton } from '../src/IconButton'; const meta: Meta = { component: IconButton, title: 'Components/Buttons/IconButton', - tags: ['autodocs'], parameters: { design: { type: 'figma', From d63412d76f921592f2084f97ac836fabd27583a8 Mon Sep 17 00:00:00 2001 From: Susanna Nevalainen Date: Mon, 4 Aug 2025 17:22:22 +0200 Subject: [PATCH 08/36] feat(components): toggleButton figma code connect and component overview docs draft --- CONTRIBUTING.md | 6 +++++ .../components/figma/FileTrigger.figma.tsx | 2 +- .../components/figma/RadioGroup.figma.tsx | 22 +++++++++++++++++++ .../components/figma/ToggleButton.figma.tsx | 21 ++++++++++++++++++ .../stories/ToggleButtonGroup.stories.tsx | 9 +++++++- .../stories/ToggleIconButton.stories.tsx | 7 ++++++ 6 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 packages/components/figma/RadioGroup.figma.tsx create mode 100644 packages/components/figma/ToggleButton.figma.tsx diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ad871d44..edf6f1acc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -162,6 +162,12 @@ Run this command to start a local instance in your browser: $ pnpm storybook ``` +### Figma Code Connect + +Figma Code Connect is a tool to connect LaunchPad code with LaunchPad Figma Design System real-time. When developers will click component or its insance in design, they will be directed which component and code they should use for implementing the design. + +Using Figma connect requires generating an access Token in LaunchDarkly Figma. You can learn more about code connect [here](https://www.figma.com/code-connect-docs/). + ### Running Tests #### Unit Tests diff --git a/packages/components/figma/FileTrigger.figma.tsx b/packages/components/figma/FileTrigger.figma.tsx index 3dce02d2b..70f50f5a4 100644 --- a/packages/components/figma/FileTrigger.figma.tsx +++ b/packages/components/figma/FileTrigger.figma.tsx @@ -5,7 +5,7 @@ import { FileTrigger } from '../src/FileTrigger'; figma.connect( FileTrigger, - 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=14350-114160&m=dev', + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=1-28805', { example: () => ( diff --git a/packages/components/figma/RadioGroup.figma.tsx b/packages/components/figma/RadioGroup.figma.tsx new file mode 100644 index 000000000..609c1c8fe --- /dev/null +++ b/packages/components/figma/RadioGroup.figma.tsx @@ -0,0 +1,22 @@ +import figma from '@figma/code-connect'; + +import { ButtonGroup, Label, RadioButton, RadioGroup } from '../src'; + +figma.connect( + RadioGroup, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=1-37500', + { + example: () => ( + + + + First + Second + Third + Fourth + Fifth + + + ), + }, +); diff --git a/packages/components/figma/ToggleButton.figma.tsx b/packages/components/figma/ToggleButton.figma.tsx new file mode 100644 index 000000000..1c34a96cd --- /dev/null +++ b/packages/components/figma/ToggleButton.figma.tsx @@ -0,0 +1,21 @@ +import type { ToggleButtonProps } from '../src'; + +import figma from '@figma/code-connect'; + +import { ToggleButton } from '../src'; + +figma.connect( + ToggleButton, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=1-29278', + { + props: { + children: figma.string('Label'), + size: figma.enum>('Size', { + Small: 'small', + Medium: 'medium', + Large: 'large', + }), + }, + example: ({ children, size }) => {children}, + }, +); diff --git a/packages/components/stories/ToggleButtonGroup.stories.tsx b/packages/components/stories/ToggleButtonGroup.stories.tsx index 527ec769c..c38a7b42d 100644 --- a/packages/components/stories/ToggleButtonGroup.stories.tsx +++ b/packages/components/stories/ToggleButtonGroup.stories.tsx @@ -8,7 +8,14 @@ import { ToggleIconButton } from '../src/ToggleIconButton'; const meta: Meta = { component: ToggleButtonGroup, subcomponents: { ToggleButton } as Record>, - title: 'Components/Buttons/ToggleButtonGroup', + title: 'Components/Buttons/ToggleButton/ToggleButtonGroup', + tags: ['autodocs'], + parameters: { + design: { + type: 'figma', + url: 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=1-37543', + }, + }, }; export default meta; diff --git a/packages/components/stories/ToggleIconButton.stories.tsx b/packages/components/stories/ToggleIconButton.stories.tsx index e2638dce8..902008643 100644 --- a/packages/components/stories/ToggleIconButton.stories.tsx +++ b/packages/components/stories/ToggleIconButton.stories.tsx @@ -7,6 +7,13 @@ import { ToggleIconButton } from '../src/ToggleIconButton'; const meta: Meta = { component: ToggleIconButton, title: 'Components/Buttons/ToggleIconButton', + tags: ['autodocs'], + parameters: { + design: { + type: 'figma', + url: 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=14355-114625&m=dev', + }, + }, }; export default meta; From 6998ad2353d8167de7833a377bba4b15c02f81da Mon Sep 17 00:00:00 2001 From: Susanna Nevalainen Date: Mon, 4 Aug 2025 18:02:29 +0200 Subject: [PATCH 09/36] feat(components): overview story draft --- .../components/stories/Overview.stories.tsx | 848 ++++++++++++++++++ 1 file changed, 848 insertions(+) create mode 100644 packages/components/stories/Overview.stories.tsx diff --git a/packages/components/stories/Overview.stories.tsx b/packages/components/stories/Overview.stories.tsx new file mode 100644 index 000000000..dfed2791b --- /dev/null +++ b/packages/components/stories/Overview.stories.tsx @@ -0,0 +1,848 @@ +import type { Meta, StoryObj } from '@storybook/react-vite'; +import type React from 'react'; + +import { Icon } from '@launchpad-ui/icons'; +import { vars } from '@launchpad-ui/vars'; + +// Import all components for the overview +import { Alert } from '../src/Alert'; +import { Avatar } from '../src/Avatar'; +import { Breadcrumb, Breadcrumbs } from '../src/Breadcrumbs'; +import { Button } from '../src/Button'; +import { ButtonGroup } from '../src/ButtonGroup'; +import { Checkbox } from '../src/Checkbox'; +import { CheckboxGroup } from '../src/CheckboxGroup'; +import { Code } from '../src/Code'; +import { DateField } from '../src/DateField'; +import { Disclosure } from '../src/Disclosure'; +import { DisclosureGroup } from '../src/DisclosureGroup'; +import { DropZone } from '../src/DropZone'; +import { FieldGroup } from '../src/FieldGroup'; +import { FileTrigger } from '../src/FileTrigger'; +import { GridList, GridListItem } from '../src/GridList'; +import { Group } from '../src/Group'; +import { Heading } from '../src/Heading'; +import { IconButton } from '../src/IconButton'; +import { Input } from '../src/Input'; +import { Label } from '../src/Label'; +import { Link } from '../src/Link'; +import { LinkButton } from '../src/LinkButton'; +import { LinkIconButton } from '../src/LinkIconButton'; +import { ListBox, ListBoxItem } from '../src/ListBox'; +import { Meter } from '../src/Meter'; +import { NumberField } from '../src/NumberField'; +import { ProgressBar } from '../src/ProgressBar'; +import { RadioGroup } from '../src/RadioGroup'; +import { SearchField } from '../src/SearchField'; +import { Switch } from '../src/Switch'; +import { Cell, Column, Row, Table, TableBody, TableHeader } from '../src/Table'; +import { Tab, TabList, TabPanel, Tabs } from '../src/Tabs'; +import { Tag, TagGroup, TagList } from '../src/TagGroup'; +import { Text } from '../src/Text'; +import { TextField } from '../src/TextField'; +import { ToggleButton } from '../src/ToggleButton'; +import { ToggleButtonGroup } from '../src/ToggleButtonGroup'; +import { ToggleIconButton } from '../src/ToggleIconButton'; +import { Toolbar } from '../src/Toolbar'; +import { Tree, TreeItem, TreeItemContent } from '../src/Tree'; + +// Component showcase data +const componentCategories = [ + { + category: 'Buttons', + components: [ + { + name: 'Button', + component: ( +
+ + + + +
+ ), + storyPath: 'components-buttons-button--docs', + }, + { + name: 'IconButton', + component: ( +
+ + + + +
+ ), + storyPath: 'components-buttons-iconbutton--docs', + }, + { + name: 'ButtonGroup', + component: ( +
+ + + + + + + + + + + + +
+ ), + storyPath: 'components-buttons-buttongroup--docs', + }, + { + name: 'FileTrigger', + component: ( + + + + ), + storyPath: 'components-buttons-filetrigger--docs', + }, + { + name: 'ToggleButton', + component: ( +
+ Toggle + Toggle + Toggle + Toggle +
+ ), + storyPath: 'components-buttons-togglebutton--docs', + }, + { + name: 'ToggleButtonGroup', + component: ( + + + First + + Second + Third + + ), + storyPath: 'components-buttons-togglebutton-togglebuttongroup--docs', + }, + { + name: 'ToggleIconButton', + component: ( +
+ + + + +
+ ), + storyPath: 'components-buttons-toggleiconbutton--docs', + }, + ], + }, + { + category: 'Content', + components: [ + { + name: 'Text', + component: ( +
+ Large text + Medium text + Small text +
+ ), + storyPath: 'components-content-text--docs', + }, + { + name: 'Heading', + component: ( +
+ Large heading + Medium heading + Small heading +
+ ), + storyPath: 'components-content-heading--docs', + }, + { + name: 'Label', + component: ( +
+ + +
+ ), + storyPath: 'components-content-label--docs', + }, + { + name: 'Code', + component: ( +
+ console.log('hello') + console.log('hello') +
+ ), + storyPath: 'components-content-code--docs', + }, + { + name: 'Avatar', + component: ( + + ), + storyPath: 'components-content-avatar--docs', + }, + { + name: 'Group', + component: ( + + Grouped content + + ), + storyPath: 'components-content-group--docs', + }, + { + name: 'Toolbar', + component: ( + + + + + ), + storyPath: 'components-content-toolbar--docs', + }, + ], + }, + { + category: 'Forms', + components: [ + { + name: 'TextField', + component: ( + + + + + ), + storyPath: 'components-forms-textfield--docs', + }, + { + name: 'NumberField', + component: ( + + + + + ), + storyPath: 'components-forms-numberfield--docs', + }, + { + name: 'SearchField', + component: ( + + + + + ), + storyPath: 'components-forms-searchfield--docs', + }, + { + name: 'Checkbox', + component: Check me, + storyPath: 'components-forms-checkbox--docs', + }, + { + name: 'CheckboxGroup', + component: ( + + + Option A + Option B + + ), + storyPath: 'components-forms-checkboxgroup--docs', + }, + { + name: 'RadioGroup', + component: ( + + + {/* Radio items would go here */} + + ), + storyPath: 'components-forms-radiogroup--docs', + }, + { + name: 'Switch', + component: Toggle setting, + storyPath: 'components-forms-switch--docs', + }, + { + name: 'FieldGroup', + component: ( + + + + + + + ), + storyPath: 'components-forms-fieldgroup--docs', + }, + ], + }, + { + category: 'Navigation', + components: [ + { + name: 'Link', + component: ( +
+ Sample Link + + Sample Link + +
+ ), + storyPath: 'components-navigation-link--docs', + }, + { + name: 'LinkButton', + component: Link Button, + storyPath: 'components-navigation-linkbutton--docs', + }, + { + name: 'LinkIconButton', + component: , + storyPath: 'components-navigation-linkiconbutton--docs', + }, + { + name: 'Breadcrumbs', + component: ( + + + Home + + + Category + + + Page + + + ), + storyPath: 'components-navigation-breadcrumbs--docs', + }, + { + name: 'Disclosure', + component: ( + + + Hidden content + + ), + storyPath: 'components-navigation-disclosure--docs', + }, + { + name: 'DisclosureGroup', + component: ( + + + + Content 1 + + + ), + storyPath: 'components-navigation-disclosuregroup--docs', + }, + { + name: 'Tabs', + component: ( + + + Tab 1 + Tab 2 + + Content 1 + Content 2 + + ), + storyPath: 'components-navigation-tabs--docs', + }, + ], + }, + { + category: 'Collections', + components: [ + { + name: 'Table', + component: ( + + + Name + Status + + + + Item 1 + Active + + +
+ ), + storyPath: 'components-collections-table--docs', + }, + { + name: 'GridList', + component: ( + + Item 1 + Item 2 + Item 3 + + ), + storyPath: 'components-collections-gridlist--docs', + }, + { + name: 'ListBox', + component: ( + + Option 1 + Option 2 + Option 3 + + ), + storyPath: 'components-collections-listbox--docs', + }, + { + name: 'Tree', + component: ( + + + Item 1 + + + Item 2 + + + ), + storyPath: 'components-collections-tree--docs', + }, + { + name: 'TagGroup', + component: ( + + + + React + TypeScript + + + ), + storyPath: 'components-collections-taggroup--docs', + }, + { + name: 'Menu', + component: , + storyPath: 'components-collections-menu--docs', + }, + ], + }, + { + category: 'Status', + components: [ + { + name: 'Alert', + component: This is an alert message, + storyPath: 'components-status-alert--docs', + }, + { + name: 'Toast', + component: ( +
+ Toast notification +
+ ), + storyPath: 'components-status-toast--docs', + }, + { + name: 'ProgressBar', + component: , + storyPath: 'components-status-progressbar--docs', + }, + { + name: 'Meter', + component: , + storyPath: 'components-status-meter--docs', + }, + ], + }, + { + category: 'Pickers', + components: [ + { + name: 'Select', + component: ( +
+ + +
+ ), + storyPath: 'components-pickers-select--docs', + }, + { + name: 'ComboBox', + component: ( +
+ +
+ + +
+
+ ), + storyPath: 'components-pickers-combobox--docs', + }, + ], + }, + { + category: 'Overlays', + components: [ + { + name: 'Modal', + component: , + storyPath: 'components-overlays-modal--docs', + }, + { + name: 'Popover', + component: , + storyPath: 'components-overlays-popover--docs', + }, + { + name: 'Tooltip', + component: , + storyPath: 'components-overlays-tooltip--docs', + }, + ], + }, + { + category: 'Date and Time', + components: [ + { + name: 'Calendar', + component: ( +
+
Dec 2024
+
+
S
+
M
+
T
+
W
+
T
+
F
+
S
+
+
+
+
+
+
+
+
1
+
2
+
+
+ ), + storyPath: 'components-date-and-time-calendar--docs', + }, + { + name: 'DateField', + component: ( + + + + + ), + storyPath: 'components-date-and-time-datefield--docs', + }, + { + name: 'DatePicker', + component: ( +
+ + + + + +
+ ), + storyPath: 'components-date-and-time-datepicker--docs', + }, + ], + }, + { + category: 'Drag and drop', + components: [ + { + name: 'DropZone', + component: ( + + Drop files here + + ), + storyPath: 'components-drag-and-drop-dropzone--docs', + }, + ], + }, + { + category: 'Recipes', + components: [ + { + name: 'CopyToClipboard', + component: ( +
+ +
+ ), + storyPath: 'recipes-copytoclipboard--docs', + }, + { + name: 'ComboBoxDialog', + component: ( +
+ + + Dialog +
+ ), + storyPath: 'recipes-comboboxdialog--docs', + }, + { + name: 'DisabledWithTooltip', + component: ( +
+ + + Tooltip +
+ ), + storyPath: 'recipes-disabledwithtooltip--docs', + }, + { + name: 'ListBoxTooltip', + component: ( +
+
+ ListBox +
+ + Tooltip +
+ ), + storyPath: 'recipes-listboxtooltip--docs', + }, + { + name: 'Pagination', + component: ( +
+ + + + ... +
+ ), + storyPath: 'recipes-pagination--docs', + }, + { + name: 'RadioButtonGroup', + component: ( +
+ + + + + Group +
+ ), + storyPath: 'recipes-radiobuttongroup--docs', + }, + ], + }, +]; + +// Component card styling +const cardStyles = { + borderRadius: vars.borderRadius.medium, + padding: vars.spacing[400], + aspectRatio: '1', + display: 'flex', + flexDirection: 'column' as const, + justifyContent: 'space-between', + alignItems: 'flex-start', + backgroundColor: vars.color.bg.ui.secondary, + textDecoration: 'none', + color: 'inherit', + transition: 'all 0.2s ease', +}; + +const ComponentCard = ({ + name, + component, + storyPath, +}: { + name: string; + component: React.ReactNode; + storyPath: string; +}) => { + return ( +
+ {name} +
+ {component} +
+
+ + + + Code + + + + + + Docs + + +
+
+ ); +}; + +const Overview = () => { + return ( +
+ {componentCategories.map(({ category, components }) => ( +
+ {category} +
+ {components.map(({ name, component, storyPath }) => ( + + ))} +
+
+ ))} +
+ ); +}; + +const meta: Meta = { + title: 'Component Overview', + component: Overview, + tags: ['!dev'], + parameters: { + layout: 'fullscreen', + }, +}; + +export default meta; + +type Story = StoryObj; + +/** + * Here you can find all available components in the design system. Click on any component to view its documentation and examples. + */ +export const AllComponents: Story = { + name: 'All Components', + render: () => , + parameters: { + controls: { disable: true }, + actions: { disable: true }, + + canvas: { + layout: 'fullscreen', + }, + }, +}; From 5ca11477339773a6238de7620bc3a0595a7cdea8 Mon Sep 17 00:00:00 2001 From: Susanna Nevalainen Date: Tue, 5 Aug 2025 00:27:42 +0200 Subject: [PATCH 10/36] feat(components): ai figma connect and figma design addon two way linking --- packages/components/figma/Alert.figma.tsx | 38 +++++++++++ packages/components/figma/Avatar.figma.tsx | 32 +++++++++ packages/components/figma/BadgeIcon.figma.tsx | 46 +++++++++++++ packages/components/figma/Calendar.figma.tsx | 23 +++++++ packages/components/figma/Checkbox.figma.tsx | 32 +++++++++ .../components/figma/CheckboxGroup.figma.tsx | 36 ++++++++++ .../components/figma/Collection.figma.tsx | 33 +++++++++ packages/components/figma/DateField.figma.tsx | 33 +++++++++ .../components/figma/DatePicker.figma.tsx | 33 +++++++++ .../components/figma/FieldGroup.figma.tsx | 32 +++++++++ packages/components/figma/Label.figma.tsx | 26 +++++++ packages/components/figma/Link.figma.tsx | 43 ++++++++++++ .../components/figma/LinkButton.figma.tsx | 20 ++++++ .../components/figma/LinkIconButton.figma.tsx | 20 ++++++ packages/components/figma/Menu.figma.tsx | 29 ++++++++ packages/components/figma/Modal.figma.tsx | 36 ++++++++++ .../components/figma/NumberField.figma.tsx | 37 ++++++++++ packages/components/figma/Popover.figma.tsx | 27 ++++++++ .../components/figma/ProgressBar.figma.tsx | 33 +++++++++ packages/components/figma/Radio.figma.tsx | 32 +++++++++ .../components/figma/SearchField.figma.tsx | 52 ++++++++++++++ packages/components/figma/Select.figma.tsx | 55 +++++++++++++++ packages/components/figma/Switch.figma.tsx | 43 ++++++++++++ packages/components/figma/Tab.figma.tsx | 15 ++++ packages/components/figma/Table.figma.tsx | 42 ++++++++++++ packages/components/figma/Tabs.figma.tsx | 41 +++++++++++ packages/components/figma/TagGroup.figma.tsx | 25 +++++++ packages/components/figma/TextField.figma.tsx | 68 +++++++++++++++++++ packages/components/figma/Toast.figma.tsx | 58 ++++++++++++++++ .../figma/ToggleIconButton.figma.tsx | 25 +++++++ packages/components/figma/Tooltip.figma.tsx | 31 +++++++++ packages/components/stories/Alert.stories.tsx | 6 ++ .../components/stories/Avatar.stories.tsx | 6 ++ .../components/stories/Button.stories.tsx | 2 +- .../components/stories/Calendar.stories.tsx | 4 ++ .../components/stories/Checkbox.stories.tsx | 6 ++ .../stories/CheckboxGroup.stories.tsx | 6 ++ .../components/stories/DateField.stories.tsx | 6 ++ .../components/stories/DatePicker.stories.tsx | 6 ++ .../stories/DateRangePicker.stories.tsx | 6 ++ .../components/stories/FieldGroup.stories.tsx | 6 ++ .../components/stories/Heading.stories.tsx | 4 ++ packages/components/stories/Label.stories.tsx | 4 ++ packages/components/stories/Link.stories.tsx | 6 ++ .../components/stories/LinkButton.stories.tsx | 6 ++ .../stories/LinkIconButton.stories.tsx | 6 ++ packages/components/stories/Menu.stories.tsx | 6 ++ packages/components/stories/Modal.stories.tsx | 6 ++ .../stories/NumberField.stories.tsx | 6 ++ .../components/stories/Popover.stories.tsx | 6 ++ .../stories/ProgressBar.stories.tsx | 6 ++ .../components/stories/RadioGroup.stories.tsx | 6 ++ .../stories/RangeCalendar.stories.tsx | 4 ++ .../stories/SearchField.stories.tsx | 6 ++ .../components/stories/Select.stories.tsx | 6 ++ .../components/stories/Switch.stories.tsx | 6 ++ packages/components/stories/Table.stories.tsx | 6 ++ packages/components/stories/Tabs.stories.tsx | 6 ++ .../components/stories/TagGroup.stories.tsx | 6 ++ packages/components/stories/Text.stories.tsx | 4 ++ .../components/stories/TextField.stories.tsx | 6 ++ .../components/stories/TimeField.stories.tsx | 4 ++ packages/components/stories/Toast.stories.tsx | 6 ++ .../stories/ToggleButton.stories.tsx | 6 ++ .../stories/ToggleIconButton.stories.tsx | 2 +- .../components/stories/Tooltip.stories.tsx | 6 ++ 66 files changed, 1284 insertions(+), 2 deletions(-) create mode 100644 packages/components/figma/Alert.figma.tsx create mode 100644 packages/components/figma/Avatar.figma.tsx create mode 100644 packages/components/figma/BadgeIcon.figma.tsx create mode 100644 packages/components/figma/Calendar.figma.tsx create mode 100644 packages/components/figma/Checkbox.figma.tsx create mode 100644 packages/components/figma/CheckboxGroup.figma.tsx create mode 100644 packages/components/figma/Collection.figma.tsx create mode 100644 packages/components/figma/DateField.figma.tsx create mode 100644 packages/components/figma/DatePicker.figma.tsx create mode 100644 packages/components/figma/FieldGroup.figma.tsx create mode 100644 packages/components/figma/Label.figma.tsx create mode 100644 packages/components/figma/Link.figma.tsx create mode 100644 packages/components/figma/LinkButton.figma.tsx create mode 100644 packages/components/figma/LinkIconButton.figma.tsx create mode 100644 packages/components/figma/Menu.figma.tsx create mode 100644 packages/components/figma/Modal.figma.tsx create mode 100644 packages/components/figma/NumberField.figma.tsx create mode 100644 packages/components/figma/Popover.figma.tsx create mode 100644 packages/components/figma/ProgressBar.figma.tsx create mode 100644 packages/components/figma/Radio.figma.tsx create mode 100644 packages/components/figma/SearchField.figma.tsx create mode 100644 packages/components/figma/Select.figma.tsx create mode 100644 packages/components/figma/Switch.figma.tsx create mode 100644 packages/components/figma/Tab.figma.tsx create mode 100644 packages/components/figma/Table.figma.tsx create mode 100644 packages/components/figma/Tabs.figma.tsx create mode 100644 packages/components/figma/TagGroup.figma.tsx create mode 100644 packages/components/figma/TextField.figma.tsx create mode 100644 packages/components/figma/Toast.figma.tsx create mode 100644 packages/components/figma/ToggleIconButton.figma.tsx create mode 100644 packages/components/figma/Tooltip.figma.tsx diff --git a/packages/components/figma/Alert.figma.tsx b/packages/components/figma/Alert.figma.tsx new file mode 100644 index 000000000..8c5328ada --- /dev/null +++ b/packages/components/figma/Alert.figma.tsx @@ -0,0 +1,38 @@ +import figma from '@figma/code-connect'; + +import { Alert } from '../src/Alert'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from your code props to Figma properties. + * You should check this is correct, and update the `example` function + * to return the code example you'd like to see in Figma + */ + +figma.connect( + Alert, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=8003%3A631', + { + props: { + // These props were automatically mapped based on your linked code: + isDismissable: figma.boolean('Dismissible'), + status: figma.enum('State', { + Neutral: 'neutral', + Information: 'info', + Warning: 'warning', + }), + variant: figma.enum('Variant', { + Inline: 'inline', + }), + // No matching props could be found for these Figma properties: + // "dismissible": figma.boolean('Dismissible'), + // "actions": figma.boolean('Actions'), + // "message": figma.string('Message'), + // "header": figma.string('Header'), + // "header": figma.boolean('Header?') + }, + example: (props) => ( + + ), + }, +); diff --git a/packages/components/figma/Avatar.figma.tsx b/packages/components/figma/Avatar.figma.tsx new file mode 100644 index 000000000..baf0e9f3f --- /dev/null +++ b/packages/components/figma/Avatar.figma.tsx @@ -0,0 +1,32 @@ +import figma from '@figma/code-connect'; + +import { Avatar } from '../src/Avatar'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from your code props to Figma properties. + * You should check this is correct, and update the `example` function + * to return the code example you'd like to see in Figma + */ + +figma.connect( + Avatar, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=1%3A43538', + { + props: { + // These props were automatically mapped based on your linked code: + size: figma.enum('Size', { + Small: 'small', + Medium: 'medium', + Large: 'large', + }), + // No matching props could be found for these Figma properties: + // "kind": figma.enum('Kind', { + // "Initials": "initials", + // "Icon": "icon", + // "Image": "image" + // }) + }, + example: (props) => , + }, +); diff --git a/packages/components/figma/BadgeIcon.figma.tsx b/packages/components/figma/BadgeIcon.figma.tsx new file mode 100644 index 000000000..ee2d1cfa6 --- /dev/null +++ b/packages/components/figma/BadgeIcon.figma.tsx @@ -0,0 +1,46 @@ +import figma from '@figma/code-connect'; + +import { BadgeIcon } from '../../icons/src/BadgeIcon'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from your code props to Figma properties. + * You should check this is correct, and update the `example` function + * to return the code example you'd like to see in Figma + */ + +figma.connect( + BadgeIcon, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=1%3A3636', + { + props: { + // These props were automatically mapped based on your linked code: + size: figma.enum('Size', { + '16 (tiny)': 'tiny', + '24 (small)': 'small', + '36 (medium)': 'medium', + '64 (large)': 'large', + }), + // No matching props could be found for these Figma properties: + // "icon": figma.instance('icon'), + // "color": figma.enum('Color', { + // "Gray": "gray", + // "Blue": "blue", + // "Cyan": "cyan", + // "Purple": "purple", + // "Pink": "pink", + // "Orange": "orange", + // "Yellow": "yellow", + // "Green": "green", + // "Gradient 1": "gradient-1", + // "Gradient 2": "gradient-2", + // "Gradient 3": "gradient-3", + // "Gradient 4": "gradient-4", + // "Gradient 5": "gradient-5", + // "Gradient 6": "gradient-6", + // "Gradient 7": "gradient-7" + // }) + }, + example: (props) => , + }, +); diff --git a/packages/components/figma/Calendar.figma.tsx b/packages/components/figma/Calendar.figma.tsx new file mode 100644 index 000000000..e262a74f1 --- /dev/null +++ b/packages/components/figma/Calendar.figma.tsx @@ -0,0 +1,23 @@ +import figma from '@figma/code-connect'; + +import { Calendar } from '../src/Calendar'; + +/** + * -- This file was auto-generated by Code Connect -- + * None of your props could be automatically mapped to Figma properties. + * You should update the `props` object to include a mapping from your + * code props to Figma properties, and update the `example` function to + * return the code example you'd like to see in Figma + */ + +figma.connect( + Calendar, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=10675%3A815', + { + props: { + // No matching props could be found for these Figma properties: + // "buttons": figma.boolean('Buttons?') + }, + example: (props) => , + }, +); diff --git a/packages/components/figma/Checkbox.figma.tsx b/packages/components/figma/Checkbox.figma.tsx new file mode 100644 index 000000000..cfd42fd5e --- /dev/null +++ b/packages/components/figma/Checkbox.figma.tsx @@ -0,0 +1,32 @@ +import figma from '@figma/code-connect'; + +import { Checkbox } from '../src/Checkbox'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from your code props to Figma properties. + * You should check this is correct, and update the `example` function + * to return the code example you'd like to see in Figma + */ + +figma.connect( + Checkbox, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=1%3A32735', + { + props: { + // These props were automatically mapped based on your linked code: + isIndeterminate: figma.enum('Check', { + Indeterminate: true, + }), + // No matching props could be found for these Figma properties: + // "hasLabel": figma.boolean('Has label'), + // "state": figma.enum('State', { + // "Base": "base", + // "Disabled": "disabled", + // "Invalid": "invalid" + // }), + // "focus": figma.boolean('Focus') + }, + example: (props) => , + }, +); diff --git a/packages/components/figma/CheckboxGroup.figma.tsx b/packages/components/figma/CheckboxGroup.figma.tsx new file mode 100644 index 000000000..5b23e3c77 --- /dev/null +++ b/packages/components/figma/CheckboxGroup.figma.tsx @@ -0,0 +1,36 @@ +import figma from '@figma/code-connect'; + +import { CheckboxGroup } from '../src/CheckboxGroup'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from your code props to Figma properties. + * You should check this is correct, and update the `example` function + * to return the code example you'd like to see in Figma + */ + +figma.connect( + CheckboxGroup, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=1%3A33127', + { + props: { + // These props were automatically mapped based on your linked code: + name: figma.string('Validation message'), + id: figma.string('Validation message'), + // No matching props could be found for these Figma properties: + // "description": figma.string('Description'), + // "validationMessage": figma.string('Validation message'), + // "description": figma.boolean('Description?'), + // "hasLabel": figma.boolean('Has label?'), + // "states": figma.enum('States', { + // "Default": "default", + // "Invalid": "invalid" + // }), + // "direction": figma.enum('Direction', { + // "Vertical": "vertical", + // "Horizontal": "horizontal" + // }) + }, + example: (props) => , + }, +); diff --git a/packages/components/figma/Collection.figma.tsx b/packages/components/figma/Collection.figma.tsx new file mode 100644 index 000000000..ced5b6b68 --- /dev/null +++ b/packages/components/figma/Collection.figma.tsx @@ -0,0 +1,33 @@ +import figma from '@figma/code-connect'; + +import { Collection } from '../src/Collection'; + +/** + * -- This file was auto-generated by Code Connect -- + * None of your props could be automatically mapped to Figma properties. + * You should update the `props` object to include a mapping from your + * code props to Figma properties, and update the `example` function to + * return the code example you'd like to see in Figma + */ + +figma.connect( + Collection, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=4655%3A50682', + { + props: { + // No matching props could be found for these Figma properties: + // "contentType": figma.enum('Content type', { + // "Basic content": "basic-content", + // "Placeholder swap": "placeholder-swap", + // "Numeric": "numeric" + // }), + // "sort": figma.enum('Sort', { + // "None": "none", + // "Descending": "descending", + // "Ascending": "ascending" + // }), + // "2ndRow": figma.boolean('2nd row?') + }, + example: (props) => , + }, +); diff --git a/packages/components/figma/DateField.figma.tsx b/packages/components/figma/DateField.figma.tsx new file mode 100644 index 000000000..e7d6c5e4d --- /dev/null +++ b/packages/components/figma/DateField.figma.tsx @@ -0,0 +1,33 @@ +import figma from '@figma/code-connect'; + +import { DateField } from '../src/DateField'; + +/** + * -- This file was auto-generated by Code Connect -- + * None of your props could be automatically mapped to Figma properties. + * You should update the `props` object to include a mapping from your + * code props to Figma properties, and update the `example` function to + * return the code example you'd like to see in Figma + */ + +figma.connect( + DateField, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=10726%3A60155', + { + props: { + // No matching props could be found for these Figma properties: + // "helpText": figma.boolean('Help text?'), + // "helpText": figma.string('Help text'), + // "label": figma.boolean('Label?'), + // "state": figma.enum('State', { + // "Resting": "resting", + // ":hover": "-hover", + // ":focus-visible": "-focus-visible", + // ":active": "-active", + // "Invalid": "invalid", + // "Disabled": "disabled" + // }) + }, + example: (props) => , + }, +); diff --git a/packages/components/figma/DatePicker.figma.tsx b/packages/components/figma/DatePicker.figma.tsx new file mode 100644 index 000000000..05041aec6 --- /dev/null +++ b/packages/components/figma/DatePicker.figma.tsx @@ -0,0 +1,33 @@ +import figma from '@figma/code-connect'; + +import { DatePicker } from '../src/DatePicker'; + +/** + * -- This file was auto-generated by Code Connect -- + * None of your props could be automatically mapped to Figma properties. + * You should update the `props` object to include a mapping from your + * code props to Figma properties, and update the `example` function to + * return the code example you'd like to see in Figma + */ + +figma.connect( + DatePicker, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=10833%3A38082', + { + props: { + // No matching props could be found for these Figma properties: + // "label": figma.boolean('Label?'), + // "helpText": figma.boolean('Help text?'), + // "helpText": figma.string('Help text'), + // "state": figma.enum('State', { + // "Resting": "resting", + // ":hover": "-hover", + // ":focus-visible": "-focus-visible", + // ":active": "-active", + // "Invalid": "invalid", + // "Disabled": "disabled" + // }) + }, + example: (props) => , + }, +); diff --git a/packages/components/figma/FieldGroup.figma.tsx b/packages/components/figma/FieldGroup.figma.tsx new file mode 100644 index 000000000..e4c4b1c79 --- /dev/null +++ b/packages/components/figma/FieldGroup.figma.tsx @@ -0,0 +1,32 @@ +import figma from '@figma/code-connect'; + +import { FieldGroup } from '../src/FieldGroup'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from your code props to Figma properties. + * You should check this is correct, and update the `example` function + * to return the code example you'd like to see in Figma + */ + +figma.connect( + FieldGroup, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=1%3A33319', + { + props: { + // These props were automatically mapped based on your linked code: + name: figma.string('Validation message'), + // No matching props could be found for these Figma properties: + // "legend": figma.boolean('Legend?'), + // "legend": figma.string('Legend'), + // "invalid": figma.boolean('Invalid?'), + // "validationMessage": figma.string('Validation message'), + // "customComponent": figma.instance('Custom component'), + // "variant": figma.enum('Variant', { + // "Default": "default", + // "Custom": "custom" + // }) + }, + example: (props) => , + }, +); diff --git a/packages/components/figma/Label.figma.tsx b/packages/components/figma/Label.figma.tsx new file mode 100644 index 000000000..f555a4aa8 --- /dev/null +++ b/packages/components/figma/Label.figma.tsx @@ -0,0 +1,26 @@ +import figma from '@figma/code-connect'; + +import { Label } from '../src/Label'; + +/** + * -- This file was auto-generated by Code Connect -- + * None of your props could be automatically mapped to Figma properties. + * You should update the `props` object to include a mapping from your + * code props to Figma properties, and update the `example` function to + * return the code example you'd like to see in Figma + */ + +figma.connect( + Label, + 'https://www.figma.com/design/98HKKXL2dTle29ikJ3tzk7/%F0%9F%9A%80-LaunchPad?node-id=1%3A34227', + { + props: { + // No matching props could be found for these Figma properties: + // "description": figma.string('Description'), + // "description": figma.boolean('Description?'), + // "required": figma.boolean('Required?'), + // "label": figma.string('Label') + }, + example: (props) =>