Steps
段階ナビゲーション(ウィザード)です。fandhe-frontend-headless-ui の steps mod は Root / List / Item / Trigger / Indicator / Separator / Content / CompletedContent / PrevTrigger / NextTrigger / Progress の 11 anatomy パーツと、complete/current/incomplete の 3 状態を導出する決定的な状態機械を提供します。Themes 版と異なりインジケーターの見た目を持たず、構造・aria-current="step" 等の属性・境界(先頭/末尾)判定のみを担います。
スタイル済みの表示例は Steps を参照してください。
キーボード操作
| キー | 対象 | 効果 |
|---|---|---|
| Tab / Shift+Tab | Trigger / PrevTrigger / NextTrigger | ネイティブ button 要素のフォーカス順序に従います。境界(step==0/step==count)では disabled によりフォーカス順序から除外されます(実装済み)。 |
| Enter / Space | Trigger / PrevTrigger / NextTrigger | ネイティブ button 要素の暗黙アクティベーション(click イベント発火)のみ機能します。fandhe-frontend-wasm-full の headless::MAPPING_TABLE に "steps" scope は登録されておらず、click から dispatch("goto"/"prev"/"next")への実配線は未実装です(イシュー #1665 時点で確認済み、別 Issue の起票対象)。呼び出し側が独自に配線するまで、Trigger をクリックしても step は遷移しません。 |
参考サイトとの差分
イシュー #1665 で ark-ui/Zag.js(steps machine)・chakra-ui の Steps と突合しました。
data-disabledの欠落を是正:prev_trigger/next_triggerの境界(step==0/step==count)で nativedisabledに加えてdata-disabledを出力するようにしました(本リポジトリの disabled 語彙統一)。data-orientationの欠落を是正: Zag.js が trigger/content に出力するdata-orientationを追加しました(completed-contentはcontentと対称にするための加算)。progressパーツを新設: Zag.js anatomy 10 パーツ中、本実装に唯一欠けていたパートです。role="progressbar"+aria-valuemin/aria-valuemax/aria-valuenow/aria-valuetextを出力し、step==count(全 step 完了)のときのみdata-completeを付与します。- 予約キーなりすまし除去を追加: 呼び出し側
attrsがrole/aria-*/data-*/type/hidden等の固定付与属性を偽装・重複出力できないようdrop_reservedを全パーツへ導入しました(toolbar/splitter等と同型のパターン)。
一方で以下は意図的に参照サイトと合わせていません。
- trigger の
data-state="open"\|"closed": 非採用(既存のcomplete/current/incompleteを維持)。変更するとfandhe-frontend-pre-styled-uiの golden CSS を壊す破壊的変更になります。 aria-current="step"の item への付与: 非採用(trigger のみに付与)。フォーカス可能な要素への付与が支援技術に読まれやすく、両方に付けると重複読み上げになります。- tabs 意味論(
listのrole="tablist"/aria-owns/aria-orientation、triggerのrole="tab"/aria-selected/aria-controls、contentのrole="tabpanel"/aria-labelledby/tabindex="0"): 非採用。id 相互参照の配管が必要でシグネチャ変更=破壊的変更になります(後続イシュー候補)。 - indicator の
aria-hidden="true": 非採用。trigger の子が indicator(数字)のみの構成が多く、無条件付与は trigger のアクセシブルネームを消してしまいます。 - root の
style="--percent"(装飾用 CSS 変数)・dir(RTL): 非採用(本リポジトリ横断で未採用の判断軸)。 data-skippable・linear時の roving tabIndex 制御・isStepValid/isStepSkippable: 非採用(アプリケーションロジック依存、UI 部品の責務境界外)。
関連 API: fandhe-frontend-headless-ui API
自前 CSS の最小例
Themes 版を使わず本部品を直接使う場合、[data-scope="steps"][data-part="..."] セレクタと data-state/data-complete/data-current/data-incomplete/data-orientation/data-disabled で見た目を組み立てます。
[data-scope="steps"][data-part="root"] {
display: flex;
flex-direction: column;
gap: 1rem;
}
[data-scope="steps"][data-part="root"][data-orientation="vertical"] {
flex-direction: row;
}
[data-scope="steps"][data-part="list"] {
display: flex;
list-style: none;
gap: 0.5rem;
padding: 0;
margin: 0;
}
[data-scope="steps"][data-part="trigger"][data-current] {
font-weight: 600;
}
[data-scope="steps"][data-part="indicator"][data-complete] {
background: #16a34a;
color: #fff;
}
[data-scope="steps"][data-part="content"][data-state="closed"] {
display: none;
}
[data-scope="steps"][data-part="prev-trigger"][data-disabled],
[data-scope="steps"][data-part="next-trigger"][data-disabled] {
opacity: 0.5;
cursor: not-allowed;
}
[data-scope="steps"][data-part="progress"] {
height: 4px;
background: #e5e7eb;
}
[data-scope="steps"] :focus-visible {
outline: 2px solid #2563eb;
outline-offset: 2px;
}Demo
枠線・余白は docs サイト側のデモ枠であり、fandhe-frontend-headless-ui 自体はスタイルを持ちません。
Features
- Root / List / Item / Trigger / Indicator / Separator / Content / CompletedContent / PrevTrigger / NextTrigger / Progress の 11 anatomy パーツを提供する(steps.rs:1-11。Progress はイシュー #1665 の参照突合で新設)。
- count/step から complete/current/incomplete の 3 状態を導出し、data-state・data-complete/-current/-incomplete へ一元反映する(steps.rs:24-34,89-121)。
- current な item の trigger のみ aria-current="step" を付与する(steps.rs:58-61,249-269)。
- trigger/content/completed-content は data-orientation を出力する(イシュー #1665 参照突合で加算。呼び出し側 CSS が単独パートのみでレイアウト条件化できるようにする)。
- separator は role="separator" + aria-hidden="true" で装飾要素として a11y ツリーから除外する(steps.rs:288-310)。
- prev_trigger/next_trigger は境界(step==0/step==count)で disabled + data-disabled 属性を付与する(イシュー #1665 で data-disabled を加算。本リポジトリの disabled 語彙統一)。
- progress は role="progressbar" + aria-valuemin/aria-valuemax/aria-valuenow/aria-valuetext を出力し、percent==100(全 step 完了)のときのみ data-complete を付与する(イシュー #1665 新設)。
- 呼び出し側 attrs からの role/aria-*/data-*/type/hidden のなりすまし・重複出力を drop_reserved で除去する(イシュー #1665、toolbar/splitter と同型)。
Anatomy
root
list
item
trigger
indicator
separator
progress
content
completed-content
prev-trigger
next-triggerAPI Reference
Arguments
| Name | Type | Default | Description |
|---|---|---|---|
Steps::new: count, step, orientation | usize, usize, Orientation | — | 全 step 数・現在位置・向き。fail-closed に正規化する(steps.rs:123-133,164-171)。 |
item/trigger/indicator/separator/content: index | usize | — | 0..count の step インデックス(3 状態・aria-current 判定の元、steps.rs:224-334)。 |
progress: attrs, children | Vec<(&str, &str)>, Vec<Node> | — | percent(step * 100 / count)を aria-valuenow/aria-valuetext へ出力する progressbar パーツ(イシュー #1665 新設)。 |
Data Attributes
| Part | Attribute | Observed Values |
|---|---|---|
completed-content | data-orientation | horizontal |
completed-content | data-state | closed |
content | data-orientation | horizontal |
content | data-state | open |
indicator | data-complete | (値なし) |
indicator | data-current | (値なし) |
indicator | data-incomplete | (値なし) |
indicator | data-state | complete, current, incomplete |
item | data-complete | (値なし) |
item | data-current | (値なし) |
item | data-incomplete | (値なし) |
item | data-orientation | horizontal |
item | data-state | complete, current, incomplete |
list | data-orientation | horizontal |
progress | data-orientation | horizontal |
root | data-orientation | horizontal |
separator | data-complete | (値なし) |
separator | data-current | (値なし) |
separator | data-orientation | horizontal |
separator | data-state | complete, current |
trigger | data-complete | (値なし) |
trigger | data-current | (値なし) |
trigger | data-incomplete | (値なし) |
trigger | data-orientation | horizontal |
trigger | data-state | complete, current, incomplete |
Examples
All steps completed
count==step(全 step 完了)で completed_content が表示される例です(Demo は 2 番目の step が current)。
Vertical orientation
Orientation::Vertical で trigger/content/progress の data-orientation="vertical" が反映される例です。
Accessibility
Keyboard Interactions
| Key | Description |
|---|---|
| Tab / Shift+Tab | trigger/prev-trigger/next-trigger はネイティブ button のためフォーカス順序に入る(disabled 境界では native disabled によりフォーカス順序から除外される)。 |
| Enter / Space | ネイティブ button の既定挙動(click イベント発火)のみ機能する。fandhe-frontend-wasm-full の headless::MAPPING_TABLE に "steps" scope は登録されておらず、trigger/prev-trigger/next-trigger の click から dispatch("goto"/"prev"/"next")への実配線は未実装(イシュー #1665 時点、別 Issue 起票対象)。 |
WAI-ARIA
| Attribute | Description |
|---|---|
| aria-current="step" | current な item の trigger のみに出力する(steps.rs:249-269)。 |
| role="separator" / aria-hidden="true" | separator に固定出力する(装飾要素、steps.rs:288-310)。 |
| data-disabled | prev-trigger/next-trigger の境界(step==0/step==count)で native disabled と併せて出力する(イシュー #1665 加算)。 |
| role="progressbar" / aria-valuemin / aria-valuemax / aria-valuenow / aria-valuetext | progress パーツに固定出力する(イシュー #1665 新設)。 |