Overlays
Tooltip
Label curto e não-essencial que aparece em hover/focus.
Overview
Tooltip é o overlay mais leve do KDS — um pequeno balão com texto
breve, ancorado ao trigger, mostrado em hover e focus. Reserve para
informação não-essencial: rótulos de ícones, atalhos de teclado,
lembretes do que um controle faz.
A regra de ouro: se a informação for crítica, não pode estar num tooltip. Touch users não conseguem fazer hover. Keyboard users só veem o tooltip quando o foco está no trigger. Conteúdo essencial fica visível na layout.
Preview
Tooltip em um botão de ícone.
Anatomy
<TooltipProvider> ← envolve o app
<Tooltip>
<TooltipTrigger />
<TooltipContent />
</Tooltip>
</TooltipProvider>TooltipProvider deve envolver o app raiz uma única vez. Ele
compartilha o timer de delayDuration entre todos os tooltips —
quando você passa o mouse de um para outro, eles entram em modo
"skip delay" para evitar o efeito de pop intermitente.
Subcomponents
| Componente | Descrição |
|---|---|
TooltipProvider | Envolve a árvore. Configura delayDuration global. |
Tooltip | Raiz para um tooltip individual. |
TooltipTrigger | Elemento ao qual o tooltip se ancora. |
TooltipContent | Bubble com texto. Inclui Arrow automaticamente. |
Usage
// app/layout.tsx
import { TooltipProvider } from "@kalvner/kds/overlays/tooltip";
export default function RootLayout({ children }) {
return (
<html>
<body>
<TooltipProvider delayDuration={200}>{children}</TooltipProvider>
</body>
</html>
);
}// in a component
import { Tooltip, TooltipTrigger, TooltipContent } from "@kalvner/kds/overlays/tooltip";
export function SaveButton() {
return (
<Tooltip>
<TooltipTrigger asChild>
<Button>Salvar</Button>
</TooltipTrigger>
<TooltipContent>
Salvar <kbd className="ml-2">⌘S</kbd>
</TooltipContent>
</Tooltip>
);
}States
With shortcut
Inclua o atalho usando
<kbd> para ergonomia.Side variants
Top é o default; Radix flipa se não couber.
When to use
- Rotular botões icon-only (sempre +
aria-labelno botão). - Mostrar atalhos de teclado.
- Lembretes do que um controle faz quando o ícone for ambíguo.
When not to use
- Para qualquer informação que o usuário precise ler para concluir uma tarefa — coloque no DOM, não num tooltip.
- Para conteúdo interativo — use
Popover. - Para previews ricos — use
HoverCard. - Para confirmações ou erros — use
AlertDialogouAlert.
Best practices
- Sentence-case, sem ponto final. "Adicionar item", não "Adicionar item." nem "Adicionar Item.". Tooltip é um label, não uma frase.
- Curto. 1–6 palavras. Se não couber, repense — a informação provavelmente não pertence ao tooltip.
- Sempre par com
aria-labelno trigger icon-only. O tooltip não é lido por SR como nome acessível na maioria dos casos. - Não use
delayDuration: 0em produção. Cria flicker. 150–300ms é o sweet spot.
Accessibility
| Concern | Comportamento |
|---|---|
| Roles | Radix Tooltip aplica role="tooltip" no content e aria-describedby no trigger. |
| Foco | Tooltip aparece em focus do trigger (não só hover). Some quando o foco sai. |
| Keyboard | Esc fecha o tooltip ativo sem mover o foco. |
| Screen reader | O conteúdo do tooltip é anunciado via aria-describedby quando o trigger ganha foco. |
| Touch | Touch users não disparam tooltip — por isso conteúdo crítico não pode viver aqui. |
| Reduced motion | Fade respeita prefers-reduced-motion. |