Skip to main content

ModalAction

ModalAction is the small configuration struct that describes one button in a Modal footer.

It exists so modal buttons stay explicit and state-driven. Instead of letting the dialog close itself implicitly, each action carries an ActionEnvelope that re-enters your normal reducer loop. That means "Cancel," "Delete," and "Save" are all just named application intents. The reducer decides what each one really does, including whether the modal should close.

Example

use fission::prelude::*;

let dialog = Modal {
id: WidgetNodeId::explicit("delete_confirm"),
title: "Delete draft?".into(),
content: Box::new(Text::new("This action cannot be undone.").into_node()),
is_open: view.state.show_delete_dialog,
on_dismiss: Some(close_dialog),
actions: vec![
ModalAction {
label: "Cancel".into(),
on_press: Some(close_dialog),
is_primary: false,
},
ModalAction {
label: "Delete".into(),
on_press: Some(confirm_delete),
is_primary: true,
},
],
width: None,
};

In that example, the modal does not close itself. Your reducers decide whether close_dialog or confirm_delete should change the state.

Field table

FieldTypeMeaningNotes / default behavior
labelStringVisible button text.Keep it short and action-oriented.
on_pressOption<ActionEnvelope>Action dispatched when the footer button is pressed.Defaults to None. A button without an action is visible but inert.
is_primaryboolWhether this is the main action in the footer.true uses the filled button style. false uses the outline style.

Specific advice

Keep the footer focused. Most modals should have one primary action and, at most, one secondary escape action. If you find yourself adding many buttons, the problem is usually bigger than a footer can explain and the interaction probably wants a full screen or routed page instead.

Also remember that is_primary is a visual emphasis choice, not business logic. The reducer should still treat every action explicitly.

Modal, Button, and ButtonVariant.