Skip to main content

orbital_date_pickers/shared/
slots.rs

1//! Customization slots and picker field context for plugin pickers.
2
3use std::sync::Arc;
4
5use leptos::prelude::*;
6use orbital_base_components::{DatetimeFormat, DatetimeTimezone};
7
8use crate::DateTimeRange;
9
10/// Context for custom field slot content inside a popover picker trigger row.
11#[derive(Clone, Copy)]
12pub struct PickerFieldContext {
13    pub value: Signal<Option<DateTimeRange>>,
14    pub disabled: Signal<bool>,
15    pub format: Signal<DatetimeFormat>,
16    pub timezone: Signal<DatetimeTimezone>,
17}
18
19#[derive(Clone, Copy)]
20struct PickerFieldInjection(Signal<PickerFieldContext>);
21
22/// Returns the active [`PickerFieldContext`] when inside a [`PickerFieldSlot`] on a range picker.
23pub fn use_picker_field() -> PickerFieldContext {
24    use_context::<PickerFieldInjection>()
25        .expect("use_picker_field requires PickerFieldSlot on DateRangePicker")
26        .0
27        .get()
28}
29
30pub(crate) fn provide_picker_field(context: Signal<PickerFieldContext>) {
31    provide_context(PickerFieldInjection(context));
32}
33
34/// Hosts custom picker field slot content with [`PickerFieldContext`].
35#[component]
36pub fn PickerFieldSlotHost(
37    context: Signal<PickerFieldContext>,
38    children: ChildrenFn,
39) -> impl IntoView {
40    provide_picker_field(context);
41    children()
42}
43
44/// Collected layout slot children for [`crate::DateCalendar`].
45#[derive(Default)]
46pub struct PickerLayoutSlots {
47    pub toolbar: Option<PickerLayoutToolbarSlot>,
48    pub action_bar: Option<PickerLayoutActionBarSlot>,
49}
50
51impl PickerLayoutSlots {
52    pub fn from_slot_props(
53        toolbar: Option<PickerLayoutToolbarSlot>,
54        action_bar: Option<PickerLayoutActionBarSlot>,
55    ) -> Self {
56        Self {
57            toolbar,
58            action_bar,
59        }
60    }
61}
62
63/// Collected trigger slots for [`crate::DateRangePicker`].
64#[derive(Default)]
65pub struct DateRangePickerSlots {
66    pub field: Option<PickerFieldSlot>,
67    pub open_trigger: Option<OpenTriggerSlot>,
68}
69
70impl DateRangePickerSlots {
71    pub fn from_slot_props(
72        field: Option<PickerFieldSlot>,
73        open_trigger: Option<OpenTriggerSlot>,
74    ) -> Self {
75        Self {
76            field,
77            open_trigger,
78        }
79    }
80}
81
82/// Optional toolbar region above shortcuts on [`crate::DateCalendar`].
83#[slot]
84pub struct PickerLayoutToolbarSlot {
85    pub(crate) children: ChildrenFn,
86}
87
88/// Optional action bar region below the calendar grid on [`crate::DateCalendar`].
89#[slot]
90pub struct PickerLayoutActionBarSlot {
91    pub(crate) children: ChildrenFn,
92}
93
94/// Replaces the default range field in [`crate::DateRangePicker`]'s trigger row.
95///
96/// Use [`use_picker_field`] inside the slot to read bind state.
97#[slot]
98pub struct PickerFieldSlot {
99    pub(crate) children: ChildrenFn,
100}
101
102/// Replaces the default calendar icon open button on [`crate::DateRangePicker`].
103#[slot]
104pub struct OpenTriggerSlot {
105    pub(crate) children: ChildrenFn,
106}
107
108/// Type alias for custom day cell renderers forwarded to core [`orbital_core_components::Calendar`].
109pub type CalendarDayRenderer =
110    Arc<dyn Fn(orbital_core_components::CalendarDayProps) -> AnyView + Send + Sync>;
111
112/// Type alias for custom month button renderers on core [`orbital_core_components::DatePicker`].
113pub type CalendarMonthButtonRenderer =
114    Arc<dyn Fn(orbital_core_components::CalendarMonthButtonProps) -> AnyView + Send + Sync>;