Tooltip
Short label on hover or keyboard focus, also wired as the trigger's aria-describedby. Warm-up: once one opens, neighbors open instantly. Hoverable, Esc dismisses, ignores touch.
Hover one, then slide across: the rest open instantly.
import { Bold, Italic } from "lucide-react";import { Button } from "@/components/ui/button";import { Tooltip } from "@/components/ui/tooltip";export function FormatToolbar() { return ( <div className="flex gap-1"> <Tooltip content="Bold ⌘B"> <Button variant="ghost" size="icon" aria-label="Bold"> <Bold /> </Button> </Tooltip> <Tooltip content="Italic ⌘I"> <Button variant="ghost" size="icon" aria-label="Italic"> <Italic /> </Button> </Tooltip> </div> );}<Tooltip>
Hover/keyboard-focus label for one element. Stays open while the pointer is on it (WCAG 1.4.13), Esc dismisses. On touch: touch and hold shows it, or a tap with touch="tap".
children*ReactNodeOne focusable element, e.g. an icon Button with an aria-label.
content*ReactNodeShort text. Also becomes the trigger's accessible description.
aligndefault"center""start" | "center" | "end"Alignment with the trigger.
delaydefault500numberHover delay in ms before the first tooltip opens (default 500).
sidedefault"top""top" | "bottom"Preferred side; flips when there is no room.
touchdefault"press""press" | "tap"How touch opens it:
press(touch and hold; a tap still reaches the control) ortap(a tap toggles it, for triggers with no action of their own).
| Prop | Type | Default |
|---|---|---|
children*One focusable element, e.g. an icon Button with an aria-label. | ReactNode | — |
content*Short text. Also becomes the trigger's accessible description. | ReactNode | — |
alignAlignment with the trigger. | "start" | "center" | "end" | "center" |
delayHover delay in ms before the first tooltip opens (default 500). | number | 500 |
sidePreferred side; flips when there is no room. | "top" | "bottom" | "top" |
touchHow touch opens it: | "press" | "tap" | "press" |
* required. Every component also takes className.