HextaUI

Toggle group

Une rangée de boutons à bascule pour un choix unique ou multiple, avec un remplissage qui glisse vers l’élément choisi, des éléments joints ou espacés et un focus aux flèches du clavier.

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

export function ToggleGroupDemo() {
  return (
    <ToggleGroup aria-label="Date range" defaultValue={["week"]}>
      <ToggleGroupItem value="day">Day</ToggleGroupItem>
      <ToggleGroupItem value="week">Week</ToggleGroupItem>
      <ToggleGroupItem value="month">Month</ToggleGroupItem>
      <ToggleGroupItem value="year">Year</ToggleGroupItem>
    </ToggleGroup>
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/toggle-group.json

Ajoute le composant, les tokens de thème HextaUI et les composants HextaUI dont il dépend.

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup aria-label="Date range" defaultValue={["week"]}>
  <ToggleGroupItem value="day">Day</ToggleGroupItem>
  <ToggleGroupItem value="week">Week</ToggleGroupItem>
  <ToggleGroupItem value="month">Month</ToggleGroupItem>
</ToggleGroup>

Quand un seul élément peut être activé à la fois, un unique remplissage glisse vers l'élément choisi et prend sa forme, si bien que le groupe se lit comme un seul contrôle. Avec multiple, chaque élément se remplit seul. Le remplissage est placé avant le premier rendu, il n'apparaît donc jamais en glissant au chargement.

ToggleGroup
└── ToggleGroupItem

Outline

variant="outline" joint les éléments en un seul contrôle bordé.

import {
  IconAlignCenter,
  IconAlignJustified,
  IconAlignLeft,
  IconAlignRight,
} from "@tabler/icons-react"

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

export function ToggleGroupOutline() {
  return (
    <ToggleGroup
      variant="outline"
      aria-label="Text alignment"
      defaultValue={["left"]}
    >
      <ToggleGroupItem value="left" aria-label="Align left">
        <IconAlignLeft />
      </ToggleGroupItem>
      <ToggleGroupItem value="center" aria-label="Align center">
        <IconAlignCenter />
      </ToggleGroupItem>
      <ToggleGroupItem value="right" aria-label="Align right">
        <IconAlignRight />
      </ToggleGroupItem>
      <ToggleGroupItem value="justify" aria-label="Justify">
        <IconAlignJustified />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

Multiple

multiple permet d'activer autant d'éléments que l'on veut, comme pour la mise en forme du texte.

import {
  IconBold,
  IconItalic,
  IconStrikethrough,
  IconUnderline,
} from "@tabler/icons-react"

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

export function ToggleGroupMultiple() {
  return (
    <ToggleGroup
      multiple
      variant="outline"
      aria-label="Text formatting"
      defaultValue={["bold", "italic"]}
    >
      <ToggleGroupItem value="bold" aria-label="Bold">
        <IconBold />
      </ToggleGroupItem>
      <ToggleGroupItem value="italic" aria-label="Italic">
        <IconItalic />
      </ToggleGroupItem>
      <ToggleGroupItem value="underline" aria-label="Underline">
        <IconUnderline />
      </ToggleGroupItem>
      <ToggleGroupItem value="strikethrough" aria-label="Strikethrough">
        <IconStrikethrough />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

Tailles

size sur le groupe définit chaque élément : sm, default ou lg.

import { IconBold, IconItalic, IconUnderline } from "@tabler/icons-react"

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

export function ToggleGroupSizes() {
  return (
    <div className="flex flex-col items-center gap-4">
      {(["sm", "default", "lg"] as const).map((size) => (
        <ToggleGroup
          key={size}
          multiple
          size={size}
          variant="outline"
          aria-label={`Formatting, ${size}`}
          defaultValue={["bold"]}
        >
          <ToggleGroupItem value="bold" aria-label="Bold">
            <IconBold />
          </ToggleGroupItem>
          <ToggleGroupItem value="italic" aria-label="Italic">
            <IconItalic />
          </ToggleGroupItem>
          <ToggleGroupItem value="underline" aria-label="Underline">
            <IconUnderline />
          </ToggleGroupItem>
        </ToggleGroup>
      ))}
    </div>
  )
}

Espacement

spacing place un espace entre les éléments sur l'échelle d'espacement. Les éléments outline espacés gardent leurs propres bordures et fonds.

import { IconStar } from "@tabler/icons-react"

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

export function ToggleGroupSpacing() {
  return (
    <div className="flex flex-col items-center gap-4">
      <ToggleGroup spacing={1} aria-label="Rating filter" defaultValue={["4"]}>
        {["1", "2", "3", "4", "5"].map((stars) => (
          <ToggleGroupItem key={stars} value={stars}>
            {stars}
            <IconStar />
          </ToggleGroupItem>
        ))}
      </ToggleGroup>
      <ToggleGroup
        multiple
        spacing={2}
        variant="outline"
        size="sm"
        aria-label="Topics"
        defaultValue={["design"]}
      >
        <ToggleGroupItem value="design">Design</ToggleGroupItem>
        <ToggleGroupItem value="engineering">Engineering</ToggleGroupItem>
        <ToggleGroupItem value="research">Research</ToggleGroupItem>
      </ToggleGroup>
    </div>
  )
}

Icônes et labels

Placez une icône avant le label. Les éléments réduits à une icône ont besoin d'un aria-label.

import { IconDeviceDesktop, IconMoon, IconSun } from "@tabler/icons-react"

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

export function ToggleGroupIcons() {
  return (
    <ToggleGroup aria-label="Theme" defaultValue={["system"]}>
      <ToggleGroupItem value="light">
        <IconSun />
        Light
      </ToggleGroupItem>
      <ToggleGroupItem value="dark">
        <IconMoon />
        Dark
      </ToggleGroupItem>
      <ToggleGroupItem value="system">
        <IconDeviceDesktop />
        System
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

Vertical

orientation="vertical" empile les éléments et déplace le focus avec ↑ et ↓.

import { IconLayoutGrid, IconLayoutList, IconList } from "@tabler/icons-react"

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

export function ToggleGroupVertical() {
  return (
    <ToggleGroup
      orientation="vertical"
      variant="outline"
      aria-label="Layout"
      defaultValue={["grid"]}
    >
      <ToggleGroupItem value="grid" aria-label="Grid">
        <IconLayoutGrid />
      </ToggleGroupItem>
      <ToggleGroupItem value="cards" aria-label="Cards">
        <IconLayoutList />
      </ToggleGroupItem>
      <ToggleGroupItem value="list" aria-label="List">
        <IconList />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

Désactivé

Désactivez un élément, ou tout le groupe avec disabled. Les éléments désactivés sont ignorés par le clavier.

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

export function ToggleGroupDisabled() {
  return (
    <div className="flex flex-col items-center gap-4">
      <ToggleGroup aria-label="Plan" defaultValue={["pro"]}>
        <ToggleGroupItem value="free">Free</ToggleGroupItem>
        <ToggleGroupItem value="pro">Pro</ToggleGroupItem>
        <ToggleGroupItem value="team" disabled>
          Team
        </ToggleGroupItem>
      </ToggleGroup>
      <ToggleGroup
        disabled
        variant="outline"
        aria-label="Billing"
        defaultValue={["monthly"]}
      >
        <ToggleGroupItem value="monthly">Monthly</ToggleGroupItem>
        <ToggleGroupItem value="yearly">Yearly</ToggleGroupItem>
      </ToggleGroup>
    </div>
  )
}

Contrôlé

Passez value et onValueChange. Ignorer la valeur vide garde un élément activé, si bien qu'appuyer de nouveau sur l'élément choisi ne fait rien.

"use client"

import * as React from "react"

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

const views = ["Board", "List", "Calendar"]

export function ToggleGroupControlled() {
  const [view, setView] = React.useState("Board")

  return (
    <div className="flex flex-col items-center gap-3">
      <ToggleGroup
        variant="outline"
        aria-label="View"
        value={[view]}
        onValueChange={(value) => {
          if (value.length > 0) {
            setView(value[0])
          }
        }}
      >
        {views.map((item) => (
          <ToggleGroupItem key={item} value={item}>
            {item}
          </ToggleGroupItem>
        ))}
      </ToggleGroup>
      <p className="text-sm text-muted-foreground">Showing the {view} view.</p>
    </div>
  )
}

De droite à gauche

L'ordre des éléments, les coins joints, le remplissage glissant et les flèches suivent le sens de lecture.

import {
  IconAlignCenter,
  IconAlignLeft,
  IconAlignRight,
} from "@tabler/icons-react"

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"

export function ToggleGroupRtl() {
  return (
    <div dir="rtl" className="flex flex-col items-center gap-4">
      <ToggleGroup aria-label="الفترة" defaultValue={["week"]}>
        <ToggleGroupItem value="day">يوم</ToggleGroupItem>
        <ToggleGroupItem value="week">أسبوع</ToggleGroupItem>
        <ToggleGroupItem value="month">شهر</ToggleGroupItem>
      </ToggleGroup>
      <ToggleGroup
        variant="outline"
        aria-label="محاذاة النص"
        defaultValue={["right"]}
      >
        <ToggleGroupItem value="right" aria-label="محاذاة لليمين">
          <IconAlignRight />
        </ToggleGroupItem>
        <ToggleGroupItem value="center" aria-label="توسيط">
          <IconAlignCenter />
        </ToggleGroupItem>
        <ToggleGroupItem value="left" aria-label="محاذاة لليسار">
          <IconAlignLeft />
        </ToggleGroupItem>
      </ToggleGroup>
    </div>
  )
}
ToucheAction
TabEntre dans le groupe sur le dernier élément focalisé, puis en sort.
←→Se déplace entre les éléments, en bouclant aux extrémités. ↑ et ↓ en vertical.
HomeEndVa au premier ou au dernier élément.
EnterSpaceActive ou désactive l'élément qui a le focus.
  • Le groupe a le rôle group ; donnez-lui un aria-label. Chaque élément est un bouton avec aria-pressed.
  • Un seul élément est dans l'ordre de tabulation : le groupe est un unique arrêt de Tab et les flèches se déplacent à l'intérieur.
  • Sans multiple, appuyer sur l'élément choisi le désactive. Contrôlez la valeur pour garder un élément activé.
  • Avec la réduction des animations, le remplissage apparaît en fondu au lieu de glisser.
PropTypePar défaut
value
string[]–
defaultValue
string[]–
onValueChange
(value: string[], details) => void–
multiple
booleanfalse
variantDéfinit la variante de chaque élément.
"default" | "outline""default"
sizeDéfinit la taille de chaque élément.
"default" | "sm" | "lg""default"
spacingEspace entre les éléments sur l'échelle d'espacement. 0 joint les éléments outline.
0 | 0.5 | 1 | 1.5 | 2 | 2.5 | 3 | 4 | 5 | 6 | 80
orientation
"horizontal" | "vertical""horizontal"
loopFocus
booleantrue
disabled
booleanfalse
render
ReactElement | (props, state) => ReactElement<div>
AttributDescription
data-slot="toggle-group"La racine.
data-slot="toggle-group-indicator"Le remplissage glissant, rendu sans multiple. data-visible quand un élément est activé.
data-variant / data-size / data-spacingLa variante, la taille et l'espacement du groupe.
data-orientation"horizontal" ou "vertical".
data-multiplePrésent quand plusieurs éléments peuvent être activés.
data-disabledPrésent lorsque le groupe est désactivé.
PropTypePar défaut
valueIdentifie l'élément dans la valeur du groupe.
string–
disabled
booleanfalse
variantUtilisé quand le groupe n'en définit aucun.
"default" | "outline"–
sizeUtilisé quand le groupe n'en définit aucun.
"default" | "sm" | "lg"–
nativeButton
booleantrue
render
ReactElement | (props, state) => ReactElement<button>
AttributDescription
data-slot="toggle-group-item"Chaque élément.
data-pressedL'élément est activé.
data-disabledL'élément est désactivé.
data-variant / data-sizeLa variante et la taille résolues de l'élément.

Utilisé dans les blocks

Des blocks qui s’appuient sur Toggle group.