Skip to content

feat(ui): add Radix overlays matched to native VS Code widgets - #1039

Merged
EhabY merged 4 commits into
mainfrom
feat/devex-619-radix-overlays
Jul 28, 2026
Merged

feat(ui): add Radix overlays matched to native VS Code widgets#1039
EhabY merged 4 commits into
mainfrom
feat/devex-619-radix-overlays

Conversation

@EhabY

@EhabY EhabY commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Closes #1038

Adds Tooltip, ContextMenu, and DropdownMenu wrapping the Radix primitives, the package's only runtime deps besides codicons. The Radix packages are declared directly in packages/ui (sole consumer, and portable for a standalone split) at their latest versions; codicons is pinned to 0.0.46-24. Menus expose Radix's compound parts as flat named exports with a one-line JSDoc each; Tooltip is a single component with a content prop and a 500ms delay matching workbench.hover.delay.

  • Styling verified against the VS Code source (getMenuWidgetCSS() in menu.ts, hover.css): 24px items, 2em gutters, cornerRadius tokens with pre-token fallbacks, highlight colors from list.hover* (what native menus actually use, not menu.selection*), and native's exact shadow-lg fallback chain.
  • Tooltips position like native hovers: flush with the target, left-aligned, 5px radius, 13px/19px type; content wraps at 700px and scrolls past the available height.
  • Shared .ui-overlay base owns stacking, border, radius, shadow, and available-height scrolling; each surface maps onto it via --ui-overlay-* properties. Menus fade in like native menus, gated on data-state; an ungated entry animation interrupted before its first frame left closed overlays mounted, because Radix waits for an animationend that never fires.
  • No typography in overlay CSS; portalled content inherits from body. High contrast, forced-colors, and prefers-reduced-motion handled.
  • sideEffects declared so unused components tree-shake out of webview bundles.
  • The README's known-gaps section lists the deliberate deferrals for the overlays (checkbox/radio/label/keybinding wrappers, shared TooltipProvider, shadow alpha, tooltip height cap) and for the package as a whole (no Button, token-layer coverage, useVscodeTheme granularity, reduced-motion activity cues).

Storybook

One stories file per overlay, five stories total; Open stories snapshot all four themes via the Pixel matrix, with menus and submenus opened by play functions through a shared openSubmenuByKeyboard helper. Portalled overlays stay in frame automatically: a preview-level afterEach grows the story root to cover anything portalled to body, replacing per-story overlaySpace reservations (layout switched to padded so growth never moves an overlay's anchor). The .story-trigger stand-in styles moved into the package next to the constant that names them.

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, groups, labels, keybinding hints, a data-driven items wrapper, a shared app-root TooltipProvider (each Tooltip mounts its own for now), 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

DEVEX-648

@EhabY EhabY self-assigned this Jul 15, 2026
@EhabY
EhabY force-pushed the feat/devex-619-radix-overlays branch from 87cb194 to bb96f01 Compare July 15, 2026 22:12
@EhabY
EhabY force-pushed the feat/devex-624-ui-scaffold branch from b9d3bea to 5a6fe06 Compare July 20, 2026 11:21
@EhabY
EhabY force-pushed the feat/devex-619-radix-overlays branch from bb96f01 to 88bb435 Compare July 20, 2026 11:37
Base automatically changed from feat/devex-624-ui-scaffold to main July 27, 2026 09:21
@EhabY
EhabY force-pushed the feat/devex-619-radix-overlays branch 3 times, most recently from 2559023 to 9289218 Compare July 27, 2026 13:57

@jakehwll jakehwll left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥳

EhabY added 3 commits July 28, 2026 16:00
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.
The menu entry fade is gated on data-state so an interrupted animation
cannot leave a closed overlay mounted. Stories snapshot the four theme
families through Pixel and assert focus handling in play functions.
- Menu highlight uses list.hover* and tooltips sit flush left like native
- .ui-overlay owns border, radius, shadow, and available-height scrolling
- Replace overlaySpace reservations with an afterEach root fit in preview
- Trim stories, add JSDoc to menu parts, drop unused Group exports
- Inline Radix deps in packages/ui and pin codicons 0.0.46-24
@EhabY
EhabY force-pushed the feat/devex-619-radix-overlays branch from ec5efce to 1db5c9a Compare July 28, 2026 13:02
@EhabY EhabY changed the title feat(ui): add Radix overlays themed to VS Code feat(ui): add Radix overlays matched to native VS Code widgets Jul 28, 2026
- Shrink #storybook-root to fit-content; the padded layout rendered it
  as a full-width block, making every Pixel snapshot viewport-wide
- Declare react-dom as a peer dependency (the Radix primitives need it)
- Extend the README known gaps to cover the whole package, not just
  the overlays
@EhabY
EhabY merged commit 82f5c6e into main Jul 28, 2026
11 checks passed
@EhabY
EhabY deleted the feat/devex-619-radix-overlays branch July 28, 2026 13:23
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: Radix-based overlays (Tooltip, ContextMenu, DropdownMenu) themed to VS Code

2 participants