codefast/ui

Command Palette

Search for a command to run...

Source
Form

Toggle Group

Single or multiple selection group of toggle buttons. Ideal for toolbars and alignment pickers.

Examples

Disabled

A set of two-state buttons that can be toggled on or off.

18 lines
import { ToggleGroup, ToggleGroupItem } from "@codefast/ui/toggle-group";
import { Bold, Italic, Underline } from "lucide-react";

export function ToggleGroupDisabled() {
  return (
    <ToggleGroup disabled type="multiple">
      <ToggleGroupItem value="bold" aria-label="Toggle bold">
        <Bold />
      </ToggleGroupItem>
      <ToggleGroupItem value="italic" aria-label="Toggle italic">
        <Italic />
      </ToggleGroupItem>
      <ToggleGroupItem value="strikethrough" aria-label="Toggle strikethrough">
        <Underline />
      </ToggleGroupItem>
    </ToggleGroup>
  );
}

Custom

A custom toggle group example.

Use font-normal to set the font weight.

56 lines
import { Field, FieldDescription, FieldLabel } from "@codefast/ui/field";
import { ToggleGroup, ToggleGroupItem } from "@codefast/ui/toggle-group";
import * as React from "react";

export function ToggleGroupFontWeightSelector() {
  const [fontWeight, setFontWeight] = React.useState("normal");
  return (
    <Field>
      <FieldLabel>Font Weight</FieldLabel>
      <ToggleGroup
        type="single"
        value={fontWeight}
        onValueChange={(value) => setFontWeight(value)}
        variant="outline"
        spacing={2}
        size="lg"
      >
        <ToggleGroupItem
          value="light"
          aria-label="Light"
          className="flex size-16 flex-col items-center justify-center rounded-xl"
        >
          <span className="text-2xl leading-none font-light">Aa</span>
          <span className="text-xs text-muted-foreground">Light</span>
        </ToggleGroupItem>
        <ToggleGroupItem
          value="normal"
          aria-label="Normal"
          className="flex size-16 flex-col items-center justify-center rounded-xl"
        >
          <span className="text-2xl leading-none font-normal">Aa</span>
          <span className="text-xs text-muted-foreground">Normal</span>
        </ToggleGroupItem>
        <ToggleGroupItem
          value="medium"
          aria-label="Medium"
          className="flex size-16 flex-col items-center justify-center rounded-xl"
        >
          <span className="text-2xl leading-none font-medium">Aa</span>
          <span className="text-xs text-muted-foreground">Medium</span>
        </ToggleGroupItem>
        <ToggleGroupItem
          value="bold"
          aria-label="Bold"
          className="flex size-16 flex-col items-center justify-center rounded-xl"
        >
          <span className="text-2xl leading-none font-bold">Aa</span>
          <span className="text-xs text-muted-foreground">Bold</span>
        </ToggleGroupItem>
      </ToggleGroup>
      <FieldDescription>
        Use <code className="rounded-md bg-muted px-1 py-0.5 font-mono">font-{fontWeight}</code> to set the font weight.
      </FieldDescription>
    </Field>
  );
}

Outline

Use variant='outline' for an outline style.

14 lines
import { ToggleGroup, ToggleGroupItem } from "@codefast/ui/toggle-group";

export function ToggleGroupOutline() {
  return (
    <ToggleGroup variant="outline" type="single" defaultValue="all">
      <ToggleGroupItem value="all" aria-label="Toggle all">
        All
      </ToggleGroupItem>
      <ToggleGroupItem value="missed" aria-label="Toggle missed">
        Missed
      </ToggleGroupItem>
    </ToggleGroup>
  );
}

RTL

Right-to-left layout support for languages such as Arabic and Hebrew.

Translations are AI-generated for demonstration and may be imperfect.

49 lines
import { ToggleGroup, ToggleGroupItem } from "@codefast/ui/toggle-group";

import type { Translations } from "#/features/components-catalog/components/detail/language";
import { useTranslation } from "#/features/components-catalog/components/detail/language-context";

const translations: Translations = {
  en: {
    dir: "ltr",
    values: {
      list: "List",
      grid: "Grid",
      cards: "Cards",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      list: "قائمة",
      grid: "شبكة",
      cards: "بطاقات",
    },
  },
  he: {
    dir: "rtl",
    values: {
      list: "רשימה",
      grid: "רשת",
      cards: "כרטיסים",
    },
  },
};

export function ToggleGroupRtl() {
  const { t } = useTranslation(translations, "ar");

  return (
    <ToggleGroup variant="outline" type="single" defaultValue="list">
      <ToggleGroupItem value="list" aria-label={t.list}>
        {t.list}
      </ToggleGroupItem>
      <ToggleGroupItem value="grid" aria-label={t.grid}>
        {t.grid}
      </ToggleGroupItem>
      <ToggleGroupItem value="cards" aria-label={t.cards}>
        {t.cards}
      </ToggleGroupItem>
    </ToggleGroup>
  );
}

Size

Use the size prop to change the size of the toggle group.

36 lines
import { ToggleGroup, ToggleGroupItem } from "@codefast/ui/toggle-group";

export function ToggleGroupSizes() {
  return (
    <div className="flex flex-col gap-4">
      <ToggleGroup type="single" size="sm" defaultValue="top" variant="outline">
        <ToggleGroupItem value="top" aria-label="Toggle top">
          Top
        </ToggleGroupItem>
        <ToggleGroupItem value="bottom" aria-label="Toggle bottom">
          Bottom
        </ToggleGroupItem>
        <ToggleGroupItem value="left" aria-label="Toggle left">
          Left
        </ToggleGroupItem>
        <ToggleGroupItem value="right" aria-label="Toggle right">
          Right
        </ToggleGroupItem>
      </ToggleGroup>
      <ToggleGroup type="single" defaultValue="top" variant="outline">
        <ToggleGroupItem value="top" aria-label="Toggle top">
          Top
        </ToggleGroupItem>
        <ToggleGroupItem value="bottom" aria-label="Toggle bottom">
          Bottom
        </ToggleGroupItem>
        <ToggleGroupItem value="left" aria-label="Toggle left">
          Left
        </ToggleGroupItem>
        <ToggleGroupItem value="right" aria-label="Toggle right">
          Right
        </ToggleGroupItem>
      </ToggleGroup>
    </div>
  );
}

Spacing

Use spacing to add spacing between toggle group items.

20 lines
import { ToggleGroup, ToggleGroupItem } from "@codefast/ui/toggle-group";

export function ToggleGroupSpacing() {
  return (
    <ToggleGroup type="single" size="sm" defaultValue="top" variant="outline" spacing={2}>
      <ToggleGroupItem value="top" aria-label="Toggle top">
        Top
      </ToggleGroupItem>
      <ToggleGroupItem value="bottom" aria-label="Toggle bottom">
        Bottom
      </ToggleGroupItem>
      <ToggleGroupItem value="left" aria-label="Toggle left">
        Left
      </ToggleGroupItem>
      <ToggleGroupItem value="right" aria-label="Toggle right">
        Right
      </ToggleGroupItem>
    </ToggleGroup>
  );
}

Vertical

Use orientation='vertical' for vertical toggle groups.

18 lines
import { ToggleGroup, ToggleGroupItem } from "@codefast/ui/toggle-group";
import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react";

export function ToggleGroupVertical() {
  return (
    <ToggleGroup type="multiple" orientation="vertical" spacing={1} defaultValue={["bold", "italic"]}>
      <ToggleGroupItem value="bold" aria-label="Toggle bold">
        <BoldIcon />
      </ToggleGroupItem>
      <ToggleGroupItem value="italic" aria-label="Toggle italic">
        <ItalicIcon />
      </ToggleGroupItem>
      <ToggleGroupItem value="underline" aria-label="Toggle underline">
        <UnderlineIcon />
      </ToggleGroupItem>
    </ToggleGroup>
  );
}

Usage

The minimal import and composition — see Examples below for styled, real-world variants.

18 lines
import { ToggleGroup, ToggleGroupItem } from "@codefast/ui/toggle-group";
import { AlignCenterIcon, AlignLeftIcon, AlignRightIcon } from "lucide-react";

export function ToggleGroupUsage() {
  return (
    <ToggleGroup defaultValue="left" type="single">
      <ToggleGroupItem aria-label="Align left" value="left">
        <AlignLeftIcon />
      </ToggleGroupItem>
      <ToggleGroupItem aria-label="Align center" value="center">
        <AlignCenterIcon />
      </ToggleGroupItem>
      <ToggleGroupItem aria-label="Align right" value="right">
        <AlignRightIcon />
      </ToggleGroupItem>
    </ToggleGroup>
  );
}

Anatomy

How the parts nest — every slot the component exposes, in composition order.

ToggleGroup
└── ToggleGroupItem

Features

  • type="single" behaves like a radio group (string value); type="multiple" toggles independently (string[] value).
  • size/variant set on the group cascade to every item automatically — no need to repeat them per item.
  • spacing={0} merges items into one segmented control with shared borders; spacing > 0 keeps them as separate pill buttons.
  • orientation="vertical" stacks items in a column instead of a row.

API reference

Props for each part of the component. All native element props are also forwarded.

ToggleGroup

A set of related toggles sharing one value.

type"single" | "multiple"

Single makes value a string; multiple makes it a string[].

valuestring | string[]

The controlled pressed item(s). In single mode value can be empty.

defaultValuestring | string[]

The pressed item(s) when initially rendered (uncontrolled).

onValueChange(value: string | string[]) => void

Called when the pressed item(s) change.

variant"default" | "outline"

Visual style of the buttons.

Default"default"

size"sm" | "default" | "lg"

Button size for the whole group.

Default"default"

ToggleGroupItem

valuestring

Identifier for this toggle (required).

Accessibility

Built to be keyboard-navigable and screen-reader friendly out of the box.

KeyFunction
TabMoves focus into the group.
Arrow+RightMoves to the next toggle.
Arrow+LeftMoves to the previous toggle.
SpaceToggles the focused button.
  • Single mode behaves as a radio group; multiple mode as a set of toggle buttons.
  • Icon-only items must carry an aria-label, since there’s no visible text.
  • In single mode, guard onValueChange against the empty string to keep a selection.

Guidelines

Conventions that keep usage consistent across an app.

Do

  • Use single for mutually-exclusive choices (alignment).
  • Use multiple for independent marks (bold, italic).

Don’t

  • Don’t mix unrelated actions into one group.
  • Don’t leave icon items without an accessible label.

Explore further

Ready to integrate?

Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.