HextaUI

Toggle group

単一または複数の選択に使うトグルの列です。選ばれた項目へ塗りがスライドし、項目は連結も間隔を空けた配置もでき、矢印キーでフォーカスを移動できます。

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

export function ToggleGroupDemo() {
  return (
    <ToggleGroup aria-label="Date range" defaultValue={["week"]}>
      <ToggleGroupItem value="day">Day</ToggleGroupItem>
      <ToggleGroupItem value="week">Week</ToggleGroupItem>
      <ToggleGroupItem value="month">Month</ToggleGroupItem>
      <ToggleGroupItem value="year">Year</ToggleGroupItem>
    </ToggleGroup>
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/toggle-group.json

コンポーネント、HextaUIのテーマトークン、依存するHextaUIコンポーネントを追加します。

import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
<ToggleGroup aria-label="Date range" defaultValue={["week"]}>
  <ToggleGroupItem value="day">Day</ToggleGroupItem>
  <ToggleGroupItem value="week">Week</ToggleGroupItem>
  <ToggleGroupItem value="month">Month</ToggleGroupItem>
</ToggleGroup>

同時にオンにできる項目が1つのときは、1つの塗りが選択された項目へスライドしてその形になるため、グループは1つのコントロールとして見えます。multiple では各項目が個別に塗られます。塗りは最初の描画前に配置されるので、読み込み時にスライドして現れることはありません。

ToggleGroup
└── ToggleGroupItem

アウトライン

variant="outline" は、項目を1つの境界線付きコントロールにつなげます。

import {
  IconAlignCenter,
  IconAlignJustified,
  IconAlignLeft,
  IconAlignRight,
} from "@tabler/icons-react"

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

export function ToggleGroupOutline() {
  return (
    <ToggleGroup
      variant="outline"
      aria-label="Text alignment"
      defaultValue={["left"]}
    >
      <ToggleGroupItem value="left" aria-label="Align left">
        <IconAlignLeft />
      </ToggleGroupItem>
      <ToggleGroupItem value="center" aria-label="Align center">
        <IconAlignCenter />
      </ToggleGroupItem>
      <ToggleGroupItem value="right" aria-label="Align right">
        <IconAlignRight />
      </ToggleGroupItem>
      <ToggleGroupItem value="justify" aria-label="Justify">
        <IconAlignJustified />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

複数

multiple は、テキストの書式設定のように、任意の数の項目をオンにできるようにします。

import {
  IconBold,
  IconItalic,
  IconStrikethrough,
  IconUnderline,
} from "@tabler/icons-react"

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

export function ToggleGroupMultiple() {
  return (
    <ToggleGroup
      multiple
      variant="outline"
      aria-label="Text formatting"
      defaultValue={["bold", "italic"]}
    >
      <ToggleGroupItem value="bold" aria-label="Bold">
        <IconBold />
      </ToggleGroupItem>
      <ToggleGroupItem value="italic" aria-label="Italic">
        <IconItalic />
      </ToggleGroupItem>
      <ToggleGroupItem value="underline" aria-label="Underline">
        <IconUnderline />
      </ToggleGroupItem>
      <ToggleGroupItem value="strikethrough" aria-label="Strikethrough">
        <IconStrikethrough />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

サイズ

グループの size はすべての項目に適用されます。sm、default、lg。

import { IconBold, IconItalic, IconUnderline } from "@tabler/icons-react"

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

export function ToggleGroupSizes() {
  return (
    <div className="flex flex-col items-center gap-4">
      {(["sm", "default", "lg"] as const).map((size) => (
        <ToggleGroup
          key={size}
          multiple
          size={size}
          variant="outline"
          aria-label={`Formatting, ${size}`}
          defaultValue={["bold"]}
        >
          <ToggleGroupItem value="bold" aria-label="Bold">
            <IconBold />
          </ToggleGroupItem>
          <ToggleGroupItem value="italic" aria-label="Italic">
            <IconItalic />
          </ToggleGroupItem>
          <ToggleGroupItem value="underline" aria-label="Underline">
            <IconUnderline />
          </ToggleGroupItem>
        </ToggleGroup>
      ))}
    </div>
  )
}

間隔

spacing は、スペーシングスケールで項目間に gap を設けます。gap のある outline の項目は、それぞれ独自の境界線と塗りを保ちます。

import { IconStar } from "@tabler/icons-react"

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

export function ToggleGroupSpacing() {
  return (
    <div className="flex flex-col items-center gap-4">
      <ToggleGroup spacing={1} aria-label="Rating filter" defaultValue={["4"]}>
        {["1", "2", "3", "4", "5"].map((stars) => (
          <ToggleGroupItem key={stars} value={stars}>
            {stars}
            <IconStar />
          </ToggleGroupItem>
        ))}
      </ToggleGroup>
      <ToggleGroup
        multiple
        spacing={2}
        variant="outline"
        size="sm"
        aria-label="Topics"
        defaultValue={["design"]}
      >
        <ToggleGroupItem value="design">Design</ToggleGroupItem>
        <ToggleGroupItem value="engineering">Engineering</ToggleGroupItem>
        <ToggleGroupItem value="research">Research</ToggleGroupItem>
      </ToggleGroup>
    </div>
  )
}

アイコンとラベル

ラベルの前にアイコンを置きます。アイコンのみの項目には aria-label が必要です。

import { IconDeviceDesktop, IconMoon, IconSun } from "@tabler/icons-react"

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

export function ToggleGroupIcons() {
  return (
    <ToggleGroup aria-label="Theme" defaultValue={["system"]}>
      <ToggleGroupItem value="light">
        <IconSun />
        Light
      </ToggleGroupItem>
      <ToggleGroupItem value="dark">
        <IconMoon />
        Dark
      </ToggleGroupItem>
      <ToggleGroupItem value="system">
        <IconDeviceDesktop />
        System
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

垂直

orientation="vertical" は項目を縦に積み、↑ と ↓ でフォーカスを移動します。

import { IconLayoutGrid, IconLayoutList, IconList } from "@tabler/icons-react"

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

export function ToggleGroupVertical() {
  return (
    <ToggleGroup
      orientation="vertical"
      variant="outline"
      aria-label="Layout"
      defaultValue={["grid"]}
    >
      <ToggleGroupItem value="grid" aria-label="Grid">
        <IconLayoutGrid />
      </ToggleGroupItem>
      <ToggleGroupItem value="cards" aria-label="Cards">
        <IconLayoutList />
      </ToggleGroupItem>
      <ToggleGroupItem value="list" aria-label="List">
        <IconList />
      </ToggleGroupItem>
    </ToggleGroup>
  )
}

無効

1つの項目、またはグループ全体を disabled で無効にします。無効な項目はキーボードでスキップされます。

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

export function ToggleGroupDisabled() {
  return (
    <div className="flex flex-col items-center gap-4">
      <ToggleGroup aria-label="Plan" defaultValue={["pro"]}>
        <ToggleGroupItem value="free">Free</ToggleGroupItem>
        <ToggleGroupItem value="pro">Pro</ToggleGroupItem>
        <ToggleGroupItem value="team" disabled>
          Team
        </ToggleGroupItem>
      </ToggleGroup>
      <ToggleGroup
        disabled
        variant="outline"
        aria-label="Billing"
        defaultValue={["monthly"]}
      >
        <ToggleGroupItem value="monthly">Monthly</ToggleGroupItem>
        <ToggleGroupItem value="yearly">Yearly</ToggleGroupItem>
      </ToggleGroup>
    </div>
  )
}

制御

value と onValueChange を渡します。空の値を無視すると1つの項目がオンのままになるため、選択済みの項目をもう一度押しても何も起きません。

"use client"

import * as React from "react"

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

const views = ["Board", "List", "Calendar"]

export function ToggleGroupControlled() {
  const [view, setView] = React.useState("Board")

  return (
    <div className="flex flex-col items-center gap-3">
      <ToggleGroup
        variant="outline"
        aria-label="View"
        value={[view]}
        onValueChange={(value) => {
          if (value.length > 0) {
            setView(value[0])
          }
        }}
      >
        {views.map((item) => (
          <ToggleGroupItem key={item} value={item}>
            {item}
          </ToggleGroupItem>
        ))}
      </ToggleGroup>
      <p className="text-sm text-muted-foreground">Showing the {view} view.</p>
    </div>
  )
}

右から左

項目の順序、つながった角、スライドする塗り、矢印キーは文字の読み方向に従います。

import {
  IconAlignCenter,
  IconAlignLeft,
  IconAlignRight,
} from "@tabler/icons-react"

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

export function ToggleGroupRtl() {
  return (
    <div dir="rtl" className="flex flex-col items-center gap-4">
      <ToggleGroup aria-label="الفترة" defaultValue={["week"]}>
        <ToggleGroupItem value="day">يوم</ToggleGroupItem>
        <ToggleGroupItem value="week">أسبوع</ToggleGroupItem>
        <ToggleGroupItem value="month">شهر</ToggleGroupItem>
      </ToggleGroup>
      <ToggleGroup
        variant="outline"
        aria-label="محاذاة النص"
        defaultValue={["right"]}
      >
        <ToggleGroupItem value="right" aria-label="محاذاة لليمين">
          <IconAlignRight />
        </ToggleGroupItem>
        <ToggleGroupItem value="center" aria-label="توسيط">
          <IconAlignCenter />
        </ToggleGroupItem>
        <ToggleGroupItem value="left" aria-label="محاذاة لليسار">
          <IconAlignLeft />
        </ToggleGroupItem>
      </ToggleGroup>
    </div>
  )
}
キーアクション
Tabグループ内の最後にフォーカスした項目に移動し、次にグループの外へ移動します。
←→項目間を移動します。端で循環します。縦向きでは ↑ と ↓。
HomeEnd最初または最後の項目に移動します。
EnterSpaceフォーカスされている項目をオンまたはオフにします。
  • グループは group role を持つため、aria-label を付けてください。各項目は aria-pressed を持つボタンです。
  • タブ順に入る項目は1つだけなので、グループは1つのタブストップとなり、矢印キーでその中を移動します。
  • multiple がない場合、選択済みの項目を押すとオフになります。1つの項目をオンのままにするには、値を制御してください。
  • 視差効果の軽減が有効な場合、塗りはスライドせずにフェードします。
プロパティ型デフォルト
value
string[]–
defaultValue
string[]–
onValueChange
(value: string[], details) => void–
multiple
booleanfalse
variantすべての項目のバリアントを設定します。
"default" | "outline""default"
sizeすべての項目のサイズを設定します。
"default" | "sm" | "lg""default"
spacingスペーシングスケールでの項目間の間隔。0にすると outline の項目がつながります。
0 | 0.5 | 1 | 1.5 | 2 | 2.5 | 3 | 4 | 5 | 6 | 80
orientation
"horizontal" | "vertical""horizontal"
loopFocus
booleantrue
disabled
booleanfalse
render
ReactElement | (props, state) => ReactElement<div>
属性説明
data-slot="toggle-group"ルート。
data-slot="toggle-group-indicator"スライドする塗り。multiple がない場合に描画されます。項目がオンのとき data-visible が付きます。
data-variant / data-size / data-spacingグループのバリアント、サイズ、間隔。
data-orientation"horizontal" または "vertical"。
data-multiple複数の項目をオンにできるときに付きます。
data-disabledグループが無効なときに付与されます。
プロパティ型デフォルト
valueグループの value の中でその項目を識別します。
string–
disabled
booleanfalse
variantグループが何も設定していない場合に使われます。
"default" | "outline"–
sizeグループが何も設定していない場合に使われます。
"default" | "sm" | "lg"–
nativeButton
booleantrue
render
ReactElement | (props, state) => ReactElement<button>
属性説明
data-slot="toggle-group-item"各項目。
data-pressedその項目はオンです。
data-disabledその項目は無効です。
data-variant / data-size項目の解決済みのバリアントとサイズ。

使用しているブロック

Toggle group の上に構築されるブロック。