Skip to content

Commit c62650d

Browse files
authored
Merge pull request #11324 from TylerAPfledderer/refactor/storybook-proj-docs-and-unification
refactor: update Storybook docs and usage
2 parents bf8a793 + f74fbbf commit c62650d

20 files changed

+170
-149
lines changed

docs/applying-storybook.md

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ It's as easy as running `yarn storybook` to boot up a dedicated localhost to see
1818

1919
## Setting up a component's stories
2020

21-
> 🚨 NOTE: This project uses Storybook v7. The following documentation outlines preferences in setup as it relates to this version. You can refer to the [main docs](https://storybook.js.org/docs/get-started/install) if you need any additional details
21+
> 🚨 NOTE: This project uses Storybook v7, using the Component Story Format v3 and the `satisfies` keyword to define the type of the meta object. The following documentation outlines preferences in setup as it relates to this version. You can refer to the [main docs](https://storybook.js.org/docs/get-started) if you need any additional details
2222
2323
A Storybook "story" is an instance of a component in a certain state or with certain parameters applied to show an alternative version of the component.
2424

@@ -57,9 +57,11 @@ export const Basic: Story = {
5757

5858
**Note**: with the `title` option, we write this based on the groupings set by the Design System. Groupings are declared with forward slashes. (i.e. `Atoms / Form / Input`). See the Storybook docs for details on [Naming conventions](https://storybook.js.org/docs/7.0/react/writing-stories/naming-components-and-hierarchy)
5959

60+
Also, please view the Figma file for the [proposed structure for the Design System](https://www.figma.com/file/Ne3iAassyfAcJ0AlgqioAP/DS-to-storybook-structure?type=design&node-id=42%3A50&mode=design&t=RGkyouvTilzF42y0-1) to provide the correct groupings.
61+
6062
We will maintain this structure for every story file, regardless of simplicity.
6163

62-
Should the component accept props on all or some renders, you can provide an `args` prop for each story and supply the necessary data. And if there is children, use the `render` prop to pass the args and supply children elements.
64+
Should the component accept props on all or some renders, you can provide an `args` prop for each story and supply the necessary data. This can be done in place of the render if only a single instance of the given component is needed with no other components. If the `children` prop is used, it can still be used in the `args` prop.
6365

6466
Let's say for a `Button` component with different style variants...
6567

@@ -77,15 +79,15 @@ export default meta
7779
type Story = StoryObj<typeof meta>;
7880

7981
export const Solid: Story = {
80-
render: (args) => <Button {...args}>A Button</Button>,
8182
args: {
8283
variant: 'solid',
84+
children: 'A Button'
8385
}
8486
}
8587
export const Outline: Story = {
86-
render: (args) => <Button {...args}>A Button</Button>,
8788
args: {
8889
variant: 'outline',
90+
children: 'A Button'
8991
}
9092
}
9193

@@ -94,26 +96,51 @@ export const Outline: Story = {
9496
* they should be shown under one story, so they can be seen side-by-side in the GUI
9597
* for reviewers to easily compare.
9698
* This can also be done for various sizes or other like alterations
99+
*
100+
* 🚨 If prop content is supplied directly to the component and the `args` prop is not used,
101+
* do not use the `StoryObj` type. This is especially important when a story rendering multiple versions
102+
* of the component.
97103
*/
98104

99105
// Assuming `solid` is the default variant in the Chakra theme config
100-
export const Variants = () => (
101-
<VStack>
102-
<Button>A Solid Button</Button>
103-
<Button variant="outline">An Outline Button</Button>
104-
<Button variant="unstyled">An Unstyled Button</Button>
105-
</VStack>
106-
)
106+
export const Variants = {
107+
render: () => (
108+
<VStack>
109+
<Button>A Solid Button</Button>
110+
<Button variant="outline">An Outline Button</Button>
111+
<Button variant="unstyled">An Unstyled Button</Button>
112+
</VStack>
113+
)
114+
}
107115
```
108116

109-
If only one story is provided for a component, the name of the exported object should match the name in the `title` meta option. (If the title is `Atoms / Form / Button` then the object should be named `Button`) This will hoist the display name up to the parent level in the Storybook dashboard's sidebar.
117+
### Story file containing a single story
118+
119+
If only one story is provided for a component, the name of the exported object should match the name in the `title` meta option. (If the title is `Atoms / Form / Button` then the object should be named `Button`) This will hoist the display name up to the parent level in the Storybook dashboard's sidebar. This will also mean you have to rename the import of the component. Call it `ButtonComponent`, say.
120+
121+
```tsx
122+
import ButtonComponent from "."
123+
124+
const meta = {
125+
title: "Atoms / Form / Button",
126+
component: ButtonComponent,
127+
} satisfies Meta<typeof ButtonComponent>
128+
129+
export default meta
130+
131+
export const Button: StoryObj<typeof meta> = {
132+
render: () => <ButtonComponent />,
133+
}
134+
```
110135

111136
As you go and make adjustments to the component itself or it's variant styles, Storybook will hot reload and those changes will appear in the stories that emphasize them.
112137

113138
## Storybook Dashboard
114139

115140
The dashboard where you view each story has a number of different addons available to check the story thoroughly.
116141

142+
![Screenshot of Storybook Dashboard for Ethereum.org](https://github.com/ethereum/ethereum-org-website/assets/65234762/7dea7692-6a6d-4f1c-b7cb-db177bcab44d)
143+
117144
Outlined below are each area going from left to right in the selections.
118145

119146
| Toolbar above the preview | Panel below the preview |

src/components/Alert/Alert.stories.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import { Meta, StoryObj } from "@storybook/react"
44

55
import Alert from "."
66

7-
type AlertType = typeof Alert
8-
9-
const meta: Meta<AlertType> = {
7+
const meta = {
108
title: "Molecules / Action Feedback / Alerts",
119
component: Alert,
1210
decorators: [
@@ -16,11 +14,11 @@ const meta: Meta<AlertType> = {
1614
</Flex>
1715
),
1816
],
19-
}
17+
} satisfies Meta<typeof Alert>
2018

2119
export default meta
2220

23-
type Story = StoryObj<AlertType>
21+
type Story = StoryObj<typeof meta>
2422

2523
const DEMO_DESC = "This is an alert to be used in the top of the content"
2624

src/components/Avatar/Avatar.stories.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@ import { Meta, StoryObj } from "@storybook/react"
44

55
import Avatar from "."
66

7-
type AvatarType = typeof Avatar
8-
9-
const meta: Meta<AvatarType> = {
7+
const meta = {
108
title: "Atoms / Media & Icons / Avatars",
119
component: Avatar,
12-
}
10+
} satisfies Meta<typeof Avatar>
1311

1412
export default meta
1513

16-
type Story = StoryObj<AvatarType>
14+
type Story = StoryObj<typeof meta>
1715

1816
export const Single: Story = {
1917
args: {
Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
11
import React from "react"
22
import { useTranslation } from "next-i18next"
33
import { Text } from "@chakra-ui/react"
4-
import { Meta, StoryFn } from "@storybook/react"
4+
import { Meta, StoryObj } from "@storybook/react"
55

66
import BannerNotification from "."
77

8-
export default {
8+
const meta = {
9+
title: "PostMergeBanner",
910
component: BannerNotification,
10-
args: {
11-
shouldShow: true,
12-
},
13-
decorators: [(Story) => <Story />],
14-
} as Meta<typeof BannerNotification>
11+
} satisfies Meta<typeof BannerNotification>
12+
13+
export default meta
1514

1615
/**
1716
* Story taken from PostMergeBanner component
1817
* and content from `../../content/developers/tutorials/hello-world-smart-contract-fullstack/index.md`
1918
*/
20-
export const PostMergeBanner: StoryFn<typeof BannerNotification> = (args) => {
21-
const { t } = useTranslation("page-upgrades")
2219

23-
return (
24-
<BannerNotification {...args}>
25-
<Text>{t("page-upgrades-post-merge-banner-tutorial-ood")}</Text>
26-
</BannerNotification>
27-
)
20+
export const PostMergeBanner: StoryObj<typeof meta> = {
21+
args: {
22+
shouldShow: true,
23+
},
24+
render: (args) => {
25+
// eslint-disable-next-line react-hooks/rules-of-hooks
26+
const { t } = useTranslation("page-upgrades")
27+
28+
return (
29+
<BannerNotification {...args}>
30+
<Text>{t("page-upgrades-post-merge-banner-tutorial-ood")}</Text>
31+
</BannerNotification>
32+
)
33+
},
2834
}
Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
11
import React from "react"
22
import { Meta, StoryObj } from "@storybook/react"
33

4-
import DismissableBanner from "../Banners/DismissableBanner"
4+
import DismissableBannerComponent from "../Banners/DismissableBanner"
55

6-
export default {
7-
component: DismissableBanner,
8-
} as Meta<typeof DismissableBanner>
6+
const meta = {
7+
component: DismissableBannerComponent,
8+
title: "DismissableBanner",
9+
} satisfies Meta<typeof DismissableBannerComponent>
910

11+
export default meta
1012
/**
1113
* Story taken from DismissableBanner component
1214
*/
1315
const dismissableBannerStoryPageKey = "dismissableBannerStoryPageKey"
1416
const bannerText = "This is a dismissable banner"
1517

16-
export const DismissableBannerStory: StoryObj<typeof DismissableBanner> = {
18+
export const DismissableBanner: StoryObj<typeof meta> = {
19+
args: {
20+
children: <div>{bannerText}</div>,
21+
storageKey: dismissableBannerStoryPageKey,
22+
},
1723
play: () => {
1824
localStorage.setItem(dismissableBannerStoryPageKey, "false")
1925
},
2026
render: () => {
2127
const children = <div>{bannerText}</div>
2228
return (
23-
<DismissableBanner storageKey={dismissableBannerStoryPageKey}>
29+
<DismissableBannerComponent storageKey={dismissableBannerStoryPageKey}>
2430
{children}
25-
</DismissableBanner>
31+
</DismissableBannerComponent>
2632
)
2733
},
2834
}

src/components/BaseStories/Checkbox.stories.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ import {
44
CheckboxGroup,
55
VStack,
66
} from "@chakra-ui/react"
7-
import { Meta, StoryObj } from "@storybook/react"
7+
import { Meta } from "@storybook/react"
88

9-
type CheckboxType = typeof CheckboxComponent
10-
11-
const meta: Meta<CheckboxType> = {
9+
const meta = {
1210
title: "Atoms / Form / Checkbox",
1311
component: CheckboxComponent,
1412
parameters: {
@@ -17,15 +15,13 @@ const meta: Meta<CheckboxType> = {
1715
expanded: false,
1816
},
1917
},
20-
}
18+
} satisfies Meta<typeof CheckboxComponent>
2119

2220
export default meta
2321

24-
type Story = StoryObj<CheckboxType>
25-
2622
const DEFAULT_VAL = "checked"
2723

28-
export const Checkbox: Story = {
24+
export const Checkbox = {
2925
render: () => (
3026
<CheckboxGroup defaultValue={[DEFAULT_VAL]}>
3127
<VStack spacing={4} align="flex-start">

src/components/BaseStories/Heading.stories.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import { Meta, StoryObj } from "@storybook/react"
1111

1212
import Translation from "../Translation"
1313

14-
type HeadingType = typeof HeadingComponent
15-
1614
const meta = {
1715
title: "Atoms / Typography / Heading",
1816
component: HeadingComponent,
@@ -26,7 +24,7 @@ const meta = {
2624
</Flex>
2725
),
2826
],
29-
} satisfies Meta<HeadingType>
27+
} satisfies Meta<typeof HeadingComponent>
3028

3129
export default meta
3230

src/components/BaseStories/Link.stories.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import { Meta, StoryObj } from "@storybook/react"
44

55
import Link from "../Link"
66

7-
type LinkType = typeof Link
8-
97
const meta = {
108
title: "Molecules / Navigation / Links",
119
component: Link,
@@ -16,7 +14,7 @@ const meta = {
1614
</Center>
1715
),
1816
],
19-
} satisfies Meta<LinkType>
17+
} satisfies Meta<typeof Link>
2018

2119
export default meta
2220

@@ -45,7 +43,7 @@ export const ExternalLink: Story = {
4543
render: (args) => <MockParagraph {...args} />,
4644
}
4745

48-
export const LinkList: Story = {
46+
export const LinkList = {
4947
render: () => (
5048
<Stack spacing="6">
5149
<Text>

src/components/BaseStories/Radio.stories.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ import * as React from "react"
22
import { Flex, Radio as RadioComponent, RadioGroup } from "@chakra-ui/react"
33
import { Meta, StoryObj } from "@storybook/react"
44

5-
type RadioType = typeof RadioComponent
6-
7-
const meta: Meta<RadioType> = {
5+
const meta = {
86
title: "Atoms / Form / Radio",
97
component: RadioComponent,
108
argTypes: {
@@ -19,11 +17,11 @@ const meta: Meta<RadioType> = {
1917
expanded: false,
2018
},
2119
},
22-
}
20+
} satisfies Meta<typeof RadioComponent>
2321

2422
export default meta
2523

26-
type Story = StoryObj<typeof RadioGroup>
24+
type Story = StoryObj<typeof meta>
2725

2826
export const Radio: Story = {
2927
args: {

src/components/BaseStories/Switch.stories.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import * as React from "react"
22
import { SimpleGrid, Switch as SwitchComponent } from "@chakra-ui/react"
3-
import { Meta, StoryObj } from "@storybook/react"
3+
import { Meta } from "@storybook/react"
44

5-
type SwitchType = typeof SwitchComponent
6-
7-
const meta: Meta<SwitchType> = {
5+
const meta = {
86
title: "Atoms / Form / Switch",
97
component: SwitchComponent,
108
parameters: {
@@ -13,13 +11,11 @@ const meta: Meta<SwitchType> = {
1311
expanded: false,
1412
},
1513
},
16-
}
14+
} satisfies Meta<typeof SwitchComponent>
1715

1816
export default meta
1917

20-
type Story = StoryObj<SwitchType>
21-
22-
export const Switch: Story = {
18+
export const Switch = {
2319
render: () => (
2420
<SimpleGrid columns={{ base: 2, lg: 4 }} columnGap={1} alignItems="center">
2521
<span>isChecked:</span>

0 commit comments

Comments
 (0)