sashigane
コンポーネント

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` に乗っている。

値はどこから来ますか
唯一の根本定数は 16px です。余白も文字サイズも行高も、そこから規則で導きます。
開いた状態で描くこともできます
その後の開閉はブラウザが持ちます。

空empty.tsx

空。中身の無い折りたたみ。

まだ中身がありません

エッジケースedge.tsx

エッジケース。一度に1つだけ開くときと、取っ手が長いとき。

一度に1つだけ開きます
下を開くと、こちらが閉じます。
同じ名前を渡しています
上が閉じたはずです。
取っ手がとても長いときでも、矢印に重ならずに折り返します。 Supercalifragilisticexpialidocious のような長い語も枠を破りません。
中身。

props

Prop

Type

型と説明はコンポーネントのソースから抽出しています。既定値は出していません——cva の defaultVariants は 署名に現れないので、表に出すと「引数のデフォルトが書かれているものだけ」になり、嘘になります。

On this page