Klarhimmel UI

Toggle group

Stable

A row of toggles that belong together: pick one, or any number.

npx shadcn add @klarhimmel/toggle-group

When to use

  • Use for

    View switches, alignment and formatting tools that belong together.

  • Not for

    Moving between pages or panels. Use Tabs.

  • Pairs with

    Icons, Tooltip.

Preview

Aligned left

toggle-group.tsx
import { AlignCenter, AlignLeft } from 'lucide-react';
import { Theme } from '@/components/klarhimmel/theme/style';
import { ToggleGroup, ToggleGroupItem } from '@/components/klarhimmel/ui/toggle-group';

export default function Example() {
  return (
    <Theme theme="brand">
      <ToggleGroup label="Text alignment" type="single" defaultValue="left">
        <ToggleGroupItem value="left" aria-label="Left"><AlignLeft aria-hidden /></ToggleGroupItem>
        <ToggleGroupItem value="center" aria-label="Centre"><AlignCenter aria-hidden /></ToggleGroupItem>
      </ToggleGroup>
    </Theme>
  );
}

Install

Import

import { ToggleGroup, ToggleGroupItem } from '@/components/klarhimmel/ui/toggle-group';
Lands in
components/klarhimmel/ui/toggle-group.tsx, plus cn() and the theme item if they are missing. Import theme.css after Tailwind.
Render in
Render it inside <Theme>, once near the root of your app. Tokens and fonts are scoped to it, so outside it the component is unstyled.

Examples

  • Multiple

    Open sat, sun

    import { useState } from 'react';
    import { ToggleGroup, ToggleGroupItem } from '@/components/klarhimmel/ui/toggle-group';
    
    export default function ToggleGroupMultiple() {
      const [days, setDays] = useState<string[]>(['sat', 'sun']);
      return (
        <div className="flex flex-col items-start gap-3">
          <ToggleGroup label="Open days" type="multiple" value={days} onValueChange={setDays}>
            {['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'].map((d) => (
              <ToggleGroupItem key={d} value={d.toLowerCase()}>{d}</ToggleGroupItem>
            ))}
          </ToggleGroup>
          <p role="status" className="text-kh-small text-kh-muted">{days.length ? `Open ${days.join(', ')}` : 'Closed every day'}</p>
        </div>
      );
    }
  • View

    Showing the rooms as a list.

    import { useState } from 'react';
    import { ToggleGroup, ToggleGroupItem } from '@/components/klarhimmel/ui/toggle-group';
    
    export default function ToggleGroupView() {
      const [view, setView] = useState('list');
      return (
        <div className="flex w-[min(24rem,calc(100cqw-3rem))] flex-col gap-3">
          <ToggleGroup label="Show rooms as" type="single" value={view} onValueChange={(v) => setView(v || 'list')}>
            <ToggleGroupItem value="list">List</ToggleGroupItem>
            <ToggleGroupItem value="grid">Grid</ToggleGroupItem>
            <ToggleGroupItem value="map">Map</ToggleGroupItem>
          </ToggleGroup>
          <p role="status" className="rounded-kh-lg border border-dashed border-kh-line p-4 text-kh-small text-kh-muted">Showing the rooms as a {view}.</p>
        </div>
      );
    }

API reference

PropTypeDefaultDescription
type'single' | 'multiple'-Required. Single is a radio group (press the chosen one again to clear it); multiple is a group of pressed buttons.
labelstring-Required. Names the group.
value / defaultValue / onValueChangestring | string[]-A string when single, a list when multiple.
ToggleGroupItem valuestring-Required. An icon-only item needs an aria-label.
classNamestring-Extra classes, merged after the component's own.

Accessibility

KeyDoes
TabEnters and leaves the group as one stop (single mode)
Right / LeftMoves focus to the next or previous button, wrapping
Home / EndFirst or last button
Enter / SpacePresses the focused button

Single is a radio group; pressing the chosen button again clears it. Multiple is a group of pressed buttons.

Accessibility