teksilo_widgets/styles/recipe_date_edit_style.rs
1// SPDX-License-Identifier: MPL-2.0
2// SPDX-FileCopyrightText: 2026 FernTech
3
4//! Default `DateEditStyle` impl + date-edit family design tokens.
5//!
6//! Design tokens for the date-edit family live as `pub const`s on this
7//! module. The four widgets (`DateEdit`, `TimeEdit`, `DateRangeEdit`,
8//! `DateTimeEdit`) read them directly when building the calendar / clock
9//! trigger icon and the segmented-field separators.
10//!
11//! In IntUI the trigger sits inside `TextInput`'s trailing slot, so the
12//! default `make_body` is a passthrough — the widget pre-assembles the
13//! complete body before handing it to the recipe. Custom recipes can
14//! wrap the body or surround it with siblings.
15
16use teksilo_core::build_context::BuildContext;
17use teksilo_core::styles::{DateEditStyle, DateEditStyleConfig, SharedDateEditStyle};
18use teksilo_core::widget_id::WidgetId;
19
20// ─── IntUI design tokens for the date-edit family ──────────────────
21
22/// Width of the trailing calendar / clock trigger button slot.
23pub const CALENDAR_BUTTON_WIDTH: f32 = 24.0;
24/// Edge length of the calendar / clock trigger glyph.
25pub const CALENDAR_ICON_SIZE: f32 = 14.0;
26/// Gap between adjacent segments (visual separator characters sit in
27/// this gap). Used by the segmented date/time editors.
28pub const SEGMENT_GAP: f32 = 1.0;
29
30/// Configurable dimension bundle for `RecipeDateEditStyle`.
31///
32/// The `Default` impl reads the module-level `pub const`s, so calling
33/// `DateEditRecipe::default()` is equivalent to the pre-recipe behaviour.
34#[derive(Debug, Clone, Copy, PartialEq)]
35pub struct DateEditRecipe {
36 /// Width of the trailing calendar / clock trigger button slot.
37 pub calendar_button_width: f32,
38 /// Edge length of the calendar / clock trigger glyph.
39 pub calendar_icon_size: f32,
40 /// Gap between adjacent segments (visual separator characters sit in
41 /// this gap). Used by the segmented date/time editors.
42 pub segment_gap: f32,
43}
44
45impl Default for DateEditRecipe {
46 fn default() -> Self {
47 Self {
48 calendar_button_width: CALENDAR_BUTTON_WIDTH,
49 calendar_icon_size: CALENDAR_ICON_SIZE,
50 segment_gap: SEGMENT_GAP,
51 }
52 }
53}
54
55/// Default `DateEditStyle` shipped with Teksilo. Currently a
56/// passthrough — IntUI's date-edit chrome lives inside `TextInput`,
57/// which is already themed. Custom styles can wrap the body to add
58/// extra siblings (clear button, status icon, etc.).
59#[derive(Debug, Default, Clone, Copy)]
60pub struct RecipeDateEditStyle {
61 pub recipe: DateEditRecipe,
62}
63
64impl RecipeDateEditStyle {
65 pub fn new(recipe: DateEditRecipe) -> Self {
66 Self { recipe }
67 }
68}
69
70impl DateEditStyle for RecipeDateEditStyle {
71 fn make_body(&self, cfg: &DateEditStyleConfig, _ctx: &mut BuildContext) -> WidgetId {
72 cfg.body
73 }
74}
75
76/// Convenience for callers that need the active style (per-call
77/// override → theme slot → `RecipeDateEditStyle`).
78pub fn resolve_date_edit_style(
79 override_: &Option<SharedDateEditStyle>,
80 ctx: &BuildContext,
81) -> SharedDateEditStyle {
82 if let Some(s) = override_.clone() {
83 return s;
84 }
85 ctx.theme_signal()
86 .get()
87 .style_slots
88 .date_edit
89 .clone()
90 .unwrap_or_else(|| std::rc::Rc::new(RecipeDateEditStyle::default()) as SharedDateEditStyle)
91}