依存フィールド
stimeo--conditional-fields
トリガーとなるコントロールの値に応じて領域を表示/非表示・有効/無効化する。
stimeo--conditional-fields コントローラはトリガーを監視し、条件が成立する領域を表示/非表示に切り替えつつ hidden / aria-hidden / disabled を同期します。各領域は data-when-checked / data-when-unchecked / data-when-value="x" で条件を宣言し、トリガーが複数なら match(any/all)でまとめます。非表示の間は領域内の入力を(disableHidden 時)disabled にして送信から外し、フォーカスがある領域を隠すときはトリガーへフォーカスを退避します。connect でトリガー値から状態を再評価し(Morph 安全)、stimeo--conditional-fields:change を発火します。ライブラリは挙動のみを提供します。
<%# Conditional fields demo: check the box to reveal the address fieldset. The
controller toggles hidden / aria-hidden and disables the hidden inputs (so they
drop out of submission); it listens for the change itself, so no consumer JS is
needed. This demo only styles the layout. %>
<div class="conditional-fields-demo">
<form data-controller="stimeo--conditional-fields">
<label class="conditional-fields-demo__toggle">
<input type="checkbox" data-stimeo--conditional-fields-target="trigger">
<%= t("components.conditional_fields.demo.toggle") %>
</label>
<fieldset
class="conditional-fields-demo__region"
data-stimeo--conditional-fields-target="region"
data-when-checked
hidden>
<legend><%= t("components.conditional_fields.demo.legend") %></legend>
<label class="conditional-fields-demo__field">
<span><%= t("components.conditional_fields.demo.street") %></span>
<input type="text" name="street">
</label>
<label class="conditional-fields-demo__field">
<span><%= t("components.conditional_fields.demo.city") %></span>
<input type="text" name="city">
</label>
</fieldset>
</form>
</div>
/*
* Presentation-only styles for the conditional-fields demo.
* The library toggles hidden / aria-hidden / disabled and data-visible; this CSS
* only lays out the toggle and the revealed fieldset.
*/
.conditional-fields-demo {
max-width: 28rem;
}
.conditional-fields-demo form {
display: flex;
flex-direction: column;
gap: 1rem;
}
.conditional-fields-demo__toggle {
display: flex;
align-items: center;
gap: 0.5rem;
}
.conditional-fields-demo__region {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin: 0;
padding: 1rem;
border: 1px solid var(--border);
border-radius: 0.5rem;
}
.conditional-fields-demo__field {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.conditional-fields-demo__field input {
padding: 0.5rem;
border: 1px solid var(--border);
border-radius: 0.375rem;
font: inherit;
}
このデモに固有の消費側 JS はありません(挙動はコントローラが担います)。
これらのスタイルは共通のデザイントークン(ライト/ダーク両対応)を使います。 共通スタイルも一緒にコピーし、ルート要素の data-theme を切り替えればダークになります。
このコンポーネントを動かすために HTML へ記述する data-* 属性です。ルート要素に下の data-controller を付け、その内側に各 target / value / action を配置します。
ルート要素に付与
data-controller="stimeo--conditional-fields"
ターゲット
| 名前 | 説明 | 属性 |
|---|---|---|
trigger
必須
|
値/チェック状態が領域を駆動するコントロール。 | data-stimeo--conditional-fields-target="trigger" |
region
必須
|
data-when-* 条件で表示/非表示される要素。 |
data-stimeo--conditional-fields-target="region" |
値(Values)
| 名前 | 説明 | 属性 |
|---|---|---|
disableHidden
|
非表示領域内の入力を disabled にして送信しないようにするか(既定 true)。 |
data-stimeo--conditional-fields-disable-hidden-value |
match
|
複数トリガーの結合方法。any か all(既定 any)。 |
data-stimeo--conditional-fields-match-value |
アクション
| 名前 | アクション |
|---|---|
evaluate
|
stimeo--conditional-fields#evaluate |
イベント
| 名前 | 説明 | イベント |
|---|---|---|
change
|
領域の表示状態が変化したときに発火。detail.region / detail.visible を伴う。 |
stimeo--conditional-fields:change |
状態フック
ライブラリが操作するのはこれらの ARIA / data 属性、カスタムプロパティだけです。見た目は利用側 CSS がこれらに反応して作ります([aria-selected] / [aria-expanded] / var(--stimeo--…) などのセレクタでフックします)。
| フック | 対象 | 意味 |
|---|---|---|
hidden / aria-hidden |
領域 | 領域の条件が成立しない間に付与。 |
disabled |
非表示領域内の入力 | (disableHidden 時)付与し送信から除外。 |
data-visible |
領域 | 領域が表示されている間に付与。 |