Aller au contenu

Alerte

Une infobulle intégrée pour signaler les erreurs de formulaire, les avertissements et les confirmations de réussite — des encadrés aux couleurs correspondant à l'état, dotés de bordures néobrutalistes et d'ombres portées marquées.

import { CheckCircle2Icon, InfoIcon } from "lucide-react"

import {

L’alerte est un encart en ligne : une icône, un titre, une description et une action facultative, disposés sur une grille CSS. C’est une div role="alert" sans dépendance — aucune primitive en dessous, identique dans les deux variantes — habillée du style néobrutaliste : bordures épaisses, ombres marquées et typographie affirmée, avec un axe status pour les couleurs d’erreur, de succès, d’avertissement et d’information.

À privilégier pour :

  • Erreurs de formulaire et de requête — affichez un échec de validation ou un appel API raté juste à côté de l’élément fautif.
  • Confirmations de succès et de statut — « réglages enregistrés », « essai bientôt expiré », « paiement reçu », colorées par la prop status.
  • Encarts avec action associée — un avertissement ou une invite de mise à niveau portant un bouton AlertAction (« Activer », « Annuler », « Mettre à niveau »).

Installation

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/alert.json
npx shadcn@latest add https://neobrutalism.com/r/base/alert.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/alert.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/alert.json

Copiez et collez le code suivant dans votre projet.

components/ui/alert.tsx
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"

import { cn } from "@/lib/utils"

// CSS-grid layout (shadcn-style): drop an icon as a direct child and the alert
// auto-arranges into an icon column + a content column — no manual flex wrapper.
// `has-[>svg]` adds the icon column only when an icon is present. NeoBrutalist
// chrome: hard 2px border, square corners, hard offset shadow.
const alertVariants = cva(
  cn(
    "group/alert relative grid w-full grid-cols-[0_1fr] items-start gap-y-1 rounded border-2 px-4 py-3 text-left text-sm shadow-md",
    "has-[>svg]:grid-cols-[1.25rem_1fr] has-[>svg]:gap-x-3",
    "has-data-[slot=alert-action]:pr-14",
    "[&>svg]:size-5 [&>svg]:translate-y-0.5 [&>svg]:shrink-0 [&>svg]:text-current"
  ),
  {
    variants: {
      // shadcn's variant axis (kept for API compatibility). `solid` is a Neobrutalism
      // addition.
      variant: {
        default:
          "border-border bg-background text-foreground *:data-[slot=alert-description]:text-muted-foreground",
        destructive:
          "border-red-900 bg-red-300 text-red-900 *:data-[slot=alert-description]:text-red-900/80",
        solid:
          "border-border bg-foreground text-background *:data-[slot=alert-description]:text-background/80",
      },
      // Neobrutalism status axis — additive; overrides the variant's colors when set.
      status: {
        error:
          "border-red-900 bg-red-300 text-red-900 *:data-[slot=alert-description]:text-red-900/80",
        success:
          "border-green-900 bg-green-300 text-green-900 *:data-[slot=alert-description]:text-green-900/80",
        warning:
          "border-yellow-900 bg-yellow-300 text-yellow-900 *:data-[slot=alert-description]:text-yellow-900/80",
        info: "border-blue-900 bg-blue-300 text-blue-900 *:data-[slot=alert-description]:text-blue-900/80",
      },
    },
    defaultVariants: {
      variant: "default",
    },
  }
)

function Alert({
  className,
  variant,
  status,
  ...props
}: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
  return (
    <div
      data-slot="alert"
      role="alert"
      className={cn(alertVariants({ variant, status }), className)}
      {...props}
    />
  )
}

function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-title"
      className={cn(
        "col-start-2 min-h-5 font-head text-base leading-tight tracking-tight [&_a]:underline [&_a]:underline-offset-3",
        className
      )}
      {...props}
    />
  )
}

function AlertDescription({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-description"
      className={cn(
        "col-start-2 grid justify-items-start gap-1 text-sm [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p]:leading-relaxed [&_p:not(:last-child)]:mb-4",
        className
      )}
      {...props}
    />
  )
}

function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-action"
      className={cn("absolute top-2 right-2", className)}
      {...props}
    />
  )
}

export { Alert, AlertTitle, AlertDescription, AlertAction, alertVariants }

Adaptez les chemins d’import à la structure de votre projet.

Utilisation

import {
  Alert,
  AlertAction,
  AlertDescription,
  AlertTitle,
} from "@/components/ui/alert"
<Alert>
  <InfoIcon />
  <AlertTitle>Heads up!</AlertTitle>
  <AlertDescription>
    You can add components and dependencies to your app using the cli.
  </AlertDescription>
  <AlertAction>
    <Button variant="outline">Enable</Button>
  </AlertAction>
</Alert>

Composition

Utilisez la composition suivante pour construire un Alert :

Alert
├── Icon
├── AlertTitle
├── AlertDescription
└── AlertAction

Exemples

Simple

Une alerte simple avec une icône, un titre et une description.

import { CheckCircle2Icon } from "lucide-react"

import {

Destructif

Utilisez variant="destructive" pour créer une alerte destructrice.

import { AlertCircleIcon } from "lucide-react"

import {

Action

Utilisez AlertAction pour ajouter un bouton ou un autre élément d’action à l’alerte.

import {
  Alert,
  AlertAction,

Couleurs personnalisées

Vous pouvez personnaliser les couleurs de l’alerte en ajoutant des classes personnalisées comme bg-amber-50 dark:bg-amber-950 sur le composant Alert.

import { AlertTriangleIcon } from "lucide-react"

import {

RTL

Pour activer le RTL dans Neobrutalism, consultez le guide de configuration RTL.

"use client"

import * as React from "react"

Accessibilité

La racine de l’alerte rend role="alert", une région live assertive implicite : les lecteurs d’écran en annoncent le contenu dès qu’elle est insérée dans le DOM. L’annonce ne se déclenche qu’à l’insertion dynamique — une alerte déjà présente au chargement de la page est lue comme du texte ordinaire ; affichez-la donc conditionnellement quand elle doit être entendue. role="alert" ne déplace jamais le focus ; si l’utilisateur doit répondre avant de continuer, utilisez plutôt une boîte de dialogue d’alerte, et traitez AlertAction comme un raccourci, pas comme le seul chemin possible.

Référence API

Alert

Le composant Alert affiche un encart pour attirer l’attention de l’utilisateur.

PropTypeDefault
variant"default" | "destructive""default"

AlertTitle

Le composant AlertTitle affiche le titre de l’alerte.

PropTypeDefault
classNamestring-

AlertDescription

Le composant AlertDescription affiche la description ou le contenu de l’alerte.

PropTypeDefault
classNamestring-

AlertAction

Le composant AlertAction affiche un élément d’action (comme un bouton) positionné en absolu dans le coin supérieur droit de l’alerte.

PropTypeDefault
classNamestring-