Cadence Clinical
Composites

Popover

A small panel that opens from a trigger and leaves the page in reach. It never outgrows the room it has.

GradeTested

Usage

import {
  Button,
  Popover,
  PopoverContent,
  PopoverDescription,
  PopoverHeader,
  PopoverTitle,
  PopoverTrigger,
} from "@cadence-clinical/ui";

<Popover>
  <PopoverTrigger render={<Button variant="outline" />}>Filters</PopoverTrigger>
  <PopoverContent align="start">
    <PopoverHeader>
      <PopoverTitle>Filter appointments</PopoverTitle>
      <PopoverDescription>Show only the appointments that match.</PopoverDescription>
    </PopoverHeader>
    ...
  </PopoverContent>
</Popover>;

Give the panel a PopoverTitle, which names it, or an aria-label on PopoverContent. Render PopoverTrigger as a Button through render. PopoverContent takes side, align, sideOffset and alignOffset to place the panel against its trigger.

Popover is built on the Base UI Popover and accepts all of its props. It follows the shadcn Popover and keeps its part names.

Popover, dialog or tooltip

  • A popover leaves the page in reach. A press on the page closes it, and the press still lands. Use it for filters, settings or more about one thing.
  • A Dialog takes over the page until its task is finished.
  • A Tooltip holds a few words and nothing to interact with. It does not open on a touch screen, so nothing that must be read goes in one. A popover opens on a press, so it works on touch.

What Cadence changes

  • The panel never outgrows the room it has. The shadcn panel is a fixed 18rem wide with no maximum height. Here it is 18rem at most, narrower on a narrow screen, and what does not fit scrolls inside it. Long words wrap.
  • From the keyboard it opens at once. Opened with the pointer, the panel grows from its trigger with a 150ms fade. Opened from the keyboard, or dismissed, it does not animate. With reduced motion it only fades.
  • The panel shows its focus. A panel with nothing inside to focus takes focus itself. shadcn hides its outline. Here it gets the focus ring.
  • Padding and text follow the density.

Accessibility

  • Opening the panel moves focus to the first control inside it, or to the panel when it has none. Escape closes it and sends focus back to the trigger.
  • The panel is a dialog named by its title and described by its description. It does not trap focus: Tab leaves it for the rest of the page.

Props

PropOnTypeDefault
open, onOpenChangePopover
defaultOpenPopoverbooleanfalse
sidePopoverContent"top" | "right" | "bottom" | "left""bottom"
alignPopoverContent"start" | "center" | "end""center"
sideOffsetPopoverContentnumber4
renderPopoverTriggerAn element, as in Base UIA button

On this page