@@ -19,6 +19,14 @@ import "@repo/ui/codicon.css";
1919
2020` tokens.css ` is the only layer that references VS Code's injected
2121` --vscode-* ` variables. Components reference ` --ui-* ` tokens only.
22+ ` --ui-background ` is the sidebar surface, the common webview host; a webview
23+ hosted in an editor tab or bottom panel uses ` --ui-panel-background ` instead,
24+ since VS Code gives webviews no host signal to resolve it automatically.
25+
26+ The radius and spacing tokens mirror VS Code's scale (` baseSizes.ts ` ), but
27+ only the rungs components actually use are declared; add one when a component
28+ needs it. Native menu, button, and hover paddings are hardcoded rather than
29+ scale-derived, so parity-pinned values stay literals.
2230
2331Component CSS is inherit-first: typography and text color come from the
2432webview (` font: inherit ` ), and controls center content with a fixed height
@@ -30,58 +38,48 @@ Every component forwards `className` and `style` to its root element, and
3038default rules use single-class specificity, so a consumer class imported
3139after the library overrides any default (width, height, spacing).
3240
41+ Where VS Code's stable rendering and its Modern UI preview
42+ (` workbench.experimental.modernUI ` ) diverge, components follow Modern UI,
43+ and new components should too. Webviews get no signal for the setting, so
44+ the default cannot follow the host. Until the design settles,
45+ ` data-ui-style="stable" ` on the document root restores the stable-parity
46+ menu motion; Storybook's "UI style" toolbar switch toggles it live.
47+
3348## Overlays
3449
3550` Tooltip ` , ` ContextMenu ` , and ` DropdownMenu ` wrap the Radix primitives,
3651styled to match the native VS Code menu and hover widgets. Menus expose
3752Radix's compound parts as flat named exports (` DropdownMenuTrigger ` ,
38- ` DropdownMenuItem ` , …); ` Tooltip ` is a single component taking a ` content `
39- prop, with a 500ms show delay matching VS Code's ` workbench.hover.delay `
40- default.
53+ ` DropdownMenuItem ` , ` DropdownMenuCheckboxItem ` , …): checkbox and radio
54+ items show a check in the icon gutter, ` *Label ` renders a group heading, and
55+ ` *Keybinding ` renders a shortcut hint. Pass ` keys ` the same ` key ` /` mac ` /
56+ ` win ` /` linux ` fields as a keybindings contribution to get the current OS's
57+ binding in its native label style (` ⇧⌘R ` on macOS, ` Ctrl+Shift+R `
58+ elsewhere); ` formatKeybinding ` does the same for other surfaces, such as
59+ tooltips.
60+
61+ ` Tooltip ` is a single component taking a ` content ` prop, and requires a
62+ ` TooltipProvider ` ancestor. Mount one provider per app so that a pointer
63+ moving between nearby triggers skips the show delay, like native hovers.
64+ The delay defaults to 500ms, matching VS Code's ` workbench.hover.delay ` ,
65+ and tooltips stop growing at half the window height.
4166
4267Overlay content is portalled to ` body ` , inherits webview typography from
4368there, and shares the ` .ui-overlay ` base for stacking, border, shadow,
44- and scrolling. Menus fade in like native menus, gated on ` data-state ` so
45- an interrupted entry animation cannot delay unmounting. High contrast,
46- ` forced-colors ` , and ` prefers-reduced-motion ` are handled.
69+ and scrolling. Menus default to the Modern UI motion: they scale and fade in
70+ from the trigger corner and fade out on close, with Radix holding unmount
71+ until the exit animation ends. High contrast, ` forced-colors ` , and
72+ ` prefers-reduced-motion ` are handled.
4773
4874## Known gaps
4975
50- Deliberate deferrals, fine to fix later.
51-
52- Overlays:
53-
54- - Menus only support plain action items; Radix's checkbox/radio items,
55- group labels, and keybinding hints have no styled wrappers yet.
56- - Moving the pointer from one tooltip trigger straight to another replays
57- the full 500ms delay, where native shows the next hover instantly. The
58- fix is one shared ` TooltipProvider ` per app instead of one per
59- ` Tooltip ` .
6076- Overlay shadows are darker than native in dark themes: menus in VS Code
6177 use ` shadow-lg ` , which webviews cannot read, so the closest available
6278 ` widget.shadow ` stands in.
63- - A very tall tooltip fills most of the viewport before it scrolls, where
64- native hovers stop at half the window height.
65-
66- Package-wide:
67-
68- - There is no ` Button ` ; the VS Code button style exists only inside the
69- state panels, and secondary-button colors have no ` --ui-* ` tokens.
70- - Only the Empty and Error panels ship; a Loading panel would need the
71- shared panel skeleton, which stays internal.
72- - The token layer maps what shipped components need: there are no
73- list/selection-row, spacing, typography, or z-index tokens, and the
74- ` --ui-radius-* ` tokens are only adopted by the overlays, with older
75- controls hardcoding their radii.
76- - ` --ui-background ` assumes a sidebar webview; a webview hosted in an
77- editor tab or panel renders on the sidebar color.
78- - ` useVscodeTheme ` reports the theme kind only; switching between two
79- themes of the same kind does not notify subscribers.
80- - Under ` prefers-reduced-motion ` the indeterminate ` ProgressBar ` renders
81- as a full bar and the ` Spinner ` as a static ring, with no other
82- activity cue.
83- - Story helpers compile against root-hoisted Storybook packages; a
84- standalone split needs its own Storybook devDependencies.
79+ - Keybinding hints show the contributed defaults the consumer passes, not
80+ user remaps: VS Code exposes no API for extensions to resolve a command's
81+ effective keybinding.
82+ - List/selection-row tokens are deferred to the Tree suite (#1037 ).
8583
8684## Codicons
8785
0 commit comments