Infobulle
Des infobulles au survol et à la mise au premier plan pour les boutons iconiques, les raccourcis clavier et les libellés tronqués — avec un effet « néobrutaliste » combinant bordure et ombre.
import { Button } from "@/components/ui/button"
import {
Tooltip,Le tooltip est une courte étiquette qui apparaît au survol ou au focus clavier et décrit le contrôle qu’elle accompagne — un texte d’appoint, jamais un réceptacle de contenu interactif. Construit sur la primitive Base UI Tooltip, rendu dans un portail et conscient des collisions, et stylisé selon la recette néobrutaliste : bordure épaisse, ombre franche et remplissage inversé pour rester lisible sur n’importe quel fond.
À privilégier dans ces cas :
- Boutons à icône seule — nommez l’action qu’une icône nue ne dit pas : barres d’outils, actions de ligne de tableau, contrôles d’éditeur.
- Raccourcis clavier — affichez la combinaison à côté du libellé avec
Kbd, comme dans l’exemple ci-dessous. - Textes tronqués ou laconiques — noms de fichiers complets, cellules de tableau coupées, codes de statut abrégés.
Installation#
Exécutez la commande suivante :
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/tooltip.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/tooltip.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/tooltip.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/tooltip.json
Ajoutez le TooltipProvider à la racine de votre application.
import { TooltipProvider } from "@/components/ui/tooltip"
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<TooltipProvider>{children}</TooltipProvider>
</body>
</html>
)
}Installez les dépendances suivantes :
pnpm add @base-ui/reactnpm install @base-ui/reactyarn add @base-ui/reactbun add @base-ui/react
Copiez-collez le code suivant dans votre projet.
"use client"
import * as React from "react"
import { Tooltip as TooltipPrimitive } from "radix-ui"
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 <TooltipPrimitive.Root data-slot="tooltip" {...props} />
}
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(
"z-50 inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-1.5 rounded border-2 bg-foreground px-2 py-1 text-xs text-background shadow-md has-data-[slot=kbd]:pr-1.5 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 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
className
)}
{...props}
>
{children}
<TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" />
</TooltipPrimitive.Content>
</TooltipPrimitive.Portal>
)
}
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }
Adaptez les chemins d’import à la configuration de votre projet.
Ajoutez le TooltipProvider à la racine de votre application.
import { TooltipProvider } from "@/components/ui/tooltip"
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<TooltipProvider>{children}</TooltipProvider>
</body>
</html>
)
}Utilisation#
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip"<Tooltip>
<TooltipTrigger>Hover</TooltipTrigger>
<TooltipContent>
<p>Add to library</p>
</TooltipContent>
</Tooltip>Composition#
Utilisez la composition suivante pour construire un Tooltip :
Tooltip
├── TooltipTrigger
└── TooltipContentExemples#
Côté#
Utilisez la prop side pour modifier la position de l’infobulle.
import { Button } from "@/components/ui/button"
import {
Tooltip,Avec raccourci clavier#
import { SaveIcon } from "lucide-react"
import { Button } from "@/components/ui/button"Bouton désactivé#
Affichez une infobulle sur un bouton désactivé en l’enveloppant dans un span.
import { Button } from "@/components/ui/button"
import {
Tooltip,RTL#
Pour activer le RTL dans Neobrutalism, consultez le guide de configuration RTL.
"use client"
import {Accessibilité#
Le tooltip suit le modèle WAI-ARIA Tooltip : le panneau flottant rend role="tooltip" et la primitive pointe l’aria-describedby du déclencheur vers lui, si bien que les lecteurs d’écran annoncent l’infobulle comme une description du contrôle. Le tooltip ne prend jamais le focus — placez liens et boutons dans un Popover à la place, et faites en sorte que le déclencheur reste compréhensible sans lui.
Interactions au clavier :
| Touche | Action |
|---|---|
Tab / Shift + Tab | Amène le focus sur le déclencheur — le focus ouvre le tooltip, le quitter le ferme |
Escape | Ferme le tooltip pendant que le focus reste sur le déclencheur |
Enter / Space | Active l’action propre au déclencheur — le tooltip est une description, pas un contrôle |
Référence API#
Consultez la documentation Base UI Tooltip.