Popover
Displays rich content in a portal, triggered by a button.
<NaviusPopover @bind-Open="_open">
<NaviusPopoverTrigger class="... data-[popup-open]:bg-accent">
Dimensions
</NaviusPopoverTrigger>
<NaviusPopoverPositioner Side="bottom" SideOffset="8">
<NaviusPopoverPopup
class="... w-72 bg-popover text-popover-foreground shadow-md">
<h4 class="text-sm font-medium">Dimensions</h4>
<p class="text-sm text-muted-foreground">Set the dimensions for the layer.</p>
<!-- width / height inputs … -->
<NaviusPopoverClose aria-label="Close" class="absolute right-3 top-3">✕</NaviusPopoverClose>
<NaviusPopoverArrow class="fill-popover" />
</NaviusPopoverPopup>
</NaviusPopoverPositioner>
</NaviusPopover>
@code { private bool _open; }Features
- Can be controlled (
@bind-Open) or uncontrolled (DefaultOpen). - Smart positioning anchored to the trigger, flipping and shifting to stay in view.
- Portals content to
document.bodyto escape overflow and stacking contexts. - Dismisses on outside pointer-down and
Escape; every dismissal is cancelable. - Optional
Modalmode that traps focus and locks page scroll. - Manages focus on open and restores it to the trigger on close.
Installation
Reference the Navius.Primitives package for the headless primitive, or vendor a styled version with the CLI: navius add copies the styled zits/ui component plus the brain files it depends on.
navius add popoverAnatomy
Import the parts and assemble them.
@using Navius.Primitives.Components.Popover
<NaviusPopover>
<NaviusPopoverTrigger />
<NaviusPopoverAnchor />
<NaviusPopoverPositioner>
<NaviusPopoverPopup>
<NaviusPopoverClose />
<NaviusPopoverArrow />
</NaviusPopoverPopup>
</NaviusPopoverPositioner>
</NaviusPopover>API Reference
Root
Contains all the parts of a popover. Owns open state and cascades context; renders no DOM.
| Prop | Type | Default |
|---|---|---|
| Open | bool | false |
| OpenChanged | EventCallback<bool> | - |
| DefaultOpen | bool | false |
| Modal | bool | false |
| ChildContent | RenderFragment? | - |
Trigger
The button that toggles the popover and anchors its positioning. Renders a button.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
| Attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-popup-open] | Present while the popover is open. |
Anchor
An optional explicit positioning reference. When present, the content anchors to it instead of the trigger. Renders a div.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
| Attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-popover-anchor] | Present on the anchor wrapper |
Portal
Teleports the content into document.body (or a custom container) so it escapes overflow clipping. Renders a div wrapper.
| Prop | Type | Default |
|---|---|---|
| Container | string? | - |
| KeepMounted | bool | false |
| ChildContent | RenderFragment? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-popover-portal] | Present on the portal wrapper |
Popup
The floating panel, wrapped by the Positioner and dismissable on outside-press / Escape. Self-portals; renders a div with role=dialog. The Side / Align / SideOffset / AlignOffset / Flip / AvoidCollisions / CollisionPadding / Sticky / HideWhenDetached / ArrowPadding props are set on the enclosing Positioner.
| Prop | Type | Default |
|---|---|---|
| Side | string | "bottom" |
| Align | string | "center" |
| SideOffset | double | 0 |
| AlignOffset | double | 0 |
| Flip | bool | true |
| AvoidCollisions | bool | true |
| CollisionPadding | double? | - |
| Sticky | string? | "partial" |
| HideWhenDetached | bool | false |
| ArrowPadding | double | 0 |
| KeepMounted | bool | false |
| OnOpenAutoFocus | EventCallback<NaviusOpenAutoFocusEventArgs> | - |
| OnCloseAutoFocus | EventCallback<NaviusCloseAutoFocusEventArgs> | - |
| OnEscapeKeyDown | EventCallback<NaviusEscapeKeyDownEventArgs> | - |
| OnPointerDownOutside | EventCallback<NaviusPointerDownOutsideEventArgs> | - |
| OnFocusOutside | EventCallback<NaviusFocusOutsideEventArgs> | - |
| OnInteractOutside | EventCallback<NaviusInteractOutsideEventArgs> | - |
| ChildContent | RenderFragment? | - |
| Attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-open] | Present while open. |
| [data-closed] | Present while closing (through the exit transition). |
| [data-starting-style] | Present at the start of the open transition. |
| [data-ending-style] | Present at the start of the close transition. |
| [data-side] | "top" | "right" | "bottom" | "left" |
| [data-align] | "start" | "center" | "end" |
| [--anchor-width] | Width of the anchor, in px |
| [--anchor-height] | Height of the anchor, in px |
| [--available-width] | Available width before collision, in px |
| [--available-height] | Available height before collision, in px |
| [--transform-origin] | Transform origin for open/close animations |
Arrow
An optional arrow pointing at the anchor, placed and rotated by the positioner. Renders an svg inside a span.
| Prop | Type | Default |
|---|---|---|
| Width | double | 10 |
| Height | double | 5 |
| ChildContent | RenderFragment? | - |
| Attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-popover-arrow] | Present on the arrow element |
Close
A button inside the content that closes the popover. Renders a button.
| Prop | Type | Default |
|---|---|---|
| ChildContent | RenderFragment? | - |
| Attributes | IDictionary<string, object>? | - |
Data attributes
| Data attribute | Values |
|---|---|
| [data-navius-popover-close] | Present on the close button |
Accessibility
Implements the Dialog WAI-ARIA APG pattern: the trigger carries aria-haspopup="dialog", aria-expanded, and aria-controls wired to the content's role="dialog". This is covered by the browser test suite and an axe-core WCAG gate in CI.
Keyboard interactions
| Key | Description |
|---|---|
| Space | Opens or closes the popover when focus is on the trigger. |
| Enter | Opens or closes the popover when focus is on the trigger. |
| Tab | Moves focus to the next focusable element. In Modal mode, focus is trapped within the content. |
| Shift + Tab | Moves focus to the previous focusable element, trapped within the content in Modal mode. |
| Escape | Closes the popover and returns focus to the trigger. |