Skip to content

Commit e89da97

Browse files
committed
chore(storybook): refresh docs and interaction tests
1 parent 2af178b commit e89da97

20 files changed

Lines changed: 265 additions & 119 deletions

File tree

.agents/skills/storybook/SKILL.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ If the user asks to “review the component library in terms of Storybook best p
3939
- Use `argTypes` for clear control labels and documentation.
4040
- Avoid coupling stories to app-specific context unless the component requires it.
4141
- Prefer minimal decorators; if needed, document why they exist.
42+
- Interaction tests should include at least one assertion so failures are meaningful; use them for behaviors, not purely visual states.
43+
- Add play functions when user interactions change the UI, trigger callbacks, or guard accessibility flows; skip for static-only components.
4244

4345
## Repo-specific conventions
4446

@@ -51,6 +53,7 @@ If the user asks to “review the component library in terms of Storybook best p
5153
rather than deep relative paths.
5254
- Use the `@/` alias for any imports within `src/`.
5355
- Do not import from `src/pages` or `src/layouts` in stories.
56+
- Always set `parameters.docs.description.component` with a concise usage note for every component story.
5457

5558
## Standard workflow
5659

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,8 @@ jobs:
2929
- name: Typecheck
3030
run: bun run typecheck
3131

32+
- name: Storybook tests
33+
run: bun run storybook:test
34+
3235
- name: Build
3336
run: bun run build

.storybook/main.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import type { StorybookConfig } from "@storybook/react-vite";
33
const config: StorybookConfig = {
44
framework: "@storybook/react-vite",
55
stories: ["../src/components/**/*.stories.@(ts|tsx|mdx)"],
6-
addons: ["@storybook/addon-a11y"],
6+
addons: [
7+
"@storybook/addon-a11y",
8+
"@storybook/addon-docs",
9+
"@storybook/addon-vitest",
10+
],
711
viteFinal: async (config) => {
812
config.resolve = config.resolve ?? {};
913
config.resolve.alias = {

bun.lock

Lines changed: 50 additions & 115 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"typecheck": "astro check",
1414
"format": "prettier --write \"src/**/*.{ts,tsx,astro,css,md,mdx}\"",
1515
"storybook": "storybook dev -p 6006",
16+
"storybook:test": "bun x @storybook/cli@10.2.15 test",
1617
"storybook:build": "storybook build"
1718
},
1819
"dependencies": {
@@ -29,6 +30,8 @@
2930
"devDependencies": {
3031
"@astrojs/check": "^0.9.6",
3132
"@storybook/addon-a11y": "^10.2.15",
33+
"@storybook/addon-docs": "^10.2.15",
34+
"@storybook/addon-vitest": "^10.2.15",
3235
"@storybook/react-vite": "10.2.15",
3336
"@tailwindcss/typography": "^0.5.15",
3437
"@types/node": "^22.10.5",
@@ -43,6 +46,7 @@
4346
"prettier-plugin-astro": "^0.14.1",
4447
"prettier-plugin-tailwindcss": "^0.6.9",
4548
"storybook": "10.2.15",
46-
"typescript": "^5.7.2"
49+
"typescript": "^5.7.2",
50+
"vitest": "^4.0.18"
4751
}
4852
}

src/components/atoms/Button/Button.stories.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Meta, StoryObj } from "@storybook/react";
2+
import { expect, fn, userEvent, within } from "storybook/test";
23

34
import { Button } from "@/components/atoms/Button";
45

@@ -10,6 +11,15 @@ const meta = {
1011
children: "Get started",
1112
variant: "primary",
1213
size: "md",
14+
onClick: fn(),
15+
},
16+
parameters: {
17+
docs: {
18+
description: {
19+
component:
20+
"Primary action button with size and variant styling. Use `href` to render as a link.",
21+
},
22+
},
1323
},
1424
} satisfies Meta<typeof Button>;
1525

@@ -19,6 +29,14 @@ type Story = StoryObj<typeof meta>;
1929

2030
export const Primary: Story = {};
2131

32+
export const Clicked: Story = {
33+
play: async ({ args, canvasElement }) => {
34+
const canvas = within(canvasElement);
35+
await userEvent.click(canvas.getByRole("button"));
36+
await expect(args.onClick).toHaveBeenCalled();
37+
},
38+
};
39+
2240
export const Secondary: Story = {
2341
args: {
2442
variant: "secondary",

src/components/atoms/HighlightedTitle/HighlightedTitle.stories.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ const meta = {
1010
title: "Understanding Your",
1111
highlight: "User Needs",
1212
},
13+
parameters: {
14+
docs: {
15+
description: {
16+
component:
17+
"Headline component that emphasizes a highlighted phrase for visual focus.",
18+
},
19+
},
20+
},
1321
} satisfies Meta<typeof HighlightedTitle>;
1422

1523
export default meta;

src/components/atoms/SectionDescription/SectionDescription.stories.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ const meta = {
1010
description:
1111
"Simple website software for research projects that want to understand their user needs.",
1212
},
13+
parameters: {
14+
docs: {
15+
description: {
16+
component:
17+
"Supporting text block for section intros and short explanatory copy.",
18+
},
19+
},
20+
},
1321
} satisfies Meta<typeof SectionDescription>;
1422

1523
export default meta;

src/components/atoms/SectionHeading/SectionHeading.stories.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ const meta = {
99
args: {
1010
title: "What We Offer",
1111
},
12+
parameters: {
13+
docs: {
14+
description: {
15+
component: "Section title with consistent spacing for page headings.",
16+
},
17+
},
18+
},
1219
} satisfies Meta<typeof SectionHeading>;
1320

1421
export default meta;

src/components/molecules/Card/Card.stories.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Meta, StoryObj } from "@storybook/react";
2+
import { expect, within } from "storybook/test";
23

34
import { Card } from "@/components/molecules/Card";
45

@@ -10,6 +11,14 @@ const meta = {
1011
title: "Insight sprint",
1112
description: "Align on user research goals with a simple playbook.",
1213
},
14+
parameters: {
15+
docs: {
16+
description: {
17+
component:
18+
"Compact summary card for features or resources. Supports optional imagery.",
19+
},
20+
},
21+
},
1322
} satisfies Meta<typeof Card>;
1423

1524
export default meta;
@@ -24,3 +33,16 @@ export const WithImage: Story = {
2433
imageAlt: "Illustration for share cards",
2534
},
2635
};
36+
37+
export const LinkOverlay: Story = {
38+
args: {
39+
href: "/resources/insight-sprint",
40+
},
41+
play: async ({ canvasElement }) => {
42+
const canvas = within(canvasElement);
43+
await expect(canvas.getByRole("link")).toHaveAttribute(
44+
"href",
45+
"/resources/insight-sprint",
46+
);
47+
},
48+
};

0 commit comments

Comments
 (0)