Aller au contenu

Groupe radio

Un ensemble de boutons radio à choix unique pour les formulaires relatifs aux formules d'abonnement, aux options de livraison et aux paramètres — avec un style néobrutaliste caractérisé par des bordures et des ombres.

import { Label } from "@/components/ui/label"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"

Le groupe radio présente un ensemble d’options mutuellement exclusives — cocher un élément décoche tous les autres. Construit sur le composant Base UI Radio Group et stylisé selon la recette néobrutaliste : bordures épaisses, ombres franches et typographie affirmée.

À privilégier dans ces cas :

  • Sélecteurs de formule — gratuit / pro / entreprise sous forme de cartes de choix, avec une seule sélection imposée.
  • Options de commande — rapidité de livraison ou moyen de paiement, quand chaque choix doit rester visible.
  • Réglages à 2–5 options — thème, densité, fréquence des notifications ; moins de clics qu’une liste déroulante.

Installation

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

Installez les dépendances suivantes :

pnpm add @base-ui/react
npm install @base-ui/react
yarn add @base-ui/react
bun add @base-ui/react

Copiez et collez le code suivant dans votre projet.

components/ui/radio-group.tsx
"use client"

import * as React from "react"
import { RadioGroup as RadioGroupPrimitive } from "radix-ui"

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

function RadioGroup({
  className,
  ...props
}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {
  return (
    <RadioGroupPrimitive.Root
      data-slot="radio-group"
      className={cn("grid w-full gap-2", className)}
      {...props}
    />
  )
}

function RadioGroupItem({
  className,
  ...props
}: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {
  return (
    <RadioGroupPrimitive.Item
      data-slot="radio-group-item"
      className={cn(
        "group/radio-group-item peer relative flex aspect-square size-5 shrink-0 rounded-full border-2 bg-input shadow-sm outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive",
        className
      )}
      {...props}
    >
      <RadioGroupPrimitive.Indicator
        data-slot="radio-group-indicator"
        className="flex size-4 items-center justify-center"
      >
        <span className="absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary" />
      </RadioGroupPrimitive.Indicator>
    </RadioGroupPrimitive.Item>
  )
}

export { RadioGroup, RadioGroupItem }

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

Utilisation

import { Label } from "@/components/ui/label"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
<RadioGroup defaultValue="option-one">
  <div className="flex items-center gap-3">
    <RadioGroupItem value="option-one" id="option-one" />
    <Label htmlFor="option-one">Option One</Label>
  </div>
  <div className="flex items-center gap-3">
    <RadioGroupItem value="option-two" id="option-two" />
    <Label htmlFor="option-two">Option Two</Label>
  </div>
</RadioGroup>

Composition

Utilisez la composition suivante pour construire un RadioGroup :

RadioGroup
├── RadioGroupItem
└── RadioGroupItem

Exemples

Description

Des éléments de groupe radio dotés d'une description grâce au composant Field.

import {
  Field,
  FieldContent,

Carte de choix

Utilisez FieldLabel pour envelopper l'ensemble du Field et obtenir une sélection cliquable en forme de carte.

import {
  Field,
  FieldContent,

Fieldset

Utilisez FieldSet et FieldLegend pour regrouper des éléments radio avec une étiquette et une description.

import {
  Field,
  FieldDescription,

Désactivé

Utilisez la prop disabled sur RadioGroup pour désactiver tous les éléments.

import { Field, FieldLabel } from "@/components/ui/field"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"

Invalide

Utilisez aria-invalid sur RadioGroupItem et data-invalid sur Field pour signaler les erreurs de validation.

import {
  Field,
  FieldDescription,

RTL

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

"use client"

import * as React from "react"

Accessibilité

Le groupe radio suit le modèle WAI-ARIA Radio Group : le conteneur rend role="radiogroup", chaque élément est un bouton role="radio" doté de aria-checked, et un tabindex itinérant fait de tout le groupe un unique arrêt de tabulation.

Interactions au clavier :

ToucheAction
Tab / Shift + TabDéplace le focus dans le groupe (élément coché, sinon premier) / hors du groupe
SpaceCoche l’élément qui a le focus s’il ne l’est pas déjà
ArrowDown / ArrowRightDéplace le focus vers l’élément suivant et le coche
ArrowUp / ArrowLeftDéplace le focus vers l’élément précédent et le coche

Les flèches gauche et droite suivent le sens de lecture en RTL.

Référence API

Consultez la documentation Base UI Radio Group.