Tour
オンボーディング向けステップガイドです。fandhe-frontend-headless-ui の tour mod は Root / Backdrop / Spotlight / Positioner / Arrow / ArrowTip / Content / Title / Description / ProgressText / Control / CloseTrigger / ActionTrigger の 13 anatomy パーツと、Idle/Active/Skipped/Completed の決定的な状態機械を提供します。Themes 版と異なり対象要素の実座標追従・スポットライトの視覚表現を持たず、role="dialog" 等の構造・ARIA 属性と静的な配置情報の出力のみを担います。
スタイル済みの表示例は Tour を参照してください。
キーボード操作
| キー | 対象 | 効果 |
|---|---|---|
| Escape | Content | zag.js は closeOnEscape 既定で dismiss(本状態機械では "skip" dispatch 相当)へ写像します。状態機械は提供済みですが、DOM keydown 配線は fandhe-frontend-wasm-full に存在せず未実装です(イシュー #1666 時点で確認済み、別 Issue の起票対象)。 |
| ArrowRight / ArrowLeft | Content | zag.js は keyboardNavigation 既定で "next"/"prev" dispatch へ写像します。DOM keydown 配線は同様に未実装です。 |
| Space / Enter | ActionTrigger / CloseTrigger | ネイティブ <button type="button"> のため、ブラウザ既定動作としてすでに機能します。 |
| Tab / Shift+Tab | Content / 対象要素 | zag.js は trapFocus([content, target]) で Content と対象要素の間を巡回させます。フォーカストラップは配線されておらず未対応です(aria-modal="true" を付与しない理由も同じ、下記「参考サイトとの差分」参照)。 |
参考サイトとの差分
イシュー #1666 で ark-ui docs・実装(tour.anatomy.ts・tour-actions.tsx・tour-control.tsx)・zag.js(tour.anatomy.ts・tour.connect.ts・tour.machine.ts)と突合しました(Radix Primitives に Tour 相当は存在しません)。
controlパーツの欠落を是正: ark-ui 実装の実 DOM 値data-part="control"(docs の Anatomy 図が示す「Actions」ラベルに対応する DOM パーツ。Tour.Actions自体は DOM を描画しない render-prop コンポーネント)を追加しました。ActionTrigger/CloseTriggerを並べるコンテナとして使う想定です。contentのtabindex="-1"/data-step欠落を是正:crate::dialog/crate::popoverの content と同型のフォーカス移動の受け皿としてtabindex="-1"を固定付与し、Active時のみ現在ステップのidをdata-stepとして出力するようにしました(zagcontent.connect.ts準拠)。action_triggerのdata-type/disabled欠落を是正:TourTriggerKind(Next/Prev/Skip/Complete/Custom)引数を追加しdata-typeを出力するようにしました(破壊的シグネチャ変更)。Prevは dispatch が no-op になる境界(先頭ステップ・非 Active)でのみdisabled/data-disabledを付与します。- 予約キーなりすまし除去を追加: 呼び出し側
attrsがrole/aria-*/tabindex/data-*/disabled/idを偽装・重複出力できないようdrop_reservedを導入しました(toast/splitter等と同型のパターン)。aria-labelは素通しします。
一方で以下は意図的に参考サイトと合わせていません。
role="alertdialog": WAI-ARIAalertdialogは即時応答を要する警告向けであり、オンボーディング案内は該当しません(支援技術の割り込み読み上げを避けるため)。role="dialog"を維持します。aria-modal="true":fandhe-frontend-wasm-fullにツアー用フォーカストラップの配線がまだ無く、SSR でトラップされていない状態を偽って主張しません。トラップ配線が入った時点で再評価します。- content 自体の
aria-live:progress_textのみにaria-live="polite"を付与する既存方針を維持します(content と progress-text の二重ライブリージョンによる重複読み上げを避けるため)。 - ステップ種別
data-type(tooltip/dialog/floating/wait):type/effect/actionsの宣言的定義は初版スコープ外です(action-triggerのdata-typeは「アクション種別」の意味で採用し、ステップ種別の意味では出しません)。 data-placement/data-sideon content/title/description:positioning::placement_attrsは positioner のみへ出力する既存設計を維持します。data-nested/data-has-nested: ネスト popover 機構は未採用です。dismissedstatus(skipとの区別):data-status語彙・hydration 語彙の変更は Themes 側 CSS へ波及するため変更しません。Escape・close-trigger はいずれも"skip"dispatch へ写像します。arrowのhidden: tooltip 配置計測結果に依存する DOM ローカル状態のため非採用です。close-triggerの既定aria-label: 呼び出し側がattrs経由で明示的に渡す既存規約を維持します。nextの最終 step でのdisabled: 本状態機械では最終 step の"next"がCompletedへ遷移する有効な操作であるため disabled にしません(zag の!hasNextStep判定とは意図的に非同値)。
関連 API: fandhe-frontend-headless-ui API
自前 CSS の最小例
Themes 版を使わず本部品を直接使う場合、[data-scope="tour"][data-part="..."] セレクタと data-state/data-status/data-disabled/[hidden] で見た目を組み立てます。
[data-scope="tour"][data-part="backdrop"] {
position: fixed;
inset: 0;
}
[data-scope="tour"][data-part="spotlight"] {
position: fixed;
}
[data-scope="tour"][data-part="positioner"] {
position: fixed;
}
[data-scope="tour"][data-part="content"] {
max-width: 320px;
}
[data-scope="tour"][data-part="control"] {
display: flex;
gap: 0.5rem;
}
[data-scope="tour"][data-part="action-trigger"][data-disabled] {
opacity: 0.5;
cursor: not-allowed;
}
[data-scope="tour"] [hidden] {
display: none;
}
[data-scope="tour"] :focus-visible {
outline: 2px solid #2563eb;
outline-offset: 2px;
}Demo
枠線・余白は docs サイト側のデモ枠であり、fandhe-frontend-headless-ui 自体はスタイルを持ちません。
Page navigation
Use this menu to jump between sections.
Features
- Root / Backdrop / Spotlight / Positioner / Arrow / ArrowTip / Content / Title / Description / ProgressText / Control / CloseTrigger / ActionTrigger の 13 anatomy パーツを提供する(イシュー #1666 で Control を追加、tour.rs:1-13)。
- Idle/Active{step}/Skipped/Completed の決定的な状態機械を持ち、終端状態からのいずれのアクションも no-op(一度終了したツアーは暗黙に再開しない、tour.rs:34-52)。
- content は role="dialog" と tabindex="-1" を固定出力し、ContentIds が Some のときのみ aria-labelledby/aria-describedby を、Active 時のみ現在ステップの id を data-step として出力する(イシュー #1666、tour.rs 参照)。
- action_trigger は TourTriggerKind(Next/Prev/Skip/Complete/Custom)に応じて data-type を出力し、Prev は dispatch が no-op になる境界(先頭ステップ)でのみ disabled/data-disabled を付与する(イシュー #1666)。
- progress_text は aria-live="polite" を固定出力し、ステップ遷移を支援技術へ読み上げさせる。
- 対象要素の実座標追従・スポットライト実測値注入・target セレクタの実解決は fandhe-frontend-wasm-full の後続イシューのスコープ(本モジュールは data-target 出力と静的な data-side/data-align のみ)。
Anatomy
root
backdrop
spotlight
positioner
arrow
arrow-tip
content
title
description
progress-text
control
action-trigger
close-triggerAPI Reference
Arguments
| Name | Type | Default | Description |
|---|---|---|---|
Tour::new: steps | Vec<TourStep> | — | ツアーの全ステップ(初期状態は常に Idle、tour.rs:238-243)。 |
content: ids | ContentIds | ContentIds::default() | id/aria-labelledby/aria-describedby の関連付け先。 |
title/description: id | Option<&str> | None | Some のとき content の labelledby/describedby と対にする。 |
action_trigger: kind | TourTriggerKind | — | Next/Prev/Skip/Complete/Custom のいずれか。data-type 出力と Prev の disabled 判定に使う(イシュー #1666)。 |
Data Attributes
| Part | Attribute | Observed Values |
|---|---|---|
action-trigger | data-disabled | (値なし) |
action-trigger | data-type | next, prev |
arrow | data-state | open |
arrow-tip | data-state | open |
backdrop | data-state | open |
content | data-state | open |
content | data-step | step-1 |
control | data-state | open |
positioner | data-align | center |
positioner | data-side | bottom |
positioner | data-state | open |
root | data-state | open |
root | data-status | active |
spotlight | data-state | open |
spotlight | data-target | #docs-toc-heading |
Examples
Second step (2-step tour)
2 ステップ構成で 2 番目の step まで進めた例です(Demo は 1 ステップのみ)。
Full-text search
Use this box to search the whole site.
Accessibility
Keyboard Interactions
| Key | Description |
|---|---|
| Escape | zag.js は closeOnEscape 既定で dismiss へ写像する(本状態機械では "skip" dispatch 相当)。DOM keydown 配線は fandhe-frontend-wasm-full の後続イシューのスコープで未実装(イシュー #1666)。 |
| ArrowRight / ArrowLeft | zag.js は keyboardNavigation 既定で "next"/"prev" dispatch へ写像する。DOM keydown 配線は同様に未実装(イシュー #1666)。 |
| Space / Enter | close_trigger/action_trigger はネイティブ <button type="button"> のため、ブラウザ既定動作としてすでに機能する。 |
| Tab / Shift+Tab | zag.js は trapFocus([content, target]) で content と対象要素の間で巡回させる。本実装はフォーカストラップを配線しておらず未対応(イシュー #1666)。 |
WAI-ARIA
| Attribute | Description |
|---|---|
| role="dialog" | content に固定出力する。alertdialog(即時応答を要する警告向け)へは非追随(オンボーディング案内は該当しないため、イシュー #1666)。 |
| tabindex="-1" | content に固定出力する(フォーカス移動の受け皿、イシュー #1666)。 |
| aria-labelledby / aria-describedby | ContentIds が Some のときのみ content に出力する。 |
| aria-live="polite" | progress_text に固定出力する。 |