Zum Inhalt springen

Umschaltgruppe

Zweistufige Schaltflächengruppen für Editor-Symbolleisten, Ansichtsumschalter und Filterleisten – mit dem neobrutalistischen Design mit Rahmen und Schatten.

import { Bold, Italic, Underline } from "lucide-react"

import {

Die Toggle Group ist eine Reihe von Buttons mit zwei Zuständen, von denen einer (der Standard) oder mehrere (multiple) zugleich gedrückt sein können. Sie basiert auf der Base UI Toggle Group-Komponente und folgt dem neobrutalistischen Rezept: dicke Rahmen, harte Schatten und kräftige Typografie.

Typische Anwendungsfälle:

  • Editor-Toolbars – Fett/Kursiv/Unterstrichen, Textausrichtung, Listenstile mit multiple.
  • Ansichtsumschalter – Raster vs. Liste, Diagramm vs. Tabelle, Tag/Woche/Monat; der Standard hält höchstens einen Eintrag aktiv.
  • Filterleisten – Tags, Kategorien oder Facetten, die Nutzer beliebig zu- und abschalten.

Installation

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

Installiere die folgenden Abhängigkeiten:

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

Kopiere den folgenden Code und füge ihn in dein Projekt ein.

components/ui/toggle-group.tsx
"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 }

Passe die Importpfade an dein Projekt-Setup an.

Verwendung

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>

Komposition

Verwende die folgende Komposition, um eine ToggleGroup zu erstellen:

ToggleGroup
├── ToggleGroupItem
└── ToggleGroupItem

Beispiele

Outline

Verwende variant="outline" für einen Umriss-Stil.

import {
  ToggleGroup,
  ToggleGroupItem,

Größe

Verwende die size-Prop, um die Größe der Toggle Group zu ändern.

import {
  ToggleGroup,
  ToggleGroupItem,

Abstand

Verwende spacing, um Abstand zwischen den Elementen der Toggle Group hinzuzufügen.

import {
  ToggleGroup,
  ToggleGroupItem,

Vertical

Verwende orientation="vertical" für vertikale Toggle Groups.

import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react"

import {

Deaktiviert

import { Bold, Italic, Underline } from "lucide-react"

import {

Benutzerdefiniert

Ein Beispiel für eine benutzerdefinierte Toggle Group.

"use client"

import * as React from "react"

RTL

Um RTL-Unterstützung in Neobrutalism zu aktivieren, siehe die RTL-Konfigurationsanleitung.

"use client"

import * as React from "react"

Barrierefreiheit

Jeder Eintrag ist ein Toggle-Button nach dem WAI-ARIA-Pattern „Button“: Die Gruppe rendert role="group", und jeder Eintrag ist ein echter <button> mit aria-pressed – im Einzel- wie im Mehrfachmodus. Der Fokus nutzt einen Roving Tabindex, die gesamte Gruppe ist also ein einziger Tab-Stopp. Icon-only-Einträge brauchen ein aria-label.

Tastaturinteraktionen:

TasteAktion
Tab / Shift + TabBewegt den Fokus in die Gruppe hinein und aus ihr heraus
Space / EnterSchaltet den fokussierten Eintrag um
ArrowRight / ArrowDownBewegt den Fokus zum nächsten Eintrag
ArrowLeft / ArrowUpBewegt den Fokus zum vorherigen Eintrag
Home / EndSpringt zum ersten / letzten Eintrag

API-Referenz

Siehe die Dokumentation zu Base UI Toggle Group.

Changelog

2026-05-17 Standardabstand

Der Standardwert von spacing wurde von 0 auf 2 geändert, sodass Toggle Groups standardmäßig mit Abstand zwischen den Elementen dargestellt werden. Verwende spacing={0} für zusammenhängende Elemente.