shadcn-remix
GitHub

Toggle Group

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

import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })
import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })

export function ToggleGroupDemo() {
  return () => (
    <ToggleGroup variant="outline" type="multiple">
      <ToggleGroupItem value="bold" aria-label="Toggle bold">
        <BoldIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="italic" aria-label="Toggle italic">
        <ItalicIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="strikethrough" aria-label="Toggle strikethrough">
        <UnderlineIcon mix={icon} />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

Installation

$ pnpm dlx shadcn@latest add https://www.shadcn-remix.com/r/toggle-group.json

Usage

import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'
<ToggleGroup type="single">
  <ToggleGroupItem value="a">A</ToggleGroupItem>
  <ToggleGroupItem value="b">B</ToggleGroupItem>
  <ToggleGroupItem value="c">C</ToggleGroupItem>
</ToggleGroup>

Examples

Outline

Use variant="outline" for an outline style.

import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })
import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })

export function ToggleGroupOutline() {
  return () => (
    <ToggleGroup type="multiple" variant="outline">
      <ToggleGroupItem value="bold" aria-label="Toggle bold">
        <BoldIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="italic" aria-label="Toggle italic">
        <ItalicIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="strikethrough" aria-label="Toggle strikethrough">
        <UnderlineIcon mix={icon} />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

Spacing

Use spacing to add spacing between toggle group items.

import { css } from 'remix/component'

import { BookmarkIcon, HeartIcon, StarIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

function filledWhenOn(color: string) {
import { css } from 'remix/component'

import { BookmarkIcon, HeartIcon, StarIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

function filledWhenOn(color: string) {
  return css({
    '&[data-state="on"]': { backgroundColor: 'transparent' },
    '&[data-state="on"] > svg': { fill: color, stroke: color },
  })
}

const star = filledWhenOn('oklch(79.5% 0.184 86.047)')
const heart = filledWhenOn('oklch(63.7% 0.237 25.331)')
const bookmark = filledWhenOn('oklch(62.3% 0.214 259.815)')

export function ToggleGroupSpacing() {
  return () => (
    <ToggleGroup type="multiple" variant="outline" spacing={2} size="sm">
      <ToggleGroupItem value="star" aria-label="Toggle star" mix={star}>
        <StarIcon />
        Star
      </ToggleGroupItem>
      <ToggleGroupItem value="heart" aria-label="Toggle heart" mix={heart}>
        <HeartIcon />
        Heart
      </ToggleGroupItem>
      <ToggleGroupItem value="bookmark" aria-label="Toggle bookmark" mix={bookmark}>
        <BookmarkIcon />
        Bookmark
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

Disabled

import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })
import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })

export function ToggleGroupDisabled() {
  return () => (
    <ToggleGroup type="multiple" disabled>
      <ToggleGroupItem value="bold" aria-label="Toggle bold">
        <BoldIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="italic" aria-label="Toggle italic">
        <ItalicIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="strikethrough" aria-label="Toggle strikethrough">
        <UnderlineIcon mix={icon} />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

Lg

import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })
import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })

export function ToggleGroupLg() {
  return () => (
    <ToggleGroup type="multiple" size="lg">
      <ToggleGroupItem value="bold" aria-label="Toggle bold">
        <BoldIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="italic" aria-label="Toggle italic">
        <ItalicIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="strikethrough" aria-label="Toggle strikethrough">
        <UnderlineIcon mix={icon} />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

Single

import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })
import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })

export function ToggleGroupSingle() {
  return () => (
    <ToggleGroup type="single">
      <ToggleGroupItem value="bold" aria-label="Toggle bold">
        <BoldIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="italic" aria-label="Toggle italic">
        <ItalicIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="strikethrough" aria-label="Toggle strikethrough">
        <UnderlineIcon mix={icon} />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

Sm

import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })
import { css } from 'remix/component'

import { BoldIcon, ItalicIcon, UnderlineIcon } from '#app/ui/icons.tsx'
import { ToggleGroup, ToggleGroupItem } from '#app/ui/toggle-group.tsx'

const icon = css({ height: '1rem', width: '1rem' })

export function ToggleGroupSm() {
  return () => (
    <ToggleGroup type="single" size="sm">
      <ToggleGroupItem value="bold" aria-label="Toggle bold">
        <BoldIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="italic" aria-label="Toggle italic">
        <ItalicIcon mix={icon} />
      </ToggleGroupItem>
      <ToggleGroupItem value="strikethrough" aria-label="Toggle strikethrough">
        <UnderlineIcon mix={icon} />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

API Reference

ToggleGroup

PropTypeDefault
type"multiple" | "single"-
valuestring | string[]-
defaultValuestring | string[]-
onValueChange((value: string) => void) | ((value: string[]) => void)-
variantToggleVariant-
sizeToggleSize-
spacingnumber0
disabledboolean-
rovingFocusboolean-
loopbooleantrue
orientation"horizontal" | "vertical"-
dir"rtl" | "ltr"-
mixMixValue-

ToggleGroupItem

PropTypeDefault
valuestring-
variantToggleVariant-
sizeToggleSize-
mixMixValue-