Popover
Popover keeps compact contextual content attached to its trigger. Choose it for a filter, picker or small detail panel; choose Dropdown for a list of commands with menu semantics.
Examples
Details attached to a control
Give the panel an ariaLabel that describes its content. The interactive Button remains the one
trigger and one tab stop for opening or closing the panel.
A controlled filter panel
Control open when the rest of the interface must react to a panel opening or closing. Use
align="end" to keep the panel's right edge with its trigger.
When to use
Use Popover for a short, non-modal panel anchored to the control that opens it.
Reach for something else when:
- The panel is a short list of commands — use Dropdown, which supplies menu and menuitem semantics plus roving keyboard focus.
- The content is only a brief hover or focus hint — use Tooltip.
- The task needs blocking focus management or a larger decision — use Dialog.
Accessibility
- Pass an interactive, focusable
trigger, such as a native<button>or Button. It receivesaria-haspopup="dialog",aria-expanded,aria-controls, click handling and Enter/Space handling directly, preserving one interactive element and one tab stop. - The open panel is an in-flow
role="dialog"named byariaLabel; it is not portaled and is not modal, so it does not move or trap focus. - A mousedown outside the component closes the panel and lets focus remain where the person clicked. Escape closes it and returns focus to the trigger.
- With
side="auto", placement is measured against the trigger and panel and can flip above the trigger.topandbottomchoose an explicit vertical side.
API and code
| Name | Type | Required | Description |
|---|---|---|---|
trigger | ReactNode | Required | Interactive element that opens and closes the panel. It receives the panel's keyboard and ARIA semantics directly, so pass a focusable control such as a `<button>` or `Button`. |
open | boolean | — | Whether the panel is open in controlled mode. |
defaultOpen | boolean | — | Whether the panel is initially open in uncontrolled mode. Default: `false`. |
onOpenChange | (open: boolean) => void | — | Called whenever the requested open state changes. |
side | 'auto' | 'bottom' | 'top' | — | Preferred vertical side. Default: automatic placement; `"top"` and `"bottom"` keep the panel on that explicit side. |
align | 'start' | 'end' | 'center' | — | Preferred horizontal alignment. Default: automatic placement; an explicit value overrides it. |
width | number | — | Fixed panel width in CSS pixels. |
ariaLabel | string | — | Accessible name for the non-modal dialog panel. Default: `"Popover"`. |
children | ReactNode | Required | Content rendered in the panel. |
x-data="lyraPopover({ … })"
| Option | Type | Required | Description |
|---|---|---|---|
defaultOpen | boolean | — | Whether the panel starts open. Default: `false`. |
side | 'auto' | 'bottom' | 'top' | — | Preferred vertical side. Default: automatic placement. |
align | 'start' | 'end' | 'center' | — | Preferred horizontal alignment. Defaults to automatic placement. |
width | number | — | Fixed panel width in CSS pixels. |
ariaLabel | string | — | Accessible name for the non-modal dialog panel. Default: `"Popover"`. |
Without React, put the panel inside its positioned anchor and own toggle, outside-click and Escape behavior:
<span class="lyra-popover-anchor">
<button
class="lyra-btn lyra-btn--secondary lyra-btn--md"
type="button"
aria-haspopup="dialog"
aria-expanded="true"
aria-controls="project-details"
>
View details
</button>
<div
class="lyra-popover lyra-popover--bottom lyra-popover--align-start"
id="project-details"
role="dialog"
aria-label="Project details"
>
Atlas is on track for its June release.
</div>
</span><lyra:popover> Generated from lyra-ds/blade v0.10.0.
The behavior comes from lyraPopover() — install @lyra-ds/alpine and see the HTML + Alpine tab.
| Prop | Default | Required | Example values |
|---|---|---|---|
defaultOpen | false | — | — |
side | 'auto' | — | — |
align | null | — | — |
width | null | — | — |
ariaLabel | 'Popover' | — | — |
wrapTrigger | true | — | — |
<lyra:popover side="bottom" align="start" aria-label="Usage details">
<x-slot:trigger>Usage details</x-slot:trigger>
<p>68% of the included API requests were used this cycle.</p>
</lyra:popover>