Skip to content

chore: implement storybook#932

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

chore: implement storybook#932
jakehwll wants to merge 87 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 added 5 commits May 6, 2026 04:16
pnpm workspace:* protocol and package.json exports fields handle
@repo/* resolution natively — the hand-rolled getWorkspaceAliases
function was redundant.
- Add react, @tanstack/react-query, and @storybook/react to
  storybook-utils package.json so it declares its own contracts.
- Rename setState param from T to state in preview.ts mock.
- Fix import ordering across story and test files (lint autofix).
- Add tsconfig.json for @repo/mocks and @repo/storybook-utils so
  eslint's project service can find them.
- Fix import ordering in mocks/tasks.ts and inbox.test.ts.
- Extract QueryClientDecorator component to satisfy rules-of-hooks.
- Sort devDependencies in tasks/package.json.
@jakehwll
Copy link
Copy Markdown
Author

jakehwll commented May 6, 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.

All 23 DEREM findings are now resolved (21 fixed, 1 accepted with documentation, 1 contested then fixed after panel decision). The author addressed every item, including the contested DEREM-14 which was fixed in ee1d2a6 after the panel's 5/5 rejection of the original defense.

The PR has been substantially refactored based on @EhabY's architectural feedback (new @repo/storybook-utils package, restructured imports, per-package CSS decorators, removed getDefaultFontStack). Those changes are under active human review.

CI is still failing on Lint. Please ensure pnpm lint passes before merging.

No new findings from this round.

🤖 This review was automatically generated with Coder Agents.

jakehwll added 7 commits May 6, 2026 05:18
These blocks were accidentally added to package.json but belong
exclusively in pnpm-workspace.yaml. The duplicate workspaces field
used an object format that eslint-plugin-package-json rejected as
invalid (expects an array per npm spec).
Reverts e346f15. The --vscode-font-family CSS variable is only
referenced in global.css, not defined by the theme data. Without the
inline font stack the Storybook preview renders with browser defaults.
CollapsibleToggle and TaskSelection play functions relied on web
component attribute reflection and IPC side-effects that don't work
reliably in Chromatic's headless environment. The stories remain as
visual-only variants covering collapsed and expanded states.
@EhabY
Copy link
Copy Markdown
Collaborator

EhabY commented May 6, 2026

Now that we have storybooks, there seems to be some inconsistencies:

tasks-actionmenu--opened, the loading item is not aligned with the others:

image

tasks-errorbanner--default, should we align the view logs to the right?

image

tasks-statepanel--error, the retry here is not a button while it is a button in the error state. Was this intentional or a storybook styling issue 🤔?

image

The status indicators are not applying the right styles it seems, like this is just a pure square:

image

tasks-tasklist--default could mix and match other states and descriptions IMO for better coverage

image

This is the "Task Selection" test but I do not see it selecting a task (or inside a selected task):

image

Comment thread package.json Outdated
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.

I meant to say that we can trigger this script and it would pull a new SHA (most recent) and add that comment in the header so we know what upstream SHA we are currently pinned against

Comment thread packages/tasks/src/utils/storybook.ts Outdated
Comment thread .storybook/tsconfig.json
Comment thread .storybook/preview.ts Outdated
Comment thread package.json Outdated
Comment thread packages/tasks/src/components/TasksPanel.stories.tsx
Comment thread packages/tasks/src/components/AgentChatHistory.stories.tsx
Comment thread packages/tasks/src/components/ActionMenu.stories.tsx
Comment thread packages/tasks/src/components/NotSupportedState.stories.tsx
@jakehwll jakehwll force-pushed the jakehwll/implement-storybook branch from b650dcc to b0ec3f2 Compare May 8, 2026 02:13
jakehwll added 3 commits May 8, 2026 02:17
… loading

Move per-package CSS injection from a runtime decorator inside src/ to
a storybook.preview.ts entry point at the package root. Stories no
longer need to import or apply the decorator manually.
…orybook

# Conflicts:
#	pnpm-lock.yaml
#	pnpm-workspace.yaml
@jakehwll
Copy link
Copy Markdown
Author

jakehwll commented May 8, 2026

tasks-actionmenu--opened, the loading item is not aligned with the others:

Not going to fix just yet, will wait for this branch to merge to tightly scope and follow up 🙂

tasks-errorbanner--default, should we align the view logs to the right?

Not going to fix just yet, will wait for this branch to merge to tightly scope and follow up 🙂

tasks-statepanel--error, the retry here is not a button while it is a button in the error state. Was this intentional or a storybook styling issue 🤔?

Hmm, fair enough. I've imported both those components to the story 🙂

The status indicators are not applying the right styles it seems, like this is just a pure square:

Looks like the display: inline was zorping these. I've added a wrapper decorator for it now!

tasks-tasklist--default could mix and match other states and descriptions IMO for better coverage

Good idea!

This is the "Task Selection" test but I do not see it selecting a task (or inside a selected task):

Oops, I think I nuked this by accident.

@jakehwll jakehwll requested a review from EhabY May 8, 2026 03:58
Copy link
Copy Markdown
Collaborator

@EhabY EhabY left a comment

Choose a reason for hiding this comment

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

There are a few follow ups in the chromatic one but this one is good!

@@ -0,0 +1,90 @@
#!/usr/bin/env node
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.

This could be simplified and parallized slightly:

#!/usr/bin/env node

// Fetches dark-v2 and light-v2 theme files from vscode-elements/webview-playground
// and rewrites .storybook/themes/{dark,light}-v2.ts in place.
//
// Usage:
//   node scripts/sync-vscode-themes.mjs          # fetch latest main
//   node scripts/sync-vscode-themes.mjs <sha>    # fetch a specific commit

import { writeFileSync } from "node:fs";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";

const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
const REPO = "vscode-elements/webview-playground";

const themes = [
	{
		remotePath: "dist/themes/dark-v2.js",
		localPath: ".storybook/themes/dark-v2.ts",
		exportName: "darkTheme",
	},
	{
		remotePath: "dist/themes/light-v2.js",
		localPath: ".storybook/themes/light-v2.ts",
		exportName: "lightTheme",
	},
];

async function fetchText(url, headers) {
	const res = await fetch(url, { headers });
	if (!res.ok) {
		throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
	}
	return res.text();
}

const sha =
	process.argv[2] ??
	(
		await fetchText(`https://api.github.com/repos/${REPO}/commits/main`, {
			Accept: "application/vnd.github.sha",
		})
	).trim();

console.log(`Syncing themes from ${REPO}@${sha}`);

await Promise.all(
	themes.map(async ({ remotePath, localPath, exportName }) => {
		const js = await fetchText(
			`https://raw.githubusercontent.com/${REPO}/${sha}/${remotePath}`,
		);
		const match = js.match(/export\s+const\s+theme\s*=\s*(\[[\s\S]*\])/);
		if (!match) {
			throw new Error(`Could not find theme array in ${remotePath}`);
		}
		// Upstream escapes dots in CSS property names (e.g. `disabled\.background`).
		// These are unnecessary in JS strings and break setProperty lookups.
		const arrayLiteral = match[1].replaceAll("\\.", ".");

		const ts = `// Sourced from \`vscode-elements/webview-playground\`.
// https://github.com/${REPO}/blob/${sha}/${remotePath}

export const ${exportName}: Array<[string, string]> = ${arrayLiteral};
`;
		writeFileSync(resolve(ROOT, localPath), ts);
		console.log(`  ${localPath}`);
	}),
);

console.log("Done. Run `pnpm format` to normalize the output.");

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