Tracked in DEVEX-619 · Project: Workspaces webview + UI library
Behavioral primitives wrapping Radix, styled to match native VS Code menus. Builds on the @repo/ui scaffold and semantic theme boundary established in DEVEX-618.
Scope
Tooltip, ContextMenu, DropdownMenu wrapping @radix-ui/react-* primitives
- Keyboard/a11y behavior comes from Radix — verify focus handling inside webviews
Out of scope
- Migration of Tasks to Radix (Tasks currently uses
@vscode-elements/react-elements; per the RFC, packages/ui standardizes on Radix and Tasks migrates later — do not add @vscode-elements to packages/ui)
VS Code fidelity
- Style via
tokens.css to match native menus/hovers, including high contrast + custom themes
- Menu geometry, separator, item hover/active, and tooltip visuals consistent with VS Code defaults
- Minimize custom styles — rely on inherited values from the WebViews wherever possible; component CSS is inherit-first and never uses line-height/vertical-padding math
tokens.css maps VS Code variables to semantic --ui-* tokens — add any new overlay-specific tokens here (create the file if it doesn't already exist; conflicts will be resolved later)
control.css provides the shared flex-centering geometry base — add menu item geometry here if applicable (create the file if it doesn't already exist; conflicts will be resolved later)
- Support high contrast through VS Code contrast variables, plus
forced-colors and prefers-reduced-motion media handling
Library boundary (NPM-ready)
- Adds the only Radix runtime dependencies of the package — keep to these 3; they share small internal utils and are tree-shakeable
- No
@repo/* or relative cross-package imports from packages/ui (enforced by ESLint)
- React stays a peer dependency; Radix packages are the only additional runtime dependencies
- Shared internals reached through
package.json subpath imports
Storybook
- One
.stories.tsx per overlay (Tooltip, ContextMenu, DropdownMenu) with a combined matrix story covering nested submenu, disabled items, separators, and icons
- Each matrix story snapshotted in Light, Dark, High Contrast, and High Contrast Light via Chromatic
Acceptance
- Renders correctly across the four theme families
- Verify focus handling inside webviews
- Validated with type checking, linting, formatting, UI tests, Storybook CI build, production build, and
git diff --check
Tracked in DEVEX-619 · Project: Workspaces webview + UI library
Behavioral primitives wrapping Radix, styled to match native VS Code menus. Builds on the
@repo/uiscaffold and semantic theme boundary established in DEVEX-618.Scope
Tooltip,ContextMenu,DropdownMenuwrapping@radix-ui/react-*primitivesOut of scope
@vscode-elements/react-elements; per the RFC,packages/uistandardizes on Radix and Tasks migrates later — do not add@vscode-elementstopackages/ui)VS Code fidelity
tokens.cssto match native menus/hovers, including high contrast + custom themestokens.cssmaps VS Code variables to semantic--ui-*tokens — add any new overlay-specific tokens here (create the file if it doesn't already exist; conflicts will be resolved later)control.cssprovides the shared flex-centering geometry base — add menu item geometry here if applicable (create the file if it doesn't already exist; conflicts will be resolved later)forced-colorsandprefers-reduced-motionmedia handlingLibrary boundary (NPM-ready)
@repo/*or relative cross-package imports frompackages/ui(enforced by ESLint)package.jsonsubpath importsStorybook
.stories.tsxper overlay (Tooltip,ContextMenu,DropdownMenu) with a combined matrix story covering nested submenu, disabled items, separators, and iconsAcceptance
git diff --check