Tooltip
A Base UI Tooltip that names an icon-only control or gives a brief, non-essential hint, on the overlay scope's face.
import {
Tooltip,
TooltipPopup,
TooltipProvider,
TooltipTrigger,
} from '@fairgarden-private/design/components/Tooltip'
It opens on hover after 500 ms (--ds-delay-tooltip) and on keyboard focus, appears instantly with no fade, stays open while the pointer moves onto it, and Esc dismisses it. The popup is one short line of caption text in a --border-size-2 frame, at most 280 px wide. Touch screens never show it, and it never prints, so never put links, actions or required information in a tooltip.
Label, hint and term
Label, hint and term
kind="label" (default) wraps your control through render; its text equals the control's accessible name. kind="hint" draws the Material help glyph beside a label, with the children as its hidden name. kind="term" underlines a term in line-dotted-fine; its definition must also exist as a footnote. A TooltipProvider lets neighbors open at once.
Membership tier
The parcel is protected by a held by the trust.
import {
Tooltip,
TooltipPopup,
TooltipProvider,
TooltipTrigger,
} from '@fairgarden-private/design/components/Tooltip'
import { Button } from '@fairgarden-private/design/components/Button'
import styles from './variants.module.css'
/**
* The three trigger forms: a label on icon-only buttons (sharing one
* Provider, so neighbors open at once), a `help` hint beside a label, and a
* dotted-underline term in running text.
*/
export function TooltipVariants() {
return (
<div className={styles.stack}>
<TooltipProvider>
<div className={styles.row}>
<Tooltip>
<TooltipTrigger render={<Button iconOnly icon="zoom_in">Zoom In</Button>} />
<TooltipPopup>Zoom In</TooltipPopup>
</Tooltip>
<Tooltip>
<TooltipTrigger render={<Button iconOnly icon="zoom_out">Zoom Out</Button>} />
<TooltipPopup>Zoom Out</TooltipPopup>
</Tooltip>
<Tooltip>
<TooltipTrigger render={<Button iconOnly icon="recenter">Reset View</Button>} />
<TooltipPopup>Reset View</TooltipPopup>
</Tooltip>
</div>
</TooltipProvider>
<p className={styles.copy}>
Membership tier{' '}
<Tooltip>
<TooltipTrigger kind="hint">About membership tiers</TooltipTrigger>
<TooltipPopup>Tiers renew each spring.</TooltipPopup>
</Tooltip>
</p>
<p className={styles.copy}>
The parcel is protected by a{' '}
<Tooltip>
<TooltipTrigger kind="term">conservation easement</TooltipTrigger>
<TooltipPopup side="bottom">A legal limit on development that stays with the deed.</TooltipPopup>
</Tooltip>{' '}
held by the trust.
</p>
</div>
)
}
Primary scale
Primary scale
The popup is a portaled overlay scope: it takes only the props passed to TooltipPopup and never inherits the trigger's scales.
import {
Tooltip,
TooltipPopup,
TooltipProvider,
TooltipTrigger,
} from '@fairgarden-private/design/components/Tooltip'
import { Button } from '@fairgarden-private/design/components/Button'
import styles from './color.module.css'
/**
* The popup takes only the props passed to it: `primary` recolors its frame
* and text, never the trigger's scales.
*/
export function TooltipColor() {
return (
<TooltipProvider>
<div className={styles.row}>
<Tooltip>
<TooltipTrigger render={<Button iconOnly icon="download">Download Map</Button>} />
<TooltipPopup>Overlay default</TooltipPopup>
</Tooltip>
<Tooltip>
<TooltipTrigger render={<Button iconOnly icon="download">Download Map</Button>} />
<TooltipPopup primary="plum">Primary plum</TooltipPopup>
</Tooltip>
</div>
</TooltipProvider>
)
}
On grounds
On paper and forest
paper
Trail grade
A sits at the center.
forest
Trail grade
A sits at the center.
import {
Tooltip,
TooltipPopup,
TooltipProvider,
TooltipTrigger,
} from '@fairgarden-private/design/components/Tooltip'
import { PresetGround } from '@/components/PresetGround'
import styles from './grounds.module.css'
const presets = ['paper', 'forest'] as const
/** The hint glyph and term underline follow the trigger's ground; the popup face is always the overlay scope. */
export function TooltipGrounds() {
return (
<div className={styles.row}>
{presets.map((preset) => (
<PresetGround key={preset} preset={preset} className={styles.face}>
<p className={styles.name}>{preset}</p>
<p className={styles.copy}>
Trail grade{' '}
<Tooltip>
<TooltipTrigger kind="hint">About trail grades</TooltipTrigger>
<TooltipPopup>Grades run from easy to strenuous.</TooltipPopup>
</Tooltip>
</p>
<p className={styles.copy}>
A{' '}
<Tooltip>
<TooltipTrigger kind="term">kettle pond</TooltipTrigger>
<TooltipPopup>A pond left by a melting glacier.</TooltipPopup>
</Tooltip>{' '}
sits at the center.
</p>
</PresetGround>
))}
</div>
)
}
API Reference
TooltipProvider and Tooltip
Shares the open delay across a group of triggers, such as a toolbar: the
first tooltip opens after --ds-delay-tooltip (500 ms), its neighbors
open at once while one is showing.
One tooltip: a TooltipTrigger and a TooltipPopup. It opens on hover
after 500 ms and on keyboard focus, appears instantly, stays open while the
pointer moves onto it, and Esc dismisses it without moving focus. Touch
screens never show it, so the trigger must make sense without it. It never
prints: definitions behind terms must also exist as footnotes.
TooltipTrigger
The element the tooltip names. With kind="label", pass the control as
render, e.g. render={<Button iconOnly icon="search">Search</Button>}.
The hint glyph and the term underline follow the trigger’s own ground.
| Prop | Type | Description |
|---|---|---|
kind | |
|
TooltipPopup
The popup: one short line of type-caption (three at most), at most
--ds-size-tooltip (280 px) wide, on the overlay scope’s --primary1 face inside a
--border-size-2 --primary12 frame with --radius-1. It sits
--size-px-2 from the trigger (side, default top) and flips or shifts
to stay inside the viewport.
| Prop | Type | Description |
|---|---|---|
portalProps | | Props for the Base UI Portal, such as |
primary | | Primary Radix scale inside the popup’s scope: face, edge and text. Omitted, the overlay scope’s default applies; the popup never inherits the trigger’s scales. |
secondary | | Secondary Radix scale inside the popup’s scope; no part uses it. |
Additional types
TOOLTIP_DELAY_MS
type TOOLTIP_DELAY_MS = 500TooltipPopupProps
Props for TooltipPopup: Base UI Tooltip Popup props plus placement and the color axes.
type TooltipPopupProps = TooltipPopupProps &
Pick<TooltipPositionerProps, 'side' | 'align'> & {
primary?:
| 'ruby'
| 'olive'
| 'sage'
| 'slate'
| 'sand'
| 'gray'
| 'mauve'
| 'brown'
| 'bronze'
| 'gold'
| 'red'
| 'crimson'
| 'tomato'
| 'pink'
| 'plum'
| 'indigo'
| 'iris'
| 'violet'
| 'purple'
| null;
secondary?:
| 'ruby'
| 'olive'
| 'sage'
| 'slate'
| 'sand'
| 'gray'
| 'mauve'
| 'brown'
| 'bronze'
| 'gold'
| 'red'
| 'crimson'
| 'tomato'
| 'pink'
| 'plum'
| 'indigo'
| 'iris'
| 'violet'
| 'purple'
| 'amber'
| 'blue'
| 'cyan'
| 'grass'
| 'green'
| 'jade'
| 'lime'
| 'mint'
| 'orange'
| 'sky'
| 'teal'
| 'yellow'
| null;
portalProps?: Omit<TooltipPortalProps, 'children'>;
}TooltipProps
Props for Tooltip: Base UI Tooltip Root props.
type TooltipProps<Payload = unknown> = TooltipRoot.Props<Payload>TooltipProviderProps
Props for TooltipProvider: Base UI Tooltip Provider props.
type TooltipProviderProps = TooltipProvider.TooltipProviderPropstooltipTrigger
type tooltipTrigger = tooltipTriggerTooltipTriggerKind
type TooltipTriggerKind = 'label' | 'hint' | 'term'<'label' | 'hint' | 'term' | null | undefined>Specification: DESIGN-SYSTEM.md §10.16 (tooltip) and §10.1 (the overlay surface).