Skip to content

Commit 700d138

Browse files
committed
[*] DatePicker: fix date range selection
1 parent 3bba304 commit 700d138

File tree

2 files changed

+35
-45
lines changed

2 files changed

+35
-45
lines changed

primitives/src/calendar.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,6 @@ pub fn Calendar(props: CalendarProps) -> Element {
557557
pub struct RangeCalendarContext {
558558
// The date that the user clicked on to begin range selection
559559
anchor_date: Signal<Option<Date>>,
560-
set_anchor_date: Callback<Option<Date>>,
561560
// Currently highlighted date range
562561
highlighted_range: Signal<Option<DateRange>>,
563562
set_selected_range: Callback<Option<DateRange>>,
@@ -570,7 +569,6 @@ impl RangeCalendarContext {
570569
Some(anchor) => {
571570
if let Some(date) = date {
572571
self.anchor_date.set(None);
573-
self.set_anchor_date.call(None);
574572

575573
let range = DateRange::new(date, anchor);
576574
self.set_selected_range.call(Some(range));
@@ -579,7 +577,6 @@ impl RangeCalendarContext {
579577
}
580578
None => {
581579
self.anchor_date.set(date);
582-
self.set_anchor_date.call(date);
583580

584581
let range = date.map(|d| DateRange::new(d, d));
585582
self.highlighted_range.set(range);
@@ -598,7 +595,6 @@ impl RangeCalendarContext {
598595
/// Set previous selected range
599596
pub fn reset_selection(&mut self, range: Option<DateRange>) {
600597
self.anchor_date.set(None);
601-
self.set_anchor_date.call(None);
602598
self.highlighted_range.set(range);
603599
}
604600
}
@@ -614,10 +610,6 @@ pub struct RangeCalendarProps {
614610
#[props(default)]
615611
pub on_range_change: Callback<Option<DateRange>>,
616612

617-
/// Callback when anchor date changes
618-
#[props(default)]
619-
pub(crate) on_anchor_change: Callback<Option<Date>>,
620-
621613
/// Callback when display weekday
622614
#[props(default = Callback::new(|weekday: Weekday| weekday_abbreviation(weekday).to_string()))]
623615
pub on_format_weekday: Callback<Weekday, String>,
@@ -739,7 +731,6 @@ pub fn RangeCalendar(props: RangeCalendarProps) -> Element {
739731
// Create RangeCalendar context provider for child components
740732
let mut ctx = use_context_provider(|| RangeCalendarContext {
741733
anchor_date,
742-
set_anchor_date: props.on_anchor_change,
743734
highlighted_range,
744735
set_selected_range: props.on_range_change,
745736
});

primitives/src/date_picker.rs

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -157,30 +157,17 @@ pub fn DatePicker(props: DatePickerProps) -> Element {
157157
/// The context provided by the [`RangeCalendar`] component to its children.
158158
#[derive(Copy, Clone)]
159159
pub struct DateRangePickerContext {
160-
anchor_date: Signal<Option<Date>>,
161-
// Currently highlighted date range
162-
highlighted_range: Signal<Option<DateRange>>,
160+
// Currently selected date range
161+
date_range: Signal<Option<DateRange>>,
163162
set_selected_range: Callback<Option<DateRange>>,
164163
}
165164

166165
impl DateRangePickerContext {
167166
/// Set the selected date
168-
pub fn set_selected_date(&mut self, date: Option<Date>) {
169-
match (self.anchor_date)() {
170-
Some(anchor) => {
171-
if let Some(date) = date {
172-
self.anchor_date.set(None);
173-
174-
let range = DateRange::new(date, anchor);
175-
tracing::info!("new range {range}");
176-
self.set_selected_range.call(Some(range));
177-
self.highlighted_range.set(Some(range));
178-
}
179-
}
180-
None => {
181-
self.anchor_date.set(date);
182-
tracing::info!("anchor {date:?}");
183-
}
167+
pub fn set_range(&mut self, range: Option<DateRange>) {
168+
if (self.date_range)() != range {
169+
self.date_range.set(range);
170+
self.set_selected_range.call(range);
184171
}
185172
}
186173
}
@@ -280,11 +267,9 @@ pub fn DateRangePicker(props: DateRangePickerProps) -> Element {
280267
enabled_date_range: DateRange::new(props.min_date, props.max_date),
281268
});
282269

283-
let anchor_date = use_signal(|| None);
284-
let highlighted_range = use_signal(|| (props.selected_range)());
270+
let date_range = use_signal(|| (props.selected_range)());
285271
use_context_provider(|| DateRangePickerContext {
286-
anchor_date,
287-
highlighted_range,
272+
date_range,
288273
set_selected_range: props.on_range_change,
289274
});
290275

@@ -561,7 +546,7 @@ pub fn DateRangePickerCalendar(props: DatePickerCalendarProps<RangeCalendarProps
561546
let RangeCalendar = props.calendar;
562547
let mut view_date = use_signal(|| UtcDateTime::now().date());
563548
use_effect(move || {
564-
if let Some(r) = (ctx.highlighted_range)() {
549+
if let Some(r) = (ctx.date_range)() {
565550
view_date.set(r.end);
566551
}
567552
});
@@ -570,13 +555,12 @@ pub fn DateRangePickerCalendar(props: DatePickerCalendarProps<RangeCalendarProps
570555

571556
rsx! {
572557
RangeCalendar {
573-
selected_range: ctx.highlighted_range,
558+
selected_range: ctx.date_range,
574559
on_range_change: move |range| {
575-
tracing::info!("calendar selected date {range:?}");
576-
ctx.highlighted_range.set(range);
560+
tracing::info!("calendar selected range {range:?}");
561+
ctx.set_range(range);
577562
base_ctx.open.set(false);
578563
},
579-
on_anchor_change: move |date| ctx.set_selected_date(date),
580564
on_format_weekday: props.on_format_weekday,
581565
on_format_month: props.on_format_month,
582566
view_date: view_date(),
@@ -850,7 +834,7 @@ struct DateElementProps {
850834

851835
#[component]
852836
fn DateElement(props: DateElementProps) -> Element {
853-
let mut ctx = use_context::<BaseDatePickerContext>();
837+
let ctx = use_context::<BaseDatePickerContext>();
854838

855839
let mut day_value = use_signal(|| None);
856840
let mut month_value = use_signal(|| None);
@@ -875,7 +859,6 @@ fn DateElement(props: DateElementProps) -> Element {
875859
{
876860
tracing::info!("Parsed date: {date:?}");
877861
props.on_date_change.call(Some(date));
878-
ctx.open.set(false);
879862
}
880863
}
881864
});
@@ -1015,13 +998,17 @@ pub struct DatePickerInputProps {
1015998
/// ```
1016999
#[component]
10171000
pub fn DatePickerInput(props: DatePickerInputProps) -> Element {
1001+
let mut base_ctx = use_context::<BaseDatePickerContext>();
10181002
let mut ctx = use_context::<DatePickerContext>();
10191003

10201004
rsx! {
10211005
div { class: "date-picker-group", ..props.attributes,
10221006
DateElement {
10231007
selected_date: ctx.selected_date,
1024-
on_date_change: move |date| ctx.set_date(date),
1008+
on_date_change: move |date| {
1009+
ctx.set_date(date);
1010+
base_ctx.open.set(false);
1011+
},
10251012
on_format_day_placeholder: props.on_format_day_placeholder,
10261013
on_format_month_placeholder: props.on_format_month_placeholder,
10271014
on_format_year_placeholder: props.on_format_year_placeholder,
@@ -1071,15 +1058,27 @@ pub fn DatePickerInput(props: DatePickerInputProps) -> Element {
10711058
#[component]
10721059
pub fn DateRangePickerInput(props: DatePickerInputProps) -> Element {
10731060
let mut ctx = use_context::<DateRangePickerContext>();
1074-
let start_date =
1075-
use_signal(|| (ctx.anchor_date)().or((ctx.highlighted_range)().map(|r| r.start)));
1076-
let end_date = use_signal(|| (ctx.highlighted_range)().map(|r| r.end));
1061+
let mut start_date = use_signal(|| None);
1062+
let mut end_date = use_signal(|| None);
1063+
1064+
use_effect(move || {
1065+
start_date.set((ctx.date_range)().map(|r| r.start));
1066+
end_date.set((ctx.date_range)().map(|r| r.end));
1067+
});
1068+
1069+
use_effect(move || {
1070+
if let (Some(start), Some(end)) = (start_date(), end_date()) {
1071+
let range = Some(DateRange::new(start, end));
1072+
tracing::info!("set range {range:?}");
1073+
ctx.set_range(range);
1074+
};
1075+
});
10771076

10781077
rsx! {
10791078
div { class: "date-picker-group", ..props.attributes,
10801079
DateElement {
10811080
selected_date: start_date(),
1082-
on_date_change: move |date| ctx.set_selected_date(date),
1081+
on_date_change: move |date| start_date.set(date),
10831082
on_format_day_placeholder: props.on_format_day_placeholder,
10841083
on_format_month_placeholder: props.on_format_month_placeholder,
10851084
on_format_year_placeholder: props.on_format_year_placeholder,
@@ -1088,7 +1087,7 @@ pub fn DateRangePickerInput(props: DatePickerInputProps) -> Element {
10881087
DateElement {
10891088
start_index: 3,
10901089
selected_date: end_date(),
1091-
on_date_change: move |date| ctx.set_selected_date(date),
1090+
on_date_change: move |date| end_date.set(date),
10921091
on_format_day_placeholder: props.on_format_day_placeholder,
10931092
on_format_month_placeholder: props.on_format_month_placeholder,
10941093
on_format_year_placeholder: props.on_format_year_placeholder,

0 commit comments

Comments
 (0)