ステッパー
stimeo--stepper
導出した状態・aria-current・linear 制約を備えたウィザードのステップ操作。
stimeo--stepper コントローラは、複数ステップの進行を管理する。専用の APG ウィジェットは無いため、現在ステップは操作要素(button)の aria-current="step" で表し、各ステップ li には現在番号から導出した data-state(complete / current / upcoming)を付与する。next/prev は 1 つ移動(端を越える移動は無視)、goto は index パラメータのステップへ移動する。linear=true では goto は現在+1 を超える飛び越しを抑止する(戻る方向は常に許可)。移動時は stimeo--stepper:change を発火する。ステップ内容やバリデーション、丸・線・番号の見た目は利用側の責務。
キーボード操作
| キー | 動作 |
|---|---|
| Enter / Space | ステップボタンを活性化(goto)。ネイティブ button の挙動。 |
| Tab | 各ステップボタンは通常のタブ順(ロービング/トラップなし)。 |
<%# Markup for the stepper (steps / wizard) demo.
The steps (ol + button) and the prev/next buttons are grouped under one controller
element. The library manages the current step number, sets data-state (complete /
current / upcoming) on each li, sets aria-current="step" on the current step's button,
enforces out-of-range / linear constraints, and fires the change event. The circle /
line / number look is in demo.css. %>
<div
class="stepper"
data-controller="stimeo--stepper"
data-stimeo--stepper-index-value="0">
<ol class="stepper__list">
<% %w[account profile review].each_with_index do |step, index| %>
<li class="stepper__step" data-stimeo--stepper-target="step">
<button
type="button"
class="stepper__button"
<%= "aria-current=\"step\"".html_safe if index.zero? %>
data-stimeo--stepper-index-param="<%= index %>"
data-action="click->stimeo--stepper#goto">
<span class="stepper__marker"><%= index + 1 %></span>
<span class="stepper__label"><%= t("components.stepper.demo.steps.#{step}") %></span>
</button>
</li>
<% end %>
</ol>
<div class="stepper__controls">
<button type="button" class="demo-trigger" data-action="click->stimeo--stepper#prev">
<%= t("components.stepper.demo.back") %>
</button>
<button type="button" class="demo-trigger" data-action="click->stimeo--stepper#next">
<%= t("components.stepper.demo.continue") %>
</button>
</div>
</div>
/*
* Presentation-only styles for the stepper demo.
* Complete / current / upcoming are built by reacting to each li's data-state
* (complete / current / upcoming) and the current button's aria-current="step". The
* state transitions are the library's.
*/
.stepper__list {
display: flex;
gap: 0;
margin: 0;
padding: 0;
list-style: none;
}
.stepper__step {
flex: 1;
position: relative;
text-align: center;
}
.stepper__step:not(:last-child)::after {
content: "";
position: absolute;
top: 1rem;
left: 50%;
width: 100%;
height: 2px;
background: var(--border-strong);
}
.stepper__step[data-state="complete"]::after {
background: var(--accent, var(--color-primary));
}
.stepper__button {
position: relative;
z-index: 1;
display: inline-flex;
flex-direction: column;
align-items: center;
gap: 0.4rem;
padding: 0;
border: 0;
background: none;
color: var(--color-text-muted);
font: inherit;
cursor: pointer;
}
.stepper__marker {
display: grid;
place-items: center;
width: 2rem;
height: 2rem;
border-radius: 50%;
border: 2px solid var(--border-strong);
background: var(--surface, var(--surface-card));
font-weight: 600;
}
.stepper__step[data-state="complete"] .stepper__marker {
border-color: var(--accent, var(--color-primary));
background: var(--accent, var(--color-primary));
color: var(--white);
}
.stepper__step[data-state="current"] .stepper__marker {
border-color: var(--accent, var(--color-primary));
color: var(--accent, var(--color-primary));
}
.stepper__button[aria-current="step"] {
color: var(--fg, var(--color-text));
font-weight: 600;
}
.stepper__controls {
display: flex;
gap: 0.5rem;
margin-top: 1.25rem;
}
このデモに固有の消費側 JS はありません(挙動はコントローラが担います)。
これらのスタイルは共通のデザイントークン(ライト/ダーク両対応)を使います。 共通スタイルも一緒にコピーし、ルート要素の data-theme を切り替えればダークになります。
このコンポーネントを動かすために HTML へ記述する data-* 属性です。ルート要素に下の data-controller を付け、その内側に各 target / value / action を配置します。
ルート要素に付与
data-controller="stimeo--stepper"
ターゲット
| 名前 | 説明 | 属性 |
|---|---|---|
step
必須
|
各ステップ項目。data-state(complete/current/upcoming)は現在インデックスから導出される。 |
data-stimeo--stepper-target="step" |
値(Values)
| 名前 | 説明 | 属性 |
|---|---|---|
index
|
現在のステップインデックス。connect 時に範囲内へ丸められる(既定 0)。 | data-stimeo--stepper-index-value |
linear
|
true のとき goto は 1 つ先までしか進めない。後退は常に許可(既定 false)。 | data-stimeo--stepper-linear-value |
アクション
| 名前 | 説明 | アクション |
|---|---|---|
goto
|
アクションの index パラメーターのステップへ移動する(linear 規則に従う)。 | stimeo--stepper#goto |
next
|
1 つ先へ進む。最終ステップでは無視。 | stimeo--stepper#next |
prev
|
1 つ前へ戻る。最初のステップでは無視。 | stimeo--stepper#prev |
イベント
| 名前 | 説明 | イベント |
|---|---|---|
change
|
ステップ移動後に発火。detail に index / previous / step 要素を持つ。 | stimeo--stepper:change |
状態フック
ライブラリが操作するのはこれらの ARIA / data 属性、カスタムプロパティだけです。見た目は利用側 CSS がこれらに反応して作ります([aria-selected] / [aria-expanded] / var(--stimeo--…) などのセレクタでフックします)。
| フック | 対象 | 意味 |
|---|---|---|
data-state |
ステップ(li) | 現在番号から導出した "complete" / "current" / "upcoming"。 |
aria-current |
現在ステップのボタン | 現在ステップのボタンにのみ "step"。 |