Tooltip
A floating label that appears on hover or focus to provide supplemental context for a trigger element.
Uses role="tooltip" on the popover surface; the trigger receives aria-describedby pointing to the tooltip content.
Preview
tsx
import { Button, Tooltip, TooltipProvider } from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<TooltipProvider>
<Tooltip content="Save your changes">
<Button>Save</Button>
</Tooltip>
</TooltipProvider>
);
}
Variants
Section titled “Variants”Placement
Section titled “Placement”Use side to control which edge the tooltip appears on: top (default), right, bottom, or left.
Preview
tsx
import { Button, Tooltip, TooltipProvider } from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<TooltipProvider>
<div
style={{
display: 'flex',
flexWrap: 'wrap',
gap: '0.75rem',
justifyContent: 'center',
padding: '2rem',
}}
>
<Tooltip content="Tooltip on top" side="top">
<Button variant="outline">Top</Button>
</Tooltip>
<Tooltip content="Tooltip on right" side="right">
<Button variant="outline">Right</Button>
</Tooltip>
<Tooltip content="Tooltip on bottom" side="bottom">
<Button variant="outline">Bottom</Button>
</Tooltip>
<Tooltip content="Tooltip on left" side="left">
<Button variant="outline">Left</Button>
</Tooltip>
</div>
</TooltipProvider>
);
}
Rich content
Section titled “Rich content”Pass any ReactNode to content for multi-line or formatted tooltips.
Preview
tsx
import { Button, Tooltip, TooltipProvider } from '@arshad-shah/cynosure-react';
function RichContent() {
return (
<div style={{ maxWidth: '16rem' }}>
<p style={{ margin: '0 0 0.25rem', fontWeight: 600 }}>Keyboard shortcut</p>
<p style={{ margin: 0, opacity: 0.85 }}>
Press <kbd style={{ fontFamily: 'monospace' }}>⌘ S</kbd> to save at any time.
</p>
</div>
);
}
export default function Example() {
return (
<TooltipProvider>
<Tooltip content={<RichContent />} side="right" withArrow>
<Button variant="outline">Hover for details</Button>
</Tooltip>
</TooltipProvider>
);
}
PropTypeDefaultDescription
content*
ReactNode
—
The tip body. Plain string or arbitrary `ReactNode`.
children*
ReactElement<unknown, string | JSXElementConstructor<any>>
—
The trigger — must be a single React element. The Tooltip composes onto it.
side
"top"|"right"|"bottom"|"left"
top
Preferred placement relative to the trigger. Flips to the opposite
side when there isn't room on the preferred side.
align
"start"|"center"|"end"
center
Alignment along the chosen side.
sideOffset
number
6
Distance (in px) between the trigger and the tooltip surface.
alignOffset
number
0
Offset (in px) along the alignment axis.
delayMs
number
—
Open delay in ms — time the pointer must rest on the trigger before
the tooltip appears. Falls back to the provider's `delayDuration`.
disabled
boolean
false
Disable the tooltip and render the child unwrapped (no portal, no
listeners).
open
boolean
—
Controlled open state; pair with `onOpenChange`.
defaultOpen
boolean
—
Initial open state in uncontrolled mode.
onOpenChange
((open: boolean) => void)
—
Change handler for the open state.
withArrow
boolean
true
Render the caret arrow pointing at the trigger.
className
string
—
Forward a `className` onto the content element.
container
HTMLElement|(() => HTMLElement)
—
Portal target — defaults to `document.body`.
Accessibility
Section titled “Accessibility”- The tooltip is announced via
role="tooltip"andaria-describedby— supplemental, non-essential context only. - The trigger receives focus and keyboard events; the tooltip opens on focus or hover with a configurable
delayMs. - Do not put interactive elements (links, buttons) inside tooltip content — use a
Popoverinstead. - Icon-only buttons must have an accessible label via
IconButton label="…"independently of the tooltip.
Recipes
Section titled “Recipes”- Wrap
TooltipProvidernear the app root to sharedelayDurationandskipDelayDurationacross all tooltips. - Use
disabledto suppress the tooltip conditionally without changing the tree structure. - Use
withArrow={false}for a flat, borderless tooltip style. - Combine with
align="start"oralign="end"to fine-tune horizontal alignment along the chosen side.