ダイアログ
モーダルダイアログ、ビューポートの端に沿って出るシート、訪問者に確認を求めるアラートダイアログです。
実行結果
dialog.rs
use hypersig::html::{div, p};
use hypersig::style::pattern::{stack, wrap};
use hypersig::style::value::rem;
use hypersig::{Page, Signals};
use hypersig_ui::{ButtonSize, ButtonVariant, Dialog, Side, TextField, dialog_footer};
use serde::{Deserialize, Serialize};
#[derive(Signals, Serialize, Deserialize)]
pub struct Project {
name: String,
status: String,
}
const RENAME: Dialog<Project> = Dialog::new("rename");
const DELETE: Dialog<Project> = Dialog::new("delete");
const DETAILS: Dialog<Project> = Dialog::new("details");
pub fn page() -> Page<Project> {
let name = Project::name();
let status = Project::status();
let initial = Project {
name: "hypersig".into(),
status: String::new(),
};
Page::new(
"プロジェクト",
initial,
)
.child(
div()
.css(stack(rem(1)))
.child(
div()
.css(wrap(rem(0.5)))
.child(
RENAME
.trigger(ButtonVariant::Outline, ButtonSize::Default)
.text("名前を変更"),
)
.child(
DETAILS
.trigger(ButtonVariant::Outline, ButtonSize::Default)
.text("詳細"),
)
.child(
DELETE
.trigger(ButtonVariant::Destructive, ButtonSize::Default)
.text("削除"),
),
)
.child(p().attr("role", "status").bind_text(status))
.child(
RENAME.dialog(
"プロジェクトの名前を変更",
"新しい名前は、プロジェクトが表示されるすべての場所に反映されます。",
div()
.css(stack(rem(1)))
.child(TextField::new(
"名前",
name,
))
.child(
dialog_footer()
.child(
RENAME
.close(ButtonVariant::Outline, ButtonSize::Default)
.text("キャンセル"),
)
.child(
RENAME
.close(ButtonVariant::Default, ButtonSize::Default)
.on_click(status.set("プロジェクトの名前を変更しました。"))
.text("保存"),
),
),
),
)
.child(
DETAILS.sheet(
Side::Right,
"プロジェクトの詳細",
"3 月 3 日に作成し、12 回デプロイしました。",
dialog_footer().child(
DETAILS
.close(ButtonVariant::Outline, ButtonSize::Default)
.text("完了"),
),
),
)
.child(
DELETE.alert_dialog(
"このプロジェクトを削除しますか?",
"プロジェクトとそのデプロイが削除されます。この操作は取り消せません。",
dialog_footer()
.child(
DELETE
.close(ButtonVariant::Outline, ButtonSize::Default)
.text("キャンセル"),
)
.child(
DELETE
.close(ButtonVariant::Destructive, ButtonSize::Default)
.on_click(status.set("プロジェクトを削除しました。"))
.text("削除"),
),
),
),
)
}アクセシビリティ
ダイアログは const として宣言し、ダイアログ本体と、それを開くボタン、閉じるボタンに使います。ボタンには commandfor と command が付き、ブラウザが <dialog> を showModal() で開きます。開いている間はページのほかの部分が inert になって操作できず、Escape でダイアログが閉じ、閉じるとフォーカスはダイアログを開いたボタンに戻ります。invoker commands は Chrome 135、Firefox 144、Safari 26.2 から使えます。
ダイアログには名前から作った id を通して、タイトルがラベルとして、説明が説明文として結び付きます。アラートダイアログは role="alertdialog" を持ち、角に閉じるボタンがないので、訪問者はダイアログのボタンのどれかで答えます。
シートは同じモーダルの <dialog> を Dialog::sheet でビューポートの端に沿って置いたものなので、フォーカス、Escape、背景のクリックの振る舞いはダイアログと同じです。
| キー | 動作 |
|---|---|
| Tab | ダイアログのコントロールの間を移り、後ろのページには移りません。 |
| Escape | ダイアログを閉じ、ダイアログを開いたボタンにフォーカスを戻します。 |
API
| 項目 | 概要 |
|---|---|
Dialog::new | id が name のダイアログ |
trigger | ダイアログを開くボタン |
open | トリガーのボタンと同じようにダイアログを開く文 |
dismiss | 閉じるボタンと同じようにダイアログを閉じる文 |
close | ダイアログの中に置く、ダイアログを閉じるボタン |
dialog | title、description、content と、角の閉じるボタンを持つダイアログ |
alert_dialog | 先に進む前に、訪問者に確認か取り消しを求めるアラートダイアログ |
sheet | シート。ビューポートの side の端に沿って出るダイアログ |
Side | Dialog::sheet が沿うビューポートの端 |
dialog_footer | ダイアログの下部に、末尾に寄せて並べるボタンの列 |