Toggle group
BetaUn control segmentado — elige una opción (o varias) con efecto inmediato.
registry/ds/toggle-group.tsximport { ToggleGroup, ToggleItem } from "@/registry/ds/toggle-group";
export default function ToggleGroupBasic() {
return (
<div className="flex flex-col items-center gap-6">
<ToggleGroup aria-label="Período" defaultValue={["semana"]}>
<ToggleItem value="dia">Día</ToggleItem>
<ToggleItem value="semana">Semana</ToggleItem>
<ToggleItem value="mes">Mes</ToggleItem>
</ToggleGroup>
<ToggleGroup aria-label="Vista" size="sm" radius="full" defaultValue={["lista"]}>
<ToggleItem value="lista">Lista</ToggleItem>
<ToggleItem value="grilla">Grilla</ToggleItem>
<ToggleItem value="mapa" disabled>Mapa</ToggleItem>
</ToggleGroup>
</div>
);
}Toggle group, Tabs o Radio
Se parece a las Tabs segmented, pero no navega: cambia cómo se ve o
se comporta algo, al instante.
| Usá Toggle group para… | Usá otra cosa para… |
|---|---|
| Cambiar la vista de los mismos datos (Lista / Grilla, Día / Semana). | Secciones distintas de contenido → Tabs. |
Formato con varias opciones a la vez (multiple). | Elegir en un formulario que se envía → Radio. |
| Opciones de icono (alinear, ordenar). | Prender/apagar una sola cosa → Switch. |
Múltiple y solo icono
import { ToggleGroup, ToggleItem } from "@/registry/ds/toggle-group";
const B = () => <svg viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden><path d="M5 3.5h6a3.25 3.25 0 0 1 0 6.5H5zM5 10h7a3.25 3.25 0 0 1 0 6.5H5z" /></svg>;
const I = () => <svg viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.667" strokeLinecap="round" aria-hidden><path d="M8 3.5h6M6 16.5h6M12 3.5l-4 13" /></svg>;
const U = () => <svg viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.667" strokeLinecap="round" aria-hidden><path d="M5.5 3.5v6a4.5 4.5 0 0 0 9 0v-6M4 17h12" /></svg>;
export default function ToggleGroupMultiple() {
return (
<ToggleGroup aria-label="Formato de texto" multiple defaultValue={["bold"]}>
<ToggleItem value="bold" aria-label="Negrita" icon={<B />} />
<ToggleItem value="italic" aria-label="Cursiva" icon={<I />} />
<ToggleItem value="underline" aria-label="Subrayado" icon={<U />} />
</ToggleGroup>
);
}- 2 a 5 opciones de label corto; los de icono llevan
aria-label. - Siempre hay una presionada (salvo
multiple).
| Size | Item | Padding X | Pista |
|---|---|---|---|
sm | 28 | 10 | padding 4 · gap 2 |
md | 36 | 12 | padding 4 · gap 2 |
Radio semi: pista radius-md, item radius-sm. full: ambos radius-full.
Solo icono: cuadrado.
| Parte | Propiedad | Token |
|---|---|---|
| Pista | Fondo | bg/surface |
| Item | Texto → hover | text/muted |
| Item presionado | Fondo + Elevation/xs | bg/elevated |
| Item presionado | Texto | text/default |
| Deshabilitado | Texto | text/disabled |
| Foco | Anillo 2 px | focus/ring |
Instalación
npx shadcn@latest add https://polen.cdc.cool/r/toggle-group.jsonPlayground
Configurá el componente y copiá el snippet: se genera del mismo estado que renderiza el preview.
size
radius
Contenido
<ToggleGroup aria-label="Vista" defaultValue={["lista"]}>
<ToggleItem value="lista">Lista</ToggleItem>
<ToggleItem value="grilla">Grilla</ToggleItem>
<ToggleItem value="mapa">Mapa</ToggleItem>
</ToggleGroup>Props
Sobre Base UI Toggle Group.
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
ToggleGroup · value / defaultValue | string[] | — | Siempre un array, aun con una sola opción. |
ToggleGroup · onValueChange | (value: string[]) => void | — | Al cambiar. |
ToggleGroup · multiple | boolean | false | Varias presionadas a la vez. |
ToggleGroup · size · radius | "sm" | "md" · "semi" | "full" | "md" · "semi" | Tamaño y forma. |
ToggleGroup · aria-label | string | — | Nombre del grupo. Requerido. |
ToggleItem · value | string | — | Identificador de la opción. |
ToggleItem · icon · aria-label | ReactNode · string | — | Solo icono: cuadrado, con nombre. |
| Tecla | Qué hace |
|---|---|
| Tab | Entra al grupo (una sola parada). |
| ←→ | Mueve el foco entre opciones. |
| EspacioEnter | Presiona la opción enfocada. |
- Cada opción es un botón con
aria-pressed; el grupo llevarole="group"y suaria-label. - El estado no depende solo del color: fondo, sombra y peso cambian.