Skip to content

chore: implement storybook#932

Open
jakehwll wants to merge 54 commits intomainfrom
jakehwll/implement-storybook
Open

chore: implement storybook#932
jakehwll wants to merge 54 commits intomainfrom
jakehwll/implement-storybook

Conversation

@jakehwll
Copy link
Copy Markdown

@jakehwll jakehwll commented May 4, 2026

This PR was modified by Coder Agents on behalf of Jake Howell.

Adds Storybook support for developing and previewing webview components in isolation outside of VS Code. Includes stories for all tasks package components with a dark/light theme switcher that mirrors VS Code CSS custom properties.

  • Add .storybook/ config with Vite integration, workspace alias resolution, codicon injection, and acquireVsCodeApi mock
  • Add dark-v2 and light-v2 themes (sourced from vscode-elements/webview-playground) with a toolbar switcher in globalTypes
  • Add 17 component stories under packages/tasks/src/components/ covering all major UI states
  • Add test/webview/decorators.tsx with a shared withQueryClient decorator for stories using React Query
  • Add storybook and build-storybook scripts to root package.json
  • Add Storybook dependencies to workspace catalog

@jakehwll
Copy link
Copy Markdown
Author

jakehwll commented May 5, 2026

/coder-agents-review

coder-agents-review[bot]

This comment was marked as outdated.

@jakehwll
Copy link
Copy Markdown
Author

jakehwll commented May 5, 2026

/coder-agents-review

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Full panel review (14 reviewers). The Storybook infrastructure is well-structured: proper theme attribution, clean workspace alias resolution, and good component coverage breadth. The DEREM-9 fix introduced CI-blocking lint errors and several play functions need attention.

1 P1, 1 P2, 6 P3, 3 Nit. All R1 findings verified fixed.

The panel found coverage gaps worth noting but not blocking: no WithPresets story for CreateTaskSection, no paused-task story for TaskDetailView, and WorkspaceLogs has no play function (static display component). These can be addressed incrementally.

Pariston on the TaskSelection assertion: "It's asserting the symptom of failure as the definition of success. The loading container appears because IPC never responds, not because the task was selected."

🤖 This review was automatically generated with Coder Agents.

Comment thread packages/tasks/src/components/ActionMenu.stories.tsx Outdated
Comment thread packages/tasks/src/components/ActionMenu.stories.tsx Outdated
Comment thread packages/tasks/src/components/TasksPanel.stories.tsx Outdated
Comment thread packages/tasks/src/components/TasksPanel.stories.tsx
Comment thread packages/tasks/src/components/TasksPanel.stories.tsx
Comment thread .storybook/preview.ts Outdated
Comment thread .storybook/preview.ts Outdated
Comment thread .storybook/global.css Outdated
Comment thread .storybook/global.css
Comment thread packages/tasks/src/components/TaskDetailView.stories.tsx Outdated
@jakehwll
Copy link
Copy Markdown
Author

jakehwll commented May 5, 2026

/coder-agents-review

@jakehwll jakehwll requested a review from EhabY May 5, 2026 05:32
@jakehwll jakehwll marked this pull request as ready for review May 5, 2026 05:32
coder-agents-review[bot]

This comment was marked as outdated.

@jakehwll jakehwll changed the title feat: implement storybook chore: implement storybook May 5, 2026
…TasksPanel

DEREM-11: TaskList.stories.tsx now passes unique IDs to task() to avoid
duplicate React keys.

DEREM-17: Replaced the comment on the TaskSelection play function to
explicitly document that the loading spinner is the expected terminal
state in Storybook (the IPC layer is mocked, so the detail fetch never
resolves).
@jakehwll
Copy link
Copy Markdown
Author

jakehwll commented May 5, 2026

/coder-agents-review

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review round (5 reviewers). All R3 findings are resolved except DEREM-14, which was contested by the author and evaluated by the panel.

The panel unanimously (5/5) rejected the defense on DEREM-14. Both premises of the author's argument are factually incorrect: (1) ActionMenu makes no API calls; isOpen is pure useState, no mock needed. (2) The play function contains no loader assertion, contradicting the claim of "checking for the loader." The story is named Opened but never verifies the open state. The fix is one line.

1 P3 re-raised (DEREM-14, panel decision), 1 P3 new (DEREM-23).

Mafuuu: "Both premises of the defense are verifiably false against the current code. The finding remains open."

🤖 This review was automatically generated with Coder Agents.

Comment thread packages/tasks/src/components/PromptInput.stories.tsx
DEREM-14: Assert .action-menu-dropdown is present after clicking the
icon in the Opened story. Without this, removing setIsOpen from
onClick would not fail the story.

DEREM-23: Add play functions to PromptInput Default and Disabled
stories that exercise the Ctrl+Enter keyboard submit path. Default
asserts onSubmit is called once; Disabled asserts it is never called.
Comment thread package.json
"build": "concurrently -g -n webviews,extension,compile-tests:integration \"pnpm build:webviews\" \"node esbuild.mjs\" \"pnpm compile-tests:integration\"",
"build:production": "cross-env NODE_ENV=production pnpm build",
"build:webviews": "pnpm -r --filter \"./packages/*\" --parallel build",
"build-storybook": "storybook build --config-dir .storybook",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not build:storybook for consistency?

Comment thread package.json
Comment on lines +620 to +624
"@storybook/addon-a11y": "catalog:",
"@storybook/addon-essentials": "catalog:",
"@storybook/react": "catalog:",
"@storybook/react-vite": "catalog:",
"@storybook/test": "catalog:",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these and storybook deps are not used anywhere then I would rather inline this. I'd keep the catalog for unifying versions between packages

Comment thread .storybook/tsconfig.json
@@ -0,0 +1,16 @@
{
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .storybook directory should be added to .vscodeignore, otherwise we'd package it

# Storybook
.storybook/**
storybook-static/**
**/*.stories.*

Also we seem to be missing the the .gitignore for the build artifacts

Comment thread .storybook/tsconfig.json
@@ -0,0 +1,16 @@
{
"extends": "../tsconfig.json",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think tsconfig.packages.json is a better fit than the extension tsconfig, or just extend @tsconfig/node22/tsconfig.json and inline what we need

Comment thread .storybook/tsconfig.json
Comment on lines +12 to +13
"../test/webview/**/*",
"../test/mocks/**/*"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't those already checked by the test/tsconfig.ts? I'd rather keep this tsconfig to only the files here

Comment thread .storybook/preview.ts
Comment on lines +100 to +103
const hasTasks = useMemo(
() => context.tags.includes("tasks"),
[context.tags.join(",")],
);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly I'd just inline this without the memo, we should have the react compiler for the tasks package anyway

Comment thread .storybook/preview.ts
useEffect(() => {
if (hasTasks) {
// Dynamically import tasks CSS
void import("../packages/tasks/src/index.css");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loading tasks/src/index.css from a global preview decorator means every new package needs its CSS wired in here.

Better to ship a per-package decorator (like withTasksStyles) from the same package as the components and have those stories opt in via decorators: [withTasksStyles]. Keeps preview.ts package-agnostic.

Comment on lines +1 to +2
// Sourced from `vscode-elements/webview-playground`.
// https://github.com/vscode-elements/webview-playground/blob/f9a6f90413d0cc535839fb92445b7a5eebc540d7/dist/themes/dark-v2.js
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid manual refreshes, add a scripts/sync-vscode-themes.mjs that fetches both files from the pinned upstream sha (already in the header comments) and rewrites them in place

I'm not sure if this would work but can we have the script filter vars referenced in our source plus those used by @vscode-elements/elements, which would cut these files by ~85% (though it's only a big change on this branch only)

* Use this for components that use React Query hooks (useQuery, useMutation, etc.)
*/
export const withQueryClient: Decorator = (Story) => {
const clientRef = useRef<QueryClient | null>(null);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about const [client] = useState(() => new QueryClient(...)) since that is the convention for lazily initializing

Comment thread .storybook/preview.ts
// that rely on it can function without errors.
if (
typeof window !== "undefined" &&
!(window as { acquireVsCodeApi?: () => VsCodeApi }).acquireVsCodeApi
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local VsCodeApi duplicates WebviewApi from @types/vscode-webview, we can put it in the same @repo/storybook-utils dev-only package proposed above, which has @types/vscode-webview as a dev dep. preview.ts then becomes import { installMockVsCodeApi } from "@repo/storybook-utils".

@EhabY
Copy link
Copy Markdown
Collaborator

EhabY commented May 5, 2026

Love the change and the story books ❤️

Pls do run the linters and make sure the pipeline passes!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants