Expand description
MessageBox — QMessageBox-style alert dialog.
A higher-level surface built on top of ModalContainer
for the classic “tell the user something and ask for a response”
pattern: unsaved-changes prompts, error surfaces, confirmation
dialogs, and informational notices. Mirrors QMessageBox (Qt),
NSAlert (AppKit), and SwiftUI’s .alert(...) while staying inside
Teksilo’s idioms — closure result handlers, Signal/Prop
reactivity, Intent/Action/Shortcut routing for keyboard
defaults, and AccessKit Role::AlertDialog accessibility.
§Quick tour
use teksilo::prelude::*;
use teksilo::widgets::{MessageBox, MessageBoxButtons, StandardButton};
fn on_close(ctx: &mut EventContext) {
MessageBox::question(lit!("Save changes?"))
.text(lit!("You have unsaved changes in report.skrib."))
.informative_text(lit!("Your changes will be lost if you don't save them."))
.buttons(MessageBoxButtons::SaveDiscardCancel)
.default_button(StandardButton::Save)
.escape_button(StandardButton::Cancel)
.on_result(|r, ctx| match r.button {
StandardButton::Save => save_and_close(ctx),
StandardButton::Discard => close(ctx),
_ => {}
})
.present(ctx);
}§Severity
MessageBoxSeverity controls the icon drawn beside the title and
its tint:
Information— info glyph,status_info_fgtint.Question— question mark glyph,accenttint.Warning— exclamation triangle,status_warning_fgtint.Critical— X-mark circle,status_error_fgtint. Also disables click-outside dismissal (Qt convention).None— no icon, no tint.
Severity is conveyed through the icon + title + text. Per Teksilo’s
Int UI baseline, buttons are never colored as “destructive”:
destructive intent lives in the dialog’s severity and wording, not
in the button. See crate::button for details.
§Default & escape buttons
default_button— activated by Enter (widget-scoped shortcut) and receives initial focus on open (viaModalRequest::focus_targetplusWidget::initial_focus_hint). Styled withButtonVariant::Filled.escape_button— activated by Escape. The fallback logic (for presets with no explicitescape_button) picks: explicitescape_button→ firstReject-role button →Cancel→ last button.
Each preset supplies a default: Ok for Ok and OkCancel, Save for
SaveDiscardCancel, Retry for RetryIgnoreAbort, and No for
YesNo and YesNoCancel.
The Yes/No default is the negative answer on purpose. An Ok/Cancel box
confirms something the user just asked for, so Ok is the answer they
meant. A Yes/No box asks a question they did not initiate, and it is
overwhelmingly asked before something irreversible — “Delete this?”,
“Discard your changes?”. Defaulting to Yes means Enter destroys, and
Enter is what a keyboard user presses on a dialog they have not
finished reading. Where the question is safe, default_button puts Yes
back in one reviewable line; the reverse default cannot be reviewed,
because there is nothing on the screen to review.
It matters more than it looks, because no platform announces which
button is the default: Node::keyboard_shortcut appears in none of
the three AccessKit adapters, so a screen-reader user discovers the
default only by pressing Enter. Where focus lands is the whole contract.
§Title and button alignment
MessageBox::title_alignment places the title in the header’s text
column (default Leading) and MessageBox::button_alignment places the
button row (default Trailing), both as [teksilo_tokens::HAlignment].
macOS alerts centre both; Windows and GNOME keep the title leading and the
buttons trailing, which is the default. Leading and Trailing follow the
layout direction.
§Result reporting
MessageBox::on_result takes impl Fn(MessageBoxResult, &mut EventContext) + 'static. The callback fires exactly once, whichever
route closes the dialog — button activation, Escape, a press outside, or a
programmatic dismissal — with MessageBoxResult::dismissal naming which
one. On a button activation the modal is then closed by the framework; on
the other routes it is already going away.
§Accessibility
The widget exposes Role::AlertDialog, with set_modal(),
set_live(Live::Assertive), set_name(title), and
set_description(text + informative_text), so screen readers
announce the dialog by its title as it opens and find the text as its
description and by walking it. The ModalContainer that presents it
publishes no dialog of its own around it, and the content under it is
Live::Off, so the title is the one thing announced, once.
Structs§
- Message
Box - A modal alert dialog that displays a severity icon, title, body text, and one or more buttons.
- Message
BoxButton - A single button placement inside a MessageBox, including an optional
per-instance label override. Callers usually build these via
From<StandardButton>(StandardButton::Ok.into()), or construct them manually whenCustomis needed. - Message
BoxResult - Report passed to
MessageBox::on_resultwhen the dialog closes.
Enums§
- Button
Role - Semantic role of a message-box button. Used for fallback escape
resolution (
Rejectwins when no explicit escape button is set). Teksilo deliberately does not renderDestructivebuttons with a red fill — the dialog’s severity icon and wording carry that signal. Seecrate::buttonfor the framework-level rationale. - Message
BoxButtons - Pre-built button bundles covering the common MessageBox shapes.
Custom combinations go through
MessageBox::add_buttonorMessageBoxButtons::Custom. - Message
BoxDismissal - How a
MessageBoxcame to close. - Message
BoxSeverity - Alert severity level. Drives the icon glyph + tint shown beside the
title, and (for
Critical) whether click-outside dismiss is enabled. - Standard
Button - The Qt-modeled catalog of standard buttons. Each variant resolves
to a localized label, a semantic
ButtonRole, and a stable intent-name string used internally for shortcut/action routing.
Traits§
- Event
Context Message BoxExt - Extension trait on [
EventContext] for ergonomic MessageBox presentation. Mirrorsctx.present_modal(...)for the general case.