Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

facett-demo/src/overlay_demo.rs

//! **`overlay` demo tab** — exercises the facett-app overlay/feedback system
//! (Fas 3): a [`Modal`] dialog + a [`Toasts`] notification queue. Buttons open the
//! dialog and push levelled toasts; confirming the dialog fires a success toast.

use facett_app::{Level, Modal, Popover, Toasts};
use facett_core::{Facet, FacetCaps};

pub struct OverlayDemo {
    title: String,
    modal: Modal,
    toasts: Toasts,
    popover: Popover,
    last_action: Option<String>,
}

impl OverlayDemo {
    pub fn new() -> Self {
        Self {
            title: "overlay".into(),
            modal: Modal::new("demo_modal", "Delete this item?").body("This action cannot be undone.").confirm_cancel(),
            toasts: Toasts::new(),
            popover: Popover::new("demo_popover"),
            last_action: None,
        }
    }

    /// Seed some observable state (for the headless coverage matrix): open the
    /// dialog + queue a couple of toasts.
    pub fn seed_for_demo(&mut self) {
        self.modal.open();
        self.toasts.push(Level::Info, "Welcome.");
        self.toasts.push_sticky(Level::Warn, "Disk almost full.");
    }
}

impl Default for OverlayDemo {
    fn default() -> Self {
        Self::new()
    }
}

impl Facet for OverlayDemo {
    fn title(&self) -> &str {
        &self.title
    }

    fn ui(&mut self, ui: &mut egui::Ui) {
        ui.horizontal_wrapped(|ui| {
            if ui.button("Open dialog").clicked() {
                self.modal.open();
            }
            if ui.button("ℹ Info").clicked() {
                self.toasts.push(Level::Info, "Heads up.");
            }
            if ui.button("✓ Success").clicked() {
                self.toasts.push(Level::Success, "Saved.");
            }
            if ui.button("⚠ Warn").clicked() {
                self.toasts.push(Level::Warn, "Careful now.");
            }
            if ui.button("✖ Error").clicked() {
                self.toasts.push_sticky(Level::Error, "Something failed (sticky).");
            }
            let pop = ui.button("Popover ▾");
            if pop.clicked() {
                self.popover.toggle();
            }
            self.popover.show(ui, &pop, |ui| {
                ui.strong("Popover");
                ui.label("An anchored floating panel (Fas 3 extra). Esc closes.");
            });
        });
        ui.separator();
        ui.label("Modal generalises the command-palette overlay (scrim + Esc); Toasts generalise the deck toast into a levelled queue. Both headless + observable (state_json).");
        if let Some(a) = self.last_action.as_deref() {
            ui.add_space(4.0);
            ui.weak(format!("last dialog action: {a}"));
        }

        // Overlays draw on top of everything.
        if let Some(action) = self.modal.show(ui) {
            self.last_action = Some(action.clone());
            match action.as_str() {
                "ok" => {
                    self.toasts.push(Level::Success, "Confirmed — item deleted.");
                }
                "cancel" | "dismiss" => {
                    self.toasts.push(Level::Info, "Cancelled.");
                }
                _ => {}
            }
        }
        self.toasts.show(ui);
    }

    fn state_json(&self) -> serde_json::Value {
        serde_json::json!({
            "modal": self.modal.state_json(),
            "toasts": self.toasts.state_json(),
            "popover": self.popover.state_json(),
            "last_action": self.last_action,
        })
    }

    fn caps(&self) -> FacetCaps {
        FacetCaps::NONE.themeable()
    }
}