Popover
Popover opens a small panel next to its trigger with richer content than a tooltip. Use it for previews, definitions and quick settings.
Beta until design adds a popover to Figma. The component is code-only: its surface comes from the menus and its arrow from the tooltip. Everything on this page is implemented and tested.
Preview
Change the controls, then select the underlined term. The popover opens on click, not on hover.
Plants capture light with .
import { LinkButton, Popover, PopoverContent, PopoverTrigger } from '@nuton/ui'
<Popover>
<PopoverTrigger asChild>
<LinkButton tone="black" underline>chlorophyll</LinkButton>
</PopoverTrigger>
<PopoverContent
title="Chlorophyll"
description="Biology · Glossary"
>
<p>The green pigment in plants that absorbs light for photosynthesis.</p>
</PopoverContent>
</Popover>Installation
Availability
@nuton/ui and @nuton/tokens are private workspace packages and aren't published yet (D4, D12). Inside the Nuton monorepo, add them as workspace dependencies.
pnpm add @nuton/ui @nuton/tokens @remixicon/reactnpm install @nuton/ui @nuton/tokens @remixicon/reactyarn add @nuton/ui @nuton/tokens @remixicon/reactimport '@nuton/tokens/tokens.css'
import '@nuton/ui/styles.css'Usage
import { Button, Popover, PopoverContent, PopoverTrigger } from '@nuton/ui'
<Popover>
<PopoverTrigger asChild><Button appearance="stroke">Source 1</Button></PopoverTrigger>
<PopoverContent title="Campbell Biology, chapter 10" description="Photosynthesis · page 187">
<p>The light reactions convert solar energy to chemical energy.</p>
</PopoverContent>
</Popover>- The trigger must be a button. Use
asChildwith a Button or LinkButton so it is focusable and announces its expanded state. - Give it a
title; it names the popover. Without one, passaria-label. - Keep content short. If it needs scrolling, forms or several steps, use a Sheet or Modal.
- For a short label on hover, use a Tooltip. For a list of commands, use a Dropdown menu.
Variants and sizes
Two widths, an optional arrow, and any side and alignment. The popover flips or shifts to stay on screen.
Sizes
| Size | Width | Use for |
|---|---|---|
sm (default) | 280 (the menu minimum width) | Glossary terms, short notes, quick settings |
md | 360 | Source and citation previews |
Anatomy and measurements
| Part | Measurement |
|---|---|
| Surface | Bg/White, 1px Stroke/Soft-200, radius 16, regular-shadow/medium (as menus); padding 16, gap 12 (code-only) |
| Title · description | Label/Small Strong-950 · Paragraph/Small Sub-600, 4 apart |
| Body | Paragraph/Small, items 12 apart |
| Close | 24 × 24 target with a 16px icon, 12 from the top and end, centred on the title line |
| Arrow | 12 × 6 (the Tooltip tail), at least 16 from a corner; 4px gap to the trigger plus the arrow |
States and interactions
Chlorophyll
The green pigment that absorbs light.
Playback speed
No close button: Escape and an explicit Done close it.
showClose={false}. Escape and a click outside always close it.State tokens
Set on .nu-popover: --nu-popover-width, --nu-popover-pad, --nu-popover-close-size and --nu-popover-bg (also used by the arrow fill).
Code-only component
Figma has no popover. The surface, arrow and close button reuse the menu, tooltip and alert specs. Padding 16, the two widths and the focus ring are code-only and need design review.
Composition examples
Citation preview in an AI Tutor answer
Quick settings
API reference
PopoverContent props
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | — | Heading (h2, Label/Small). Names the popover with aria-labelledby. |
description | ReactNode | — | Text under the title (Sub-600). Wired to aria-describedby. |
size | 'sm' | 'md' | 'sm' | 280 or 360 wide; shrinks to fit the screen. |
arrow | boolean | false | Shows the 12 × 6 pointer. A popover with an arrow does not scroll, so keep it short. |
showClose | boolean | true | Shows the close button in the top corner. |
closeLabel | string | 'Close' | Accessible name of the close button. |
side · align | 'top' | 'right' | 'bottom' | 'left' · 'start' | 'center' | 'end' | 'bottom' · 'center' | Preferred placement. It flips or shifts to stay on screen. |
sideOffset · collisionPadding | number | 4 (+6 with arrow) · 8 | Distance from the trigger and from the screen edge. |
container | HTMLElement | — | Portal container. Defaults to document.body. |
…Radix props | Popover.Content | — | onEscapeKeyDown, onOpenAutoFocus, aria-label and others. The ref points at the panel. |
Popover takes open, defaultOpen, onOpenChange and modal. PopoverTrigger, PopoverClose and PopoverAnchor take asChild.
Accessibility
Keyboard
| Key | Behaviour |
|---|---|
| Enter / Space | Opens or closes it from the trigger |
| Tab | Moves through the content; leaving it keeps it open |
| Esc | Closes it and returns focus to the trigger |
Screen readers
The trigger announces its expanded state and controls the panel. The panel is a non-modal dialog named by its title and described by its description.
Focus
Focus moves into the panel on open and back to the trigger on close. The close button is last in the tab order and shows a 2px primary ring.
Contrast and colour
Title 17.93:1 and description 6.69:1 on white. The 1px border and shadow separate it from the page; forced-colours mode draws a system border.
Touch and pointer
Opens on tap or click, never on hover alone. The close button is 24 × 24 (WCAG 2.5.8); a tap outside also closes it.
You must: use a real button as the trigger, and give the popover a title or an aria-label.
Guidelines and related components
Use Popover for
- Previewing a source or citation
- Defining a glossary term in a lesson
- A few quick settings
Don't use Popover for
- Short labels on hover (use Tooltip)
- Lists of commands (use Dropdown menu)
- Long forms or tasks (use Sheet or Modal)
Do and don't
Chlorophyll
The green pigment that absorbs light for photosynthesis.
Create a space
Name, subject, members, privacy, cover image, description…
Campbell Biology, ch. 10
Photosynthesis · page 187
Opens when you point at the word…