Skip to content

FormSelect: dropdown teleports to document.body and loses styles inside a shadow root #30

Description

@antfubot

Problem

components/Form/FormSelect.vue wraps its list in <SelectPortal>, which teleports SelectContent to document.body. When the component is mounted inside a shadow root (for example a devtools overlay built with defineCustomElement({ shadowRoot: true })), the list leaves the shadow tree. The UnoCSS stylesheet lives inside that shadow root, so the list renders unstyled on the host page, and the host page's own CSS applies to it instead.

The same applies to the other Overlay* components that use a reka-ui *Portal.

Reproduction

  1. Mount FormSelect from a Vue custom element created with defineCustomElement(App, { shadowRoot: true, styles: [unoCss] }).
  2. Open the select.
  3. Inspect the list: it is a child of document.body, with none of the border-base / bg-glass / z-dropdown rules applied.

Suggested fix

Let a caller keep the list inside its own tree. Options:

  • A portal?: boolean prop (default true) that skips SelectPortal when false, or
  • A to?: string | HTMLElement prop passed through to SelectPortal's to, so the caller can target a container inside the shadow root.

Either one lets FormSelect replace a native <select> in shadow-root surfaces. Context: devframes/devframe#415 uses a native <select> for a language picker for this reason and would switch to FormSelect once it works in a shadow root.


Created with the help of an agent.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions