Components

Toggle Group

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

Installation

Cortexcn
pnpm dlx shadcn@latest add @cortexcn/toggle-group

Usage

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group";

Examples

Basic

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react"export function ToggleGroupBasic() {  return (    <div className="flex flex-col gap-6">      <ToggleGroup type="multiple" spacing={1}>        <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>    </div>  )}

Outline

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"export function ToggleGroupOutline() {  return (    <div className="flex flex-col gap-6">      <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>    </div>  )}

Outline with icons

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react"export function ToggleGroupOutlineWithIcons() {  return (    <div className="flex flex-col gap-6">      <ToggleGroup variant="outline" type="multiple" size="sm">        <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>    </div>  )}

Sizes

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"export function ToggleGroupSizes() {  return (    <div className="flex flex-col gap-6">      <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>    </div>  )}

With spacing

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"export function ToggleGroupSpacing() {  return (    <div className="flex flex-col gap-6">      <ToggleGroup type="single" size="sm" defaultValue="top" 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>    </div>  )}

With icons

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"import { BookmarkIcon, HeartIcon, StarIcon } from "lucide-react"export function ToggleGroupWithIcons() {  return (    <div className="flex flex-col gap-6">      <ToggleGroup type="multiple" variant="outline" spacing={1} size="sm">        <ToggleGroupItem          value="star"          aria-label="Toggle star"          className="aria-pressed:*:[svg]:stroke-foregfill-foreground aria-pressed:bg-transparent aria-pressed:*:[svg]:fill-foreground"        >          <StarIcon data-icon="inline-start" />          Star        </ToggleGroupItem>        <ToggleGroupItem          value="heart"          aria-label="Toggle heart"          className="aria-pressed:bg-transparent aria-pressed:*:[svg]:fill-foreground aria-pressed:*:[svg]:stroke-foreground"        >          <HeartIcon data-icon="inline-start" />          Heart        </ToggleGroupItem>        <ToggleGroupItem          value="bookmark"          aria-label="Toggle bookmark"          className="aria-pressed:bg-transparent aria-pressed:*:[svg]:fill-foreground aria-pressed:*:[svg]:stroke-foreground"        >          <BookmarkIcon data-icon="inline-start" />          Bookmark        </ToggleGroupItem>      </ToggleGroup>    </div>  )}

Filter

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"export function ToggleGroupFilter() {  return (    <div className="flex flex-col gap-6">      <ToggleGroup type="single" defaultValue="all" variant="outline" size="sm">        <ToggleGroupItem value="all" aria-label="All">          All        </ToggleGroupItem>        <ToggleGroupItem value="active" aria-label="Active">          Active        </ToggleGroupItem>        <ToggleGroupItem value="completed" aria-label="Completed">          Completed        </ToggleGroupItem>        <ToggleGroupItem value="archived" aria-label="Archived">          Archived        </ToggleGroupItem>      </ToggleGroup>    </div>  )}

Date range

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"export function ToggleGroupDateRange() {  return (    <div className="flex flex-col gap-6">      <ToggleGroup        type="single"        defaultValue="today"        variant="outline"        size="sm"        spacing={2}      >        <ToggleGroupItem value="today" aria-label="Today">          Today        </ToggleGroupItem>        <ToggleGroupItem value="week" aria-label="This Week">          This Week        </ToggleGroupItem>        <ToggleGroupItem value="month" aria-label="This Month">          This Month        </ToggleGroupItem>        <ToggleGroupItem value="year" aria-label="This Year">          This Year        </ToggleGroupItem>      </ToggleGroup>    </div>  )}

Sort

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"import { ArrowDownIcon, ArrowUpIcon, TrendingUpIcon } from "lucide-react"export function ToggleGroupSort() {  return (    <div className="flex flex-col gap-6">      <ToggleGroup        type="single"        defaultValue="newest"        variant="outline"        size="sm"      >        <ToggleGroupItem value="newest" aria-label="Newest">          <ArrowDownIcon data-icon="inline-start" />          Newest        </ToggleGroupItem>        <ToggleGroupItem value="oldest" aria-label="Oldest">          <ArrowUpIcon data-icon="inline-start" />          Oldest        </ToggleGroupItem>        <ToggleGroupItem value="popular" aria-label="Popular">          <TrendingUpIcon data-icon="inline-start" />          Popular        </ToggleGroupItem>      </ToggleGroup>    </div>  )}

With input and select

import { Input } from "@/components/input"import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/select"import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"export function ToggleGroupWithInputAndSelect() {  return (    <div className="flex flex-col gap-6">      <div className="flex items-center gap-2">        <Input type="search" placeholder="Search..." className="flex-1" />        <Select defaultValue="all">          <SelectTrigger className="w-32">            <SelectValue />          </SelectTrigger>          <SelectContent>            <SelectGroup>              <SelectItem value="all">All</SelectItem>              <SelectItem value="active">Active</SelectItem>              <SelectItem value="archived">Archived</SelectItem>            </SelectGroup>          </SelectContent>        </Select>        <ToggleGroup type="single" defaultValue="grid" variant="outline">          <ToggleGroupItem value="grid" aria-label="Grid view">            Grid          </ToggleGroupItem>          <ToggleGroupItem value="list" aria-label="List view">            List          </ToggleGroupItem>        </ToggleGroup>      </div>    </div>  )}

Vertical

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react"export function ToggleGroupVertical() {  return (    <div className="flex flex-col gap-6">      <ToggleGroup type="multiple" orientation="vertical" spacing={2}>        <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>    </div>  )}

Vertical outline

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"export function ToggleGroupVerticalOutline() {  return (    <div className="flex flex-col gap-6">      <ToggleGroup        variant="outline"        type="single"        defaultValue="all"        orientation="vertical"        size="sm"      >        <ToggleGroupItem value="all" aria-label="Toggle all">          All        </ToggleGroupItem>        <ToggleGroupItem value="active" aria-label="Toggle active">          Active        </ToggleGroupItem>        <ToggleGroupItem value="completed" aria-label="Toggle completed">          Completed        </ToggleGroupItem>        <ToggleGroupItem value="archived" aria-label="Toggle archived">          Archived        </ToggleGroupItem>      </ToggleGroup>    </div>  )}

Vertical outline with icons

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react"export function ToggleGroupVerticalOutlineWithIcons() {  return (    <div className="flex flex-col gap-6">      <ToggleGroup        variant="outline"        type="multiple"        orientation="vertical"        size="sm"      >        <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>    </div>  )}

Vertical with spacing

import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"export function ToggleGroupVerticalWithSpacing() {  return (    <div className="flex flex-col gap-6">      <ToggleGroup        type="single"        size="sm"        defaultValue="top"        orientation="vertical"        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>    </div>  )}

Font weight selector

Use font-normal to set the font weight.

import * as React from "react"import { Field, FieldDescription, FieldLabel } from "@/components/field"import { ToggleGroup, ToggleGroupItem } from "@/components/toggle-group"export function ToggleGroupFontWeightSelector() {  const [fontWeight, setFontWeight] = React.useState("normal")  return (    <div className="flex flex-col gap-6">      <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>    </div>  )}

Adapted from the shadcn/ui Toggle Group (MIT).