ComponentsTooltip
Tooltip
Show a short hint when users hover over or focus a control.
On this page
Use this component from the local workspace package. Follow the setup guide first. A public npm package and registry are not available yet.
View registry filesImport the component into your page or component file.
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@dethink/components";Try the examples, then open the code to use them in your app. Tab to a trigger — tooltips show on focus too.
Basic
An icon-only trigger keeps its aria-label; the tooltip adds the visible hint.
Show sourceexamples/tooltip/basic.tsx
"use client";
import { Tooltip, TooltipContent, TooltipTrigger } from "@dethink/components";
import { RefreshCw } from "lucide-react";
export function TooltipBasic() {
return (
<div className="flex justify-center">
<Tooltip>
<TooltipTrigger
aria-label="Refresh dashboard"
size="icon"
variant="outline"
>
<RefreshCw className="size-4" aria-hidden="true" />
</TooltipTrigger>
<TooltipContent>Refresh dashboard data</TooltipContent>
</Tooltip>
</div>
);
}Timing and placement
delay and closeDelay tune hover intent; placement and showArrow position the hint.
Show sourceexamples/tooltip/timing.tsx
"use client";
import { Tooltip, TooltipContent, TooltipTrigger } from "@dethink/components";
export function TooltipTiming() {
return (
<div className="flex flex-wrap justify-center gap-3">
<Tooltip delay={0} closeDelay={0}>
<TooltipTrigger variant="soft" size="sm">
Instant
</TooltipTrigger>
<TooltipContent>Shows immediately</TooltipContent>
</Tooltip>
<Tooltip delay={700} closeDelay={300}>
<TooltipTrigger variant="soft" size="sm">
Patient
</TooltipTrigger>
<TooltipContent>700ms open delay, 300ms close delay</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger variant="soft" size="sm">
Placed top
</TooltipTrigger>
<TooltipContent placement="top" showArrow>
Anchored above with an arrow
</TooltipContent>
</Tooltip>
</div>
);
}Examples that combine components for common tasks.
Formatting toolbar with shortcut hints
Tooltips in their strongest seat: an icon-only toolbar where each hint pairs the action name with its keyboard shortcut, while aria-label and aria-pressed keep the buttons fully accessible without the tooltip.
Show sourceexamples/tooltip/recipe-toolbar.tsx
"use client";
import { useState } from "react";
import { Tooltip, TooltipContent, TooltipTrigger } from "@dethink/components";
import { Bold, Italic, Link2, Strikethrough } from "lucide-react";
const tools = [
{ id: "bold", label: "Bold", keys: "⌘B", icon: Bold },
{ id: "italic", label: "Italic", keys: "⌘I", icon: Italic },
{ id: "strike", label: "Strikethrough", keys: "⌘⇧X", icon: Strikethrough },
{ id: "link", label: "Add link", keys: "⌘K", icon: Link2 },
];
/**
* Icon-only toolbars are where tooltips earn their keep: each trigger keeps
* a real aria-label (the tooltip is a hint, not the accessible name) and the
* content pairs the label with its keyboard shortcut.
*/
export function TooltipRecipeToolbar() {
const [active, setActive] = useState<Set<string>>(new Set(["bold"]));
return (
<div
role="toolbar"
aria-label="Text formatting"
className="border-border bg-muted/40 mx-auto flex w-fit gap-1 rounded-lg border p-1"
>
{tools.map((tool) => (
<Tooltip key={tool.id} delay={300}>
<TooltipTrigger
aria-label={tool.label}
aria-pressed={active.has(tool.id)}
size="icon"
variant={active.has(tool.id) ? "soft" : "ghost"}
onClick={() =>
setActive((current) => {
const next = new Set(current);
if (next.has(tool.id)) {
next.delete(tool.id);
} else {
next.add(tool.id);
}
return next;
})
}
>
<tool.icon className="size-4" aria-hidden="true" />
</TooltipTrigger>
<TooltipContent placement="top">
<span className="flex items-center gap-2">
{tool.label}
<kbd className="border-border/60 rounded border px-1 font-mono text-[0.7em]">
{tool.keys}
</kbd>
</span>
</TooltipContent>
</Tooltip>
))}
</div>
);
}Tooltip coordinates timing; the trigger is a real Button and the content carries placement.
| Prop | What it does | Default |
|---|---|---|
delay / closeDelaynumber (ms) | Hover intent timing before showing and hiding. | library defaults |
open / onOpenChangeboolean / (open) => void | Controlled visibility for programmatic tooltips. | Not set |
disabledboolean | Suppresses the tooltip without disabling the trigger. | false |
TooltipTriggervariant + size (Button API) | A real button trigger — keep the accessible name on the trigger (aria-label); the tooltip is a hint, not the name. | Not set |
TooltipContent — placement"top" | "bottom" | "left" | "right" (+ alignment) | Preferred side relative to the trigger. | "top" |
TooltipContent — showArrowboolean | Renders a pointing arrow. | false |