Skip to main content

DateRangePicker

DateRangePicker is a convenience wrapper for two coordinated DatePicker instances.

Use it when the product question is "from when to when?" rather than "which single day?" Typical examples are reporting ranges, booking windows, and filter panels.

Example

use chrono::NaiveDate;
use fission::prelude::*;
use std::sync::Arc;

let node = DateRangePicker {
id_start: WidgetNodeId::explicit("range_start"),
id_end: WidgetNodeId::explicit("range_end"),
start: view.state.range_start,
end: view.state.range_end,
is_start_open: view.state.range_start_open,
is_end_open: view.state.range_end_open,
on_change: Some(Arc::new(move |start: Option<NaiveDate>, end: Option<NaiveDate>| ActionEnvelope {
id: set_range_id,
payload: serde_json::to_vec(&SetDateRange { start, end }).unwrap(),
})),
on_toggle_start: Some(toggle_start_action),
on_toggle_end: Some(toggle_end_action),
on_close_start: Some(close_start_action),
on_close_end: Some(close_end_action),
}
.build(ctx, view);

This keeps the whole interaction inside the normal state loop: each side has explicit open state, and the reducer stays responsible for validating the final range.

Field table

FieldTypeMeaningNotes / default behavior
id_startWidgetNodeIdStable identity for the start-date trigger.Required.
id_endWidgetNodeIdStable identity for the end-date trigger.Required.
startOption<NaiveDate>Current start date.Controlled by app state.
endOption<NaiveDate>Current end date.Controlled by app state.
is_start_openboolWhether the start picker popup is open.Controlled by app state.
is_end_openboolWhether the end picker popup is open.Controlled by app state.
on_changeOption<Arc<dyn Fn(Option<NaiveDate>, Option<NaiveDate>) -> ActionEnvelope + Send + Sync>>Closure that receives the updated pair.Called when either side changes.
on_toggle_startOption<ActionEnvelope>Action for opening or toggling the start picker.Defaults to None.
on_toggle_endOption<ActionEnvelope>Action for opening or toggling the end picker.Defaults to None.
on_close_startOption<ActionEnvelope>Explicit close action for the start picker.Defaults to None.
on_close_endOption<ActionEnvelope>Explicit close action for the end picker.Defaults to None.

Value model and validation

The widget only helps present the two pickers together. It does not decide whether the end date must be after the start date, whether empty values are allowed, or whether the two dates should snap to preset windows. Those rules belong in your reducer or validation layer.

A common pattern is to accept either side individually while the user is editing, then validate the pair before submitting or querying.

Specific advice

Keep the real range in state as dates, not formatted strings. Also think about what should happen when a user picks an end date earlier than the start date. Some products swap them automatically. Others keep the invalid state visible until the user fixes it. Pick one behavior intentionally and test it.

DatePicker, TimePicker, FormControl, and Popover.