pnpm dlx @glinui/cli@latest add tooltipHover or focus a button to see its name and shortcut.
Installation
pnpm dlx @glinui/cli@latest add tooltipPrefer the package?
Usage
Sides
Tooltips on all four sides, plus an explanation on a disabled action.
"use client"
import { DownloadSimple } from "@phosphor-icons/react"import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "@glinui/ui"
export function TooltipSidesExample() { return ( <TooltipProvider delayDuration={100}> <div className="mx-auto flex flex-wrap items-center justify-center gap-3 py-8"> {(["top", "right", "bottom", "left"] as const).map((side) => ( <Tooltip key={side}> <TooltipTrigger asChild><Button variant="outline" size="sm">{side}</Button></TooltipTrigger> <TooltipContent side={side}>{`Opens on the ${side}`}</TooltipContent> </Tooltip> ))} <Tooltip> <TooltipTrigger asChild><Button size="sm" disabled aria-label="Export, unavailable"><DownloadSimple aria-hidden="true" />Export</Button></TooltipTrigger> <TooltipContent>Export is unavailable on the free plan</TooltipContent> </Tooltip> </div> </TooltipProvider> )}Variants
Every look of the shared vocabulary: glinr (the default), plain (shadcn), solid, soft, outline, ghost, gradient and glass. Omit `variant` to follow the ambient design style. The default tooltip is a compact high-contrast pill that inverts per theme scope.
import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@glinui/ui"
const variants = ["glinr", "plain", "solid", "soft", "outline", "ghost", "gradient", "glass"] as const
export function Demo() { return ( <TooltipProvider delayDuration={0}> <div className="flex flex-wrap gap-2"> {variants.map((variant) => ( <Tooltip key={variant}> <TooltipTrigger asChild><Button size="sm" variant="outline">{variant}</Button></TooltipTrigger> <TooltipContent variant={variant}>{variant} tooltip</TooltipContent> </Tooltip> ))} </div> </TooltipProvider> )}Glass (opt-in)
variant="glass" is opt-in. It blurs and tints what sits behind the panel (with a readable opacity floor), so it needs a colourful or photographic backdrop: switch the stage backdrop to see it.
import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@glinui/ui"
export function Demo() { return ( <TooltipProvider delayDuration={0}> <Tooltip> <TooltipTrigger asChild><Button variant="outline">Hover me</Button></TooltipTrigger> <TooltipContent variant="glass">Frosted tooltip</TooltipContent> </Tooltip> </TooltipProvider> )}Custom Delay
Override the open delay per-tooltip by passing `delayDuration` to the `Tooltip` root. A delay of `0` opens instantly.
import { Button } from "@glinui/ui"
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from "@glinui/ui"
export function TooltipDelayDemo() {
return (
<TooltipProvider>
<div className="flex items-center gap-4">
<Tooltip delayDuration={0}>
<TooltipTrigger asChild>
<Button variant="outline" size="sm">Instant</Button>
</TooltipTrigger>
<TooltipContent>
<p>Opens immediately (0 ms)</p>
</TooltipContent>
</Tooltip>
<Tooltip delayDuration={700}>
<TooltipTrigger asChild>
<Button variant="outline" size="sm">Delayed</Button>
</TooltipTrigger>
<TooltipContent>
<p>Opens after 700 ms</p>
</TooltipContent>
</Tooltip>
</div>
</TooltipProvider>
)
}Side Positioning
Use `side` on `TooltipContent` to anchor the hint above, below, left, or right of the trigger. The tooltip auto-adjusts to avoid viewport clipping.
import { Button } from "@glinui/ui"
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from "@glinui/ui"
export function TooltipSideDemo() {
return (
<TooltipProvider>
<div className="flex items-center justify-center gap-4">
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="sm">Top</Button>
</TooltipTrigger>
<TooltipContent side="top">
<p>Top tooltip</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="sm">Right</Button>
</TooltipTrigger>
<TooltipContent side="right">
<p>Right tooltip</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="sm">Bottom</Button>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>Bottom tooltip</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="sm">Left</Button>
</TooltipTrigger>
<TooltipContent side="left">
<p>Left tooltip</p>
</TooltipContent>
</Tooltip>
</div>
</TooltipProvider>
)
}Accessibility
- Built on Radix Tooltip with `role="tooltip"`.
- Shows on hover and focus.
- TooltipProvider wraps the usage context.
- Built on Radix Tooltip; the content is linked via `aria-describedby` on the trigger automatically.
- Tooltip opens on focus as well as hover, ensuring keyboard users receive the same context hints.
- Do not place interactive elements (buttons, links) inside `TooltipContent`, use a Popover for that pattern.
- Keep tooltip text to a single short phrase. For longer explanations, prefer an inline description.
Keyboard Interactions
| Key | Action |
|---|---|
| Escape | Dismiss the tooltip when focused. |
ARIA Attributes
- `role="tooltip"`
- `aria-describedby` linking trigger to tooltip content
Reduced Motion
Show/hide transitions respect `prefers-reduced-motion`.
Tooltip fade and scale transitions respect `prefers-reduced-motion`. When enabled, the content appears instantly without animation.
Affected properties
opacitytransformAPI Reference
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
variant | "glinr" | "plain" | "solid" | "soft" | "outline" | "ghost" | "gradient" | "glass" | - | ambient style (glinr) | TooltipContent look. Omit it for a compact high-contrast pill that inverts per theme scope (dark in light, light in dark). `glass` is opt-in and needs a backdrop. Legacy `default` follows the ambient style, `frosted` maps to `glass`. |
sideOffset | number | - | 6 | Distance from trigger in pixels. |
delayDuration | number | No | 700 | Delay before showing (ms). |
side | "top" | "right" | "bottom" | "left" | - | - | Preferred tooltip position. |
defaultOpen | boolean | No | - | Initial open state for uncontrolled usage. |
onOpenChange | (open: boolean) => void | No | - | Callback when open state changes. |
open | boolean | No | - | Controlled open state. |
Source
Import directly from the package or browse the source on GitHub. Click any file to view it.
Generated API Snapshot
Beta
Generated API Snapshot
BetaAuto-extracted from TypeScript source in packages/ui/src/components/tooltip.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.
Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata
Primary Props Type
TooltipProps
TooltipContentProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
container | HTMLElement | null | No | - | Element to portal into. Defaults to document.body. |
side | "top" | "right" | "bottom" | "left" | No | - | Preferred side for tooltip content. |
sideOffset | number | No | 6 | Gap in px between trigger and content. |
variant | PanelVariantProp | No | - | Surface look. Omit for the ambient design style: a compact high-contrast pill that inverts per theme scope (dark pill in light, light pill in dark). `glass` is opt-in and needs a rich backdrop. |
TooltipProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
defaultOpen | boolean | No | - | Initial open state for uncontrolled usage. |
delayDuration | number | No | - | Delay in ms before showing tooltip content. |
onOpenChange | (open: boolean) => void | No | - | Callback when open state changes. |
open | boolean | No | - | Controlled open state. |