pub struct Dialog<S> { /* private fields */ }Expand description
A modal dialog on a page whose signals are S.
Declare one as a const and use the same value for the dialog and for the
buttons that open and close it, so they agree on its id. The buttons carry
commandfor and command, and the browser opens the <dialog> with
showModal(): it makes the rest of the page inert, so that Tab moves
between the dialog’s controls and the browser’s own and never reaches the
page behind, closes on Escape, and returns focus to the button that
opened it. The
browser needs invoker commands for this, which Chrome 135, Firefox 144,
and Safari 26.2 ship.
The dialog is labeled by its title and described by its description through ids derived from the name. Two dialogs with the same name on one page share an id, and rendering the page panics.
use hypersig::Signals;
use hypersig::html::p;
use hypersig_ui::{ButtonSize, ButtonVariant, Dialog, dialog_footer};
use serde::{Deserialize, Serialize};
#[derive(Signals, Serialize, Deserialize)]
struct Profile {}
const EDIT: Dialog<Profile> = Dialog::new("edit-profile");
let open = EDIT.trigger(ButtonVariant::Outline, ButtonSize::Default).text("Edit profile");
let dialog = EDIT.dialog(
"Edit profile",
"Changes are saved when you press Save.",
dialog_footer().child(EDIT.close(ButtonVariant::Default, ButtonSize::Default).text("Save")),
);
assert!(open.render().contains(r#"command="show-modal""#));
assert!(dialog.render().contains(r#"aria-labelledby="edit-profile-title""#));Implementations§
Source§impl<S> Dialog<S>
impl<S> Dialog<S>
Sourcepub const fn new(name: &'static str) -> Self
pub const fn new(name: &'static str) -> Self
A dialog whose id is name.
§Panics
Panics if name is empty or holds a character other than an ASCII
letter, digit, -, or _. In a const, that is a compile error.
Sourcepub fn trigger(self, variant: ButtonVariant, size: ButtonSize) -> El<S>
pub fn trigger(self, variant: ButtonVariant, size: ButtonSize) -> El<S>
A button that opens the dialog.
Sourcepub fn open(self) -> Stmt<S>
pub fn open(self) -> Stmt<S>
A statement that opens the dialog, as its trigger button does.
Use it where no button opens the dialog, such as a keyboard shortcut
from Page::on_key. Focus returns to the
element that had it when the dialog closes.
Sourcepub fn close(self, variant: ButtonVariant, size: ButtonSize) -> El<S>
pub fn close(self, variant: ButtonVariant, size: ButtonSize) -> El<S>
A button that closes the dialog. Put it inside the dialog.
Sourcepub fn dialog(
self,
title: impl Into<String>,
description: impl Into<String>,
content: impl Into<Node<S>>,
) -> El<S>
pub fn dialog( self, title: impl Into<String>, description: impl Into<String>, content: impl Into<Node<S>>, ) -> El<S>
The dialog, with title, description, content, and a close button
in its corner.
A click on the backdrop closes it as Escape does (closedby="any"),
in a browser that supports closedby. Focus moves to the first
control in content when it opens, and the corner button comes after
content so that it is not that control.
Sourcepub fn sheet(
self,
side: Side,
title: impl Into<String>,
description: impl Into<String>,
content: impl Into<Node<S>>,
) -> El<S>
pub fn sheet( self, side: Side, title: impl Into<String>, description: impl Into<String>, content: impl Into<Node<S>>, ) -> El<S>
A sheet: a dialog along the side edge of the viewport, with
title, description, content, and a close button in its corner.
It is the same modal <dialog> as Dialog::dialog, opened by
Dialog::trigger, with the same focus, Escape, and backdrop
behavior. Only its place and size differ: it spans the full height of
the viewport at the left or the right, and the full width at the top
or the bottom.
use hypersig::Signals;
use hypersig::html::p;
use hypersig_ui::{ButtonSize, ButtonVariant, Dialog, Side};
use serde::{Deserialize, Serialize};
#[derive(Signals, Serialize, Deserialize)]
struct Shop {}
const CART: Dialog<Shop> = Dialog::new("cart");
let open = CART.trigger(ButtonVariant::Outline, ButtonSize::Default).text("Cart");
let sheet = CART.sheet(Side::Right, "Cart", "Two items.", p().text("Tea, cups"));
assert!(sheet.render().contains(r#"aria-labelledby="cart-title""#));Sourcepub fn alert_dialog(
self,
title: impl Into<String>,
description: impl Into<String>,
content: impl Into<Node<S>>,
) -> El<S>
pub fn alert_dialog( self, title: impl Into<String>, description: impl Into<String>, content: impl Into<Node<S>>, ) -> El<S>
An alert dialog, which asks the visitor to confirm or cancel before
going on, with title, description, and content.
It has role="alertdialog", no corner button, and stays open on a
click on the backdrop, so that the visitor answers with one of the
buttons in content. Escape still cancels it.