Collapsible
単一の開閉パネルです。fandhe-frontend-headless-ui の collapsible mod は Root / Trigger / Indicator / Content の 4 anatomy パーツと、開閉状態を表す data-state・aria-expanded・aria-controls を提供します。開閉状態の遷移は open/close/toggle の dispatch で行い、closed のときは hidden 存在属性を付与して JS なしの SSR でも閉状態を表現します。indicator/content は disabled 引数を受け取り、data-disabled を root/trigger と同じく 4 パートすべてへ反映します(ネイティブ disabled 存在属性は button にのみ付与し、span/div には付与しません)。fandhe-frontend-pre-styled-ui に対応するスタイル済み部品があります。Themes 版は Collapsible を参照してください。
キーボード操作
| キー | 対象 | 効果 |
|---|---|---|
| Space / Enter | Trigger | ネイティブ <button type="button"> のため、フォーカス時の Space/Enter によるクリック相当の発火はブラウザ標準操作として成立します。クリックから開閉切替への dispatch 配線("toggle")は fandhe-frontend-wasm-full の責務です。 |
| Tab | Trigger | trigger のみがタブ順に含まれます。closed の content は hidden 存在属性によりタブ順・支援技術双方から除外されます。 |
参考サイトとの差分
ark-ui・Radix Primitives の Collapsible と突合し、content/indicator への data-disabled 追加・キーボード操作の明示を是正しました(イシュー #1637)。一方、以下は意図的に合わせていません。
contentのdata-collapsible存在属性(ark-ui)は採用しません。本クレートはdata-scope="collapsible" data-part="content"を常に出力するため、同じ情報を重複して持たせるだけで状態値でもないからです。- サイズ計測・アニメーション系(ark-ui の
data-has-collapsed-size・--height/--width等の CSS 変数、Radix の--radix-collapsible-content-*)は headless-ui へ持ち込みません。レイアウト計測・アニメーションの関心であり(docs/policy/intentional-non-adoption.md§3.25 規則 2)、必要ならスタイル済み部品(Themes 側、fandhe-frontend-pre-styled-ui)の責務です。 rootのdata-disabledは維持します。ark-ui の Root には無い属性ですが、Radix Primitives の Root には存在し、fandhe-frontend-wasm-fullの祖先 root disabled 判定が既存契約として依存しているためです。
関連 API: fandhe-frontend-headless-ui API
自前 CSS の最小例
Themes 版(fandhe-frontend-pre-styled-ui::collapsible)を使わず headless 層を直接使う場合は、[data-scope="collapsible"][data-part="..."] セレクタでスタイルを当てます。以下は indicator の回転アニメーション、content の折り畳み、disabled の見た目、フォーカスリングの最小例です(開閉アニメーション用の高さ計測は含みません。高さ計測を伴うアニメーションは JS 前提のレイアウト計測の関心のため、Themes 版でも意図的に非採用です)。
[data-scope="collapsible"][data-part="trigger"] {
display: inline-flex;
align-items: center;
gap: 0.25rem;
border: 1px solid #ccc;
border-radius: 4px;
padding: 0.375rem 0.75rem;
background: none;
cursor: pointer;
}
[data-scope="collapsible"][data-part="trigger"]:focus-visible {
outline: 2px solid #06c;
outline-offset: 2px;
}
[data-scope="collapsible"][data-part="indicator"] {
transition: transform 0.15s ease;
}
[data-scope="collapsible"][data-part="indicator"][data-state="open"] {
transform: rotate(180deg);
}
[data-scope="collapsible"][data-part="content"][data-state="closed"] {
display: none;
}
[data-scope="collapsible"][data-part="content"][data-state="open"] {
padding: 0.5rem 0;
}
[data-scope="collapsible"] [data-disabled] {
opacity: 0.5;
cursor: not-allowed;
}Demo
枠線・余白は docs サイト側のデモ枠であり、fandhe-frontend-headless-ui 自体はスタイルを持ちません。
Features
- Disclosure を埋め込んだ単純な開閉状態機械 Collapsible を提供する(dispatch: open/close/toggle)。
- Root / Trigger / Indicator / Content の 4 anatomy パーツで構成される。
- trigger は type="button" を固定付与し、フォーム内配置時の意図しない submit を防ぐ。
- content は closed のとき hidden 存在属性を付与し、JS なしの SSR でも閉状態を表現する。
- content / indicator は disabled 状態を data-disabled へ反映する(#1637。ネイティブ disabled 存在属性は div/span に無効なため付与しない)。
- Space/Enter はネイティブ button 経由(wasm-full の MAPPING_TABLE がクリックを toggle dispatch へ配線する、#1637)。
Anatomy
root
trigger
indicator
contentAPI Reference
Arguments
| Name | Type | Default | Description |
|---|---|---|---|
root: state | OpenState | Closed | パネル全体の開閉状態(data-state へ反映)。 |
root: disabled | bool | — | disabled 状態(data-disabled へ反映)。 |
trigger: state | OpenState | Closed | 開閉状態(aria-expanded/data-state へ反映)。 |
trigger: disabled | bool | — | disabled 状態(ネイティブ disabled 属性 + data-disabled の両方へ反映)。 |
trigger: controls | Option<&str> | — | Some のとき aria-controls で content と関連付ける。 |
indicator: state | OpenState | Closed | 開閉状態を data-state へ反映する装飾用パーツ。 |
indicator: disabled | bool | — | disabled 状態(data-disabled へ反映。#1637、ark-ui Indicator 準拠)。 |
content: state | OpenState | Closed | 開閉状態(closed のとき hidden 存在属性を付与)。 |
content: disabled | bool | — | disabled 状態(data-disabled へ反映。#1637、ark-ui/Radix Content 準拠)。 |
content: id | Option<&str> | — | trigger の controls と対で aria-controls 関連付けを成立させる。 |
Data Attributes
| Part | Attribute | Observed Values |
|---|---|---|
content | data-disabled | (値なし) |
content | data-state | closed, open |
indicator | data-disabled | (値なし) |
indicator | data-state | closed, open |
root | data-disabled | (値なし) |
root | data-state | closed, open |
trigger | data-disabled | (値なし) |
trigger | data-state | closed, open |
Examples
Disabled trigger
disabled な trigger はネイティブ disabled 属性と data-disabled が付与され、フォーカス・展開ができなくなります。
Accessibility
Keyboard Interactions
| Key | Description |
|---|---|
| Space / Enter | trigger はネイティブ <button type="button"> のため、フォーカス時の Space/Enter によるクリック相当の発火はブラウザ標準操作として成立する。クリックから開閉切替への dispatch 配線("toggle")は fandhe-frontend-wasm-full の MAPPING_TABLE の責務(#1637)。 |
| Tab | trigger のみがタブ順に含まれる。closed の content は hidden 存在属性によりタブ順・支援技術双方から除外される。 |
WAI-ARIA
| Attribute | Description |
|---|---|
| aria-expanded | trigger に付与。開閉状態(open で true)を表す。 |
| aria-controls | trigger に付与。controls が Some のとき対応する content の id を指す。 |
| hidden | content に付与(closed のとき)。支援技術・タブ順の双方から除外する。 |