Accordion
アコーディオン。見出しを押して中身を開く。長い内容を畳んでおける
状態を持ちません
素の details / summary に乗っています。 開閉もキーボードも読み上げも、
ブラウザが既に持っています。
<Accordion>
<AccordionItem>
<AccordionTrigger>見出し</AccordionTrigger>
<AccordionContent>中身</AccordionContent>
</AccordionItem>
</Accordion>aria-expanded は書いていません。ブラウザが既に申告しており、書くと二重になります。
一度に1つだけ開く
同じ name を項目に渡してください。 これもブラウザが面倒を見ます。
<AccordionItem name="faq">…</AccordionItem>
<AccordionItem name="faq">…</AccordionItem>枠が名前を作って配る形にはしていません。安定した名前を作るには useId が要り、
枠がクライアント側のコンポーネントになるためです。いまのコンポーネントはどれもサーバ側で描けます。
開閉にアニメーションが付きます
中身の高さが伸び縮みします。開閉を示す三角と同じ時間で動くので、 三角が回りきってから中身が現れる、ということになりません。
アニメーションは ::details-content という擬似要素に当てています。
クラスでは書けないので、規則はトークン層の CSS が持っています。
AccordionItem が付ける属性を見て当たります。
動きを減らす設定(prefers-reduced-motion)のときは止まります。 利用側で何かする必要はありません。
閉じていても中身は DOM にあります
details は閉じていても中身を持ちます。検索で見つかり、印刷にも出ます。
描かないようにしたいときは、利用側が中身の側で決めてください。
既定の三角は出ません
summary の三角は display: list-item に付くので、flex にすると出なくなります。
list-style だけでは Safari で残ります。効いているのは flex の方です。
3つの状態
通常・空・エッジケースの3つは、どのコンポーネントにも必ずあります。
通常default.tsx
通常。素の `details` に乗っている。
値はどこから来ますか
開いた状態で描くこともできます
空empty.tsx
空。中身の無い折りたたみ。
まだ中身がありません
エッジケースedge.tsx
エッジケース。一度に1つだけ開くときと、取っ手が長いとき。
一度に1つだけ開きます
同じ名前を渡しています
取っ手がとても長いときでも、矢印に重ならずに折り返します。 Supercalifragilisticexpialidocious のような長い語も枠を破りません。
props
Prop
Type
型と説明はコンポーネントのソースから抽出しています。既定値は出していません——cva の defaultVariants は 署名に現れないので、表に出すと「引数のデフォルトが書かれているものだけ」になり、嘘になります。