English

ダイアログ

モーダルダイアログ、ビューポートの端に沿って出るシート、訪問者に確認を求めるアラートダイアログです。

実行結果

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::newid が name のダイアログ
triggerダイアログを開くボタン
openトリガーのボタンと同じようにダイアログを開く文
dismiss閉じるボタンと同じようにダイアログを閉じる文
closeダイアログの中に置く、ダイアログを閉じるボタン
dialogtitle、description、content と、角の閉じるボタンを持つダイアログ
alert_dialog先に進む前に、訪問者に確認か取り消しを求めるアラートダイアログ
sheetシート。ビューポートの side の端に沿って出るダイアログ
SideDialog::sheet が沿うビューポートの端
dialog_footerダイアログの下部に、末尾に寄せて並べるボタンの列