Tooltip
Hoja clienteA brief, supplementary label revealed on hover or focus.
Vista previa en vivo
Renderizado desde el código fuente instalado de VEXA — los mismos archivos que recibes.
Instalación
Añade el código del componente a tu proyecto. Las dependencias del registry se resuelven automáticamente.
npx shadcn@latest add https://vexa.valfiguer.com/r/tooltip.jsonSe instala en components/vexa/tooltip.tsx
Dependencias npm
- @radix-ui/react-tooltip
Dependencias del registry
- @vexa/utils
Otros items de VEXA que necesita este componente. Instálalos primero — la CLI los resuelve automáticamente.
Código
Cópialo a su ruta destino, o instálalo con el comando de arriba.
"use client";
import type * as React from "react";
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import { cn } from "@/lib/utils";
/**
* Tooltip — a brief, supplementary label revealed on hover or focus.
*
* Client leaf. Wrap your app (or a subtree) in a single `TooltipProvider`.
* Radix reveals the tooltip on both pointer hover and keyboard focus and hides
* it on Escape, per APG. A tooltip must only enhance an already-labelled
* control — never use it as the sole accessible name of an interactive element,
* and never place interactive content inside it.
*/
export function TooltipProvider({
delayDuration = 200,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
return (
<TooltipPrimitive.Provider
data-slot="tooltip-provider"
delayDuration={delayDuration}
{...props}
/>
);
}
export function Tooltip(
props: React.ComponentProps<typeof TooltipPrimitive.Root>,
) {
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />;
}
export function TooltipTrigger(
props: React.ComponentProps<typeof TooltipPrimitive.Trigger>,
) {
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
}
export function TooltipContent({
className,
sideOffset = 6,
children,
...props
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
return (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content
data-slot="tooltip-content"
sideOffset={sideOffset}
className={cn(
"z-50 max-w-xs rounded-vexa-sm bg-vexa-primary px-2.5 py-1.5 text-xs font-medium text-vexa-primary-foreground shadow-vexa-md",
"transition-opacity duration-[var(--vexa-duration-fast)] ease-[var(--vexa-ease-standard)] motion-reduce:transition-none",
"data-[state=closed]:opacity-0 data-[state=delayed-open]:opacity-100 data-[state=instant-open]:opacity-100",
className,
)}
{...props}
>
{children}
<TooltipPrimitive.Arrow className="fill-vexa-primary" />
</TooltipPrimitive.Content>
</TooltipPrimitive.Portal>
);
}
JSON del registryr/tooltip.json
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "tooltip",
"type": "registry:ui",
"title": "Tooltip",
"description": "A brief, supplementary label revealed on hover or focus.",
"dependencies": [
"@radix-ui/react-tooltip"
],
"registryDependencies": [
"@vexa/utils"
],
"files": [
{
"path": "registry/default/ui/tooltip.tsx",
"type": "registry:ui",
"target": "components/vexa/tooltip.tsx",
"content": "\"use client\";\n\nimport type * as React from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * Tooltip — a brief, supplementary label revealed on hover or focus.\n *\n * Client leaf. Wrap your app (or a subtree) in a single `TooltipProvider`.\n * Radix reveals the tooltip on both pointer hover and keyboard focus and hides\n * it on Escape, per APG. A tooltip must only enhance an already-labelled\n * control — never use it as the sole accessible name of an interactive element,\n * and never place interactive content inside it.\n */\nexport function TooltipProvider({\n delayDuration = 200,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nexport function Tooltip(\n props: React.ComponentProps<typeof TooltipPrimitive.Root>,\n) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />;\n}\n\nexport function TooltipTrigger(\n props: React.ComponentProps<typeof TooltipPrimitive.Trigger>,\n) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nexport function TooltipContent({\n className,\n sideOffset = 6,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"z-50 max-w-xs rounded-vexa-sm bg-vexa-primary px-2.5 py-1.5 text-xs font-medium text-vexa-primary-foreground shadow-vexa-md\",\n \"transition-opacity duration-[var(--vexa-duration-fast)] ease-[var(--vexa-ease-standard)] motion-reduce:transition-none\",\n \"data-[state=closed]:opacity-0 data-[state=delayed-open]:opacity-100 data-[state=instant-open]:opacity-100\",\n className,\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"fill-vexa-primary\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n"
}
],
"meta": {
"frameworks": [
"react",
"next"
],
"rsc": "client",
"exports": [
"TooltipProvider",
"Tooltip",
"TooltipTrigger",
"TooltipContent"
],
"cssVars": [
"--vexa-primary",
"--vexa-primary-foreground"
],
"a11y": "Reveals on hover AND keyboard focus and hides on Escape. Only enhances an already-labelled control — never the sole accessible name, and no interactive content inside. Wrap a subtree in one TooltipProvider.",
"example": "<TooltipProvider><Tooltip><TooltipTrigger asChild><IconButton aria-label=\"Info\"><InfoIcon /></IconButton></TooltipTrigger><TooltipContent>More details</TooltipContent></Tooltip></TooltipProvider>",
"tests": "planned — see docs/README.md#roadmap"
}
}Detalles
Accesibilidad
Reveals on hover AND keyboard focus and hides on Escape. Only enhances an already-labelled control — never the sole accessible name, and no interactive content inside. Wrap a subtree in one TooltipProvider.
Uso
A brief text hint that enhances an already-labelled control on hover or focus.
Anatomía
- TooltipProvider
- Wrap a subtree once to share timing.
- Tooltip
- Root; owns the open state.
- TooltipTrigger
- The control the tooltip describes.
- TooltipContent
- The hint text.
Accesibilidad
role=tooltip — supplementary only; never the sole accessible name.
Teclado
| Tecla | Acción |
|---|---|
| Escape | Hide the tooltip |
Foco: Reveals on hover AND keyboard focus; hides on Escape.
- Content on hover/focus must be dismissible, hoverable and persistent (WCAG 1.4.13). No interactive content inside.
Buenas prácticas
Recomendado
- Wrap the subtree once in a TooltipProvider.
- Use it to add non-essential detail.
- Trigger it from a control that already has a label.
Evitar
- Don't put links or buttons inside a tooltip.
- Don't use it as a control's only label.
- Don't hide essential information behind hover only.
¿Te ha resultado útil esta página?
Guardado localmente en este navegador. Sin cuenta ni servidor.