teksilo_core/styles/popover_style.rs
1// SPDX-License-Identifier: MPL-2.0
2// SPDX-FileCopyrightText: 2026 FernTech
3
4//! Tier-3 style protocol for `Popover`. See `docs/styling-system.md`.
5
6use std::rc::Rc;
7
8use serde::{Deserialize, Serialize};
9
10use crate::build_context::BuildContext;
11use crate::overlay::OverlayPlacement;
12use crate::widget_id::WidgetId;
13
14#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default, Serialize, Deserialize)]
15pub enum PopoverVariant {
16 /// Generic popover (combo-box dropdown, color picker, etc.).
17 #[default]
18 Default,
19 /// Menu popover (rounded, slightly-elevated). Distinct from
20 /// `MenuItemStyle` which paints the rows; this draws the
21 /// surrounding container.
22 Menu,
23 /// Tooltip-flavored container (dark surface in IntUI even in
24 /// light theme).
25 Tooltip,
26}
27
28#[derive(Clone, Debug)]
29pub struct PopoverStyleConfig {
30 /// Pre-built content subtree that the popover frame wraps.
31 pub content: WidgetId,
32 pub variant: PopoverVariant,
33 /// Accessible name for the popover dialog node — typically the
34 /// trigger label.
35 pub name: String,
36 /// Overlay placement (drives caret direction + which side of the
37 /// shadow to suppress so the panel reads as attached to its
38 /// trigger).
39 pub placement: OverlayPlacement,
40 /// Whether to paint a directional caret pointing at the trigger.
41 pub show_caret: bool,
42 /// Caret half-extent in logical pixels (the apex protrudes by
43 /// this amount). Honoured only when `show_caret == true` AND the
44 /// placement is one of the cardinal Above/Below directions.
45 pub caret_size: f32,
46}
47
48pub trait PopoverStyle: 'static {
49 fn make_body(&self, cfg: &PopoverStyleConfig, ctx: &mut BuildContext) -> WidgetId;
50}
51
52pub type SharedPopoverStyle = Rc<dyn PopoverStyle>;