Segmented
Segmentedは、排他的な単一選択を提供するピル型のコントロールです。タブやフィルターの切り替えに最適です。
Playground
<Segmented defaultValue="play">
<Segmented.Item value="prev">Prev</Segmented.Item>
<Segmented.Item value="play">Play</Segmented.Item>
<Segmented.Item value="next">Next</Segmented.Item>
</Segmented>Variants
defaultPill StyleoutlineBordered StyleunderlineTab StyleghostMinimal StyleSizes
Text Only
smmddefaultlg| Size | 高さ | 横パディング | フォント | プレビュー |
|---|---|---|---|---|
sm | 32px | 14px | 12px | |
md | 36px | 14px | 13px | |
default | 40px | 16px | 13px | |
lg | 48px | 24px | 14px |
Icon Only (正方形)
smmddefaultlg| Size | コンテナ高さ | アイテムサイズ | アイコン | プレビュー |
|---|---|---|---|---|
sm | 32px | 24px × 24px | 14px | |
md | 36px | 28px × 28px | 16px | |
default | 40px | 32px × 32px | 16px | |
lg | 48px | 40px × 40px | 16px |
Icon + Text
smmddefaultlg| Size | 高さ | 横パディング | Gap | アイコン | フォント | プレビュー |
|---|---|---|---|---|---|---|
sm | 32px | 12px | 8px | 14px | 12px | |
md | 36px | 14px | 8px | 16px | 13px | |
default | 40px | 16px | 8px | 16px | 13px | |
lg | 48px | 24px | 8px | 16px | 14px |
Features
Use Cases
Notion, Linear, タスク管理アプリ
Stripe, Google Analytics, ダッシュボード
Figma, Notion, プロジェクト管理ツール
SaaS料金ページ、サブスクリプション
// Status Filter — Notion, Linear style
<Segmented defaultValue="all">
<Segmented.Item value="all">すべて</Segmented.Item>
<Segmented.Item value="active">有効</Segmented.Item>
<Segmented.Item value="completed">完了</Segmented.Item>
</Segmented>
// Date Range Filter — Stripe, Analytics style
<Segmented defaultValue="30d">
<Segmented.Item value="7d">7日</Segmented.Item>
<Segmented.Item value="30d">30日</Segmented.Item>
<Segmented.Item value="90d">90日</Segmented.Item>
</Segmented>
// View Switch — Figma, Notion style
<Segmented defaultValue="table">
<Segmented.Item value="table">テーブル</Segmented.Item>
<Segmented.Item value="board">ボード</Segmented.Item>
<Segmented.Item value="calendar">カレンダー</Segmented.Item>
</Segmented>
// Billing Cycle — SaaS pricing style
<Segmented defaultValue="yearly">
<Segmented.Item value="monthly">月払い</Segmented.Item>
<Segmented.Item value="yearly">年払い</Segmented.Item>
</Segmented>States
Default
選択されたアイテムはハイライト表示。
Disabled
全アイテムが無効化された状態。
個別 Disabled
特定のアイテムのみ無効化。
多数のアイテム
2〜5個のアイテムに最適。
API
Component Structure
Segmented— Radix RadioGroup.ItemPropsセグメントアイテムProps
Segmented
valueundefinedstring制御モードでの選択値
defaultValueundefinedstring非制御モードでの初期選択値
onValueChangeundefined(value: string) => void選択変更時のコールバック
variant"default""default" | "outline" | "underline" | "ghost"スタイルバリアント(default: iOS風, outline: ボーダー風, underline: Stripe風, ghost: Notion風)
size"default""sm" | "md" | "default" | "lg"セグメントのサイズ (32/36/40/48px)
radius"default""none" | "sm" | "base" | "default" | "lg" | "xl" | "2xl" | "3xl" | "full"角丸のサイズ (6px)
fontWeight"normal""normal" | "semibold"フォントの太さ(全variantでnormalがデフォルト)
disabledfalseboolean全アイテム無効状態
| Name | Type | Default | Description |
|---|---|---|---|
value | string | undefined | 制御モードでの選択値 |
defaultValue | string | undefined | 非制御モードでの初期選択値 |
onValueChange | (value: string) => void | undefined | 選択変更時のコールバック |
variant | "default" | "outline" | "underline" | "ghost" | "default" | スタイルバリアント(default: iOS風, outline: ボーダー風, underline: Stripe風, ghost: Notion風) |
size | "sm" | "md" | "default" | "lg" | "default" | セグメントのサイズ (32/36/40/48px) |
radius | "none" | "sm" | "base" | "default" | "lg" | "xl" | "2xl" | "3xl" | "full" | "default" | 角丸のサイズ (6px) |
fontWeight | "normal" | "semibold" | "normal" | フォントの太さ(全variantでnormalがデフォルト) |
disabled | boolean | false | 全アイテム無効状態 |
Segmented.Item
value—stringアイテムの一意な値
disabledfalseboolean個別の無効状態
sizeinherit"sm" | "md" | "default" | "lg"個別のサイズ上書き
radiusinherit"none" | "sm" | ... | "full"個別の角丸上書き
contentType"text""text" | "icon-text" | "icon"コンテンツタイプ(icon: 正方形、icon-text: gap付き、text: 標準)
| Name | Type | Default | Description |
|---|---|---|---|
value | string | — | アイテムの一意な値 |
disabled | boolean | false | 個別の無効状態 |
size | "sm" | "md" | "default" | "lg" | inherit | 個別のサイズ上書き |
radius | "none" | "sm" | ... | "full" | inherit | 個別の角丸上書き |
contentType | "text" | "icon-text" | "icon" | "text" | コンテンツタイプ(icon: 正方形、icon-text: gap付き、text: 標準) |
Customization
すべてのアイテムはデザインシステムのスペーシングルールに基づいたデフォルト値を使用します。グループのclassNameで全アイテムを一括カスタマイズできます。
横パディングの変更
className="[&>button]:px-10"Icon Onlyの幅変更
className="[&>button]:aspect-auto [&>button]:px-5"Tip:デフォルト値はコンポーネントの一貫性を保つよう設計されています。UI実装上カスタマイズが必要な場合にご活用ください。
Anatomy
Best Practices
推奨
- ✓2〜5個の排他的なオプションに使用
- ✓同じコンテンツエリア内のビュー切替に使用
- ✓ラベルは短く簡潔に(1〜2語)
- ✓フィルターやソートの切り替えに最適
避けるべき
- ✗6個以上のオプションには使用しない
- ✗ページナビゲーションには使用しない(→ Tabs)
- ✗複数選択が必要な場合は使用しない(→ ToggleGroup)
- ✗長いラベルテキストを使用しない
Accessibility
キーボード操作
ARIA属性
role="radiogroup"自動付与role="radio"各アイテムに付与aria-checked自動更新- フォーカスインジケーター
Segmented vs Tabs
似たような見た目ですが、用途と構造が異なります。適切なコンポーネントを選択してください。
用途
Segmented: 値の選択(フィルター、切替)
Tabs: コンテンツナビゲーション
構造
Segmented: 単独コンポーネント
Tabs: TabList + TabPanel の組み合わせ
結果
Segmented: 同じエリア内のデータ変更
Tabs: パネルの切替表示
配置
Segmented: コンテンツ内、どこでも
Tabs: ページ/セクションの上部
Radix Primitive
Segmented: RadioGroup
Tabs: @radix-ui/react-tabs
| 特徴 | Segmented | Tabs |
|---|---|---|
| 用途 | 値の選択(フィルター、切替) | コンテンツナビゲーション |
| 構造 | 単独コンポーネント | TabList + TabPanel の組み合わせ |
| 結果 | 同じエリア内のデータ変更 | パネルの切替表示 |
| 配置 | コンテンツ内、どこでも | ページ/セクションの上部 |
| Radix Primitive | RadioGroup | @radix-ui/react-tabs |
使い分けのポイント:Segmentedは「同じコンテンツエリア内で表示を変える」場合に使用。Tabsは「異なるコンテンツパネルを切り替える」場合に使用します。