teksilo_core/styles/dialog_style.rs
1// SPDX-License-Identifier: MPL-2.0
2// SPDX-FileCopyrightText: 2026 FernTech
3
4//! Tier-3 style protocol for `Dialog` (`ModalContainer`). See
5//! `docs/styling-system.md`.
6//!
7//! `Dialog` has two themable surfaces, so the trait carries two
8//! methods: [`DialogStyle::make_panel`] wraps the `DialogContent`
9//! subtree in the modal panel chrome (rounded surface, border, content
10//! padding), and [`DialogStyle::make_scrim`] builds the full-window
11//! dimming scrim painted behind the panel. The modal-presentation
12//! pipeline owns *mounting* both — `DialogStyle` only owns their look.
13
14use std::rc::Rc;
15
16use crate::build_context::BuildContext;
17use crate::widget_id::WidgetId;
18
19#[derive(Clone, Debug)]
20pub struct DialogStyleConfig {
21 /// Pre-built `DialogContent` subtree the panel wraps.
22 pub content: WidgetId,
23 /// Whether the modal is presented with a dimming scrim behind it.
24 /// `ModalContainer` is always modal today, so this is always
25 /// `true`; custom styles may branch on it.
26 pub has_scrim: bool,
27 /// Caller override for the panel content padding — `None` means
28 /// "use the recipe default". Custom styles may ignore it.
29 pub padding_override: Option<f32>,
30 /// Caller override for the panel minimum width — `None` means
31 /// "use the recipe default". Custom styles may ignore it.
32 pub min_width_override: Option<f32>,
33}
34
35pub trait DialogStyle: 'static {
36 /// The modal panel surface that wraps `content` — rounded surface
37 /// fill, border stroke, and the content-padding inset.
38 fn make_panel(&self, cfg: &DialogStyleConfig, ctx: &mut BuildContext) -> WidgetId;
39 /// The full-window scrim that dims the content behind the modal
40 /// panel. Mounted by the modal-presentation pipeline, not by
41 /// `ModalContainer` itself.
42 fn make_scrim(&self, ctx: &mut BuildContext) -> WidgetId;
43}
44
45pub type SharedDialogStyle = Rc<dyn DialogStyle>;