Skip to content

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

Merged
EhabY merged 4 commits into
mainfrom
feat/devex-624-ui-scaffold
Jul 27, 2026
Merged

feat(ui): scaffold packages/ui with theme foundations#1030
EhabY merged 4 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 #1036

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 and consumed as source like webview-shared, but shaped for a future standalone NPM split: exports map (., ./tokens.css, ./codicon.css), react as the only peer dependency, @vscode/codicons (asset-only) as the only runtime dependency, no workspace:* 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. Every token always resolves: variables VS Code may omit (hover/selection fills in high contrast themes, contrast borders outside them) declare fallbacks that match native behavior.
  • useVscodeTheme: returns the active theme kind from the data-vscode-theme-kind body attribute VS Code maintains in webviews, synced via MutationObserver + useSyncExternalStore.
  • Storybook: the theme switcher now covers all four theme kinds (Light, Dark, High Contrast, High Contrast Light) and the decorator mirrors data-vscode-theme-kind on the body. Theme data is no longer vendored: all four themes import from @vscode-elements/webview-playground, deleting the two ~700-line copied theme files. Net, the PR removes ~1,500 lines.
  • UI/Foundations story: enumerates every --ui-* token from the loaded stylesheets (cannot drift from tokens.css) and renders each as a swatch with its resolved value. Chromatic modes snapshot it in all four themes, scoped to this story to keep snapshot counts down.

Testing

  • test/webview/ui/useVscodeTheme.test.ts: theme-kind mapping, missing-attribute default, re-render on theme change.
  • Story rendered headlessly against the production Storybook build in all four themes; all 16 tokens resolve to expected values and fallbacks engage where variables are absent.
  • pnpm typecheck, lint, format:check, test, build, and storybook:ci all pass.

Note: webview-playground 1.9.0 carries newer VS Code theme captures than the previously vendored copy, so existing Chromatic baselines will show a one-time diff.

Implementation decisions
  1. Build: source-consumed like webview-shared (no vite build), but self-contained so a real build step can be added at the actual NPM split.
  2. Codicon export: ./codicon.css added now since follow-up issues will use it.
  3. Semantic token layer (vs raw --vscode-* per component, as vscode-elements does): the deprecated @vscode/webview-ui-toolkit validated the token-layer pattern 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.
  4. No sideEffects field: with it, this Vite/rolldown pipeline tree-shook the storybook.preview.ts to tokens.css chain out of the production Storybook build (even with **/*.css). Dev mode masked it. Dropped as speculative; revisit at the actual split.
  5. Radix: deferred to DEVEX-619, which explicitly scopes adding the only Radix runtime deps.
  6. Theme data from npm: @vscode-elements/webview-playground publishes the exact theme modules the repo had copied by hand. Importing them (typed via a small wildcard .d.ts) deletes the vendored data and makes theme refreshes a pnpm update.
  7. No webview-shared re-export of useVscodeTheme: no consumers exist yet and it would add a workspace dep.

@linear-code

linear-code Bot commented Jul 10, 2026

Copy link
Copy Markdown

DEVEX-624

DEVEX-649

EhabY and others added 4 commits July 20, 2026 14:21
Source all VS Code themes (light, dark, hc-dark, hc-light) from
@vscode-elements/webview-playground instead of maintaining local
copies, and add per-theme Chromatic snapshot modes.

Also drops the sideEffects field that broke CSS tree-shaking, and
fixes the Foundations story's token value column inheriting an
unrelated --vscode-textPreformat-background instead of the row's own
background, which made values unreadable in both high-contrast themes.
@EhabY
EhabY force-pushed the feat/devex-624-ui-scaffold branch from b9d3bea to 5a6fe06 Compare July 20, 2026 11:21
@EhabY
EhabY merged commit d4fc707 into main Jul 27, 2026
11 checks passed
@EhabY
EhabY deleted the feat/devex-624-ui-scaffold branch July 27, 2026 09:21
EhabY added a commit that referenced this pull request Jul 27, 2026
Turn the @repo/ui scaffold from #1030 into the reusable primitives needed
for the upcoming Workspaces states: Icon, IconButton, Spinner, ProgressBar,
SearchInput, StatusPill, EmptyState, and ErrorState. Components are native
HTML elements styled to match VS Code's own controls through a semantic
--ui-* token layer, with Storybook themed by variable dumps captured from a
real VS Code instance and visual regressions guarded by Pixel.

- Match VS Code control geometry and behavior (toolbar buttons, search
  input, progress, buttons), including high-contrast, forced-colors, and
  reduced-motion handling; EmptyState/ErrorState share one internal
  StatePanel.
- StatusPill defaults to VS Code's native badge; tones and icons are an
  extra that tints the pill GitHub-style with its own accent so it stays
  legible in all four themes.
- Keep the package NPM-ready: ESLint-enforced isolation, React as a peer
  dependency, codicons as the only runtime dependency, and subpath imports
  for shared internals.
- Capture theme variables and the default webview stylesheet from a pinned
  VS Code via pnpm sync:vscode-themes (verbatim, diff-free resyncs) and
  apply them as a single synchronous :root stylesheet swap in Storybook.
- Snapshot every story with Pixel in light, dark, and both high-contrast
  themes, with a VSCodeParity story comparing each control to its
  @vscode-elements counterpart so styling drift shows up as a visual diff.
- Cover accessibility and behavior with focused Testing Library tests in
  test/webview/ui/.

Closes #1035
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.

ui: scaffold packages/ui with theme foundations (tokens.css, useVscodeTheme)

2 participants