Popover
An anchored native popover whose trigger snippet renders the owning control or component.
Usage
The trigger snippet renders TextInput directly. Its input and click handlers open the panel; click outside or press Escape to dismiss. The default soft glass panel fits its content and is at least as wide as the trigger, within the viewport. Toggle wide to check the anchor minimum.
<script>
import { Checkbox, Popover, TextInput } from 'bref-ui';
let open = $state(false);
let wide = $state(false);
</script>
<label><Checkbox bind:checked={wide} /> Wide input</label>
<Popover bind:open scroll>
{#snippet trigger()}
<TextInput
{wide}
value="Sample text"
aria-label="Search"
aria-expanded={open}
oninput={() => (open = true)}
onclick={() => (open = true)}
/>
{/snippet}
<p>Helpful details beside the input.</p>
</Popover>
Playground
Live preview
Settings
View generated code
<script>
import { Button, Popover, TextInput } from 'bref-ui';
let open = $state(false);
</script>
<Popover
bind:open
disabled={false}
as="div"
variant="soft"
color="background"
shadow={'medium'}
spacing="medium"
orientation="vertical"
radius="small"
scroll={false}
>
{#snippet trigger()}
<Button
label="Toggle preview popover"
wide={false}
disabled={false}
aria-expanded={open}
onClick={() => (open = !open)}
/>
{/snippet}
<p>Helpful details beside the trigger.</p>
<Button label="Done" onClick={() => (open = false)} />
</Popover>
<p role="status">{open ? 'Open' : 'Closed'}</p>
Open the preview after changing settings. Width fill follows the trigger; fit and default follow content. Every panel uses glass.
Bound state
Settings closed.
<script>
import { Button, Popover, TextInput } from 'bref-ui';
let open = $state(false);
</script>
<Popover bind:open variant="filled" spacing="medium" radius="small" shadow scroll>
{#snippet trigger()}
<Button label="Edit settings" onClick={() => (open = !open)} aria-expanded={open} />
{/snippet}
<label>Display name <TextInput value="Example" /></label>
<Button label="Done" onClick={() => (open = false)} />
</Popover>
Scrolling and multiple instances
This bound example starts open when the page loads.
Resize the viewport, scroll the page and switch the shared theme control to test fitting, anchoring and light/dark modes.
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
trigger | Snippet | Yes | — | The owning control or component; manages its own events and accessibility. |
children | Snippet | Yes | — | Parameterless content inside the popover. |
open | boolean | No | false | Bindable visibility; native dismissals update it. |
disabled | boolean | No | false | Keep the panel closed; the trigger controls its own disabled state. |
as | 'div' | 'section' | 'span' | No | div | Native root element of the Surface inside the panel. |
variant | Variant | No | soft | neutral, soft or filled; every variant uses glass. |
color | Color | No | background | Theme role for panel paint. |
shadow | BaseSize | boolean | No | medium | Shadow strength; true means medium and false disables it. |
hover | BaseSize | No | Omitted | Optional hover treatment strength. |
spacing | Size | No | medium | Padding and gap from x-small to x-large. |
orientation | Orientation | No | vertical | Horizontal or vertical Surface layout. |
width | Dimension | No | Omitted | fill follows trigger width; fit or omitted grows with content, at least as wide as the trigger. |
height | Dimension | No | Omitted | fit follows content; fill fills available Surface height within the viewport cap. |
radius | SurfaceRadius | No | small | Size token, rem value or percentage. |
scroll | boolean | No | false | Enable scrolling within the Surface. |
class | string | No | Omitted | Additional Surface classes. |
style | string | No | Omitted | Inline styles on the Surface. |
Popover accepts Surface props for styling and layout, including class and style, without inheriting generic HTML attributes. Every panel uses glass, with soft as the default variant. Explicit spacing, radius, shadow, variant, color and class choices customize that material. Another instance uses a soft primary color.
Both snippets receive no arguments. The trigger owns its native attributes, events, accessible
name and expanded state. Its handlers control bind:open ; Popover handles native dismissal and positioning.
Keyboard and focus
The trigger controls its keyboard behavior: buttons toggle with Enter or Space; the TextInput example opens on click or typing. Tab moves through the Surface and interactive content without trapping focus. Escape dismisses; closing from within the content returns focus to the owning control.
Content and explicit widths
Short content keeps the anchor minimum. Explicit fill follows the anchor; fit follows content. Both stay within the viewport and use glass automatically.