Skip to main content

Overview

Appearance settings
Customize your display preferences.
Dark mode
Compact view
Popover is a non-modal floating panel anchored to a trigger. Unlike Tooltip (hover, read-only), Popover can contain interactive elements — forms, toggles, pickers — and is triggered by click.
Popover vs Tooltip: use Popover for interactive content (buttons, inputs, forms). Use Tooltip for short read-only labels shown on hover.

Installation

npm install @araf-ds/core

Usage

import {
  Popover,
  PopoverTrigger,
  PopoverContent,
} from "@araf-ds/core"

export default function Example() {
  return (
    <Popover>
      <PopoverTrigger asChild>
        <Button variant="outline">Open popover</Button>
      </PopoverTrigger>
      <PopoverContent className="w-64">
        <p className="text-sm text-muted-foreground">
          Popover content goes here.
        </p>
      </PopoverContent>
    </Popover>
  )
}

Variants

Basic

Quick info
This component anchors floating content to any trigger element.
<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline">Open popover</Button>
  </PopoverTrigger>
  <PopoverContent className="w-60">
    <div className="space-y-1">
      <h4 className="font-medium text-sm">Quick info</h4>
      <p className="text-sm text-muted-foreground">
        This component anchors floating content to any trigger element.
      </p>
    </div>
  </PopoverContent>
</Popover>

With Form

Dimensions
<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline">Edit dimensions</Button>
  </PopoverTrigger>
  <PopoverContent className="w-56">
    <div className="grid gap-3">
      <h4 className="font-medium text-sm">Dimensions</h4>
      <FormItem>
        <FormLabel>Width</FormLabel>
        <Input defaultValue="100%" />
      </FormItem>
      <FormItem>
        <FormLabel>Height</FormLabel>
        <Input defaultValue="100%" />
      </FormItem>
      <Button size="sm">Apply</Button>
    </div>
  </PopoverContent>
</Popover>

Placement

// Control placement with the `side` prop
<PopoverContent side="top">...</PopoverContent>
<PopoverContent side="right">...</PopoverContent>
<PopoverContent side="bottom">...</PopoverContent>  {/* default */}
<PopoverContent side="left">...</PopoverContent>

API Reference

Popover

open
boolean
Controlled open state.
onOpenChange
(open: boolean) => void
Callback fired when open state changes.
defaultOpen
boolean
default:"false"
Uncontrolled default open state.

PopoverContent

side
string
default:"bottom"
Which side of the trigger to render on. Values: top · right · bottom · left
align
string
default:"center"
Alignment relative to the trigger. Values: start · center · end
sideOffset
number
default:"4"
Distance in px between trigger and popover panel.
className
string
Additional class names for the popover panel.

Accessibility

  • Popover uses role="dialog" and is not modal — background content remains accessible
  • Trigger has aria-haspopup="dialog" and aria-expanded
  • Focus moves into the popover when it opens; Escape closes it and returns focus to the trigger
  • Unlike Tooltip, Popover is not announced on hover — it requires a deliberate click

Do’s & Don’ts

Do

  • Use Popover for interactive content: forms, pickers, toggles
  • Keep popover content focused — avoid making it too wide or tall
  • Provide a clear close mechanism (Escape key or a close button)
  • Use align="end" for popovers triggered from right-aligned buttons

Don't

  • Don’t use Popover for read-only labels — use Tooltip
  • Don’t use Popover for critical blocking decisions — use AlertDialog
  • Don’t put navigation inside a Popover — use DropdownMenu
  • Don’t make Popover content taller than the viewport