ダイアログ
stimeo--dialog
アクセシブルなモーダルダイアログ。フォーカスを閉じ込め、背景のスクロールを止め、Esc で閉じます。
WAI-ARIA のモーダルダイアログパターンをそのまま実装しています。開くとフォーカスがダイアログの中へ移り、Tab を押し続けても外へ出ません。開いている間は背景のスクロールが止まります。Esc で閉じると、フォーカスは開いたときのボタンへ戻ります。背景をクリックしても閉じます。
実行中
アクションの確認
本当に実行してもよろしいですか?
キーボード操作
| キー | 動作 |
|---|---|
| Tab / Shift+Tab | ダイアログ内でフォーカスを循環させる(フォーカストラップ)。 |
| Esc | ダイアログを閉じ、フォーカスをトリガーへ戻す。 |
<%# Markup for the dialog demo.
The single source used for both the live render and the copy-paste code.
stimeo--dialog provides the focus trap, Esc, and background scroll lock.
The behavior is the library's; the look (classes) is the Playground's CSS. %>
<div class="dialog" data-controller="stimeo--dialog">
<button
type="button"
class="demo-trigger"
data-stimeo--dialog-target="trigger"
data-action="click->stimeo--dialog#open">
<%= t("components.dialog.demo.open_button") %>
</button>
<%# The role="dialog" + aria-modal region. Starts hidden (closed).
Clicking this element itself (the backdrop) also closes it. %>
<div
class="dialog__backdrop"
role="dialog"
aria-modal="true"
aria-labelledby="dialog-title"
data-stimeo--dialog-target="dialog"
data-action="click->stimeo--dialog#closeOnBackdrop"
hidden>
<div class="dialog__panel">
<h3 id="dialog-title" class="dialog__title"><%= t(
"components.dialog.demo.confirm_title"
) %></h3>
<p><%= t("components.dialog.demo.confirm_desc") %></p>
<div class="dialog__actions">
<button
type="button"
class="demo-trigger"
data-action="click->stimeo--dialog#close"><%= t(
"components.dialog.demo.cancel"
) %></button>
<button
type="button"
class="demo-trigger demo-trigger--primary"
data-action="click->stimeo--dialog#close"><%= t(
"components.dialog.demo.ok"
) %></button>
</div>
</div>
</div>
</div>
/* Use the role="dialog" region as a centered backdrop. */
.dialog__backdrop {
position: fixed;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
background: rgba(0, 0, 0, 0.5);
z-index: 50;
}
/* Setting display explicitly overrides the hidden attribute's default display:none, so
re-declare display:none while closed to honor the library's hidden control. */
.dialog__backdrop[hidden] {
display: none;
}
.dialog__panel {
width: min(28rem, 100%);
padding: 1.5rem;
background: var(--bg);
border-radius: 0.5rem;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
}
.dialog__title {
margin: 0 0 0.5rem;
}
.dialog__actions {
display: flex;
gap: 0.5rem;
justify-content: flex-end;
margin-top: 1.5rem;
}
このデモに固有の消費側 JS はありません(挙動はコントローラが担います)。
これらのスタイルは共通のデザイントークン(ライト/ダーク両対応)を使います。共通スタイルも一緒にコピーし、ルート要素の data-theme を切り替えればダークになります。
このコンポーネントを動かすために HTML へ記述する data-* 属性です。ルート要素に下の data-controller を付け、その内側に各 target / value / action を配置します。
ルート要素に付与
data-controller="stimeo--dialog"
ターゲット
| 名前 | 説明 | 属性 |
|---|---|---|
trigger
必須
|
ダイアログを開くボタン。閉じるとフォーカスがここへ戻る。 | data-stimeo--dialog-target="trigger" |
dialog
必須
|
ダイアログ要素(role=dialog)。内容の外側=バックドロップをクリックすると閉じる。 |
data-stimeo--dialog-target="dialog" |
アクション
| 名前 | 説明 | アクション |
|---|---|---|
close
|
ダイアログを閉じ、フォーカスをトリガーへ戻す。 | stimeo--dialog#close |
closeOnBackdrop
|
バックドロップ(内容の外側のダイアログ要素)クリックで閉じる。ダイアログ要素に結線する。 | stimeo--dialog#closeOnBackdrop |
open
|
ダイアログを開き、フォーカスを内側へ移動して Tab を閉じ込め、背景スクロールをロックする。 | stimeo--dialog#open |
状態フック
ライブラリが操作するのはこれらの ARIA / data 属性、カスタムプロパティだけです。見た目は利用側 CSS がこれらに反応して作ります([aria-selected] / [aria-expanded] / var(--stimeo--…) などのセレクタでフックします)。
| フック | 対象 | 意味 |
|---|---|---|
hidden |
ダイアログ要素 | 閉じている間は付与され、開くと外れる(表示を切り替える)。 |
aria-modal="true" |
ダイアログ要素 | 支援技術にモーダルであることを伝える。 |
inert |
背景の兄弟要素 | 開いている間、背景の各要素に付与して操作できなくする。 |