Tooltip
Contextual helper text that appears on hover or focus.
npx shadcn@latest add @aavya/ui-tooltip
One-time setup — add the @aavya registry to your components.json so branded dependencies resolve to Aavya (not stock shadcn):
"registries": { "@aavya": "https://registry-dev.aavya.com/r/{name}.json" }Or install by full URL: npx shadcn@latest add https://registry-dev.aavya.com/r/ui-tooltip.json
Tooltip forwards remaining props to TooltipPrimitive.Root props.
Do
- Use a tooltip for a brief, supplementary hint on an already-labelled control.
- Keep it to a few words; it shows on hover and on keyboard focus.
- Attach it to a focusable element.
Don’t
- Don't put essential information or actions in a tooltip — it's unreachable on touch and vanishes.
- Don't use a tooltip as the only label for an icon button — give the button an aria-label too.
- Don't make tooltip content interactive.
Role
tooltip, shown on hover and keyboard focus (handled by Radix).
Keyboard
Appears on focus; Esc dismisses. (handled)
Screen reader
Associated with its trigger via aria-describedby. It supplements — not replaces — an accessible name; you still provide the trigger's label.
Focus
The trigger must be focusable for keyboard users to see it. (handled when the trigger is a real control)
Gotcha
Tooltips don't appear on touch and aren't a reliable label — never hide an icon button's only name in a tooltip; add an aria-label.
import { Tooltip } from '@/components/ui/tooltip'
export default function Example() {
return (
<div className="p-6">
<Tooltip />
</div>
)
}
'use client'
import * as React from 'react'
import * as TooltipPrimitive from '@radix-ui/react-tooltip'
import { cn } from '@/lib/utils'
function TooltipProvider({ delayDuration = 0, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
return <TooltipPrimitive.Provider data-slot='tooltip-provider' delayDuration={delayDuration} {...props} />
}
function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {
return (
<TooltipProvider>
<TooltipPrimitive.Root data-slot='tooltip' {...props} />
</TooltipProvider>
)
}
function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
return <TooltipPrimitive.Trigger data-slot='tooltip-trigger' {...props} />
}
function TooltipContent({
className,
sideOffset = 0,
children,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
return (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
data-slot='tooltip-content'
sideOffset={sideOffset}
className={cn(
'bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin