diff --git a/crates/story/src/calendar_story.rs b/crates/story/src/calendar_story.rs index 8499a18f..e4e376da 100644 --- a/crates/story/src/calendar_story.rs +++ b/crates/story/src/calendar_story.rs @@ -14,6 +14,7 @@ pub struct CalendarStory { date_picker_large: View, date_picker_value: Option, date_range_picker: View, + default_range_mode_picker: View, } impl CalendarStory { @@ -65,11 +66,26 @@ impl CalendarStory { }) .detach(); + let default_range_mode_picker = cx.new_view(|cx| { + DatePicker::range_picker("default_range_mode_picker", cx) + .width(px(300.)) + .placeholder("Range mode picker") + .cleanable() + }); + + cx.subscribe(&default_range_mode_picker, |this, _, ev, _| match ev { + DatePickerEvent::Change(date) => { + this.date_picker_value = date.format("%Y-%m-%d").map(|s| s.to_string()); + } + }) + .detach(); + Self { date_picker, date_picker_large, date_picker_small, date_range_picker, + default_range_mode_picker, date_picker_value: None, } } @@ -83,6 +99,7 @@ impl Render for CalendarStory { .child(self.date_picker_small.clone()) .child(self.date_picker_large.clone()) .child(self.date_range_picker.clone()) + .child(self.default_range_mode_picker.clone()) .child(format!("Date picker value: {:?}", self.date_picker_value).into_element()) } } diff --git a/crates/ui/src/time/calendar.rs b/crates/ui/src/time/calendar.rs index 3e1fb44d..e850d93b 100644 --- a/crates/ui/src/time/calendar.rs +++ b/crates/ui/src/time/calendar.rs @@ -638,7 +638,7 @@ impl Calendar { impl EventEmitter for Calendar {} impl Render for Calendar { - fn render(&mut self, cx: &mut gpui::ViewContext) -> impl gpui::IntoElement { + fn render(&mut self, cx: &mut ViewContext) -> impl gpui::IntoElement { v_flex() .track_focus(&self.focus_handle) .gap_0p5() diff --git a/crates/ui/src/time/date_picker.rs b/crates/ui/src/time/date_picker.rs index 7d0a50b8..c4d405ec 100644 --- a/crates/ui/src/time/date_picker.rs +++ b/crates/ui/src/time/date_picker.rs @@ -38,12 +38,33 @@ pub struct DatePicker { } impl DatePicker { + /// Create a date picker. pub fn new(id: impl Into, cx: &mut ViewContext) -> Self { + Self::new_with_range(id, false, cx) + } + + /// Create a date picker with range mode. + pub fn range_picker(id: impl Into, cx: &mut ViewContext) -> Self { + Self::new_with_range(id, true, cx) + } + + fn new_with_range( + id: impl Into, + is_range: bool, + cx: &mut ViewContext, + ) -> Self { + let date = if is_range { + Date::Range(None, None) + } else { + Date::Single(None) + }; + let calendar = cx.new_view(Calendar::new); + calendar.update(cx, |view, cx| view.set_date(date, cx)); cx.subscribe(&calendar, |this, _, ev: &CalendarEvent, cx| match ev { CalendarEvent::Selected(date) => { - this.update_date(*date, cx); + this.update_date(*date, true, cx); } }) .detach(); @@ -51,7 +72,7 @@ impl DatePicker { Self { id: id.into(), focus_handle: cx.focus_handle(), - date: Date::Single(None), + date, calendar, open: false, size: Size::default(), @@ -100,16 +121,18 @@ impl DatePicker { /// Set the date of the date picker. pub fn set_date(&mut self, date: impl Into, cx: &mut ViewContext) { - self.update_date(date.into(), cx); + self.update_date(date.into(), false, cx); } - fn update_date(&mut self, date: Date, cx: &mut ViewContext) { + fn update_date(&mut self, date: Date, emit: bool, cx: &mut ViewContext) { self.date = date; self.calendar.update(cx, |view, cx| { view.set_date(date, cx); }); self.open = false; - cx.emit(DatePickerEvent::Change(date)); + if emit { + cx.emit(DatePickerEvent::Change(date)); + } cx.notify(); } @@ -119,7 +142,14 @@ impl DatePicker { } fn clean(&mut self, _: &gpui::ClickEvent, cx: &mut ViewContext) { - self.update_date(Date::Single(None), cx); + match self.date { + Date::Single(_) => { + self.update_date(Date::Single(None), true, cx); + } + Date::Range(_, _) => { + self.update_date(Date::Range(None, None), true, cx); + } + } } fn toggle_calendar(&mut self, _: &gpui::ClickEvent, cx: &mut ViewContext) {