Skip to main content

orbital_date_pickers/guides/
custom_open.rs

1//! Custom open trigger slot (DP-32).
2
3use leptos::prelude::*;
4use orbital_macros::component_doc;
5
6/// Replace the default calendar icon trigger with a custom open button.
7///
8/// Range and date popover pickers render a default icon button to open the panel.
9/// Provide [`OpenTriggerSlot`](crate::OpenTriggerSlot) content to swap in a labeled
10/// [`Button`](orbital_core_components::Button) or any other focusable control while
11/// keeping popover wiring intact.
12///
13/// # When to use
14///
15/// - Range pickers that need a text label ("Choose dates") instead of an icon
16/// - Forms where the open control must match secondary button styling
17/// - Flows that open the calendar from a branded trigger elsewhere in the layout
18///
19/// # Usage
20///
21/// 1. Wrap the picker (for example [`DateRangePicker`](crate::DateRangePicker)) with an [`OpenTriggerSlot`] child.
22/// 2. Place an Orbital [`Button`](orbital_core_components::Button) inside the slot — the picker attaches open handlers automatically.
23/// 3. Use `ButtonAppearance::Secondary` for neutral triggers; reserve primary for form submit actions.
24///
25/// # Best Practices
26///
27/// ## Do's
28///
29/// * Use descriptive button text ("Choose dates", "Select range")
30/// * Keep the trigger focusable and visible — do not rely on hover-only affordances
31/// * Match button density to surrounding form controls
32///
33/// ## Don'ts
34///
35/// * Do not use raw `<button>` elements — use Orbital [`Button`] for consistent focus rings and density
36/// * Do not nest another popover trigger inside the slot without testing focus return
37///
38/// # Examples
39///
40/// ## Text open button
41/// Replace the default calendar icon with a labeled secondary button.
42/// <!-- preview -->
43/// ```rust
44/// use crate::preview::{PickerPreviewExample, PickerPreviewKnobs};
45/// use crate::{DateRangePicker, DateTimeRange, OpenTriggerSlot};
46/// use orbital_core_components::{Button, ButtonAppearance};
47/// let value = RwSignal::new(None::<DateTimeRange>);
48/// view! {
49///     <PickerPreviewExample data_testid="date-pickers-custom-open-preview">
50///         <PickerPreviewKnobs />
51///         <DateRangePicker bind=value>
52///             <OpenTriggerSlot slot>
53///                 <Button
54///                     appearance=ButtonAppearance::Secondary
55///                     attr:data-testid="date-pickers-custom-open-button"
56///                 >
57///                     "Choose dates"
58///                 </Button>
59///             </OpenTriggerSlot>
60///         </DateRangePicker>
61///     </PickerPreviewExample>
62/// }
63/// ```
64#[component_doc(
65    category = "Calendar & Time",
66    preview_slug = "date-pickers-custom-open",
67    preview_label = "Custom Open Button",
68    preview_icon = icondata::AiCalendarOutlined,
69)]
70#[component]
71pub fn DatePickersCustomOpenGuide() -> impl IntoView {
72    view! { () }
73}