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.
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.
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.
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.
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.
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.
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.
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.
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.
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[]) => voidCalled 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
valuestringIdentifier for this toggle (required).
Accessibility
Built to be keyboard-navigable and screen-reader friendly out of the box.
| Key | Function |
|---|---|
| Tab | Moves focus into the group. |
| Arrow+Right | Moves to the next toggle. |
| Arrow+Left | Moves to the previous toggle. |
| Space | Toggles 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.