Popover

Shows a few lines next to a control.

Opening

  • clickdefault

  • hover preview

  • Retention

    info

Modal

  • falsedefault

  • true

Usage

When to use it
Use
A few lines about one thing, next to it: a partition's size, a worker's load.
Use
A small control or two that act on that thing, with the page still usable.
Use
A term on the page needs a sentence of explanation (PopoverInfo).
Not for
The person must decide before the page goes on. Use Dialog.
Not for
A list of actions on one thing. Use Dropdown menu.
Not for
Only the name of an icon button. Use Tooltip.

Rules

6 rules
Must
Name the thing in PopoverTitle, a mono label, and say the rest in PopoverDescription, in sentences. Because the title names a place or a thing and the label role carries its capitals, while a sentence in capitals reads slowly.
Must
Hold at most one primary Button in a popover; the way out is secondary or a PopoverClose. Because the popover is one group of actions, and the yellow slab marks the one thing to act on.
Never
Put a link or a button inside PopoverInfo. Because focus stays on the info button, so nothing inside can be reached by keyboard; use a Popover.
Must
Use openOnHover only for detail a person can also reach another way, such as the page the link opens. Because a hover preview never opens on touch, and a screen reader may never meet it.
Never
Add a shadow, an arrow or a rounded corner to PopoverContent. Because Sodium has no shadows, only rules: the panel fill and a rule edge set it apart, and the lint flags every shadow class.
Should
Keep the popover at its 288px width; past a few lines, move the content to a Sheet. Because a wide popover covers what it describes.

State order

4 states, highest first
1
pinned
2
open
3
peeking
4
closed

Accessibility

4 checks
The trigger has aria-expanded and aria-controls; the popup is a dialog named by PopoverTitle.
The edge is --line, the rule colour; the popover is a dialog named by its title, not found by its edge.
PopoverInfo is a 24px square button named "About <title>", described by its text, so focus alone reads it.
A link trigger keeps the link role; a tap on touch only follows it.

Keyboard

3 keys
Enter, Space
On the trigger: opens and closes the popover.
Escape
Closes it and returns focus to the trigger.
Tab
Moves into the popover's controls, then on to the page after the trigger.

Edge cases

5 edge cases
Near a viewport edge
It flips to the other side or shifts to stay 8px inside.
Taller than the screen
It stops at the available height and scrolls inside.
Touch
A hover preview never opens; a tap follows the link.
Phone, 390 wide
It narrows to the available width less 8px each side.
Reduced motion
It cuts in and out.

API

6 props
Popover modal
boolean default false
PopoverTrigger openOnHover
boolean default false
PopoverTrigger delay, closeDelay
number default 600, 300
PopoverContent side, align
Base UI default 'bottom', 'center'
PopoverInfo title, label
ReactNode, string
PopoverInfo children
ReactNode

Tokens

16 tokens
--panel
#fafaf7
--line
#e2dfd5
--popover
288px
--space-4
16px
--type-label
400 13px/16px var(--font-mono)
--type-label-sm
400 12px/16px var(--font-mono)
--type-body-sm
400 14px/20px var(--font-sans)
--text-1
#161512
--text-2
#55524a
--hover
rgb(22 21 18 / 0.04)
--pressed
rgb(22 21 18 / 0.08)
--overlay-shift
4px
--z-overlay
50
--dur-overlay
160ms
--dur-state
120ms
--ease-out
cubic-bezier(0.2, 0.8, 0.2, 1)

Install

For your coding agent

GitHub

Please star me pookie

198

A new design system every week

Leave your email before you copy the prompt.