Context
vitejs/devtools#518 ("fix(core): FloatingPopover escapes a transformed ancestor's containing block; native Select mode") by @dvcolomban targeted FloatingPopover, floating-position.ts, and the json-render Select component, at packages/core/src/client/webcomponents/** in vitejs/devtools. That tree moved here as part of the v0.9 migration — the equivalent code today lives under packages/hub-ui/src/client/components/floating/ and packages/json-render-ui/src/components/Select.ts.
Since the original repo has since deleted that source, the PR is unmergeable there. This issue tracks porting its fix here instead.
Original PR description
What changed
FloatingPopover resolves the outermost ancestor that forms a containing block for position: fixed descendants and <Teleport>s its panel into that ancestor's parent. With no such ancestor, it renders in place as before.
- New
surface prop on FloatingPopover, tooltip (default) or menu. menu renders p0 bg-glass:25 border-#8883 in place of px2 p1 bg-glass:80 border-base.
Select gains native, rendering a real <select> instead of the custom listbox. It has no icon, description or searchable support.
Select's dropdown now uses surface="menu" and gap: 4, colours the selected option with primary and the active row with surfaceBadge, and no longer passes !p0 in panelClass.
webcomponents API snapshot updated for SelectProps.native.
Why it changed
A position: fixed panel is positioned relative to its nearest ancestor carrying a non-none transform or filter, not the viewport, and is clipped by that ancestor's overflow. Rendered inside such a panel, the Select dropdown was offset from its trigger and cut off — unusable. Escaping the outermost rather than the nearest such ancestor matters because escaping one can land inside another. The teleport target stays inside the shadow root, since that is where the panel's stylesheet is adopted and document.body would strip its styling.
The menu surface exists because a floating panel stacks over an already-tinted surface, where tooltip-strength glass composites to near-black, and because tooltip padding is wrong for a listbox — it inset the options and made the panel wider than its trigger.
native is an escape hatch worth having regardless of the fix above: the browser draws a native option list outside the page's layout, so no ancestor can clip or misposition it at all, which is the dependable choice for a Select embedded in a host layout this component doesn't control. Its option list needs no styling here, as ColorSchemeRoot already sets color-scheme inline and that inherits.
Diff: https://github.com/vitejs/devtools/pull/518/files
For agents picking this up
Context
vitejs/devtools#518 ("fix(core): FloatingPopover escapes a transformed ancestor's containing block; native Select mode") by @dvcolomban targeted
FloatingPopover,floating-position.ts, and the json-renderSelectcomponent, atpackages/core/src/client/webcomponents/**in vitejs/devtools. That tree moved here as part of the v0.9 migration — the equivalent code today lives underpackages/hub-ui/src/client/components/floating/andpackages/json-render-ui/src/components/Select.ts.Since the original repo has since deleted that source, the PR is unmergeable there. This issue tracks porting its fix here instead.
Original PR description
Diff: https://github.com/vitejs/devtools/pull/518/files
For agents picking this up
packages/hub-ui/src/client/components/floating/FloatingPopover.ts/floating-position.ts, andpackages/json-render-ui/src/components/Select.ts— and re-implement the same behavior, adapting to whatever has shifted since the fork.Co-authored-by: dvcolomban <...>trailer (look up their GitHub noreply email, or omit if unavailable) and mention them in the PR description.