コンテンツにスキップ

ダイアログ

hc-dialog は、標準の <dialog> 要素に適用する薄いクラスです。 モーダルのライフサイクル — フォーカストラップ、Escape で閉じる、 背景の inert、トップレイヤー描画 — はブラウザが所有し、この コンポーネントは見た目の面だけを足します。

別名: モーダル、モーダルダイアログ(modal)。

Confirm something

Body content.

パーツ用途
.hc-dialogルートの <dialog> 要素。
.hc-dialog__headerタイトル行。下に区切り線。
.hc-dialog__titleヘッダー内の見出し。
.hc-dialog__bodyメインのコンテンツ領域。ダイアログがビューポートより高いときスクロールするのはここ。
.hc-dialog__footerアクション行。右寄せ、上に区切り線。

パーツは慣習です — どれでも省略できます。

開いているダイアログはカラムなので、ビューポートより高い内容は 本文の中でスクロールし、ヘッダーとフッターはその場に留まります。 主要アクションはフッターにあるためこれが効きます — フィールドが十数個 ある検索パネルでは、そうしないとボタンが画面外に押し出されます。

3 つのパーツをまとめて 1 つのフォームで包んでも構いません。フッターの ボタンが本文のフィールドを送信する場合の通常の形です:

<dialog class="hc-dialog" id="filters" aria-labelledby="filters-title">
<form method="get" action="/orders">
<div class="hc-dialog__header">
<h2 class="hc-dialog__title" id="filters-title">検索条件</h2>
</div>
<div class="hc-dialog__body">…多数のフィールド…</div>
<div class="hc-dialog__footer">
<button class="hc-button" type="submit" data-variant="primary">検索</button>
</div>
</form>
</dialog>

横幅の広いパネルには --hc-dialog-max-width で余裕を与えてください。 高さの上限はブラウザが持つので、指定は不要です。

ネイティブのメソッドを使います:

dialog.showModal(); // modal, with focus trap and ::backdrop
dialog.show(); // non-modal, no backdrop
dialog.close(); // close (modal or non-modal)
dialog.close('confirm'); // close and set returnValue

解散に反応するには close イベントを待ち受けます:

dialog.addEventListener('close', () => {
if (dialog.returnValue === 'confirm') {
// user accepted
}
});

本文がサーバから来るモーダルは リモートダイアログレシピを 参照。事前の確認ステップ(承認までラウンドトリップなし)は 確認アクションを 参照してください。

ダイアログ内のフォームを成功時に閉じるには、 data-hc-close-dialog-on-success でオプトインします:

<form
data-hx-post="/items"
data-hx-target="closest dialog"
data-hx-swap="outerHTML"
data-hc-close-dialog-on-success>
</form>

この糊付けは installCloseDialog() ビヘイビアです — htmx:afterRequest を待ち受けて成功を確認し、最寄りの <dialog> 祖先の dialog.close() を呼びます。installCloseDialog() は冪等で、 アンインストーラを返します。ゼロ設定の @hypermedia-components/core/behaviors エントリが自動インストールし、 htmx でスワップされた内容も自動で拾います。

  • ネイティブの <dialog> 要素を使ってください。showModal() を 本当に使えないのでない限り、<div role="dialog"> でダイアログを 模倣しないでください。
  • showModal() で開かれたダイアログでは、フォーカストラップと Escape をブラウザが自動処理します。
  • ダイアログにラベルを付けてください。次のいずれかで:
    • ダイアログにタイトルの id を指す aria-labelledby を設定する、 または
    • タイトルを最初のフォーカス可能要素より前に置き、開いたときに 読み上げられるようにする。
  • 破壊的な確認では、開いたときに Cancel ボタンへフォーカスして ください — 破壊的アクションへは決して。
トークンパス用途
dialog.bg / -fg面の色。
dialog.borderダイアログ周りの枠線。
dialog.radius角丸。
dialog.padding各パーツのパディング。
dialog.gapフッターのボタン間のギャップ。
dialog.max-width最大インラインサイズ。
dialog.backdrop::backdrop の色。
dialog.duration開閉トランジションの時間。
生成される CSS 変数を表示
--hc-dialog-bg | -fg | -border
--hc-dialog-radius | -padding | -gap | -max-width | -duration
--hc-dialog-backdrop

レシピでの利用: リモートダイアログ · セッション切れ再認証