Skip to content

feat(ui): scaffold packages/ui with theme foundations#1030

Open
EhabY wants to merge 3 commits into
mainfrom
feat/devex-624-ui-scaffold
Open

feat(ui): scaffold packages/ui with theme foundations#1030
EhabY wants to merge 3 commits into
mainfrom
feat/devex-624-ui-scaffold

Conversation

@EhabY

@EhabY EhabY commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

🤖 This PR was created by Coder Agents on behalf of @EhabY.

Closes DEVEX-624.

Scaffolds the shared component library for the Workspaces webview work. Foundations only — no components yet (DEVEX-618/619/620 build on this).

  • packages/ui — React + TS package wired like existing packages (catalog deps, root Storybook/ESLint/typecheck globs pick it up automatically). Consumed as source like webview-shared, but shaped for a future standalone NPM split: proper exports map (., ./tokens.css, ./codicon.css), react as the only peer dependency, @vscode/codicons (asset-only) as the only runtime dependency, no workspace:* runtime deps. A short README documents the theming model and the rules that keep the package splittable.
  • tokens.css — semantic --ui-* tokens mapped to --vscode-* variables; the single place the library is theme-matched to VS Code. Same pattern as Microsoft's Webview UI Toolkit design-token layer, but pure CSS: components style against a small curated semantic set instead of scattering raw --vscode-* references (VS Code exposes 500+). High contrast needs no JS edge-case handling — --vscode-contrast* vars only exist in HC themes, so --ui-contrast-* tokens use transparent fallbacks and become no-ops elsewhere.
  • useVscodeTheme — the issue asked to move it from webview-shared, but no such hook existed anywhere in the repo, so it is implemented here instead: returns the active theme kind from the data-vscode-theme-kind body attribute VS Code maintains in webviews, synced via MutationObserver + useSyncExternalStore. No re-export from webview-shared since there are no consumers yet.
  • Storybook — trivial UI/Foundations story rendering the token swatches and current theme kind. The theme decorator now also mirrors data-vscode-theme-kind on the body so theme-aware hooks behave in Storybook as they do in real webviews.

Testing

  • test/webview/ui/useVscodeTheme.test.ts — theme-kind mapping, missing-attribute default, re-render on theme change.
  • pnpm typecheck, pnpm lint, pnpm format:check, pnpm test, pnpm build, pnpm storybook:ci all pass.
Implementation plan & decisions

Context

  • Monorepo already has packages/{shared,webview-shared,tasks,workspaces,netcheck,speedtest,mocks,storybook-utils} with pnpm catalog: deps (catalogMode: strict).
  • Root .storybook globs packages/*/src/**/*.stories.@(ts|tsx) — a packages/ui story is picked up with zero config.
  • Root typecheck:packages / build:webviews run pnpm -r --filter ./packages/* — packages without a build script are skipped (e.g. webview-shared, consumed as source via its exports map).

Finding: useVscodeTheme did not exist

The issue says "move useVscodeTheme from packages/webview-shared", but no such hook exists on main or any branch. Decision: implement it fresh in packages/ui (DOM data-vscode-theme-kind + MutationObserver via useSyncExternalStore).

Decisions

  1. useVscodeTheme: implement fresh (nothing to move).
  2. Build: source-consumed like webview-shared (no vite build), but kept easy to separate later — self-contained package, proper exports map, react peer dep, no workspace:* deps. A real build step only becomes necessary at the actual NPM split.
  3. Codicon export: added now (./codicon.css re-exporting @vscode/codicons) since follow-up issues will use it.
  4. webview-shared re-export: skipped — no consumers exist yet, and it would add a workspace dep.
  5. Semantic token layer (vs raw --vscode-* per component, as vscode-elements does): the deprecated @vscode/webview-ui-toolkit validated the token-layer pattern but implemented it with a JS design-token system; a pure-CSS layer gets the same single theming point without the machinery, and gives the future standalone package one place to define non-webview fallbacks.

Deliverables

  • packages/ui/{package.json,tsconfig.json,storybook.preview.ts,README.md} + src/{index.ts,tokens.css,codicon.css,useVscodeTheme.ts,foundations.stories.tsx,css.d.ts}
  • @repo/ui aliases in vitest.config.ts (webview project) and test/tsconfig.json
  • Storybook theme decorator mirrors data-vscode-theme-kind
  • Unit tests in test/webview/ui/

@linear-code

linear-code Bot commented Jul 10, 2026

Copy link
Copy Markdown

DEVEX-624

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.

1 participant