Theme studio

Design a theme, preview it live, then export it. Saved in this browser.

Quick picks #10b981
Generated scale
50100200300400500600700800900
Some text is below AA

Popover

  • Stable
  • WCAG 2.2 evidence
  • RTL

A short, non-modal panel anchored to a trigger. Built on React Aria DialogTrigger and Popover (isNonModal), with a role="dialog" panel: the trigger exposes aria-expanded and aria-controls; focus moves into the panel when it opens and back to the trigger when Escape, the close button or a slot="close" action closes it (WCAG 2.1.1, 2.4.3, 4.1.2). Nothing is trapped: Tab past the last control leaves the panel for the element after the trigger and closes it, a click outside closes it, and the rest of the page stays available (WCAG 2.1.2). Placement flips and the panel stays inside the viewport. Consumer duties: content wording; for blocking decisions use a modal Dialog, for lists of actions use Menu.

import { Popover } from "@nexera-ui/react";
Loading example…
6
examples
26
props
4
live controls
1
platform
11
WCAG criteria
1
block uses it

Try every prop. Copy the code.

Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.

Loading…
children
defaultOpen
variant
title
Generated code
import { Popover } from "@nexera-ui/react";

<Popover />

Examples 5

The same examples as Storybook, rendered live. Open Code to copy one.

With header

Figma Variant=With header: a title (level 2 heading, the dialog's name) and a close button.

Loading example…

With actions

Figma Variant=With actions: header plus a ghost and a primary small Button. slot="close" makes an action close the popover and return focus to the trigger.

Loading example…

Placements

placement on each side of the trigger, all open (isOpen). Each panel flips to the other side when there is no room and stays 12 px inside the viewport.

Loading example…

Long content

Long titles, body text and action labels wrap; long content scrolls inside the panel when it reaches the viewport edge.

Loading example…

Right to left

Right-to-left: the close button and actions move to the left; placement="start"/"end" follow the reading direction.

Loading example…

Props 26

Press "Try it" on a card to load that prop into the playground.

26 props shown

children*Nexera
ReactNode

The trigger: one pressable element, usually a Nexera Button. It gets aria-expanded and aria-controls, toggles the popover when pressed and receives focus back when the popover closes.

Default –
body*Nexera
ReactNode

Main text. Also the dialog's description (aria-describedby).

Default –
isOpenNexera
boolean

Whether the popover is open (controlled). Use with onOpenChange.

Default –
defaultOpenNexera
boolean

Whether the popover is open on first render (uncontrolled).

Default false
onOpenChangeNexera
(isOpen: boolean) => void

Called when the popover opens or closes.

Default –
closeLabelNexera
string

Accessible name of the close button. Translate it for your locale.

Default "Close"
classNameNexera
string

Extra classes for the surface, merged last so they win over the defaults.

Default –
styleNexera
CSSProperties

Inline style for the surface.

Default –
variantNexera
"default" | "with-header" | "with-actions"

Panel layout: default is the body only; with-header adds a title and a close button; with-actions adds a row of actions under the body.

Default "default"
titleNexera
ReactNode

Title, a level 2 heading that names the dialog.

Default –
primaryActionNexera
ReactNode

Main action at the end of the row: <Button size="sm">. Give it slot="close" to close the popover when pressed.

Default –
secondaryActionNexera
ReactNode

Secondary action before it: <Button variant="ghost" size="sm">. Shown when provided.

Default –
aria-labelNexera
string

Accessible name of the dialog. Without it the dialog is named by the trigger's label.

Default –
placementReact Aria
"bottom" | "bottom left" | "bottom right" | "bottom start" | "bottom end" | "top" | "top left" | "top right" | "top start" | "top end" | "left" | "left top" | "left bottom" | "start" | "start top" | "start bottom" | "right" | "right top" | "right bottom" | "end" | "end top" | "end bottom"

The placement of the element with respect to its anchor element.

Default 'bottom'
containerPaddingReact Aria
number

The placement padding that should be applied between the element and its surrounding container.

Default 12
offsetReact Aria
number

The additional offset applied along the main axis between the element and its anchor element.

Default 8
crossOffsetReact Aria
number

The additional offset applied along the cross axis between the element and its anchor element.

Default 0
shouldFlipReact Aria
boolean

Whether the element should flip its orientation (e.g. top to bottom or left to right) when there is insufficient room for it to render completely.

Default true
boundaryElementReact Aria
Element

Element that that serves as the positioning boundary.

Default document.body
scrollRefReact Aria
RefObject<Element | null>

A ref for the scrollable region within the overlay.

Default overlayRef
shouldUpdatePositionReact Aria
boolean

Whether the overlay should update its position automatically.

Default true
maxHeightReact Aria
number

The maxHeight specified for the overlay element. By default, it will take all space up to the current viewport height.

Default –
arrowBoundaryOffsetReact Aria
number

The minimum distance the arrow's edge should be from the edge of the overlay element.

Default 0
getTargetRectReact Aria
(target: Element) => DOMRect | null

Overrides the target element's bounding rectangle. Useful for positioning relative to a specific point such as the mouse cursor (e.g. context menus) or text selection. @param target - The target element.

Default target.getBoundingClientRect()
isKeyboardDismissDisabledReact Aria
boolean

Whether pressing the escape key to close the popover should be disabled. Most popovers should not use this option. When set to true, an alternative way to close the popover with a keyboard must be provided.

Default false
shouldCloseOnInteractOutsideReact Aria
(element: Element) => boolean

When user interacts with the argument element outside of the popover ref, return true if onClose should be called. This gives you a chance to filter out interaction with elements that should not dismiss the popover. By default, onClose will always be called on interaction outside the popover ref.

Default –

* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.

Accessible by default.

Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.

WCAG 2.2 evidence

5 direct · 6 supporting
  • 1.3.1Info and RelationshipsLevel A · tested directly
  • 1.3.2Meaningful SequenceLevel A · supporting test
  • 1.4.10ReflowLevel AA · supporting test
  • 1.4.12Text SpacingLevel AA · supporting test
  • 2.1.1KeyboardLevel A · tested directly
  • 2.1.2No Keyboard TrapLevel A · tested directly
  • 2.3.3Animation from InteractionsLevel AAA · supporting test
  • 2.4.3Focus OrderLevel A · tested directly
  • 2.4.7Focus VisibleLevel AA · supporting test
  • 2.5.8Target Size (Minimum)Level AA · supporting test
  • 4.1.2Name, Role, ValueLevel A · tested directly

Fits any width.

Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.

0 px · drag the corner

Styling hooks

Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.

  • data-hovered
  • data-pressed
Usage
<Popover className="data-hovered:opacity-90 shadow-sm" />

Used in blocks

Related components