Skip to content

Commit 862e7ce

Browse files
refactor: update Storybook docs and usage
1 parent 1022068 commit 862e7ce

21 files changed

+164
-174
lines changed

docs/applying-storybook.md

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ 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 has version 7, which is currently still in beta. The following documentation outlines preferences in setup as it relates to this version. You can refer to the [7.0 beta docs](https://storybook.js.org/docs/7.0/react/) if you need any additional details
21+
> 🚨 NOTE: This project uses Storybook 7, using the Component Story Format v3 and the `satisfies` keyword to define the type of the meta object. See [Storybook 7 docs](https://storybook.js.org/docs/react/get-started/whats-a-story) for details.
22+
>
23+
> These docs are also still a work in progress as we create new stories inline with the new Design System. Check back here regularly for updates to the approach and structure as we keep inline with the latest Storybook versions and usage.
2224
2325
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.
2426

@@ -40,15 +42,13 @@ The initial structure of each story file will look something like this (in types
4042
```tsx
4143
import ComponentA from "."
4244

43-
type ComponentAType = typeof ComponentA
44-
45-
const meta: Meta<ComponentAType> {
45+
const meta {
4646
title: "ComponentA",
4747
component: ComponentA
48-
}
48+
} satisfies Meta<typeof ComponentA>
4949

5050
export default meta
51-
type Story = StoryObj<ComponentAType>;
51+
type Story = StoryObj<typeof meta>;
5252

5353
export const Basic: Story = {
5454
render: () => <ComponentA />
@@ -59,33 +59,31 @@ export const Basic: Story = {
5959

6060
We will maintain this structure for every story file, regardless of simplicity.
6161

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.
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. 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.
6363

6464
Let's say for a `Button` component with different style variants...
6565

6666
```tsx
6767
import Button from "."
6868

69-
type ButtonType = typeof Button
70-
71-
const meta: Meta<ButtonType> {
69+
const meta {
7270
title: "Button",
7371
component: Button
74-
}
72+
} satisfies Meta<typeof Button>
7573

7674
export default meta
77-
type Story = StoryObj<ButtonType>;
75+
type Story = StoryObj<typeof meta>;
7876

7977
export const Solid: Story = {
80-
render: (args) => <Button {...args}>A Button</Button>,
8178
args: {
8279
variant: 'solid',
80+
children: 'A Button'
8381
}
8482
}
8583
export const Outline: Story = {
86-
render: (args) => <Button {...args}>A Button</Button>,
8784
args: {
8885
variant: 'outline',
86+
children: 'A Button'
8987
}
9088
}
9189

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

99101
// 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-
)
102+
export const Variants = {
103+
render: () => (
104+
<VStack>
105+
<Button>A Solid Button</Button>
106+
<Button variant="outline">An Outline Button</Button>
107+
<Button variant="unstyled">An Unstyled Button</Button>
108+
</VStack>
109+
)
110+
}
107111
```
108112

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.
113+
### Story file containing a single story
114+
115+
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.
116+
117+
```tsx
118+
import ButtonComponent from "."
119+
120+
const meta = {
121+
title: "Atoms / Form / Button",
122+
component: ButtonComponent,
123+
} satisfies Meta<typeof ButtonComponent>
124+
125+
export default meta
126+
127+
export const Button: StoryObj<typeof meta> = {
128+
render: () => <ButtonComponent />,
129+
}
130+
```
110131

111132
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.
112133

113134
## Storybook Dashboard
114135

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

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

119142
| Sidebar above the preview | Dashboard 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 { Box, Flex, Text } from "@chakra-ui/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
@@ -3,16 +3,14 @@ import { Meta, StoryObj } from "@storybook/react"
33
import { VStack, AvatarGroup, HStack } from "@chakra-ui/react"
44
import Avatar from "."
55

6-
type AvatarType = typeof Avatar
7-
8-
const meta: Meta<AvatarType> = {
6+
const meta = {
97
title: "Atoms / Media & Icons / Avatars",
108
component: Avatar,
11-
}
9+
} satisfies Meta<typeof Avatar>
1210

1311
export default meta
1412

15-
type Story = StoryObj<AvatarType>
13+
type Story = StoryObj<typeof meta>
1614

1715
export const Single: Story = {
1816
args: {
Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
11
import React from "react"
22
import { Text } from "@chakra-ui/react"
3-
import { Meta, StoryFn } from "@storybook/react"
3+
import { Meta, StoryObj } from "@storybook/react"
44
import { useTranslation } from "react-i18next"
55
import BannerNotification from "."
66

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

12+
export default meta
13+
1514
/**
1615
* Story taken from PostMergeBanner component
1716
* and content from `../../content/developers/tutorials/hello-world-smart-contract-fullstack/index.md`
1817
*/
19-
export const PostMergeBanner: StoryFn<typeof BannerNotification> = (args) => {
20-
const { t } = useTranslation()
2118

22-
return (
23-
<BannerNotification {...args}>
24-
<Text>{t("page-upgrades-post-merge-banner-tutorial-ood")}</Text>
25-
</BannerNotification>
26-
)
19+
export const PostMergeBanner: StoryObj<typeof meta> = {
20+
args: {
21+
shouldShow: true,
22+
},
23+
render: (args) => {
24+
const { t } = useTranslation()
25+
26+
return (
27+
<BannerNotification {...args}>
28+
<Text>{t("page-upgrades-post-merge-banner-tutorial-ood")}</Text>
29+
</BannerNotification>
30+
)
31+
},
2732
}
Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,25 @@
11
import { Meta, StoryObj } from "@storybook/react"
22
import React from "react"
3-
import DismissableBanner from "../Banners/DismissableBanner"
3+
import DismissableBannerComponent from "../Banners/DismissableBanner"
44

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

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

15-
export const DismissableBannerStory: StoryObj<typeof DismissableBanner> = {
17+
export const DismissableBanner: StoryObj<typeof meta> = {
18+
args: {
19+
children: <div>{bannerText}</div>,
20+
storageKey: dismissableBannerStoryPageKey,
21+
},
1622
play: () => {
1723
localStorage.setItem(dismissableBannerStoryPageKey, "false")
1824
},
19-
render: () => {
20-
const children = <div>{bannerText}</div>
21-
return (
22-
<DismissableBanner
23-
children={children}
24-
storageKey={dismissableBannerStoryPageKey}
25-
/>
26-
)
27-
},
2825
}

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
Checkbox as CheckboxComponent,
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
@@ -10,8 +10,6 @@ import {
1010
import { Meta, StoryObj } from "@storybook/react"
1111
import Translation from "../Translation"
1212

13-
type HeadingType = typeof HeadingComponent
14-
1513
const meta = {
1614
title: "Atoms / Typography / Heading",
1715
component: HeadingComponent,
@@ -25,7 +23,7 @@ const meta = {
2523
</Flex>
2624
),
2725
],
28-
} satisfies Meta<HeadingType>
26+
} satisfies Meta<typeof HeadingComponent>
2927

3028
export default meta
3129

src/components/BaseStories/Link.stories.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import { Center, ListItem, Stack, Text, UnorderedList } from "@chakra-ui/react"
33
import { Meta, StoryObj } from "@storybook/react"
44
import Link from "../Link"
55

6-
type LinkType = typeof Link
7-
86
const meta = {
97
title: "Molecules / Navigation / Links",
108
component: Link,
@@ -15,7 +13,7 @@ const meta = {
1513
</Center>
1614
),
1715
],
18-
} satisfies Meta<LinkType>
16+
} satisfies Meta<typeof Link>
1917

2018
export default meta
2119

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

47-
export const LinkList: Story = {
45+
export const LinkList = {
4846
render: () => (
4947
<Stack spacing="6">
5048
<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 { RadioGroup, Radio as RadioComponent, Flex } 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)