Grupo de alternancia
Grupos de botones de dos estados para barras de herramientas de editor, selectores de vista y barras de filtro, con el estilo neobrutalista de bordes y sombras.
import { Bold, Italic, Underline } from "lucide-react"
import {El grupo de conmutadores es una fila de botones de dos estados en la que puede haber uno (el comportamiento por defecto) o varios (multiple) pulsados a la vez. Está construido sobre el componente Base UI Toggle Group y sigue la receta neobrutalista: bordes gruesos, sombras marcadas y tipografía en negrita.
Recurre a este componente cuando:
- Barras de herramientas de editor — negrita/cursiva/subrayado, alineación del texto, estilos de lista con
multiple. - Conmutadores de vista — cuadrícula o lista, gráfico o tabla, día/semana/mes; el modo por defecto mantiene como mucho uno activo.
- Barras de filtros — etiquetas, categorías o facetas que el usuario puede ir activando y desactivando.
Instalación#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/toggle-group.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/toggle-group.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/toggle-group.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/toggle-group.json
Instala las siguientes dependencias:
pnpm add @base-ui/reactnpm install @base-ui/reactyarn add @base-ui/reactbun add @base-ui/react
Copia y pega el siguiente código en tu proyecto.
"use client"
import * as React from "react"
import { type VariantProps } from "class-variance-authority"
import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"
import { toggleVariants } from "@/components/ui/toggle"
const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants> & {
spacing?: number
orientation?: "horizontal" | "vertical"
}
>({
size: "default",
variant: "default",
spacing: 2,
orientation: "horizontal",
})
function ToggleGroup({
className,
variant,
size,
spacing = 2,
orientation = "horizontal",
children,
...props
}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleVariants> & {
spacing?: number
orientation?: "horizontal" | "vertical"
}) {
return (
<ToggleGroupPrimitive.Root
data-slot="toggle-group"
data-variant={variant}
data-size={size}
data-spacing={spacing}
data-orientation={orientation}
style={{ "--gap": spacing } as React.CSSProperties}
className={cn(
"group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch",
className
)}
{...props}
>
<ToggleGroupContext.Provider
value={{ variant, size, spacing, orientation }}
>
{children}
</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
)
}
function ToggleGroupItem({
className,
children,
variant = "default",
size = "default",
...props
}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>) {
const context = React.useContext(ToggleGroupContext)
return (
<ToggleGroupPrimitive.Item
data-slot="toggle-group-item"
data-variant={context.variant || variant}
data-size={context.size || size}
data-spacing={context.spacing}
className={cn(
"shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t",
toggleVariants({
variant: context.variant || variant,
size: context.size || size,
}),
className
)}
{...props}
>
{children}
</ToggleGroupPrimitive.Item>
)
}
export { ToggleGroup, ToggleGroupItem }
Ajusta las rutas de importación a la configuración de tu proyecto.
Uso#
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"<ToggleGroup type="single">
<ToggleGroupItem value="a">A</ToggleGroupItem>
<ToggleGroupItem value="b">B</ToggleGroupItem>
<ToggleGroupItem value="c">C</ToggleGroupItem>
</ToggleGroup>Composición#
Usa la siguiente composición para construir un ToggleGroup:
ToggleGroup
├── ToggleGroupItem
└── ToggleGroupItemEjemplos#
Outline#
Usa variant="outline" para un estilo con contorno.
import {
ToggleGroup,
ToggleGroupItem,Tamaño#
Usa la prop size para cambiar el tamaño del grupo de botones.
import {
ToggleGroup,
ToggleGroupItem,Espaciado#
Usa spacing para añadir espacio entre los elementos del grupo.
import {
ToggleGroup,
ToggleGroupItem,Vertical#
Usa orientation="vertical" para grupos verticales.
import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react"
import {Deshabilitado#
import { Bold, Italic, Underline } from "lucide-react"
import {Personalizado#
Un ejemplo de grupo de botones personalizado.
"use client"
import * as React from "react"RTL#
Para activar el soporte RTL en Neobrutalism, consulta la guía de configuración de RTL.
"use client"
import * as React from "react"Accesibilidad#
Cada elemento es un botón conmutador según el patrón Button de WAI-ARIA: el grupo renderiza role="group" y cada elemento es un <button> real con aria-pressed, tanto en modo único como múltiple. El foco usa un tabindex itinerante (roving tabindex), así que todo el grupo es una única parada de tabulación. Los elementos de solo icono necesitan un aria-label.
Interacciones de teclado:
| Tecla | Acción |
|---|---|
Tab / Shift + Tab | Lleva el foco al grupo y lo saca de él |
Space / Enter | Alterna el elemento con foco |
ArrowRight / ArrowDown | Mueve el foco al siguiente elemento |
ArrowLeft / ArrowUp | Mueve el foco al elemento anterior |
Home / End | Salta al primer / último elemento |
Referencia de API#
Consulta la documentación de Base UI Toggle Group.
Registro de cambios#
2026-05-17 Espaciado predeterminado#
El valor predeterminado de spacing cambia de 0 a 2, de modo que los grupos ahora se muestran con espacio entre los elementos por defecto. Usa spacing={0} para elementos contiguos.