Skip to main content

Module message_box

Module message_box 

Source
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_fg tint.
  • Question — question mark glyph, accent tint.
  • Warning — exclamation triangle, status_warning_fg tint.
  • Critical — X-mark circle, status_error_fg tint. 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 (via ModalRequest::focus_target plus Widget::initial_focus_hint). Styled with ButtonVariant::Filled.
  • escape_button — activated by Escape. The fallback logic (for presets with no explicit escape_button) picks: explicit escape_button → first Reject-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§

MessageBox
A modal alert dialog that displays a severity icon, title, body text, and one or more buttons.
MessageBoxButton
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 when Custom is needed.
MessageBoxResult
Report passed to MessageBox::on_result when the dialog closes.

Enums§

ButtonRole
Semantic role of a message-box button. Used for fallback escape resolution (Reject wins when no explicit escape button is set). Teksilo deliberately does not render Destructive buttons with a red fill — the dialog’s severity icon and wording carry that signal. See crate::button for the framework-level rationale.
MessageBoxButtons
Pre-built button bundles covering the common MessageBox shapes. Custom combinations go through MessageBox::add_button or MessageBoxButtons::Custom.
MessageBoxDismissal
How a MessageBox came to close.
MessageBoxSeverity
Alert severity level. Drives the icon glyph + tint shown beside the title, and (for Critical) whether click-outside dismiss is enabled.
StandardButton
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§

EventContextMessageBoxExt
Extension trait on [EventContext] for ergonomic MessageBox presentation. Mirrors ctx.present_modal(...) for the general case.