diff options
Diffstat (limited to 'src/components/atoms')
58 files changed, 2086 insertions, 2883 deletions
diff --git a/src/components/atoms/buttons/button-link/button-link.mdx b/src/components/atoms/buttons/button-link/button-link.mdx new file mode 100644 index 0000000..e22471e --- /dev/null +++ b/src/components/atoms/buttons/button-link/button-link.mdx @@ -0,0 +1,71 @@ +import { ArgTypes, Canvas, Meta, Primary } from '@storybook/blocks'; +import * as ButtonLinkStories from './button-link.stories'; + +<Meta of={ButtonLinkStories} /> + +# Button + +<Primary /> + +## Kind + +The button appearance can change depending on its kind. + +### Primary + +<Canvas of={ButtonLinkStories.Primary} /> + +### Secondary (default) + +<Canvas of={ButtonLinkStories.Secondary} /> + +### Tertiary + +<Canvas of={ButtonLinkStories.Tertiary} /> + +## States + +It can be: +* enabled, +* disabled +* external. + +### Enabled (default) + +<Canvas of={ButtonLinkStories.Enabled} /> + +### Disabled + +<Canvas of={ButtonLinkStories.Disabled} /> + +### External + +<Canvas of={ButtonLinkStories.ExternalLink} /> + +## Shapes + +It can either: +* be a circle, +* be a rectangle +* be a square, +* or have an automatic shape. + +### Circle + +<Canvas of={ButtonLinkStories.Circle} /> + +### Rectangle (default) + +<Canvas of={ButtonLinkStories.Rectangle} /> + +### Square + +<Canvas of={ButtonLinkStories.Square} /> + +### Auto + +<Canvas of={ButtonLinkStories.Auto} /> + +## Props + +<ArgTypes of={ButtonLinkStories} /> diff --git a/src/components/atoms/buttons/button-link/button-link.stories.ts b/src/components/atoms/buttons/button-link/button-link.stories.ts new file mode 100644 index 0000000..bbf940c --- /dev/null +++ b/src/components/atoms/buttons/button-link/button-link.stories.ts @@ -0,0 +1,99 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ButtonLink } from './button-link'; + +const meta = { + component: ButtonLink, + title: 'Atoms/Buttons/ButtonLink', +} satisfies Meta<typeof ButtonLink>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Default: Story = { + args: { + children: 'Button Link', + isDisabled: false, + to: '#', + }, +}; + +export const Primary: Story = { + name: 'Kind: Primary', + args: { + ...Default.args, + kind: 'primary', + }, +}; + +export const Secondary: Story = { + name: 'Kind: Secondary', + args: { + ...Default.args, + kind: 'secondary', + }, +}; + +export const Tertiary: Story = { + name: 'Kind: Tertiary', + args: { + ...Default.args, + kind: 'tertiary', + }, +}; + +export const Enabled: Story = { + name: 'State: Enabled', + args: { + ...Default.args, + isDisabled: false, + }, +}; + +export const Disabled: Story = { + name: 'State: Disabled', + args: { + ...Default.args, + isDisabled: true, + }, +}; + +export const ExternalLink: Story = { + name: 'State: External', + args: { + ...Default.args, + isExternal: true, + }, +}; + +export const Circle: Story = { + name: 'Shape: Circle', + args: { + ...Default.args, + shape: 'circle', + }, +}; + +export const Rectangle: Story = { + name: 'Shape: Rectangle', + args: { + ...Default.args, + shape: 'rectangle', + }, +}; + +export const Square: Story = { + name: 'Shape: Square', + args: { + ...Default.args, + shape: 'square', + }, +}; + +export const Auto: Story = { + name: 'Shape: Auto', + args: { + ...Default.args, + shape: 'auto', + }, +}; diff --git a/src/components/atoms/buttons/button-link/button-link.stories.tsx b/src/components/atoms/buttons/button-link/button-link.stories.tsx deleted file mode 100644 index f048ce9..0000000 --- a/src/components/atoms/buttons/button-link/button-link.stories.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { ButtonLink } from './button-link'; - -/** - * ButtonLink - Storybook Meta - */ -export default { - title: 'Atoms/Buttons/ButtonLink', - component: ButtonLink, - args: { - isExternal: false, - shape: 'rectangle', - }, - argTypes: { - children: { - control: { - type: 'text', - }, - description: 'The link body.', - type: { - name: 'string', - required: true, - }, - }, - isExternal: { - control: { - type: 'boolean', - }, - description: 'Determine if the link is an external link.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - kind: { - control: { - type: 'select', - }, - description: 'The link kind.', - options: ['primary', 'secondary', 'tertiary'], - table: { - category: 'Options', - defaultValue: { summary: 'secondary' }, - }, - type: { - name: 'string', - required: false, - }, - }, - shape: { - control: { - type: 'select', - }, - description: 'The link shape.', - options: ['circle', 'rectangle', 'square'], - table: { - category: 'Options', - defaultValue: { summary: 'rectangle' }, - }, - type: { - name: 'string', - required: false, - }, - }, - to: { - control: { - type: 'text', - }, - description: 'The link target.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof ButtonLink>; - -const Template: ComponentStory<typeof ButtonLink> = (args) => ( - <ButtonLink {...args} /> -); - -/** - * ButtonLink Story - Primary - */ -export const Primary = Template.bind({}); -Primary.args = { - children: 'Link', - kind: 'primary', - to: '#', -}; - -/** - * ButtonLink Story - Secondary - */ -export const Secondary = Template.bind({}); -Secondary.args = { - children: 'Link', - kind: 'secondary', - to: '#', -}; - -/** - * ButtonLink Story - Tertiary - */ -export const Tertiary = Template.bind({}); -Tertiary.args = { - children: 'Link', - kind: 'tertiary', - to: '#', -}; diff --git a/src/components/atoms/buttons/button/button.mdx b/src/components/atoms/buttons/button/button.mdx new file mode 100644 index 0000000..d90156e --- /dev/null +++ b/src/components/atoms/buttons/button/button.mdx @@ -0,0 +1,80 @@ +import { ArgTypes, Canvas, Meta, Primary } from '@storybook/blocks'; +import * as ButtonStories from './button.stories'; + +<Meta of={ButtonStories} /> + +# Button + +<Primary /> + +## Kind + +The button appearance can change depending on its kind. + +### Primary + +<Canvas of={ButtonStories.Primary} /> + +### Secondary (default) + +<Canvas of={ButtonStories.Secondary} /> + +### Tertiary + +<Canvas of={ButtonStories.Tertiary} /> + +### Neutral + +<Canvas of={ButtonStories.Neutral} /> + +## States + +It can either: +* be enabled, +* be disabled +* indicate a loading state, +* indicate a pressed state. + +### Enabled (default) + +<Canvas of={ButtonStories.Enabled} /> + +### Disabled + +<Canvas of={ButtonStories.Disabled} /> + +### Loading + +<Canvas of={ButtonStories.Loading} /> + +### Pressed + +<Canvas of={ButtonStories.Pressed} /> + +## Shapes + +It can either: +* be a circle, +* be a rectangle +* be a square, +* or conserves its initial shape. + +### Circle + +<Canvas of={ButtonStories.Circle} /> + +### Rectangle (default) + +<Canvas of={ButtonStories.Rectangle} /> + +### Square + +<Canvas of={ButtonStories.Square} /> + +### Initial + +<Canvas of={ButtonStories.Initial} /> + +## Props + +<ArgTypes of={ButtonStories} /> diff --git a/src/components/atoms/buttons/button/button.stories.ts b/src/components/atoms/buttons/button/button.stories.ts new file mode 100644 index 0000000..25fb9f8 --- /dev/null +++ b/src/components/atoms/buttons/button/button.stories.ts @@ -0,0 +1,112 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Button } from './button'; + +const meta = { + component: Button, + title: 'Atoms/Buttons/Button', +} satisfies Meta<typeof Button>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Default: Story = { + args: { + children: 'Button', + }, +}; + +export const Primary: Story = { + name: 'Kind: Primary', + args: { + ...Default.args, + kind: 'primary', + }, +}; + +export const Secondary: Story = { + name: 'Kind: Secondary', + args: { + ...Default.args, + kind: 'secondary', + }, +}; + +export const Tertiary: Story = { + name: 'Kind: Tertiary', + args: { + ...Default.args, + kind: 'tertiary', + }, +}; + +export const Neutral: Story = { + name: 'Kind: Neutral', + args: { + ...Default.args, + kind: 'neutral', + }, +}; + +export const Enabled: Story = { + name: 'State: Enabled', + args: { + ...Default.args, + }, +}; + +export const Disabled: Story = { + name: 'State: Disabled', + args: { + ...Default.args, + isDisabled: true, + }, +}; + +export const Loading: Story = { + name: 'State: Loading', + args: { + ...Default.args, + isLoading: true, + }, +}; + +export const Pressed: Story = { + name: 'State: Pressed', + args: { + ...Default.args, + isPressed: true, + }, +}; + +export const Circle: Story = { + name: 'Shape: Circle', + args: { + ...Default.args, + shape: 'circle', + }, +}; + +export const Rectangle: Story = { + name: 'Shape: Rectangle', + args: { + ...Default.args, + shape: 'rectangle', + }, +}; + +export const Square: Story = { + name: 'Shape: Square', + args: { + ...Default.args, + shape: 'square', + }, +}; + +export const Initial: Story = { + name: 'Shape: Initial', + args: { + ...Default.args, + shape: 'initial', + }, +}; diff --git a/src/components/atoms/buttons/button/button.stories.tsx b/src/components/atoms/buttons/button/button.stories.tsx deleted file mode 100644 index 5ce28fb..0000000 --- a/src/components/atoms/buttons/button/button.stories.tsx +++ /dev/null @@ -1,172 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Button } from './button'; - -/** - * Button - Storybook Meta - */ -export default { - title: 'Atoms/Buttons/Button', - component: Button, - args: { - type: 'button', - }, - argTypes: { - children: { - control: { - type: 'text', - }, - description: 'The button body.', - type: { - name: 'string', - required: true, - }, - }, - isDisabled: { - control: { - type: 'boolean', - }, - description: 'Should the button be disabled?', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - isLoading: { - control: { - type: 'boolean', - }, - description: - 'Should the button be disabled because it is loading something?', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - isPressed: { - control: { - type: 'boolean', - }, - description: 'Define if the button is currently pressed.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - kind: { - control: { - type: 'select', - }, - description: 'Button kind.', - options: ['primary', 'secondary', 'tertiary', 'neutral'], - table: { - category: 'Options', - defaultValue: { summary: 'secondary' }, - }, - type: { - name: 'string', - required: false, - }, - }, - onClick: { - control: { - type: null, - }, - description: 'A callback function to handle click.', - table: { - category: 'Events', - }, - type: { - name: 'function', - required: false, - }, - }, - shape: { - control: { - type: 'select', - }, - description: 'The link shape.', - options: ['circle', 'rectangle', 'square', 'initial'], - table: { - category: 'Options', - defaultValue: { summary: 'rectangle' }, - }, - type: { - name: 'string', - required: false, - }, - }, - type: { - control: { - type: 'select', - }, - description: 'Button type attribute.', - options: ['button', 'reset', 'submit'], - table: { - category: 'Options', - defaultValue: { summary: 'button' }, - }, - type: { - name: 'string', - required: false, - }, - }, - }, -} as ComponentMeta<typeof Button>; - -const Template: ComponentStory<typeof Button> = (args) => <Button {...args} />; - -const logClick = () => { - console.log('Button has been clicked!'); -}; - -/** - * Button Story - Primary - */ -export const Primary = Template.bind({}); -Primary.args = { - children: 'Click on the button', - kind: 'primary', - onClick: logClick, -}; - -/** - * Button Story - Secondary - */ -export const Secondary = Template.bind({}); -Secondary.args = { - children: 'Click on the button', - kind: 'secondary', - onClick: logClick, -}; - -/** - * Button Story - Tertiary - */ -export const Tertiary = Template.bind({}); -Tertiary.args = { - children: 'Click on the button', - kind: 'tertiary', - onClick: logClick, -}; - -/** - * Button Story - Neutral - */ -export const Neutral = Template.bind({}); -Neutral.args = { - children: 'Click on the button', - kind: 'neutral', - onClick: logClick, -}; diff --git a/src/components/atoms/figure/figure.stories.tsx b/src/components/atoms/figure/figure.stories.tsx index 7763641..ece08b7 100644 --- a/src/components/atoms/figure/figure.stories.tsx +++ b/src/components/atoms/figure/figure.stories.tsx @@ -1,74 +1,39 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import type { Meta, StoryObj } from '@storybook/react'; import NextImage from 'next/image'; import { Figure } from './figure'; -/** - * Figure - Storybook Meta - */ -export default { - title: 'Atoms/Figure', +const meta = { component: Figure, - args: {}, - argTypes: { - caption: { - control: { - type: 'text', - }, - description: 'A figure caption.', - table: { - category: 'Options', - }, - type: { - name: 'string', - required: false, - }, - }, - hasBorders: { - control: { - type: 'boolean', - }, - description: 'Add borders around the figure.', - table: { - category: 'Styles', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - }, -} as ComponentMeta<typeof Figure>; + title: 'Atoms/Figure', +} satisfies Meta<typeof Figure>; -const Template: ComponentStory<typeof Figure> = (args) => <Figure {...args} />; +export default meta; -/** - * Figure Stories - Illustration - */ -export const Illustration = Template.bind({}); -Illustration.args = { - children: ( - <NextImage - alt="An example" - height={480} - src="https://picsum.photos/640/480" - width={640} - /> - ), +type Story = StoryObj<typeof meta>; + +export const Default: Story = { + args: { + children: ( + <NextImage + alt="An example" + height={480} + src="https://picsum.photos/640/480" + width={640} + /> + ), + }, }; -/** - * Figure Stories - BorderedIllustration - */ -export const BorderedIllustration = Template.bind({}); -BorderedIllustration.args = { - children: ( - <NextImage - alt="An example" - height={480} - src="https://picsum.photos/640/480" - width={640} - /> - ), - hasBorders: true, +export const Bordered: Story = { + args: { + children: ( + <NextImage + alt="An example" + height={480} + src="https://picsum.photos/640/480" + width={640} + /> + ), + hasBorders: true, + }, }; diff --git a/src/components/atoms/flip/flip.stories.tsx b/src/components/atoms/flip/flip.stories.tsx index 1e470b1..19b4242 100644 --- a/src/components/atoms/flip/flip.stories.tsx +++ b/src/components/atoms/flip/flip.stories.tsx @@ -1,61 +1,53 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Flip as FlipComponent } from './flip'; +import type { Meta, StoryObj } from '@storybook/react'; +import { Flip } from './flip'; import { FlipSide } from './flip-side'; -/** - * Flip - Storybook Meta - */ -export default { +const meta = { + component: Flip, title: 'Atoms/Flip', - component: FlipComponent, - argTypes: {}, -} as ComponentMeta<typeof FlipComponent>; +} satisfies Meta<typeof Flip>; -const Template: ComponentStory<typeof FlipComponent> = (args) => ( - <FlipComponent {...args} tabIndex={0} /> -); +export default meta; -/** - * Images Stories - Horizontal Flipping - */ -export const Horizontal = Template.bind({}); -Horizontal.args = { - children: ( - <> - <FlipSide style={{ padding: '10px' }}> - Consequatur natus possimus quia consequatur placeat consectetur. Quia - vel magnam. Dolorem in quas non inventore aut sapiente. Consequuntur est - cum et. - </FlipSide> - <FlipSide isBack style={{ background: '#eee', padding: '10px' }}> - Iusto voluptatem repudiandae odit quo amet. Dolores vitae et neque - minima velit. Ad consequatur assumenda qui placeat aut consectetur - officia numquam illo. Neque quos voluptate ipsam eum ipsa officiis et - autem non. - </FlipSide> - </> - ), +type Story = StoryObj<typeof meta>; + +export const Horizontal: Story = { + args: { + children: ( + <> + <FlipSide style={{ padding: '10px' }}> + Consequatur natus possimus quia consequatur placeat consectetur. Quia + vel magnam. Dolorem in quas non inventore aut sapiente. Consequuntur + est cum et. + </FlipSide> + <FlipSide isBack style={{ background: '#eee', padding: '10px' }}> + Iusto voluptatem repudiandae odit quo amet. Dolores vitae et neque + minima velit. Ad consequatur assumenda qui placeat aut consectetur + officia numquam illo. Neque quos voluptate ipsam eum ipsa officiis et + autem non. + </FlipSide> + </> + ), + }, }; -/** - * Images Stories - Vertical Flipping - */ -export const Vertical = Template.bind({}); -Vertical.args = { - children: ( - <> - <FlipSide style={{ padding: '10px' }}> - Consequatur natus possimus quia consequatur placeat consectetur. Quia - vel magnam. Dolorem in quas non inventore aut sapiente. Consequuntur est - cum et. - </FlipSide> - <FlipSide isBack style={{ background: '#eee', padding: '10px' }}> - Iusto voluptatem repudiandae odit quo amet. Dolores vitae et neque - minima velit. Ad consequatur assumenda qui placeat aut consectetur - officia numquam illo. Neque quos voluptate ipsam eum ipsa officiis et - autem non. - </FlipSide> - </> - ), - direction: 'vertical', +export const Vertical: Story = { + args: { + children: ( + <> + <FlipSide style={{ padding: '10px' }}> + Consequatur natus possimus quia consequatur placeat consectetur. Quia + vel magnam. Dolorem in quas non inventore aut sapiente. Consequuntur + est cum et. + </FlipSide> + <FlipSide isBack style={{ background: '#eee', padding: '10px' }}> + Iusto voluptatem repudiandae odit quo amet. Dolores vitae et neque + minima velit. Ad consequatur assumenda qui placeat aut consectetur + officia numquam illo. Neque quos voluptate ipsam eum ipsa officiis et + autem non. + </FlipSide> + </> + ), + direction: 'vertical', + }, }; diff --git a/src/components/atoms/forms/fields/boolean-field/boolean-field.stories.ts b/src/components/atoms/forms/fields/boolean-field/boolean-field.stories.ts new file mode 100644 index 0000000..d1be590 --- /dev/null +++ b/src/components/atoms/forms/fields/boolean-field/boolean-field.stories.ts @@ -0,0 +1,31 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { BooleanField } from './boolean-field'; + +const meta = { + component: BooleanField, + title: 'Atoms/Forms/Fields/BooleanField', +} satisfies Meta<typeof BooleanField>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Checkbox: Story = { + args: { + id: 'checkbox', + isChecked: false, + name: 'checkbox', + type: 'checkbox', + value: 'checkbox', + }, +}; + +export const Radio: Story = { + args: { + id: 'radio', + isChecked: false, + name: 'radio', + type: 'radio', + value: 'radio', + }, +}; diff --git a/src/components/atoms/forms/fields/boolean-field/boolean-field.stories.tsx b/src/components/atoms/forms/fields/boolean-field/boolean-field.stories.tsx deleted file mode 100644 index 60dd352..0000000 --- a/src/components/atoms/forms/fields/boolean-field/boolean-field.stories.tsx +++ /dev/null @@ -1,172 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { useCallback, useState } from 'react'; -import { BooleanField } from './boolean-field'; - -/** - * BooleanField - Storybook Meta - */ -export default { - title: 'Atoms/Forms/Fields', - component: BooleanField, - args: { - isHidden: false, - }, - argTypes: { - 'aria-labelledby': { - control: { - type: 'text', - }, - description: 'One or more ids that refers to the field name.', - table: { - category: 'Accessibility', - }, - type: { - name: 'string', - required: false, - }, - }, - className: { - control: { - type: 'text', - }, - description: 'Set additional classnames to the field.', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - id: { - control: { - type: 'text', - }, - description: 'The field id.', - type: { - name: 'string', - required: true, - }, - }, - isChecked: { - control: { - type: null, - }, - description: 'The field state: true if checked.', - type: { - name: 'boolean', - required: true, - }, - }, - isHidden: { - control: { - type: 'boolean', - }, - description: 'Define if the field should be visually hidden.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - name: { - control: { - type: 'text', - }, - description: 'The field name.', - type: { - name: 'string', - required: true, - }, - }, - onChange: { - control: { - type: null, - }, - description: 'A callback function to handle field state change.', - table: { - category: 'Events', - }, - type: { - name: 'function', - required: true, - }, - }, - onClick: { - control: { - type: null, - }, - description: 'A callback function to handle click on field.', - table: { - category: 'Events', - }, - type: { - name: 'function', - required: false, - }, - }, - type: { - control: { - type: 'select', - }, - description: 'The field type. Either checkbox or radio.', - options: ['checkbox', 'radio'], - type: { - name: 'string', - required: true, - }, - }, - value: { - control: { - type: 'text', - }, - description: 'The field value.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof BooleanField>; - -const Template: ComponentStory<typeof BooleanField> = ({ - isChecked: checked, - onChange: _onChange, - ...args -}) => { - const [isChecked, setIsChecked] = useState(checked); - const handleChange = useCallback(() => { - setIsChecked((prev) => !prev); - }, []); - - return ( - <BooleanField isChecked={isChecked} onChange={handleChange} {...args} /> - ); -}; - -/** - * Checkbox Story - */ -export const Checkbox = Template.bind({}); -Checkbox.args = { - id: 'checkbox', - isChecked: false, - name: 'checkbox', - type: 'checkbox', - value: 'checkbox', -}; - -/** - * Radio Story - */ -export const Radio = Template.bind({}); -Radio.args = { - id: 'radio', - isChecked: false, - name: 'radio', - type: 'radio', - value: 'radio', -}; diff --git a/src/components/atoms/forms/fields/checkbox/checkbox.stories.ts b/src/components/atoms/forms/fields/checkbox/checkbox.stories.ts new file mode 100644 index 0000000..e815b91 --- /dev/null +++ b/src/components/atoms/forms/fields/checkbox/checkbox.stories.ts @@ -0,0 +1,20 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Checkbox as CheckboxComponent } from './checkbox'; + +const meta = { + component: CheckboxComponent, + title: 'Atoms/Forms/Fields', +} satisfies Meta<typeof CheckboxComponent>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Checkbox: Story = { + args: { + id: 'checkbox', + isChecked: false, + name: 'checkbox', + value: 'checkbox', + }, +}; diff --git a/src/components/atoms/forms/fields/input/input.stories.tsx b/src/components/atoms/forms/fields/input/input.stories.tsx index 4744bc5..af1ca60 100644 --- a/src/components/atoms/forms/fields/input/input.stories.tsx +++ b/src/components/atoms/forms/fields/input/input.stories.tsx @@ -1,237 +1,231 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { type ChangeEvent, useCallback, useState } from 'react'; -import { Input } from './input'; - -/** - * Input - Storybook Meta - */ -export default { - title: 'Atoms/Forms/Fields', +import { useArgs } from '@storybook/client-api'; +import type { Meta, StoryObj } from '@storybook/react'; +import { type ChangeEvent, useCallback } from 'react'; +import { Input, type InputProps } from './input'; + +const meta = { component: Input, + title: 'Atoms/Forms/Fields/Input', + excludeStories: /Controlled.*$/, +} satisfies Meta<typeof Input>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const ControlledInput = ({ value, ...args }: InputProps) => { + const [_, updateArgs] = useArgs<InputProps>(); + + const handleChange = useCallback( + (e: ChangeEvent<HTMLInputElement>) => { + updateArgs({ ...args, value: e.target.value }); + }, + [args, updateArgs] + ); + + return <Input {...args} onChange={handleChange} value={value} />; +}; + +const InputTemplate: Story = { args: { + id: 'default', isDisabled: false, + isReadOnly: false, isRequired: false, + name: 'default', + type: 'text', + value: '', }, - argTypes: { - 'aria-labelledby': { - control: { - type: 'text', - }, - description: 'One or more ids that refers to the field name.', - table: { - category: 'Accessibility', - }, - type: { - name: 'string', - required: false, - }, - }, - className: { - control: { - type: 'text', - }, - description: 'Add classnames to the field.', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - id: { - control: { - type: 'text', - }, - description: 'Input id.', - type: { - name: 'string', - required: true, - }, - }, - isDisabled: { - control: { - type: 'boolean', - }, - description: 'Input state: either enabled or disabled.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - isRequired: { - control: { - type: 'boolean', - }, - description: 'Determine if the field is required.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - max: { - control: { - type: 'number', - }, - description: 'Maximum value.', - table: { - category: 'Options', - }, - type: { - name: 'number', - required: false, - }, - }, - min: { - control: { - type: 'number', - }, - description: 'Minimum value.', - table: { - category: 'Options', - }, - type: { - name: 'number', - required: false, - }, - }, - name: { - control: { - type: 'text', - }, - description: 'Input name.', - type: { - name: 'string', - required: true, - }, - }, - placeholder: { - control: { - type: 'text', - }, - description: 'A placeholder value.', - table: { - category: 'Options', - }, - type: { - name: 'string', - required: false, - }, - }, - step: { - control: { - type: 'number', - }, - description: 'Input incremental values that are valid.', - table: { - category: 'Options', - }, - type: { - name: 'number', - required: false, - }, - }, - type: { - control: { - type: 'select', - }, - description: 'Input type: input type or textarea.', - options: [ - 'datetime-local', - 'email', - 'number', - 'search', - 'tel', - 'text', - 'textarea', - 'time', - 'url', - ], - type: { - name: 'string', - required: true, - }, - }, - value: { - control: { - type: null, - }, - description: 'Input value.', - type: { - name: 'string', - required: true, - }, - }, + render: ControlledInput, +}; + +export const IsEditable: Story = { + ...InputTemplate, + name: 'State: Editable', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of an editable input field', + id: 'editable-input', + name: 'editable', + }, +}; + +export const IsDisabled: Story = { + ...InputTemplate, + name: 'State: Disabled', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a disabled input field', + id: 'disabled-input', + isDisabled: true, + name: 'disabled', + }, +}; + +export const IsReadOnly: Story = { + ...InputTemplate, + name: 'State: Readonly', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a read-only input field', + id: 'readonly-input', + isReadOnly: true, + name: 'readonly', + }, +}; + +export const IsRequired: Story = { + ...InputTemplate, + name: 'State: Required', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a required input field', + id: 'required-input', + isRequired: true, + name: 'required', + }, +}; + +export const DateInput: Story = { + ...InputTemplate, + name: 'Type: Date', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a date field', + id: 'date', + name: 'date', + type: 'date', + }, +}; + +export const DatetimeInput: Story = { + ...InputTemplate, + name: 'Type: Datetime', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a datetime field', + id: 'datetime', + name: 'datetime', + type: 'datetime-local', + }, +}; + +export const EmailInput: Story = { + ...InputTemplate, + name: 'Type: Email', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of an email field', + id: 'email', + name: 'email', + type: 'email', + }, +}; + +export const MonthInput: Story = { + ...InputTemplate, + name: 'Type: Month', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a month field', + id: 'month', + name: 'month', + type: 'month', + }, +}; + +export const NumberInput: Story = { + ...InputTemplate, + name: 'Type: Number', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a number field', + id: 'number', + name: 'number', + type: 'number', + }, +}; + +export const PasswordInput: Story = { + ...InputTemplate, + name: 'Type: Password', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a password field', + id: 'password', + name: 'password', + type: 'password', + }, +}; + +export const SearchInput: Story = { + ...InputTemplate, + name: 'Type: Search', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a search field', + id: 'search', + name: 'search', + type: 'search', + }, +}; + +export const TelInput: Story = { + ...InputTemplate, + name: 'Type: Tel', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a tel field', + id: 'tel', + name: 'tel', + type: 'tel', + }, +}; + +export const TextInput: Story = { + ...InputTemplate, + name: 'Type: Text', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a text field', + id: 'text', + name: 'text', + type: 'text', + }, +}; + +export const TimeInput: Story = { + ...InputTemplate, + name: 'Type: Time', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a time field', + id: 'time', + name: 'time', + type: 'time', + }, +}; + +export const UrlInput: Story = { + ...InputTemplate, + name: 'Type: Url', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of an url field', + id: 'url', + name: 'url', + type: 'url', + }, +}; + +export const WeekInput: Story = { + ...InputTemplate, + name: 'Type: Week', + args: { + ...InputTemplate.args, + 'aria-label': 'Example of a week field', + id: 'week', + name: 'week', + type: 'week', }, -} as ComponentMeta<typeof Input>; - -const Template: ComponentStory<typeof Input> = ({ - value: initialValue, - onChange: _onChange, - ...args -}) => { - const [value, setValue] = useState(initialValue); - const updateValue = useCallback((e: ChangeEvent<HTMLInputElement>) => { - setValue(e.target.value); - }, []); - - return <Input value={value} onChange={updateValue} {...args} />; -}; - -/** - * Input Story - DateTimeField - */ -export const DateTimeField = Template.bind({}); -DateTimeField.args = { - id: 'field-storybook', - name: 'field-storybook', - type: 'datetime-local', -}; - -/** - * Input Story - EmailField - */ -export const EmailField = Template.bind({}); -EmailField.args = { - id: 'field-storybook', - name: 'field-storybook', - type: 'email', -}; - -/** - * Input Story - NumericField - */ -export const NumericField = Template.bind({}); -NumericField.args = { - id: 'field-storybook', - name: 'field-storybook', - type: 'number', -}; - -/** - * Input Story - TextField - */ -export const TextField = Template.bind({}); -TextField.args = { - id: 'field-storybook', - name: 'field-storybook', - type: 'text', -}; - -/** - * Input Story - TimeField - */ -export const TimeField = Template.bind({}); -TimeField.args = { - id: 'field-storybook', - name: 'field-storybook', - type: 'time', }; diff --git a/src/components/atoms/forms/fields/radio/radio.stories.ts b/src/components/atoms/forms/fields/radio/radio.stories.ts new file mode 100644 index 0000000..c1f5eed --- /dev/null +++ b/src/components/atoms/forms/fields/radio/radio.stories.ts @@ -0,0 +1,20 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Radio as RadioComponent } from './radio'; + +const meta = { + component: RadioComponent, + title: 'Atoms/Forms/Fields', +} satisfies Meta<typeof RadioComponent>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Radio: Story = { + args: { + id: 'radio', + isChecked: false, + name: 'radio', + value: 'radio', + }, +}; diff --git a/src/components/atoms/forms/fields/select/select.stories.tsx b/src/components/atoms/forms/fields/select/select.stories.tsx index fddf354..7884cfb 100644 --- a/src/components/atoms/forms/fields/select/select.stories.tsx +++ b/src/components/atoms/forms/fields/select/select.stories.tsx @@ -1,143 +1,91 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { type ChangeEvent, useCallback, useState } from 'react'; -import { Select as SelectComponent } from './select'; +import type { Meta, StoryObj } from '@storybook/react'; +import { type ChangeEvent, useState, useCallback } from 'react'; +import { Select, type SelectOptions, type SelectProps } from './select'; -const selectOptions = [ - { id: 'option1', name: 'Option 1', value: 'option1' }, - { id: 'option2', name: 'Option 2', value: 'option2' }, - { id: 'option3', name: 'Option 3', value: 'option3' }, -]; +const meta = { + component: Select, + title: 'Atoms/Forms/Fields/Select', + excludeStories: /Controlled.*$/, +} satisfies Meta<typeof Select>; -/** - * Select - Storybook Meta - */ -export default { - title: 'Atoms/Forms/Fields', - component: SelectComponent, +export default meta; + +type Story = StoryObj<typeof meta>; + +export const ControlledSelect = ({ multiple, ...args }: SelectProps) => { + const [selected, setSelected] = useState(multiple === true ? [''] : ''); + const handler = useCallback( + (e: ChangeEvent<HTMLSelectElement>) => { + if (multiple) + setSelected( + Array.from(e.target.selectedOptions, (option) => option.value) + ); + else setSelected(e.target.value); + }, + [multiple] + ); + + return ( + <Select {...args} multiple={multiple} onChange={handler} value={selected} /> + ); +}; + +const options = [ + { id: 'option-1', name: 'Option 1', value: 'option-1' }, + { id: 'option-2', name: 'Option 2', value: 'option-2' }, + { id: 'option-3', name: 'Option 3', value: 'option-3' }, + { id: 'option-4', name: 'Option 4', value: 'option-4' }, + { id: 'option-5', name: 'Option 5', value: 'option-5' }, +] satisfies SelectOptions[]; + +const SelectTemplate: Story = { args: { isDisabled: false, isRequired: false, + multiple: false, + options, + value: '', }, - argTypes: { - 'aria-labelledby': { - control: { - type: 'text', - }, - description: 'One or more ids that refers to the select field name.', - table: { - category: 'Accessibility', - }, - type: { - name: 'string', - required: false, - }, - }, - className: { - control: { - type: 'text', - }, - description: 'Add classnames to the select field.', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - id: { - control: { - type: 'text', - }, - description: 'Field id.', - type: { - name: 'string', - required: true, - }, - }, - isDisabled: { - control: { - type: 'boolean', - }, - description: 'Field state: either enabled or disabled.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - isRequired: { - control: { - type: 'boolean', - }, - description: 'Determine if the field is required.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - name: { - control: { - type: 'text', - }, - description: 'Field name.', - type: { - name: 'string', - required: true, - }, - }, - options: { - description: 'Select options.', - type: { - name: 'array', - required: true, - value: { - name: 'string', - }, - }, - }, - value: { - control: { - type: null, - }, - description: 'Field value.', - type: { - name: 'string', - required: true, - }, - }, + render: ControlledSelect, +}; + +export const SingleChoice: Story = { + ...SelectTemplate, + args: { + ...SelectTemplate.args, + 'aria-label': 'Example of a default select field', + options, }, -} as ComponentMeta<typeof SelectComponent>; +}; -const Template: ComponentStory<typeof SelectComponent> = ({ - onChange: _onChange, - value, - ...args -}) => { - const [selected, setSelected] = useState(value); - const updateSelection = useCallback((e: ChangeEvent<HTMLSelectElement>) => { - setSelected(e.target.value); - }, []); +export const MultipleChoices: Story = { + ...SelectTemplate, + args: { + ...SelectTemplate.args, + 'aria-label': 'Example of a select field with multiple choices', + multiple: true, + options, + }, +}; - return ( - <SelectComponent {...args} onChange={updateSelection} value={selected} /> - ); +export const IsDisabled: Story = { + ...SelectTemplate, + name: 'State: Disabled', + args: { + ...SelectTemplate.args, + 'aria-label': 'Example of a disabled select field', + isDisabled: true, + options, + }, }; -/** - * Select Story - */ -export const Select = Template.bind({}); -Select.args = { - id: 'storybook-select', - name: 'storybook-select', - options: selectOptions, - value: 'option2', +export const IsRequired: Story = { + ...SelectTemplate, + name: 'State: Required', + args: { + ...SelectTemplate.args, + 'aria-label': 'Example of a required select field', + isRequired: true, + options, + }, }; diff --git a/src/components/atoms/forms/fields/text-area/text-area.stories.tsx b/src/components/atoms/forms/fields/text-area/text-area.stories.tsx index 21214bd..d98dfe3 100644 --- a/src/components/atoms/forms/fields/text-area/text-area.stories.tsx +++ b/src/components/atoms/forms/fields/text-area/text-area.stories.tsx @@ -1,136 +1,86 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { type ChangeEvent, useCallback, useState } from 'react'; -import { TextArea as TextAreaComponent } from './text-area'; +import { useArgs } from '@storybook/client-api'; +import type { Meta, StoryObj } from '@storybook/react'; +import { type ChangeEvent, useCallback } from 'react'; +import { TextArea, type TextAreaProps } from './text-area'; -/** - * TextArea - Storybook Meta - */ -export default { - title: 'Atoms/Forms/Fields', - component: TextAreaComponent, +const meta = { + component: TextArea, + title: 'Atoms/Forms/Fields/TextArea', + excludeStories: /Controlled.*$/, +} satisfies Meta<typeof TextArea>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const ControlledTextArea = ({ value, ...args }: TextAreaProps) => { + const [_, updateArgs] = useArgs<TextAreaProps>(); + + const handleChange = useCallback( + (e: ChangeEvent<HTMLTextAreaElement>) => { + updateArgs({ ...args, value: e.target.value }); + }, + [args, updateArgs] + ); + + return <TextArea {...args} onChange={handleChange} value={value} />; +}; + +const TextAreaTemplate: Story = { args: { + id: 'default', isDisabled: false, + isReadOnly: false, isRequired: false, + name: 'default', + value: '', }, - argTypes: { - 'aria-labelledby': { - control: { - type: 'text', - }, - description: 'One or more ids that refers to the field name.', - table: { - category: 'Accessibility', - }, - type: { - name: 'string', - required: false, - }, - }, - className: { - control: { - type: 'text', - }, - description: 'Add classnames to the field.', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - id: { - control: { - type: 'text', - }, - description: 'TextArea id.', - type: { - name: 'string', - required: true, - }, - }, - isDisabled: { - control: { - type: 'boolean', - }, - description: 'TextArea state: either enabled or disabled.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - isRequired: { - control: { - type: 'boolean', - }, - description: 'Determine if the field is required.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - name: { - control: { - type: 'text', - }, - description: 'TextArea name.', - type: { - name: 'string', - required: true, - }, - }, - placeholder: { - control: { - type: 'text', - }, - description: 'A placeholder value.', - table: { - category: 'Options', - }, - type: { - name: 'string', - required: false, - }, - }, - value: { - control: { - type: null, - }, - description: 'TextArea value.', - type: { - name: 'string', - required: true, - }, - }, + render: ControlledTextArea, +}; + +export const IsEditable: Story = { + ...TextAreaTemplate, + name: 'State: Editable', + args: { + ...TextAreaTemplate.args, + 'aria-label': 'Example of a default text area', + id: 'disabled', + name: 'disabled', }, -} as ComponentMeta<typeof TextAreaComponent>; +}; -const Template: ComponentStory<typeof TextAreaComponent> = ({ - value: initialValue, - onChange: _onChange, - ...args -}) => { - const [value, setValue] = useState(initialValue); - const updateValue = useCallback((e: ChangeEvent<HTMLTextAreaElement>) => { - setValue(e.target.value); - }, []); +export const IsDisabled: Story = { + ...TextAreaTemplate, + name: 'State: Disabled', + args: { + ...TextAreaTemplate.args, + 'aria-label': 'Example of a disabled text area', + id: 'disabled', + isDisabled: true, + name: 'disabled', + }, +}; - return <TextAreaComponent value={value} onChange={updateValue} {...args} />; +export const IsReadOnly: Story = { + ...TextAreaTemplate, + name: 'State: Readonly', + args: { + ...TextAreaTemplate.args, + 'aria-label': 'Example of a read-only text area', + id: 'readonly', + isReadOnly: true, + name: 'readonly', + }, }; -/** - * TextArea Story - TextArea - */ -export const TextArea = Template.bind({}); -TextArea.args = { - id: 'field-storybook', - name: 'field-storybook', +export const IsRequired: Story = { + ...TextAreaTemplate, + name: 'State: Required', + args: { + ...TextAreaTemplate.args, + 'aria-label': 'Example of a required text area', + id: 'required', + isRequired: true, + name: 'required', + }, }; diff --git a/src/components/atoms/forms/fieldset/fieldset.stories.tsx b/src/components/atoms/forms/fieldset/fieldset.stories.tsx index a7d665d..e3dd53e 100644 --- a/src/components/atoms/forms/fieldset/fieldset.stories.tsx +++ b/src/components/atoms/forms/fieldset/fieldset.stories.tsx @@ -1,61 +1,47 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import type { Meta, StoryObj } from '@storybook/react'; import { Input } from '../fields'; -import { Legend } from '../legend'; -import { Fieldset as FieldsetComponent } from './fieldset'; - -/** - * Fieldset - Storybook Meta - */ -export default { - title: 'Atoms/Forms', - component: FieldsetComponent, +import { Fieldset, type FieldsetProps } from './fieldset'; + +const meta = { + component: Fieldset, + title: 'Atoms/Forms/Fieldset', +} satisfies Meta<typeof Fieldset>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Default: Story = { + args: {}, +}; + +const FieldsetWithFields = ({ + inputLabel, + ...props +}: FieldsetProps & { inputLabel: string }) => ( + <Fieldset {...props}> + <Input aria-label={inputLabel} id="field" name="field" type="text" /> + </Fieldset> +); + +type WithFieldStory = StoryObj<FieldsetProps & { inputLabel: string }>; + +export const Enabled: WithFieldStory = { + name: 'State: Enabled', args: { + ...Default.args, + inputLabel: 'Example of a field inside an enabled fieldset', isDisabled: false, }, - argTypes: { - isDisabled: { - control: { - type: 'boolean', - }, - description: - 'Define if the fields inside the fieldset should be disabled.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - }, -} as ComponentMeta<typeof FieldsetComponent>; - -const Template: ComponentStory<typeof FieldsetComponent> = (args) => ( - <FieldsetComponent {...args}> - <div> - <Input - aria-label="A field example" - id="field1" - name="field1" - type="text" - /> - </div> - <div> - <Input - aria-label="Another field example" - id="field2" - name="field2" - type="text" - /> - </div> - </FieldsetComponent> -); + render: FieldsetWithFields, +}; -/** - * Fieldset Story - */ -export const Fieldset = Template.bind({}); -Fieldset.args = { - legend: <Legend>The fieldset legend</Legend>, +export const Disabled: WithFieldStory = { + name: 'State: Disabled', + args: { + ...Default.args, + inputLabel: 'Example of a field inside a disabled fieldset', + isDisabled: true, + }, + render: FieldsetWithFields, }; diff --git a/src/components/atoms/forms/label/label.stories.ts b/src/components/atoms/forms/label/label.stories.ts new file mode 100644 index 0000000..094a432 --- /dev/null +++ b/src/components/atoms/forms/label/label.stories.ts @@ -0,0 +1,48 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Label } from './label'; + +const meta = { + component: Label, + title: 'Atoms/Forms/Label', +} satisfies Meta<typeof Label>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Default: Story = { + args: { + children: 'A label', + }, +}; + +export const VisuallyHidden: Story = { + args: { + children: 'A visually hidden label', + isHidden: true, + }, +}; + +export const IsRequired: Story = { + name: 'State: Required', + args: { + ...Default.args, + isRequired: true, + }, +}; + +export const SizeSM: Story = { + name: 'Size: Small', + args: { + ...Default.args, + size: 'sm', + }, +}; + +export const SizeMD: Story = { + name: 'Size: Medium', + args: { + ...Default.args, + size: 'md', + }, +}; diff --git a/src/components/atoms/forms/label/label.stories.tsx b/src/components/atoms/forms/label/label.stories.tsx deleted file mode 100644 index 195be97..0000000 --- a/src/components/atoms/forms/label/label.stories.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Label as LabelComponent } from './label'; - -/** - * Label - Storybook Meta - */ -export default { - title: 'Atoms/Forms', - component: LabelComponent, - args: { - isHidden: false, - isRequired: false, - size: 'sm', - }, - argTypes: { - 'aria-label': { - control: { - type: 'text', - }, - description: 'Define an accessible name.', - table: { - category: 'Accessibility', - }, - type: { - name: 'string', - required: false, - }, - }, - className: { - control: { - type: 'text', - }, - description: 'Add classnames to the label.', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - children: { - control: { - type: 'text', - }, - description: 'The label body.', - type: { - name: 'string', - required: true, - }, - }, - htmlFor: { - control: { - type: 'text', - }, - description: 'The field id.', - type: { - name: 'string', - required: true, - }, - }, - isHidden: { - control: { - type: 'boolean', - }, - description: 'Set to true if the label should be visually hidden.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - isRequired: { - control: { - type: 'boolean', - }, - description: 'Set to true if the field is required.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - size: { - control: { - type: 'select', - }, - description: 'The label size.', - options: ['md', 'sm'], - table: { - category: 'Options', - defaultValue: { summary: 'sm' }, - }, - type: { - name: 'string', - required: false, - }, - }, - }, -} as ComponentMeta<typeof LabelComponent>; - -const Template: ComponentStory<typeof LabelComponent> = ({ - children, - ...args -}) => <LabelComponent {...args}>{children}</LabelComponent>; - -/** - * Label Story - */ -export const Label = Template.bind({}); -Label.args = { - children: 'A label', -}; diff --git a/src/components/atoms/forms/legend/legend.stories.tsx b/src/components/atoms/forms/legend/legend.stories.tsx index b23d889..963fe33 100644 --- a/src/components/atoms/forms/legend/legend.stories.tsx +++ b/src/components/atoms/forms/legend/legend.stories.tsx @@ -1,27 +1,25 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import type { Meta, StoryObj } from '@storybook/react'; import { Fieldset } from '../fieldset'; -import { Legend as LegendComponent } from './legend'; +import { Legend, type LegendProps } from './legend'; -/** - * Legend - Storybook Meta - */ -export default { - title: 'Atoms/Forms', - component: LegendComponent, - args: {}, - argTypes: {}, -} as ComponentMeta<typeof LegendComponent>; - -const Template: ComponentStory<typeof LegendComponent> = (args) => ( +const FieldsetWithLegend = (args: LegendProps) => ( <Fieldset> - <LegendComponent {...args} /> + <Legend {...args} /> </Fieldset> ); -/** - * Legend Story - */ -export const Legend = Template.bind({}); -Legend.args = { - children: 'A fieldset legend', +const meta = { + component: Legend, + title: 'Atoms/Forms/Legend', + render: FieldsetWithLegend, +} satisfies Meta<typeof Legend>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Default: Story = { + args: { + children: 'A legend', + }, }; diff --git a/src/components/atoms/heading/heading.stories.ts b/src/components/atoms/heading/heading.stories.ts new file mode 100644 index 0000000..0bc8c68 --- /dev/null +++ b/src/components/atoms/heading/heading.stories.ts @@ -0,0 +1,69 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Heading } from './heading'; + +const meta = { + component: Heading, + title: 'Atoms/Headings', +} satisfies Meta<typeof Heading>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +const HeadingTemplate: Story = { + args: { + children: 'The quick brown fox jumps over a lazy dog', + isFake: false, + level: 2, + }, +}; + +export const H1: Story = { + args: { + ...HeadingTemplate.args, + level: 1, + }, +}; + +export const H2: Story = { + args: { + ...HeadingTemplate.args, + level: 2, + }, +}; + +export const H3: Story = { + args: { + ...HeadingTemplate.args, + level: 3, + }, +}; + +export const H4: Story = { + args: { + ...HeadingTemplate.args, + level: 4, + }, +}; + +export const H5: Story = { + args: { + ...HeadingTemplate.args, + level: 5, + }, +}; + +export const H6: Story = { + args: { + ...HeadingTemplate.args, + level: 6, + }, +}; + +export const FakeH2: Story = { + args: { + ...HeadingTemplate.args, + isFake: true, + level: 2, + }, +}; diff --git a/src/components/atoms/heading/heading.stories.tsx b/src/components/atoms/heading/heading.stories.tsx deleted file mode 100644 index c5ac4a0..0000000 --- a/src/components/atoms/heading/heading.stories.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Heading } from './heading'; - -/** - * Heading - Storybook Meta - */ -export default { - title: 'Atoms/Headings', - component: Heading, - args: { - isFake: false, - }, - argTypes: { - children: { - description: 'Heading body.', - type: { - name: 'string', - required: true, - }, - }, - isFake: { - control: { - type: 'boolean', - }, - description: 'Use an heading element or only its styles.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - level: { - control: { - type: 'number', - min: 1, - max: 6, - }, - description: 'Heading level.', - type: { - name: 'number', - required: true, - }, - }, - }, -} as ComponentMeta<typeof Heading>; - -const Template: ComponentStory<typeof Heading> = (args) => ( - <Heading {...args} /> -); - -/** - * Heading Story - h1 - */ -export const H1 = Template.bind({}); -H1.args = { - children: 'Your title', - level: 1, -}; - -/** - * Heading Story - h2 - */ -export const H2 = Template.bind({}); -H2.args = { - children: 'Your title', - level: 2, -}; - -/** - * Heading Story - h3 - */ -export const H3 = Template.bind({}); -H3.args = { - children: 'Your title', - level: 3, -}; - -/** - * Heading Story - h4 - */ -export const H4 = Template.bind({}); -H4.args = { - children: 'Your title', - level: 4, -}; - -/** - * Heading Story - h5 - */ -export const H5 = Template.bind({}); -H5.args = { - children: 'Your title', - level: 5, -}; - -/** - * Heading Story - h6 - */ -export const H6 = Template.bind({}); -H6.args = { - children: 'Your title', - level: 6, -}; diff --git a/src/components/atoms/images/icons/icon.stories.ts b/src/components/atoms/images/icons/icon.stories.ts new file mode 100644 index 0000000..55b5c31 --- /dev/null +++ b/src/components/atoms/images/icons/icon.stories.ts @@ -0,0 +1,135 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Icon } from './icon'; + +const meta = { + component: Icon, + title: 'Atoms/Images/Icons', +} satisfies Meta<typeof Icon>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const ArrowRight: Story = { + args: { + orientation: 'right', + shape: 'arrow', + }, +}; + +export const ArrowLeft: Story = { + args: { + orientation: 'left', + shape: 'arrow', + }, +}; + +export const ArrowBottom: Story = { + args: { + orientation: 'bottom', + shape: 'arrow', + }, +}; + +export const ArrowTop: Story = { + args: { + orientation: 'top', + shape: 'arrow', + }, +}; + +export const Career: Story = { + args: { + shape: 'career', + }, +}; + +export const CCBySA: Story = { + args: { + shape: 'cc-by-sa', + }, +}; + +export const Cog: Story = { + args: { + shape: 'cog', + }, +}; + +export const Computer: Story = { + args: { + shape: 'computer', + }, +}; + +export const Cross: Story = { + args: { + shape: 'cross', + }, +}; + +export const Envelop: Story = { + args: { + shape: 'envelop', + }, +}; + +export const Feed: Story = { + args: { + shape: 'feed', + }, +}; + +export const Hamburger: Story = { + args: { + shape: 'hamburger', + }, +}; + +export const Help: Story = { + args: { + shape: 'help', + }, +}; + +export const Home: Story = { + args: { + shape: 'home', + }, +}; + +export const MagnifyingGlass: Story = { + args: { + shape: 'magnifying-glass', + }, +}; + +export const Minus: Story = { + args: { + shape: 'minus', + }, +}; + +export const Moon: Story = { + args: { + shape: 'moon', + }, +}; + +export const Plus: Story = { + args: { + shape: 'plus', + }, +}; + +export const PostsStack: Story = { + args: { + shape: 'posts-stack', + }, +}; + +export const Sun: Story = { + args: { + shape: 'sun', + }, +}; diff --git a/src/components/atoms/images/icons/icon.stories.tsx b/src/components/atoms/images/icons/icon.stories.tsx deleted file mode 100644 index 0da568a..0000000 --- a/src/components/atoms/images/icons/icon.stories.tsx +++ /dev/null @@ -1,210 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Icon, type IconProps, type IconShape } from './icon'; - -/** - * Home icon - Storybook Meta - */ -export default { - title: 'Atoms/Images/Icons', - component: Icon, - argTypes: { - shape: { - control: { - type: 'select', - }, - options: [ - 'arrow', - 'career', - 'cc-by-sa', - 'cog', - 'computer', - 'cross', - 'envelop', - 'feed', - 'hamburger', - 'help', - 'home', - 'magnifying-glass', - 'minus', - 'moon', - 'posts-stack', - 'plus', - 'sun', - ], - description: 'Define the icon shape.', - type: { - name: 'string', - required: false, - }, - }, - }, -} as ComponentMeta<typeof Icon>; - -const Template: ComponentStory<typeof Icon> = ({ - shape, - ...args -}: IconProps<IconShape>) => <Icon {...args} shape={shape} />; - -/** - * Icon Stories - ArrowRight - */ -export const ArrowRight = Template.bind({}); -ArrowRight.args = { - orientation: 'right', - shape: 'arrow', -}; - -/** - * Icon Stories - ArrowLeft - */ -export const ArrowLeft = Template.bind({}); -ArrowLeft.args = { - orientation: 'left', - shape: 'arrow', -}; - -/** - * Icon Stories - ArrowBottom - */ -export const ArrowBottom = Template.bind({}); -ArrowBottom.args = { - orientation: 'bottom', - shape: 'arrow', -}; - -/** - * Icon Stories - ArrowTop - */ -export const ArrowTop = Template.bind({}); -ArrowTop.args = { - orientation: 'top', - shape: 'arrow', -}; - -/** - * Icon Stories - Career - */ -export const Career = Template.bind({}); -Career.args = { - shape: 'career', -}; - -/** - * Icon Stories - CCBySA - */ -export const CCBySA = Template.bind({}); -CCBySA.args = { - shape: 'cc-by-sa', -}; - -/** - * Icon Stories - Cog - */ -export const Cog = Template.bind({}); -Cog.args = { - shape: 'cog', -}; - -/** - * Icon Stories - Computer - */ -export const Computer = Template.bind({}); -Computer.args = { - shape: 'computer', -}; - -/** - * Icon Stories - Cross - */ -export const Cross = Template.bind({}); -Cross.args = { - shape: 'cross', -}; - -/** - * Icon Stories - Envelop - */ -export const Envelop = Template.bind({}); -Envelop.args = { - shape: 'envelop', -}; - -/** - * Icon Stories - Feed - */ -export const Feed = Template.bind({}); -Feed.args = { - shape: 'feed', -}; - -/** - * Icon Stories - Hamburger - */ -export const Hamburger = Template.bind({}); -Hamburger.args = { - shape: 'hamburger', -}; - -/** - * Icon Stories - Help - */ -export const Help = Template.bind({}); -Help.args = { - shape: 'help', -}; - -/** - * Icon Stories - Home - */ -export const Home = Template.bind({}); -Home.args = { - shape: 'home', -}; - -/** - * Icon Stories - MagnifyingGlass - */ -export const MagnifyingGlass = Template.bind({}); -MagnifyingGlass.args = { - shape: 'magnifying-glass', -}; - -/** - * Icon Stories - Minus - */ -export const Minus = Template.bind({}); -Minus.args = { - shape: 'minus', -}; - -/** - * Icon Stories - Moon - */ -export const Moon = Template.bind({}); -Moon.args = { - shape: 'moon', -}; - -/** - * Icon Stories - Plus - */ -export const Plus = Template.bind({}); -Plus.args = { - shape: 'plus', -}; - -/** - * Icon Stories - PostsStack - */ -export const PostsStack = Template.bind({}); -PostsStack.args = { - shape: 'posts-stack', -}; - -/** - * Icon Stories - Sun - */ -export const Sun = Template.bind({}); -Sun.args = { - shape: 'sun', -}; diff --git a/src/components/atoms/images/logo/logo.stories.ts b/src/components/atoms/images/logo/logo.stories.ts new file mode 100644 index 0000000..4324c80 --- /dev/null +++ b/src/components/atoms/images/logo/logo.stories.ts @@ -0,0 +1,15 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Logo } from './logo'; + +const meta = { + component: Logo, + title: 'Atoms/Images/Logo', +} satisfies Meta<typeof Logo>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Default: Story = { + args: {}, +}; diff --git a/src/components/atoms/images/logo/logo.stories.tsx b/src/components/atoms/images/logo/logo.stories.tsx deleted file mode 100644 index cfccb65..0000000 --- a/src/components/atoms/images/logo/logo.stories.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Logo as LogoComponent } from './logo'; - -/** - * Logo - Storybook Meta - */ -export default { - title: 'Atoms/Images', - component: LogoComponent, - argTypes: { - heading: { - control: { - type: 'text', - }, - description: 'The SVG title.', - table: { - category: 'Accessibility', - }, - type: { - name: 'string', - required: false, - }, - }, - }, -} as ComponentMeta<typeof LogoComponent>; - -const Template: ComponentStory<typeof LogoComponent> = (args) => ( - <LogoComponent {...args} /> -); - -/** - * Images Stories - Logo - */ -export const Logo = Template.bind({}); diff --git a/src/components/atoms/layout/article/article.stories.ts b/src/components/atoms/layout/article/article.stories.ts new file mode 100644 index 0000000..f0bda0e --- /dev/null +++ b/src/components/atoms/layout/article/article.stories.ts @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Article } from './article'; + +const meta = { + component: Article, + title: 'Atoms/Layout/Article', +} satisfies Meta<typeof Article>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Example: Story = { + args: { + children: 'The article contents.', + }, +}; diff --git a/src/components/atoms/layout/article/article.stories.tsx b/src/components/atoms/layout/article/article.stories.tsx deleted file mode 100644 index 4c5b158..0000000 --- a/src/components/atoms/layout/article/article.stories.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Article as ArticleComponent } from './article'; - -/** - * Article - Storybook Meta - */ -export default { - title: 'Atoms/Layout', - component: ArticleComponent, - argTypes: { - children: { - control: { - type: 'text', - }, - description: 'The contents.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof ArticleComponent>; - -const Template: ComponentStory<typeof ArticleComponent> = (args) => ( - <ArticleComponent {...args} /> -); - -/** - * Layout Stories - Article - */ -export const Article = Template.bind({}); -Article.args = { - children: 'The article content.', -}; diff --git a/src/components/atoms/layout/aside/aside.stories.ts b/src/components/atoms/layout/aside/aside.stories.ts new file mode 100644 index 0000000..c58372a --- /dev/null +++ b/src/components/atoms/layout/aside/aside.stories.ts @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Aside } from './aside'; + +const meta = { + component: Aside, + title: 'Atoms/Layout/Aside', +} satisfies Meta<typeof Aside>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Example: Story = { + args: { + children: 'The aside contents.', + }, +}; diff --git a/src/components/atoms/layout/aside/aside.stories.tsx b/src/components/atoms/layout/aside/aside.stories.tsx deleted file mode 100644 index a394d1b..0000000 --- a/src/components/atoms/layout/aside/aside.stories.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Aside as AsideComponent } from './aside'; - -/** - * Aside - Storybook Meta - */ -export default { - title: 'Atoms/Layout', - component: AsideComponent, - argTypes: { - children: { - control: { - type: 'text', - }, - description: 'The contents.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof AsideComponent>; - -const Template: ComponentStory<typeof AsideComponent> = (args) => ( - <AsideComponent {...args} /> -); - -/** - * Layout Stories - Aside - */ -export const Aside = Template.bind({}); -Aside.args = { - children: 'The aside content.', -}; diff --git a/src/components/atoms/layout/footer/footer.stories.ts b/src/components/atoms/layout/footer/footer.stories.ts new file mode 100644 index 0000000..662524c --- /dev/null +++ b/src/components/atoms/layout/footer/footer.stories.ts @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Footer } from './footer'; + +const meta = { + component: Footer, + title: 'Atoms/Layout/Footer', +} satisfies Meta<typeof Footer>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Example: Story = { + args: { + children: 'The footer contents.', + }, +}; diff --git a/src/components/atoms/layout/footer/footer.stories.tsx b/src/components/atoms/layout/footer/footer.stories.tsx deleted file mode 100644 index 0df1647..0000000 --- a/src/components/atoms/layout/footer/footer.stories.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Footer as FooterComponent } from './footer'; - -/** - * Footer - Storybook Meta - */ -export default { - title: 'Atoms/Layout', - component: FooterComponent, - argTypes: { - children: { - control: { - type: 'text', - }, - description: 'The contents.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof FooterComponent>; - -const Template: ComponentStory<typeof FooterComponent> = (args) => ( - <FooterComponent {...args} /> -); - -/** - * Layout Stories - Footer - */ -export const Footer = Template.bind({}); -Footer.args = { - children: 'The footer content.', -}; diff --git a/src/components/atoms/layout/header/header.stories.ts b/src/components/atoms/layout/header/header.stories.ts new file mode 100644 index 0000000..2afe715 --- /dev/null +++ b/src/components/atoms/layout/header/header.stories.ts @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Header } from './header'; + +const meta = { + component: Header, + title: 'Atoms/Layout/Header', +} satisfies Meta<typeof Header>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Example: Story = { + args: { + children: 'The header contents.', + }, +}; diff --git a/src/components/atoms/layout/header/header.stories.tsx b/src/components/atoms/layout/header/header.stories.tsx deleted file mode 100644 index 3d98263..0000000 --- a/src/components/atoms/layout/header/header.stories.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Header as HeaderComponent } from './header'; - -/** - * Header - Storybook Meta - */ -export default { - title: 'Atoms/Layout', - component: HeaderComponent, - argTypes: { - children: { - control: { - type: 'text', - }, - description: 'The contents.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof HeaderComponent>; - -const Template: ComponentStory<typeof HeaderComponent> = (args) => ( - <HeaderComponent {...args} /> -); - -/** - * Layout Stories - Header - */ -export const Header = Template.bind({}); -Header.args = { - children: 'The header content.', -}; diff --git a/src/components/atoms/layout/main/main.stories.ts b/src/components/atoms/layout/main/main.stories.ts new file mode 100644 index 0000000..79aedbb --- /dev/null +++ b/src/components/atoms/layout/main/main.stories.ts @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Main } from './main'; + +const meta = { + component: Main, + title: 'Atoms/Layout/Main', +} satisfies Meta<typeof Main>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Example: Story = { + args: { + children: 'The main contents.', + }, +}; diff --git a/src/components/atoms/layout/main/main.stories.tsx b/src/components/atoms/layout/main/main.stories.tsx deleted file mode 100644 index 6a22ed5..0000000 --- a/src/components/atoms/layout/main/main.stories.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Main as MainComponent } from './main'; - -/** - * Main - Storybook Meta - */ -export default { - title: 'Atoms/Layout', - component: MainComponent, - argTypes: { - children: { - control: { - type: 'text', - }, - description: 'The content.', - type: { - name: 'string', - required: true, - }, - }, - className: { - control: { - type: 'text', - }, - description: 'Set additional classnames to the main element.', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - id: { - control: { - type: 'text', - }, - description: 'The main element id.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof MainComponent>; - -const Template: ComponentStory<typeof MainComponent> = (args) => ( - <MainComponent {...args} /> -); - -/** - * Layout Stories - Main - */ -export const Main = Template.bind({}); -Main.args = { - children: 'The main content.', -}; diff --git a/src/components/atoms/layout/nav/nav.stories.ts b/src/components/atoms/layout/nav/nav.stories.ts new file mode 100644 index 0000000..6ee4e5e --- /dev/null +++ b/src/components/atoms/layout/nav/nav.stories.ts @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Nav } from './nav'; + +const meta = { + component: Nav, + title: 'Atoms/Layout/Nav', +} satisfies Meta<typeof Nav>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Example: Story = { + args: { + children: 'The nav contents.', + }, +}; diff --git a/src/components/atoms/layout/nav/nav.stories.tsx b/src/components/atoms/layout/nav/nav.stories.tsx deleted file mode 100644 index 5649abf..0000000 --- a/src/components/atoms/layout/nav/nav.stories.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Nav as NavComponent } from './nav'; - -/** - * Nav - Storybook Meta - */ -export default { - title: 'Atoms/Layout', - component: NavComponent, - argTypes: { - children: { - control: { - type: 'text', - }, - description: 'The contents.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof NavComponent>; - -const Template: ComponentStory<typeof NavComponent> = (args) => ( - <NavComponent {...args} /> -); - -/** - * Layout Stories - Nav - */ -export const Nav = Template.bind({}); -Nav.args = { - children: 'The nav content.', -}; diff --git a/src/components/atoms/layout/section/section.stories.ts b/src/components/atoms/layout/section/section.stories.ts new file mode 100644 index 0000000..f8df223 --- /dev/null +++ b/src/components/atoms/layout/section/section.stories.ts @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Section } from './section'; + +const meta = { + component: Section, + title: 'Atoms/Layout/Section', +} satisfies Meta<typeof Section>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Example: Story = { + args: { + children: 'The section contents.', + }, +}; diff --git a/src/components/atoms/layout/section/section.stories.tsx b/src/components/atoms/layout/section/section.stories.tsx deleted file mode 100644 index fdc8217..0000000 --- a/src/components/atoms/layout/section/section.stories.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Heading } from '../../heading'; -import { Section as SectionComponent } from './section'; - -/** - * Section - Storybook Meta - */ -export default { - title: 'Atoms/Layout/Section', - component: SectionComponent, - argTypes: { - children: { - description: 'The section contents.', - type: { - name: 'function', - required: true, - }, - }, - }, -} as ComponentMeta<typeof SectionComponent>; - -const Template: ComponentStory<typeof SectionComponent> = (args) => ( - <SectionComponent {...args} /> -); - -/** - * Section Story - */ -export const Section = Template.bind({}); -Section.args = { - children: ( - <> - <Heading level={2}>A section title</Heading> - <div>The body</div> - </> - ), -}; diff --git a/src/components/atoms/layout/time/time.stories.ts b/src/components/atoms/layout/time/time.stories.ts new file mode 100644 index 0000000..6e00a4c --- /dev/null +++ b/src/components/atoms/layout/time/time.stories.ts @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Time } from './time'; + +const meta = { + component: Time, + title: 'Atoms/Layout/Time', +} satisfies Meta<typeof Time>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Example: Story = { + args: { + date: '2022-03-15 10:44:20', + }, +}; diff --git a/src/components/atoms/layout/time/time.stories.tsx b/src/components/atoms/layout/time/time.stories.tsx deleted file mode 100644 index d534f14..0000000 --- a/src/components/atoms/layout/time/time.stories.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Time } from './time'; - -/** - * Time - Storybook Meta - */ -export default { - title: 'Atoms/Layout/Time', - component: Time, - argTypes: { - date: { - control: { - type: 'text', - }, - description: 'A valid date string.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof Time>; - -const Template: ComponentStory<typeof Time> = (args) => <Time {...args} />; - -/** - * Time Stories - Default - */ -export const Default = Template.bind({}); -Default.args = { - date: '2022-03-15 10:44:20', -}; diff --git a/src/components/atoms/links/link/link.stories.tsx b/src/components/atoms/links/link/link.stories.tsx index 0a6a6c5..30b0eab 100644 --- a/src/components/atoms/links/link/link.stories.tsx +++ b/src/components/atoms/links/link/link.stories.tsx @@ -1,178 +1,84 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import type { Meta, StoryObj } from '@storybook/react'; import { Link } from './link'; -/** - * Link - Storybook Meta - */ -export default { - title: 'Atoms/Links/Link', +const meta = { component: Link, - argTypes: { - children: { - control: { - type: 'text', - }, - description: 'The link body.', - type: { - name: 'string', - required: true, - }, - }, - className: { - control: { - type: 'text', - }, - description: 'Set additional classnames.', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - href: { - control: { - type: 'text', - }, - description: 'The link target.', - type: { - name: 'string', - required: true, - }, - }, - isDownload: { - control: { - type: 'boolean', - }, - description: 'Determine if the link purpose is to download a file.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - isExternal: { - control: { - type: 'boolean', - }, - description: 'Determine if the link is external of the current website.', - table: { - category: 'Options', - defaultValue: { summary: false }, - }, - type: { - name: 'boolean', - required: false, - }, - }, - lang: { - control: { - type: 'text', - }, - table: { - category: 'Options', - }, - description: 'The target language as code language.', - type: { - name: 'string', - required: false, - }, - }, - }, -} as ComponentMeta<typeof Link>; + title: 'Atoms/Links', +} satisfies Meta<typeof Link>; + +export default meta; -const Template: ComponentStory<typeof Link> = (args) => <Link {...args} />; +type Story = StoryObj<typeof meta>; -/** - * Links Stories - Default - */ -export const Default = Template.bind({}); -Default.args = { - children: 'A link', - href: '#', +export const Default: Story = { + args: { + children: 'A link', + href: '#link', + }, }; -/** - * Links Stories - Download - */ -export const DownloadLink = Template.bind({}); -DownloadLink.args = { - children: 'A link to a file', - href: '#', - isDownload: true, - isExternal: false, +export const WithLang: Story = { + args: { + children: 'Github repository', + href: 'https://github.com/ArmandPhilippot/apcom', + lang: 'en', + }, + render: (args) => ( + <> + Go to the <Link {...args} />. + </> + ), }; -/** - * Links Stories - Download link with lang - */ -export const DownloadLinkWithLang = Template.bind({}); -DownloadLinkWithLang.args = { - children: 'A link to a file', - href: '#', - isDownload: true, - isExternal: false, - lang: 'en', +export const DownloadLink: Story = { + args: { + children: 'Download the file', + href: '#file', + isDownload: true, + }, }; -/** - * Links Stories - External - */ -export const ExternalLink = Template.bind({}); -ExternalLink.args = { - children: 'A link', - href: '#', - isDownload: false, - isExternal: true, +export const DownloadLinkWithLang: Story = { + args: { + children: 'Download the file', + href: '#file', + isDownload: true, + lang: 'en', + }, }; -/** - * Links Stories - External download link - */ -export const ExternalDownload = Template.bind({}); -ExternalDownload.args = { - children: 'A link', - href: '#', - isDownload: true, - isExternal: true, +export const ExternalLink: Story = { + args: { + children: 'Go to the Github repository', + href: 'https://github.com/ArmandPhilippot/apcom', + isExternal: true, + }, }; -/** - * Links Stories - External link with Lang - */ -export const ExternalLinkWithLang = Template.bind({}); -ExternalLinkWithLang.args = { - children: 'A link', - href: '#', - isDownload: false, - isExternal: true, - lang: 'en', +export const ExternalLinkWithLang: Story = { + args: { + children: 'Go to the Github repository', + href: 'https://github.com/ArmandPhilippot/apcom', + isExternal: true, + lang: 'en', + }, }; -/** - * Links Stories - External download with lang - */ -export const ExternalDownloadWithLang = Template.bind({}); -ExternalDownloadWithLang.args = { - children: 'A link', - href: '#', - isDownload: true, - isExternal: true, - lang: 'en', +export const ExternalDownloadLink: Story = { + args: { + children: 'Download the file', + href: '#file', + isDownload: true, + isExternal: true, + }, }; -/** - * Links Stories - With Lang - */ -export const LinkLang = Template.bind({}); -LinkLang.args = { - children: 'A link', - href: '#', - isDownload: false, - isExternal: false, - lang: 'en', +export const ExternalDownloadLinkWithLang: Story = { + args: { + children: 'Download the file', + href: '#file', + isDownload: true, + isExternal: true, + lang: 'en', + }, }; diff --git a/src/components/atoms/links/sharing-link/sharing-link.stories.ts b/src/components/atoms/links/sharing-link/sharing-link.stories.ts new file mode 100644 index 0000000..53d2507 --- /dev/null +++ b/src/components/atoms/links/sharing-link/sharing-link.stories.ts @@ -0,0 +1,59 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { SharingLink } from './sharing-link'; + +const meta = { + component: SharingLink, + title: 'Atoms/Links/Share', +} satisfies Meta<typeof SharingLink>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Diaspora: Story = { + args: { + label: 'Share on Diaspora', + medium: 'diaspora', + url: '#diaspora', + }, +}; + +export const Email: Story = { + args: { + label: 'Share by Email', + medium: 'email', + url: '#email', + }, +}; + +export const Facebook: Story = { + args: { + label: 'Share on Facebook', + medium: 'facebook', + url: '#facebook', + }, +}; + +export const JournalDuHacker: Story = { + args: { + label: 'Share on Journal du Hacker', + medium: 'journal-du-hacker', + url: '#journal-du-hacker', + }, +}; + +export const LinkedIn: Story = { + args: { + label: 'Share on LinkedIn', + medium: 'linkedin', + url: '#linkedin', + }, +}; + +export const Twitter: Story = { + args: { + label: 'Share on Twitter', + medium: 'twitter', + url: '#twitter', + }, +}; diff --git a/src/components/atoms/links/sharing-link/sharing-link.stories.tsx b/src/components/atoms/links/sharing-link/sharing-link.stories.tsx deleted file mode 100644 index 932d468..0000000 --- a/src/components/atoms/links/sharing-link/sharing-link.stories.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { SharingLink } from './sharing-link'; - -/** - * SharingLink - Storybook Meta - */ -export default { - title: 'Atoms/Links/Sharing', - component: SharingLink, - argTypes: { - medium: { - control: { - type: 'select', - }, - description: 'The sharing medium.', - options: [ - 'diaspora', - 'email', - 'facebook', - 'journal-du-hacker', - 'linkedin', - 'twitter', - ], - type: { - name: 'string', - required: true, - }, - }, - label: { - control: { - type: 'text', - }, - description: 'An accessible label that describe the link..', - type: { - name: 'string', - required: true, - }, - }, - url: { - control: { - type: 'text', - }, - description: 'The sharing url.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof SharingLink>; - -const Template: ComponentStory<typeof SharingLink> = (args) => ( - <SharingLink {...args} /> -); - -/** - * Sharing Link Stories - Diaspora - */ -export const Diaspora = Template.bind({}); -Diaspora.args = { - label: 'Share on Diaspora', - medium: 'diaspora', - url: '#', -}; - -/** - * Sharing Link Stories - Email - */ -export const Email = Template.bind({}); -Email.args = { - label: 'Share by Email', - medium: 'email', - url: '#', -}; - -/** - * Sharing Link Stories - Facebook - */ -export const Facebook = Template.bind({}); -Facebook.args = { - label: 'Share on Facebook', - medium: 'facebook', - url: '#', -}; - -/** - * Sharing Link Stories - Journal du Hacker - */ -export const JournalDuHacker = Template.bind({}); -JournalDuHacker.args = { - label: 'Share on Journal du Hacker', - medium: 'journal-du-hacker', - url: '#', -}; - -/** - * Sharing Link Stories - LinkedIn - */ -export const LinkedIn = Template.bind({}); -LinkedIn.args = { - label: 'Share on LinkedIn', - medium: 'linkedin', - url: '#', -}; - -/** - * Sharing Link Stories - Twitter - */ -export const Twitter = Template.bind({}); -Twitter.args = { - label: 'Share on Twitter', - medium: 'twitter', - url: '#', -}; diff --git a/src/components/atoms/links/social-link/social-link.stories.ts b/src/components/atoms/links/social-link/social-link.stories.ts new file mode 100644 index 0000000..f7f4302 --- /dev/null +++ b/src/components/atoms/links/social-link/social-link.stories.ts @@ -0,0 +1,43 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { SocialLink } from './social-link'; + +const meta = { + component: SocialLink, + title: 'Atoms/Links/Social', +} satisfies Meta<typeof SocialLink>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Github: Story = { + args: { + icon: 'Github', + label: 'Github profile', + url: '#github', + }, +}; + +export const Gitlab: Story = { + args: { + icon: 'Gitlab', + label: 'Gitlab profile', + url: '#gitlab', + }, +}; + +export const LinkedIn: Story = { + args: { + icon: 'LinkedIn', + label: 'LinkedIn profile', + url: '#linkedin', + }, +}; + +export const Twitter: Story = { + args: { + icon: 'Twitter', + label: 'Twitter profile', + url: '#twitter', + }, +}; diff --git a/src/components/atoms/links/social-link/social-link.stories.tsx b/src/components/atoms/links/social-link/social-link.stories.tsx deleted file mode 100644 index cfb4ac7..0000000 --- a/src/components/atoms/links/social-link/social-link.stories.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { SocialLink } from './social-link'; - -/** - * SocialLink - Storybook Meta - */ -export default { - title: 'Atoms/Links/Social', - component: SocialLink, - argTypes: { - url: { - control: { - type: null, - }, - description: 'Social profile url.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof SocialLink>; - -const Template: ComponentStory<typeof SocialLink> = (args) => ( - <SocialLink {...args} /> -); - -/** - * Social Link Stories - Github - */ -export const Github = Template.bind({}); -Github.args = { - icon: 'Github', - label: 'Github profile', - url: '#', -}; - -/** - * Social Link Stories - Gitlab - */ -export const Gitlab = Template.bind({}); -Gitlab.args = { - icon: 'Gitlab', - label: 'Gitlab profile', - url: '#', -}; - -/** - * Social Link Stories - LinkedIn - */ -export const LinkedIn = Template.bind({}); -LinkedIn.args = { - icon: 'LinkedIn', - label: 'LinkedIn profile', - url: '#', -}; - -/** - * Social Link Stories - Twitter - */ -export const Twitter = Template.bind({}); -Twitter.args = { - icon: 'Twitter', - label: 'Twitter profile', - url: '#', -}; diff --git a/src/components/atoms/lists/description-list/description-list.stories.tsx b/src/components/atoms/lists/description-list/description-list.stories.tsx index d051fcd..65efc28 100644 --- a/src/components/atoms/lists/description-list/description-list.stories.tsx +++ b/src/components/atoms/lists/description-list/description-list.stories.tsx @@ -1,150 +1,270 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import type { Meta, StoryObj } from '@storybook/react'; import { Description } from './description'; import { DescriptionList } from './description-list'; import { Group } from './group'; import { Term } from './term'; -/** - * DescriptionList - Storybook Meta - */ -export default { - title: 'Atoms/Lists/DescriptionList', +const meta = { component: DescriptionList, + title: 'Atoms/Lists/Description List', +} satisfies Meta<typeof DescriptionList>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +const Default: Story = { + args: { + children: [ + <Term key="term">A term</Term>, + <Description key="description">A description of the term.</Description>, + ], + }, +}; + +export const SingleTermSingleDescription: Story = { + args: { + ...Default.args, + }, +}; + +export const MultipleTermsSingleDescription: Story = { + args: { + ...Default.args, + children: [ + <Term key="term-1">First term</Term>, + <Term key="term-2">Second term</Term>, + <Term key="term-3">Third term</Term>, + <Description key="description-1">Description of the terms</Description>, + ], + }, +}; + +export const SingleTermMultipleDescriptions: Story = { + args: { + ...Default.args, + children: [ + <Term key="term-1">A term</Term>, + <Description key="description-1"> + First description of the term + </Description>, + <Description key="description-2"> + Second description of the term + </Description>, + <Description key="description-3"> + Third description of the term + </Description>, + ], + }, +}; + +export const MultipleTermsMultipleDescriptions: Story = { + args: { + ...Default.args, + children: [ + <Term key="term-1">First term</Term>, + <Description key="description-1"> + Description of the first term + </Description>, + <Term key="term-2">Second term</Term>, + <Term key="term-2-alternative">Alternative of second term</Term>, + <Description key="description-2"> + Description of the second term + </Description>, + <Term key="term-3">Third term</Term>, + <Description key="first-description-3"> + First description of the third term + </Description>, + <Description key="second-description-3"> + Second description of the third term + </Description>, + ], + }, +}; + +export const GroupOfMultipleTermsMultipleDescriptions: Story = { + args: { + ...Default.args, + children: [ + <Group key="group-1"> + <Term>First term</Term> + <Description>Description of the first term</Description> + </Group>, + <Group key="group-2"> + <Term>Second term</Term> + <Term>Alternative of second term</Term> + <Description>Description of the second term</Description> + </Group>, + <Group key="group-3"> + <Term>Third term</Term> + <Description>First description of the third term</Description> + <Description>Second description of the third term</Description> + </Group>, + ], + }, +}; + +export const SpacingXXSWithoutGroup: Story = { + name: 'Spacing: Double extra-small (without group)', + args: { + ...MultipleTermsMultipleDescriptions.args, + spacing: '2xs', + }, +}; + +export const SpacingXSWithoutGroup: Story = { + name: 'Spacing: Extra-small (without group)', + args: { + ...MultipleTermsMultipleDescriptions.args, + spacing: 'xs', + }, +}; + +export const SpacingSMWithoutGroup: Story = { + name: 'Spacing: Small (without group)', + args: { + ...MultipleTermsMultipleDescriptions.args, + spacing: 'sm', + }, +}; + +export const SpacingMDWithoutGroup: Story = { + name: 'Spacing: Medium (without group)', + args: { + ...MultipleTermsMultipleDescriptions.args, + spacing: 'md', + }, +}; + +export const SpacingLGWithoutGroup: Story = { + name: 'Spacing: Large (without group)', + args: { + ...MultipleTermsMultipleDescriptions.args, + spacing: 'lg', + }, +}; + +export const SpacingXLWithoutGroup: Story = { + name: 'Spacing: Extra-large (without group)', args: { - isInline: false, - }, - argTypes: { - className: { - control: { - type: 'text', - }, - description: 'Set additional classnames to the list wrapper', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - }, -} as ComponentMeta<typeof DescriptionList>; - -const Template: ComponentStory<typeof DescriptionList> = (args) => ( - <DescriptionList {...args} /> -); - -/** - * Description List Stories - Single term, single description - */ -export const SingleTermSingleDescription = Template.bind({}); -SingleTermSingleDescription.args = { - children: ( - <> - <Term>A term</Term> - <Description>A description of the term.</Description> - </> - ), -}; - -/** - * Description List Stories - Multiple terms, single description - */ -export const MultipleTermsSingleDescription = Template.bind({}); -MultipleTermsSingleDescription.args = { - children: ( - <> - <Term>A first term</Term> - <Term>A second term</Term> - <Term>A third term</Term> - <Description>A description of the term.</Description> - </> - ), -}; - -/** - * Description List Stories - Single term, multiple descriptions - */ -export const SingleTermMultipleDescriptions = Template.bind({}); -SingleTermMultipleDescriptions.args = { - children: ( - <> - <Term>A term</Term> - <Description>A first description of the term.</Description> - <Description>A second description of the term.</Description> - <Description>A third description of the term.</Description> - </> - ), -}; - -/** - * Description List Stories - Multiple terms, multiple descriptions - */ -export const MultipleTermsMultipleDescriptions = Template.bind({}); -MultipleTermsMultipleDescriptions.args = { - children: ( - <> - <Term>A first term</Term> - <Term>A second term</Term> - <Term>A third term</Term> - <Description>A first description of the term.</Description> - <Description>A second description of the term.</Description> - <Description>A third description of the term.</Description> - </> - ), -}; - -/** - * Description List Stories - Group of terms & descriptions - */ -export const GroupOfTermsDescriptions = Template.bind({}); -GroupOfTermsDescriptions.args = { - children: ( - <> - <Group> + ...MultipleTermsMultipleDescriptions.args, + spacing: 'xl', + }, +}; + +export const SpacingXXLWithoutGroup: Story = { + name: 'Spacing: Double extra-large (without group)', + args: { + ...MultipleTermsMultipleDescriptions.args, + spacing: '2xl', + }, +}; + +export const SpacingXXSWithGroup: Story = { + name: 'Spacing: Double extra-small (with group)', + args: { + ...GroupOfMultipleTermsMultipleDescriptions.args, + spacing: '2xs', + }, +}; + +export const SpacingXSWithGroup: Story = { + name: 'Spacing: Extra-small (with group)', + args: { + ...GroupOfMultipleTermsMultipleDescriptions.args, + spacing: 'xs', + }, +}; + +export const SpacingSMWithGroup: Story = { + name: 'Spacing: Small (with group)', + args: { + ...GroupOfMultipleTermsMultipleDescriptions.args, + spacing: 'sm', + }, +}; + +export const SpacingMDWithGroup: Story = { + name: 'Spacing: Medium (with group)', + args: { + ...GroupOfMultipleTermsMultipleDescriptions.args, + spacing: 'md', + }, +}; + +export const SpacingLGWithGroup: Story = { + name: 'Spacing: Large (with group)', + args: { + ...GroupOfMultipleTermsMultipleDescriptions.args, + spacing: 'lg', + }, +}; + +export const SpacingXLWithGroup: Story = { + name: 'Spacing: Extra-large (with group)', + args: { + ...GroupOfMultipleTermsMultipleDescriptions.args, + spacing: 'xl', + }, +}; + +export const SpacingXXLWithGroup: Story = { + name: 'Spacing: Double extra-large (with group)', + args: { + ...GroupOfMultipleTermsMultipleDescriptions.args, + spacing: '2xl', + }, +}; + +export const InlinedWithoutGroups: Story = { + name: 'Alignment: inlined without groups', + args: { + ...Default.args, + children: [ + <Term key="term1">A term</Term>, + <Description key="description1">A description.</Description>, + <Term key="term2">Another term</Term>, + <Description key="description2">Another description.</Description>, + ], + isInline: true, + spacing: 'xs', + }, +}; + +export const InlinedWithGroups: Story = { + name: 'Alignment: inlined with groups', + args: { + ...Default.args, + children: [ + <Group key="group1"> <Term>A term</Term> - <Description>A description of the term.</Description> - </Group> - <Group> + <Description>A description.</Description> + </Group>, + <Group key="group2"> <Term>Another term</Term> - <Description>A description of the other term.</Description> - </Group> - </> - ), -}; - -/** - * Description List Stories - Inlined list of term and descriptions - */ -export const InlinedList = Template.bind({}); -InlinedList.args = { - children: ( - <> - <Term>A term:</Term> - <Description>A first description of the term.</Description> - <Description>A second description of the term.</Description> - <Description>A third description of the term.</Description> - </> - ), - isInline: true, - spacing: 'xs', -}; - -/** - * Description List Stories - Inlined group of terms & descriptions - */ -export const InlinedGroupOfTermsDescriptions = Template.bind({}); -InlinedGroupOfTermsDescriptions.args = { - children: ( - <> - <Group isInline spacing="2xs"> - <Term>A term:</Term> - <Description>A description of the term.</Description> - </Group> - <Group isInline spacing="2xs"> - <Term>Another term:</Term> - <Description>A description of the other term.</Description> - </Group> - </> - ), + <Description>Another description.</Description> + </Group>, + ], + isInline: true, + spacing: 'xs', + }, +}; + +export const InlinedWithInlinedGroups: Story = { + name: 'Alignment: inlined with inlined groups', + args: { + ...Default.args, + children: [ + <Group key="group1" isInline spacing="xs"> + <Term>A term</Term> + <Description>A description.</Description> + </Group>, + <Group key="group2" isInline spacing="xs"> + <Term>Another term</Term> + <Description>Another description.</Description> + </Group>, + ], + isInline: true, + spacing: 'xs', + }, }; diff --git a/src/components/atoms/lists/list/list.stories.tsx b/src/components/atoms/lists/list/list.stories.tsx index 538947a..6e7d254 100644 --- a/src/components/atoms/lists/list/list.stories.tsx +++ b/src/components/atoms/lists/list/list.stories.tsx @@ -1,196 +1,140 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { List, type ListProps } from './list'; +import type { Meta, StoryObj } from '@storybook/react'; +import { List } from './list'; import { ListItem } from './list-item'; -/** - * List - Storybook Meta - */ -export default { - title: 'Atoms/Lists', +const meta = { component: List, - args: {}, - argTypes: { - className: { - control: { - type: 'text', - }, - description: 'Set additional classnames to the list wrapper', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - }, -} as ComponentMeta<typeof List>; + title: 'Atoms/Lists/List', +} satisfies Meta<typeof List>; + +export default meta; + +type Story = StoryObj<typeof meta>; -const Template: ComponentStory<typeof List> = < - O extends boolean, - H extends boolean, ->( - args: ListProps<O, H> -) => <List {...args} />; +export const Default: Story = { + args: { + children: [ + <ListItem key="item-1">Item 1</ListItem>, + <ListItem key="item-2">Item 2</ListItem>, + <ListItem key="item-3">Item 3</ListItem>, + ], + }, +}; -/** - * List Stories - Hierarchical list - */ -export const Hierarchical = Template.bind({}); -Hierarchical.args = { - children: [ - <ListItem key="item-1"> - Item 1 - <List isHierarchical isOrdered> - <ListItem>Subitem 1</ListItem> - <ListItem>Subitem 2</ListItem> - </List> - </ListItem>, - <ListItem key="item-2"> - Item 2 - <List isHierarchical isOrdered> - <ListItem>Subitem 1</ListItem> - <ListItem> - Subitem 2 - <List isHierarchical isOrdered> - <ListItem>Nested item 1</ListItem> - <ListItem>Nested item 2</ListItem> - </List> - </ListItem> - <ListItem>Subitem 3</ListItem> - </List> - </ListItem>, - <ListItem key="item-3">Item 3</ListItem>, - ], - isHierarchical: true, +export const OrderedList: Story = { + args: { + ...Default.args, + isOrdered: true, + }, }; -/** - * List Stories - Ordered list - */ -export const Ordered = Template.bind({}); -Ordered.args = { - children: [ - <ListItem key="item-1"> - Item 1 - <List isOrdered> - <ListItem>Subitem 1</ListItem> - <ListItem>Subitem 2</ListItem> - </List> - </ListItem>, - <ListItem key="item-2"> - Item 2 - <List isOrdered> - <ListItem>Subitem 1</ListItem> - <ListItem> - Subitem 2 - <List isOrdered> - <ListItem>Nested item 1</ListItem> - <ListItem>Nested item 2</ListItem> - </List> - </ListItem> - <ListItem>Subitem 3</ListItem> - </List> - </ListItem>, - <ListItem key="item-3">Item 3</ListItem>, - ], - isOrdered: true, +export const UnorderedList: Story = { + args: { + ...Default.args, + isOrdered: false, + }, }; -/** - * List Stories - Unordered list - */ -export const Unordered = Template.bind({}); -Unordered.args = { - children: [ - <ListItem key="item-1"> - Item 1 - <List> - <ListItem>Subitem 1</ListItem> - <ListItem>Subitem 2</ListItem> - </List> - </ListItem>, - <ListItem key="item-2"> - Item 2 - <List isOrdered> - <ListItem>Subitem 1</ListItem> - <ListItem> - Subitem 2 - <List> - <ListItem>Nested item 1</ListItem> - <ListItem>Nested item 2</ListItem> - </List> - </ListItem> - <ListItem>Subitem 3</ListItem> - </List> - </ListItem>, - <ListItem key="item-3">Item 3</ListItem>, - ], +export const Nested: Story = { + args: { + ...Default.args, + children: [ + <ListItem key="item-1">Item 1</ListItem>, + <ListItem key="item-2"> + Item 2 + <List isOrdered> + <ListItem>Nested item 1</ListItem> + <ListItem>Nested item 2</ListItem> + <ListItem> + Nested item 3 + <List> + <ListItem>Deeper item 1</ListItem> + <ListItem>Deeper item 2</ListItem> + <ListItem>Deeper item 3</ListItem> + </List> + </ListItem> + </List> + </ListItem>, + <ListItem key="item-3">Item 3</ListItem>, + ], + isOrdered: false, + }, }; -const items = [ - { id: 'item-1', label: 'Item 1' }, - { id: 'item-2', label: 'Item 2' }, - { - id: 'item-3', - label: ( - <> - Item 3 - <List> +export const HierarchicalList: Story = { + args: { + ...OrderedList.args, + children: [ + <ListItem key="item-1"> + Item 1 + <List isHierarchical isOrdered> <ListItem>Subitem 1</ListItem> <ListItem>Subitem 2</ListItem> </List> - </> - ), + </ListItem>, + <ListItem key="item-2"> + Item 2 + <List isHierarchical isOrdered> + <ListItem>Subitem 1</ListItem> + <ListItem> + Subitem 2 + <List isHierarchical isOrdered> + <ListItem>Nested item 1</ListItem> + <ListItem>Nested item 2</ListItem> + </List> + </ListItem> + <ListItem>Subitem 3</ListItem> + </List> + </ListItem>, + <ListItem key="item-3">Item 3</ListItem>, + ], + isHierarchical: true, }, - { id: 'item-4', label: 'Item 4' }, - { id: 'item-5', label: 'Item 5' }, -]; +}; -/** - * List Stories - Inline and ordered list - */ -export const InlineOrdered = Template.bind({}); -InlineOrdered.args = { - children: items.map((item) => ( - <ListItem key={item.id}>{item.label}</ListItem> - )), - isInline: true, - isOrdered: true, - spacing: 'sm', +export const WithMarker: Story = { + args: { + ...Default.args, + hideMarker: false, + }, }; -/** - * List Stories - Inline and unordered list - */ -export const InlineUnordered = Template.bind({}); -InlineUnordered.args = { - children: items.map((item) => ( - <ListItem key={item.id}>{item.label}</ListItem> - )), - isInline: true, - spacing: 'sm', +export const WithoutMarker: Story = { + args: { + ...Default.args, + hideMarker: true, + }, }; -/** - * List Stories - Ordered list without marker - */ -export const OrderedHideMarker = Template.bind({}); -OrderedHideMarker.args = { - children: items.map((item) => ( - <ListItem key={item.id}>{item.label}</ListItem> - )), - hideMarker: true, - isOrdered: true, +export const InlineList: Story = { + args: { + ...Default.args, + children: [ + <ListItem key="item-1">Item 1</ListItem>, + <ListItem key="sep-1">{'>'}</ListItem>, + <ListItem key="item-2">Item 2</ListItem>, + <ListItem key="sep-2">{'>'}</ListItem>, + <ListItem key="item-3">Item 3</ListItem>, + ], + hideMarker: true, + isInline: true, + spacing: 'xs', + }, }; -/** - * List Stories - Unordered list without marker - */ -export const UnorderedHideMarker = Template.bind({}); -UnorderedHideMarker.args = { - children: items.map((item) => ( - <ListItem key={item.id}>{item.label}</ListItem> - )), - hideMarker: true, +export const ListInInlineList: Story = { + args: { + ...InlineList.args, + children: [ + <ListItem key="item-1">Item 1</ListItem>, + <ListItem key="item-2"> + Item 2 + <List> + <ListItem>Nested item 1</ListItem> + <ListItem>Nested item 2</ListItem> + </List> + </ListItem>, + <ListItem key="item-3">Item 3</ListItem>, + ], + }, }; diff --git a/src/components/atoms/loaders/progress-bar/progress-bar.stories.ts b/src/components/atoms/loaders/progress-bar/progress-bar.stories.ts new file mode 100644 index 0000000..82f6f18 --- /dev/null +++ b/src/components/atoms/loaders/progress-bar/progress-bar.stories.ts @@ -0,0 +1,23 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ProgressBar } from './progress-bar'; + +const meta = { + component: ProgressBar, + title: 'Atoms/Loaders/ProgressBar', +} satisfies Meta<typeof ProgressBar>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +const max = 50; +const current = 10; +const label = `${current} loaded out of a total of ${max}`; + +export const Example: Story = { + args: { + current, + label, + max, + }, +}; diff --git a/src/components/atoms/loaders/progress-bar/progress-bar.stories.tsx b/src/components/atoms/loaders/progress-bar/progress-bar.stories.tsx deleted file mode 100644 index fb600fb..0000000 --- a/src/components/atoms/loaders/progress-bar/progress-bar.stories.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { ProgressBar as ProgressBarComponent } from './progress-bar'; - -/** - * ProgressBar - Storybook Meta - */ -export default { - title: 'Atoms/Loaders', - component: ProgressBarComponent, - argTypes: { - current: { - control: { - type: 'number', - }, - description: 'The current value.', - type: { - name: 'number', - required: true, - }, - }, - label: { - control: { - type: 'text', - }, - description: 'The progress bar label.', - type: { - name: 'string', - required: true, - }, - }, - max: { - control: { - type: 'number', - }, - description: 'The maximal value.', - type: { - name: 'number', - required: true, - }, - }, - }, -} as ComponentMeta<typeof ProgressBarComponent>; - -const Template: ComponentStory<typeof ProgressBarComponent> = (args) => ( - <ProgressBarComponent {...args} /> -); - -const max = 50; -const current = 10; -const label = `${current} loaded out of a total of ${max}`; - -/** - * Loaders Stories - Progress bar - */ -export const ProgressBar = Template.bind({}); -ProgressBar.args = { - current, - label, - max, -}; diff --git a/src/components/atoms/loaders/spinner/spinner.stories.ts b/src/components/atoms/loaders/spinner/spinner.stories.ts new file mode 100644 index 0000000..63d7f21 --- /dev/null +++ b/src/components/atoms/loaders/spinner/spinner.stories.ts @@ -0,0 +1,45 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Spinner } from './spinner'; + +const meta = { + component: Spinner, + title: 'Atoms/Loaders/Spinner', +} satisfies Meta<typeof Spinner>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Example: Story = { + args: { + 'aria-label': 'A spinner example', + }, +}; + +export const WithTextOnBottom: Story = { + args: { + children: 'A spinner example', + position: 'bottom', + }, +}; + +export const WithTextOnLeft: Story = { + args: { + children: 'A spinner example', + position: 'left', + }, +}; + +export const WithTextOnRight: Story = { + args: { + children: 'A spinner example', + position: 'right', + }, +}; + +export const WithTextOnTop: Story = { + args: { + children: 'A spinner example', + position: 'top', + }, +}; diff --git a/src/components/atoms/loaders/spinner/spinner.stories.tsx b/src/components/atoms/loaders/spinner/spinner.stories.tsx deleted file mode 100644 index e9dfae4..0000000 --- a/src/components/atoms/loaders/spinner/spinner.stories.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Spinner as SpinnerComponent } from './spinner'; - -/** - * Spinner - Storybook Meta - */ -export default { - title: 'Atoms/Loaders', - component: SpinnerComponent, - argTypes: { - children: { - control: { - type: 'text', - }, - description: 'Loading message.', - table: { - category: 'Options', - }, - type: { - name: 'string', - required: false, - }, - }, - }, -} as ComponentMeta<typeof SpinnerComponent>; - -const Template: ComponentStory<typeof SpinnerComponent> = (args) => ( - <SpinnerComponent {...args} /> -); - -/** - * Loaders Stories - Spinner - */ -export const Spinner = Template.bind({}); -Spinner.args = { - children: 'Submitting...', -}; diff --git a/src/components/atoms/notice/notice.stories.ts b/src/components/atoms/notice/notice.stories.ts new file mode 100644 index 0000000..1f0723b --- /dev/null +++ b/src/components/atoms/notice/notice.stories.ts @@ -0,0 +1,39 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Notice } from './notice'; + +const meta = { + component: Notice, + title: 'Atoms/Notice', +} satisfies Meta<typeof Notice>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const ErrorKind: Story = { + args: { + children: 'Nisi provident sapiente.', + kind: 'error', + }, +}; + +export const InfoKind: Story = { + args: { + children: 'Nisi provident sapiente.', + kind: 'info', + }, +}; + +export const SuccessKind: Story = { + args: { + children: 'Nisi provident sapiente.', + kind: 'success', + }, +}; + +export const WarningKind: Story = { + args: { + children: 'Nisi provident sapiente.', + kind: 'warning', + }, +}; diff --git a/src/components/atoms/notice/notice.stories.tsx b/src/components/atoms/notice/notice.stories.tsx deleted file mode 100644 index 60d97d9..0000000 --- a/src/components/atoms/notice/notice.stories.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Notice as NoticeComponent } from './notice'; - -/** - * Notice - Storybook Meta - */ -export default { - title: 'Atoms/Notice', - component: NoticeComponent, - argTypes: { - className: { - control: { - type: 'text', - }, - description: 'Set additional classnames to the notice wrapper.', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - kind: { - control: { - type: 'select', - }, - description: 'The notice kind.', - options: ['error', 'info', 'success', 'warning'], - type: { - name: 'string', - required: true, - }, - }, - children: { - control: { - type: 'text', - }, - description: 'The notice body.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof NoticeComponent>; - -const Template: ComponentStory<typeof NoticeComponent> = (args) => ( - <NoticeComponent {...args} /> -); - -/** - * Notice stories - Error - */ -export const ErrorKind = Template.bind({}); -ErrorKind.args = { - children: 'Nisi provident sapiente.', - kind: 'error', -}; - -/** - * Notice stories - Info - */ -export const InfoKind = Template.bind({}); -InfoKind.args = { - children: 'Nisi provident sapiente.', - kind: 'info', -}; - -/** - * Notice stories - Success - */ -export const SuccessKind = Template.bind({}); -SuccessKind.args = { - children: 'Nisi provident sapiente.', - kind: 'success', -}; - -/** - * Notice stories - Warning - */ -export const WarningKind = Template.bind({}); -WarningKind.args = { - children: 'Nisi provident sapiente.', - kind: 'warning', -}; diff --git a/src/components/atoms/overlay/overlay.stories.tsx b/src/components/atoms/overlay/overlay.stories.tsx index f9c478c..5c56d6a 100644 --- a/src/components/atoms/overlay/overlay.stories.tsx +++ b/src/components/atoms/overlay/overlay.stories.tsx @@ -1,63 +1,65 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { useToggle } from '../../../utils/hooks'; +import type { Meta, StoryObj } from '@storybook/react'; +import { useCallback, useState } from 'react'; import { Button } from '../buttons'; -import { Overlay } from './overlay'; +import { Overlay, type OverlayProps } from './overlay'; -/** - * Overlay - Storybook Meta - */ -export default { - title: 'Atoms/Overlay', - component: Overlay, - argTypes: {}, -} as ComponentMeta<typeof Overlay>; +type OverlayTemplateProps = OverlayProps & { + isActive?: boolean; +}; -const Template: ComponentStory<typeof Overlay> = ({ isVisible, ...props }) => { - const [isActive, toggle] = useToggle(isVisible); +const OverlayTemplate = ({ + isActive: active = false, + ...props +}: OverlayTemplateProps) => { + const [isActive, setIsActive] = useState(active); + + const handleClick = useCallback(() => { + setIsActive((prev) => !prev); + }, []); return ( <div> <p> - Itaque reprehenderit sint rerum placeat et sapiente similique ut - distinctio. Libero illo reprehenderit qui quaerat dolorem. Officiis - asperiores sapiente eaque. Aut numquam porro quasi delectus excepturi - aut eaque et. Commodi et necessitatibus provident blanditiis rem qui - atque. + Ad eos id. In nihil fugit nisi dolorem numquam fuga aut quod voluptatem. + Dicta id nisi quia laboriosam sit ipsam deserunt ex. Omnis quia error + ipsum ea numquam quia veniam omnis voluptatem. Dolor corrupti mollitia + quod fugit est animi totam sed. </p> <p> - Aut architecto vitae dolor hic explicabo iure quia quae beatae. - Exercitationem nulla dignissimos doloribus sunt at nisi. A modi quasi - est sed quas repellendus vel sed dolores. Sed neque aperiam adipisci eos - autem. Libero omnis quis aut quas omnis magni harum et. + Eum et laudantium eaque cumque. Voluptatem voluptas fugit incidunt quos + voluptatibus velit et voluptatem laboriosam. Et voluptas ut quia + mollitia eum voluptatem. Similique cum ratione ea illo autem facilis + laudantium. </p> - <Button onClick={toggle}>Open overlay</Button> - <Overlay {...props} isVisible={isActive} onClick={toggle} /> + <Button onClick={handleClick}>Open overlay</Button> + {isActive ? <Overlay {...props} onClick={handleClick} /> : null} </div> ); }; -/** - * Overlay Stories - Hidden - */ -export const Hidden = Template.bind({}); -Hidden.args = { - children: ( - <div style={{ background: '#FFF', margin: '1rem', padding: '1rem' }}> - Some modal contents. - </div> - ), - isVisible: false, -}; +const meta = { + title: 'Atoms/Overlay', + component: Overlay, + render: OverlayTemplate, +} satisfies Meta<typeof Overlay>; -/** - * Overlay Stories - Visible - */ -export const Visible = Template.bind({}); -Visible.args = { - children: ( - <div style={{ background: '#FFF', margin: '1rem', padding: '1rem' }}> - Some modal contents. - </div> - ), - isVisible: true, +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Default: Story = { + args: { + children: ( + <div + style={{ + background: '#FFF', + padding: '1rem', + margin: '1rem', + }} + > + The modal contents. + </div> + ), + isActive: true, + }, }; diff --git a/src/components/atoms/sidebar/sidebar.stories.ts b/src/components/atoms/sidebar/sidebar.stories.ts new file mode 100644 index 0000000..f3883b9 --- /dev/null +++ b/src/components/atoms/sidebar/sidebar.stories.ts @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Sidebar } from './sidebar'; + +const meta = { + component: Sidebar, + title: 'Atoms/Sidebar', +} satisfies Meta<typeof Sidebar>; + +export default meta; + +type Story = StoryObj<typeof meta>; + +export const Example: Story = { + args: { + children: 'Some widgets.', + }, +}; diff --git a/src/components/atoms/sidebar/sidebar.stories.tsx b/src/components/atoms/sidebar/sidebar.stories.tsx deleted file mode 100644 index 4debb41..0000000 --- a/src/components/atoms/sidebar/sidebar.stories.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Sidebar as SidebarComponent } from './sidebar'; - -/** - * Sidebar - Storybook Meta - */ -export default { - title: 'Atoms/Layout', - component: SidebarComponent, - argTypes: { - 'aria-label': { - control: { - type: 'text', - }, - description: 'An accessible name for the sidebar.', - table: { - category: 'Accessibility', - }, - type: { - name: 'string', - required: false, - }, - }, - children: { - control: { - type: 'text', - }, - description: 'The sidebar content.', - type: { - name: 'string', - required: true, - }, - }, - className: { - control: { - type: 'text', - }, - description: 'Set additional classnames to the aside element.', - table: { - category: 'Styles', - }, - type: { - name: 'string', - required: false, - }, - }, - }, -} as ComponentMeta<typeof SidebarComponent>; - -const Template: ComponentStory<typeof SidebarComponent> = (args) => ( - <SidebarComponent {...args} /> -); - -/** - * Layout Stories - Sidebar - */ -export const Sidebar = Template.bind({}); -Sidebar.args = { - children: 'Some widgets.', -}; diff --git a/src/components/atoms/visually-hidden/visually-hidden.stories.tsx b/src/components/atoms/visually-hidden/visually-hidden.stories.tsx index 24ac921..f2868fd 100644 --- a/src/components/atoms/visually-hidden/visually-hidden.stories.tsx +++ b/src/components/atoms/visually-hidden/visually-hidden.stories.tsx @@ -1,48 +1,30 @@ -import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { Link } from '../links'; +import type { Meta, StoryObj } from '@storybook/react'; import { VisuallyHidden } from './visually-hidden'; -/** - * Sidebar - Storybook Meta - */ -export default { - title: 'Atoms/VisuallyHidden', +const meta = { component: VisuallyHidden, - argTypes: { - children: { - control: { - type: 'text', - }, - description: 'The contents to visually hide.', - type: { - name: 'string', - required: true, - }, - }, - }, -} as ComponentMeta<typeof VisuallyHidden>; + title: 'Atoms/Visually Hidden', +} satisfies Meta<typeof VisuallyHidden>; + +export default meta; -const Template: ComponentStory<typeof VisuallyHidden> = (args) => ( - <VisuallyHidden {...args} /> -); +type Story = StoryObj<typeof meta>; -/** - * VisuallyHidden Stories - Not focusable - */ -export const NotFocusable = Template.bind({}); -NotFocusable.args = { - children: 'Esse quia deserunt animi id sit voluptatem aperiam.', +const VisuallyHiddenTemplate: Story = { + args: { + children: 'Some content not focusable.', + }, }; -/** - * VisuallyHidden Stories - Focusable - */ -export const Focusable = Template.bind({}); -Focusable.args = { - children: ( - <> - {'Esse quia deserunt animi id sit voluptatem aperiam. '} - <Link href="#">Any link.</Link> - </> - ), +export const NotFocusable: Story = { + args: { + ...VisuallyHiddenTemplate.args, + }, +}; + +export const Focusable: Story = { + args: { + ...VisuallyHiddenTemplate.args, + children: <a href="#anchor">A skip to anchor link</a>, + }, }; |
