Accordion
それぞれがパネルを表示する見出しの積み重ねです。途中で反転できる高さのモーションを持ち、閉じている間もパネルの内容を検索できます。
pnpm dlx shadcn@latest add https://hextaui.com/r/accordion.jsonコンポーネント、HextaUIのテーマトークン、依存するHextaUIコンポーネントを追加します。
まだ追加していない場合は、グローバルCSSにテーマトークンを追加してください。
依存関係をインストールします。
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cn次のコードをコピーしてプロジェクトに貼り付けてください。
components/ui/accordion.tsx インポートパスは、お使いのプロジェクト構成に合わせて更新してください。
アウトライン
項目は枠線付きの 1 つの面を共有し、外側の角が丸くなります。
Separated
各項目が独立したカードになります。
Ghost
枠線なし。トリガーはホバー時と開いているときに、淡い塗りが付きます。
複数
multiple を設定すると、複数の項目を開いたままにできます。
無効
個別の項目は <AccordionItem /> の disabled で、アコーディオン全体はルートで無効にできます。
制御
開いている項目を独自の state で管理するには、value と onValueChange を渡します。
カスタムアイコン
icon には任意の要素を渡せます。開いたときのスタイルは group-data-panel-open/accordion-trigger で指定します。
先頭のアイコン
ラベルの前に置くアイコンは、サイズと位置が自動で調整されます。icon={null} を指定すると山形アイコンが削除されます。
長いコンテンツ
長いタイトルは折り返されますが、アイコンは 1 行目に残ります。閉じたパネルも検索対象のままなので、Cmd/Ctrl+F で「retention」を検索するとこのパネルが開きます。
入れ子
内側のアコーディオンは、独自の variant、フォーカススタイル、矢印キーによる操作を保持します。
右から左
コンテンツ、アイコン、開くときのモーションは、読む方向に従います。
| キー | アクション |
|---|---|
| EnterSpace | フォーカス中の項目を開閉します。 |
| ↓ | フォーカスを次のトリガーに移動します。 |
| ↑ | フォーカスを前のトリガーに移動します。 |
| Home | フォーカスを最初のトリガーに移動します。 |
| End | フォーカスを最後のトリガーに移動します。 |
| Tab | フォーカスを開いたパネルの中へ移し、その後は次のトリガーへ移動します。 |
Base UI の accordion をベースにしています。各パーツは、ラップしているプリミティブの props をすべて受け付けます。
| プロパティ | 型 | デフォルト |
|---|---|---|
variant | "default" | "outline" | "separated" | "ghost" | "default" |
multiple複数の項目を同時に開けるようにします。 | boolean | false |
value | Value[] | – |
defaultValue | Value[] | – |
onValueChange | (value: Value[], details) => void | – |
disabled | boolean | false |
hiddenUntilFound閉じたパネルも、ブラウザのページ内検索で見つけられるようにします。 | boolean | true |
keepMountedhiddenUntilFound が有効な間は無視されます。 | boolean | false |
render | ReactElement | (props, state) => ReactElement | <div> |
| 属性 | 説明 |
|---|---|
data-slot="accordion" | CSSでルートを指定します。 |
data-variant | 現在のバリアント。 |
data-disabled | アコーディオンが無効なときに付与されます。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
value省略すると自動生成されます。 | Value | – |
disabled | boolean | false |
onOpenChange | (open: boolean, details) => void | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| 属性 | 説明 |
|---|---|
data-slot="accordion-item" | CSSで項目を指定します。 |
data-open | 項目が開いているときに付与されます。 |
data-disabled | 項目が無効のときに存在します。 |
data-index | 項目の位置。0 から始まります。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
iconnull を指定するとアイコンが削除されます。 | ReactNode | null | <IconChevronDown /> |
render | ReactElement | (props, state) => ReactElement | <button> |
| 属性 | 説明 |
|---|---|
data-slot="accordion-trigger" | CSSでトリガーを指定します。 |
data-panel-open | パネルが開いているときに付与されます。アイコンのスタイルは group-data-panel-open/accordion-trigger で指定します。 |
data-disabled | 項目が無効のときに存在します。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
className内側のラッパーに適用されるため、パディングが高さのアニメーションと干渉しません。 | string | – |
keepMounted | boolean | false |
hiddenUntilFound | boolean | – |
| 属性 | 説明 |
|---|---|
data-slot="accordion-content" | CSS でパネルを指定します。 |
data-open | パネルが開いているときに付与されます。 |
data-starting-style | パネルが開くアニメーションの間、付与されます。 |
data-ending-style | パネルが閉じるアニメーションの間、付与されます。 |
data-settled | パネルが完全に開いた時点で付与されます。このときクリッピングが解除されるため、ネストしたアコーディオン内のフォーカスリングが全体表示されます。 |
--accordion-panel-height | 高さアニメーションに使われる、パネルの計測された高さ。 |
- Aspect ratioメディアの読み込み前も形を保ち、読み込み中はシマー表示になり、メディアをフェードインさせ、失敗時はフォールバックを表示するボックスです。
- Carouselネイティブのスクロールスナップによるスライドです。タッチでの慣性、マウスドラッグ、矢印キー、ドット、サムネイル、適切なタイミングで一時停止する自動再生に対応します。
- Collapsible高さのモーションで表示と非表示を切り替えるパネルです。途中で反転でき、レイアウトが跳ねません。
- Resizableドラッグで分割できるパネルです。ホバーで目覚める控えめな区切り線、リセットや折りたたみで滑らかに動くサイズ、永続化されるレイアウトに対応します。
- Scroll area最小限のスクロールバーを備えたネイティブスクロールです。端は続きがある側だけフェードし、最後の項目を半分で切って見せるピークも任意で使えます。
- Separatorコンテンツを水平または垂直に区切る細線です。ラベルを付けたり、見た目だけの線として装飾モードにしたりできます。