Accordion
アコーディオン要素を作成できるUIコンポーネントです。
<details> / <summary> ではなく、<div> / <button> ベースで構成されており、JavaScriptで開閉アニメーションを制御します。
パネルには hidden="until-found" を活用しているため、アコーディオンが閉じた状態でもブラウザのページ内検索でコンテンツを検出でき、ヒット時に自動的にパネルが展開されます。
Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint.
Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint.
<Accordion.Root> <Accordion.Item> <Accordion.Heading> <Accordion.Button p="20">Accordion Example</Accordion.Button> </Accordion.Heading> <Accordion.Panel p="20" pt="5"> <DummyText length="l" /> </Accordion.Panel> </Accordion.Item> <Accordion.Item bd-t> <Accordion.Heading> <Accordion.Button p="20">Accordion Example 2</Accordion.Button> </Accordion.Heading> <Accordion.Panel p="20" pt="5"> <DummyText length="l" /> </Accordion.Panel> </Accordion.Item></Accordion.Root>How to use
@lism-css/ui パッケージでAccordionとして提供しています。
Import
import { Accordion } from '@lism-css/ui/react'; 以下のコンポーネントが利用できます。
<Accordion.Root>: 複数のアコーディオンアイテムをラップするルート要素(Stackベース)<Accordion.Item>: 個別のアコーディオン要素<Accordion.Heading>: 見出しエリアのラッパー(デフォルトは<div role="heading">)<Accordion.Button>: 開閉トリガーのボタン(末尾に<Accordion.Icon>を自動で含みます)<Accordion.Icon>: 開閉状態を示すアイコン(CSS疑似要素で描画)<Accordion.Panel>: 開閉されるコンテンツパネル(hidden="until-found"を使用)
Props
| プロパティ | 説明 |
|---|---|
<Accordion.Root> allowMultiple | 複数のアコーディオンを同時に展開できるようにします。デフォルトでは一つしか展開できません。 |
<Accordion.Item> isOpen | アイテムを初期状態で展開します(data-opened を付与)。<Accordion.Button> / <Accordion.Panel> の isOpen と併せて指定します。 |
<Accordion.Heading> as | 見出しのHTMLタグを指定します。デフォルトは div(role="heading" が自動付与されます)。h2〜h6 を指定すると role は付与されません。 |
<Accordion.Button> isOpen | 初期展開状態に合わせて aria-expanded を設定します。 |
<Accordion.Panel> flow | パネル内のコンテンツ領域(__content)に渡すフローレイアウトの設定。 |
<Accordion.Panel> isOpen | パネルを初期表示します(hidden を解除)。 |
基本構造
<Accordion.Root> <Accordion.Item> <Accordion.Heading> <Accordion.Button>Accordion Label</Accordion.Button> </Accordion.Heading> <Accordion.Panel p="20" pt="5"> ...Contents... </Accordion.Panel> </Accordion.Item></Accordion.Root><Accordion.Button> には、末尾に <Accordion.Icon> が自動的に配置されます。
アイコンはCSSの疑似要素(::before / ::after)で描画されるため、SVGの指定は不要です。
ソースコード
ソースコードは GitHub で公開しています。
Examples
見出しタグを変更する
<Accordion.Heading> はデフォルトでは <div role="heading"> として出力されますが、as に h3 などの見出しタグを指定することで、実際の見出し要素として出力できます。
Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint.
Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint.
<Accordion.Root bd> <Accordion.Item> <Accordion.Heading as="h3"> <Accordion.Button p="20">Accordion Label</Accordion.Button> </Accordion.Heading> <Accordion.Panel p="20" pt="5"> <DummyText length="l" /> </Accordion.Panel> </Accordion.Item> <Accordion.Item bd-t> <Accordion.Heading as="h3"> <Accordion.Button p="20">Accordion Label</Accordion.Button> </Accordion.Heading> <Accordion.Panel p="20" pt="5"> <DummyText length="l" /> </Accordion.Panel> </Accordion.Item></Accordion.Root>アニメーション時間を変更する
アコーディオンの開閉アニメーションの速度は --duration 変数で管理されており、デフォルトは 0.25s です。
<Accordion.Root>(全体)または <Accordion.Item>(個別)に CSS変数として指定することで変更できます。
Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint.
Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint.
<Accordion.Root style={{ '--duration': '.15s' }}> <Accordion.Item> <Accordion.Heading> <Accordion.Button p="20">Accordion Example 1</Accordion.Button> </Accordion.Heading> <Accordion.Panel p="20" pt="5"> ... </Accordion.Panel> </Accordion.Item> ...</Accordion.Root>最初の一つを開いた状態にする
初期状態で展開しておきたいアイテムには、<Accordion.Item> / <Accordion.Button> / <Accordion.Panel> のそれぞれに isOpen を指定します。
isOpen はコンポーネントごとに役割が異なるため、3つ揃えて指定します。
<Accordion.Item> では data-opened を付与してパネルの高さとアイコンを開いた状態にし、<Accordion.Button> では aria-expanded を、<Accordion.Panel> では hidden の切り替えを担当します。
Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint.
Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint.
<Accordion.Root bd> <Accordion.Item isOpen> <Accordion.Heading> <Accordion.Button p="20" isOpen>Accordion Label 1</Accordion.Button> </Accordion.Heading> <Accordion.Panel p="20" pt="5" isOpen> ... </Accordion.Panel> </Accordion.Item> <Accordion.Item bd-t> <Accordion.Heading> <Accordion.Button p="20">Accordion Label 2</Accordion.Button> </Accordion.Heading> <Accordion.Panel p="20" pt="5"> ... </Accordion.Panel> </Accordion.Item></Accordion.Root>複数同時展開を許可する
デフォルトでは、同じ <Accordion.Root> 内で一つのアコーディオンしか同時に展開できません。
allowMultiple を指定することで、複数を同時に展開できるようになります。
Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint.
Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint. Occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis undeomnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam.
Lorem ipsum dolor sit amet. Consectetur adipiscing elit, sed do eiusmod tempor Incididunt ut. Labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut. Aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint.
<Accordion.Root allowMultiple bd> <Accordion.Item> <Accordion.Heading> <Accordion.Button p="20">Accordion Label 1</Accordion.Button> </Accordion.Heading> <Accordion.Panel p="20" pt="5"> ... </Accordion.Panel> </Accordion.Item> <Accordion.Item bd-t> <Accordion.Heading> <Accordion.Button p="20">Accordion Label 2</Accordion.Button> </Accordion.Heading> <Accordion.Panel p="20" pt="5"> ... </Accordion.Panel> </Accordion.Item> ...</Accordion.Root>