Tooltip
Tooltips show a short description of a control on hover or keyboard focus.
import { Tooltip } from '@aksornproject/aksara-ui'Basic tooltip
Tooltip is a namespace of five parts. Root holds the state, Trigger is the control, Portal draws the floating bubble, and Title and Content fill it.
Trigger renders a <button> with reset classes and opens the tooltip after a 300ms hover. delay changes that. disabled on the Trigger turns off the tooltip, not the control.
The bubble is black, at most 200px wide and 4px from the trigger. It has an arrow by default. Pass withArrow={false} for a plain bubble, as in this demo.
<Tooltip.Root>
<Tooltip.Trigger
aria-label="About late submissions"
className="inline-flex size-size-size-44 items-center justify-center text-color-icon-primary"
>
<IconInterfaceEssentialInfoInformationCircle size={20} aria-hidden />
</Tooltip.Trigger>
<Tooltip.Portal withArrow={false}>
<Tooltip.Content>
Work handed in after the deadline loses 10% per day.
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>Placement
placement picks the side, top by default. align picks the edge, center by default. The popup flips and shifts at the edge of the viewport.
render on the Trigger swaps the <button> for your own control, here a Button. A render target keeps its own styles.
{placements.map((placement) => (
<Tooltip.Root key={placement}>
<Tooltip.Trigger render={<Button variant="secondary-accent" />}>
{placement}
</Tooltip.Trigger>
<Tooltip.Portal placement={placement} align="start" withArrow={false}>
<Tooltip.Content>Opens on the {placement}</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
))}Title and colour
variant on Portal is black, the default, or white. The white bubble has a surface fill and a border. Title adds a semibold line above Content. Content takes the Portal variant unless it sets its own.
<Tooltip.Root>
<Tooltip.Trigger render={<Button variant="secondary-accent" />}>
Black
</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Title>Auto-save</Tooltip.Title>
<Tooltip.Content>Drafts save every 30 seconds.</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
<Tooltip.Root>
<Tooltip.Trigger render={<Button variant="secondary-accent" />}>
White
</Tooltip.Trigger>
<Tooltip.Portal variant="white" placement="bottom">
<Tooltip.Title>Auto-save</Tooltip.Title>
<Tooltip.Content>Drafts save every 30 seconds.</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>Long content
The popup is not hoverable by default, so the pointer cannot move onto it. Pass disableHoverablePopup={false} on Root when the content is long.
The bubble caps its width at 200px. A wider className on Portal also needs max-w-none, as here.
<Tooltip.Root disableHoverablePopup={false}>
<Tooltip.Trigger render={<Button variant="secondary-accent" />}>
Grading policy
</Tooltip.Trigger>
<Tooltip.Portal withArrow={false} className="w-[320px] max-w-none">
<Tooltip.Content>
Quizzes count for 20% of the final grade, homework for 30% and the
end-of-term exam for 50%. Late work loses 10% per day.
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>Accessibility
- The popup has
role="tooltip". While it is open, the trigger'saria-describedbypoints at it. - Hover opens after the delay. Keyboard focus opens it only on
:focus-visible. Escape closes it and keeps the focus. - Touch does not open a tooltip.
- An icon-only trigger needs an
aria-label. The tooltip becomes its description, not its name. - Content is descriptive only. Use a popover for links and buttons.
- The popup portals to
body. Put theme and scale attributes onhtmlso it inherits them.
API
Tooltip.Root
Prop
Type
Tooltip.Trigger
Prop
Type
Tooltip.Portal
Prop
Type
Tooltip.Title
Title takes the attributes and the ref of a div. className merges last.
Tooltip.Content
Prop
Type