HextaUI

Toggle group

Uma linha de toggles para uma ou várias escolhas, com um preenchimento que desliza até o item escolhido, itens unidos ou espaçados e foco por setas do teclado.

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

Adiciona o componente, os tokens de tema do HextaUI e quaisquer componentes do HextaUI dos quais ele depende.

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>

Quando um item de cada vez pode estar ligado, um único preenchimento desliza até o item escolhido e assume sua forma, então o grupo se lê como um só controle. Com multiple, cada item se preenche por conta própria. O preenchimento é posicionado antes da primeira pintura, então nunca desliza ao carregar.

ToggleGroup
└── ToggleGroupItem

Outline

variant="outline" une os itens em um único controle com borda.

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>
  )
}

Múltiplo

multiple permite que qualquer número de itens esteja ligado, como na formatação de texto.

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>
  )
}

Tamanhos

size no grupo define todos os itens: 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>
  )
}

Espaçamento

spacing coloca um espaço entre os itens na escala de espaçamento. Itens outline com espaço mantêm suas próprias bordas e preenchimentos.

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>
  )
}

Ícones e rótulos

Coloque um ícone antes do rótulo. Itens apenas com ícone precisam de um 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" empilha os itens e move o foco com ↑ e ↓.

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>
  )
}

Desabilitado

Desabilite um item, ou o grupo inteiro com disabled. Itens desabilitados são ignorados pelo teclado.

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>
  )
}

Controlado

Passe value e onValueChange. Ignorar o valor vazio mantém um item ligado, então pressionar o item escolhido de novo não faz nada.

"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>
  )
}

Da direita para a esquerda

A ordem dos itens, os cantos unidos, o preenchimento deslizante e as setas seguem a direção de leitura.

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>
  )
}
TeclaAção
TabEntra no grupo no último item com foco e depois sai dele.
←→Move entre os itens, voltando ao início nas extremidades. ↑ e ↓ na vertical.
HomeEndMove para o primeiro ou o último item.
EnterSpaceLiga ou desliga o item com foco.
  • O grupo tem o role group; dê a ele um aria-label. Cada item é um botão com aria-pressed.
  • Só um item está na ordem de tabulação, então o grupo é uma única parada de Tab e as setas se movem dentro dele.
  • Sem multiple, pressionar o item escolhido o desliga. Controle o valor para manter um item ligado.
  • Com movimento reduzido, o preenchimento aparece com fade em vez de deslizar.
PropTipoPadrão
value
string[]–
defaultValue
string[]–
onValueChange
(value: string[], details) => void–
multiple
booleanfalse
variantDefine a variante de todos os itens.
"default" | "outline""default"
sizeDefine o tamanho de todos os itens.
"default" | "sm" | "lg""default"
spacingEspaço entre os itens na escala de espaçamento. 0 une os itens 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>
AtributoDescrição
data-slot="toggle-group"A raiz.
data-slot="toggle-group-indicator"O preenchimento deslizante, renderizado sem multiple. data-visible quando um item está ligado.
data-variant / data-size / data-spacingA variante, o tamanho e o espaçamento do grupo.
data-orientation"horizontal" ou "vertical".
data-multiplePresente quando vários itens podem estar ligados.
data-disabledPresente quando o grupo está desativado.
PropTipoPadrão
valueIdentifica o item no valor do grupo.
string–
disabled
booleanfalse
variantUsado quando o grupo não define nenhum.
"default" | "outline"–
sizeUsado quando o grupo não define nenhum.
"default" | "sm" | "lg"–
nativeButton
booleantrue
render
ReactElement | (props, state) => ReactElement<button>
AtributoDescrição
data-slot="toggle-group-item"Cada item.
data-pressedO item está ligado.
data-disabledO item está desabilitado.
data-variant / data-sizeA variante e o tamanho resolvidos do item.

Usado em blocos

Blocos que se baseiam em Toggle group.