Skip to content

feat(ui): add Radix overlays themed to VS Code#1039

Open
EhabY wants to merge 1 commit into
feat/devex-624-ui-scaffoldfrom
feat/devex-619-radix-overlays
Open

feat(ui): add Radix overlays themed to VS Code#1039
EhabY wants to merge 1 commit into
feat/devex-624-ui-scaffoldfrom
feat/devex-619-radix-overlays

Conversation

@EhabY

@EhabY EhabY commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Closes #1038 (DEVEX-619)

Stacked on #1030 (the packages/ui scaffold); this diff is overlay-only.

What

  • Tooltip, ContextMenu, DropdownMenu wrapping @radix-ui/react-* — the package's only runtime deps besides codicons; React stays a peer.
  • Menus expose Radix's compound parts as flat named exports; Tooltip is a single component with a content prop (Radix Themes / Fluent v9 shape) and a 500ms delay matching workbench.hover.delay.
  • Styled to the native widgets via new --ui-menu-* / --ui-tooltip-* tokens in tokens.css (menu colors from menu.* IDs, tooltip from editorHoverWidget.*, shadow from widget.shadow which self-removes in HC). Metrics verified against the VS Code source: 24px items, 2em check-column gutters, corner-radius tokens with the pre-token 5px/4px fallbacks.
  • Inherit-first: overlay CSS declares no typography — portalled content inherits from body, matching real webview default styles (Storybook's global.css stand-in moved typography from #root to body accordingly).
  • High contrast via the VS Code contrast variables, plus forced-colors (system colors re-pointed through custom properties) and prefers-reduced-motion handling.
  • Long content caps to the available height Radix reports and scrolls, like native menus/hovers.
  • Library boundary: ESLint now rejects @repo/* and relative cross-package imports in packages/ui; shared internals go through #cx/#storybook subpath imports; sideEffects declared for tree-shaking.

Storybook

One .stories.tsx per overlay. The Open matrix stories (nested submenu, disabled items, separators, icons) snapshot Light, Dark, High Contrast, and High Contrast Light via Chromatic modes; play functions open the overlays pre-snapshot. ManyItems/OverflowScrolls assert the scroll caps.

Webview focus handling

Verified via play assertions (the preview iframe owns its document, like a webview): focus moves into the menu on open, Escape closes and returns focus to the trigger, tooltip opens on keyboard focus.

Manual checklist for the first real webview consumer:

  • Escape returns focus to the trigger, not the workbench
  • Clicking workbench chrome (webview blur) closes the menu
  • Tab from an open menu strands no focus on body
  • Check a real HC theme and Windows forced colors

Out of scope

Checkbox/radio items, labels, keybinding hints, a data-driven items wrapper, and Tasks' migration off @vscode-elements.

🤖 Generated with Claude Code

@linear-code

linear-code Bot commented Jul 15, 2026

Copy link
Copy Markdown

DEVEX-619

@EhabY EhabY self-assigned this Jul 15, 2026
Tooltip, ContextMenu, and DropdownMenu wrap the Radix primitives with
flat compound exports (Tooltip takes a content prop) and are styled to
match the native menu and hover widgets via --ui-* tokens, including
high contrast, forced-colors, and reduced-motion handling. Long menus
and tooltips cap to the space Radix reports and scroll like native.
Stories snapshot the four theme families through Chromatic and assert
focus handling in play functions.
@EhabY EhabY force-pushed the feat/devex-619-radix-overlays branch from 87cb194 to bb96f01 Compare July 15, 2026 22:12
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