date_picker: Add range_mode method to DatePicker to set as range mode. (#216)

Co-authored-by: Jason Lee <huacnlee@gmail.com>
This commit is contained in:
ihavecoke 2024-09-04 21:41:01 +08:00 committed by GitHub
parent 2c469da55a
commit d996144713
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 54 additions and 7 deletions

View file

@ -14,6 +14,7 @@ pub struct CalendarStory {
date_picker_large: View<DatePicker>, date_picker_large: View<DatePicker>,
date_picker_value: Option<String>, date_picker_value: Option<String>,
date_range_picker: View<DatePicker>, date_range_picker: View<DatePicker>,
default_range_mode_picker: View<DatePicker>,
} }
impl CalendarStory { impl CalendarStory {
@ -65,11 +66,26 @@ impl CalendarStory {
}) })
.detach(); .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 { Self {
date_picker, date_picker,
date_picker_large, date_picker_large,
date_picker_small, date_picker_small,
date_range_picker, date_range_picker,
default_range_mode_picker,
date_picker_value: None, date_picker_value: None,
} }
} }
@ -83,6 +99,7 @@ impl Render for CalendarStory {
.child(self.date_picker_small.clone()) .child(self.date_picker_small.clone())
.child(self.date_picker_large.clone()) .child(self.date_picker_large.clone())
.child(self.date_range_picker.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()) .child(format!("Date picker value: {:?}", self.date_picker_value).into_element())
} }
} }

View file

@ -638,7 +638,7 @@ impl Calendar {
impl EventEmitter<CalendarEvent> for Calendar {} impl EventEmitter<CalendarEvent> for Calendar {}
impl Render for Calendar { impl Render for Calendar {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement { fn render(&mut self, cx: &mut ViewContext<Self>) -> impl gpui::IntoElement {
v_flex() v_flex()
.track_focus(&self.focus_handle) .track_focus(&self.focus_handle)
.gap_0p5() .gap_0p5()

View file

@ -38,12 +38,33 @@ pub struct DatePicker {
} }
impl DatePicker { impl DatePicker {
/// Create a date picker.
pub fn new(id: impl Into<ElementId>, cx: &mut ViewContext<Self>) -> Self { pub fn new(id: impl Into<ElementId>, cx: &mut ViewContext<Self>) -> Self {
Self::new_with_range(id, false, cx)
}
/// Create a date picker with range mode.
pub fn range_picker(id: impl Into<ElementId>, cx: &mut ViewContext<Self>) -> Self {
Self::new_with_range(id, true, cx)
}
fn new_with_range(
id: impl Into<ElementId>,
is_range: bool,
cx: &mut ViewContext<Self>,
) -> Self {
let date = if is_range {
Date::Range(None, None)
} else {
Date::Single(None)
};
let calendar = cx.new_view(Calendar::new); 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 { cx.subscribe(&calendar, |this, _, ev: &CalendarEvent, cx| match ev {
CalendarEvent::Selected(date) => { CalendarEvent::Selected(date) => {
this.update_date(*date, cx); this.update_date(*date, true, cx);
} }
}) })
.detach(); .detach();
@ -51,7 +72,7 @@ impl DatePicker {
Self { Self {
id: id.into(), id: id.into(),
focus_handle: cx.focus_handle(), focus_handle: cx.focus_handle(),
date: Date::Single(None), date,
calendar, calendar,
open: false, open: false,
size: Size::default(), size: Size::default(),
@ -100,16 +121,18 @@ impl DatePicker {
/// Set the date of the date picker. /// Set the date of the date picker.
pub fn set_date(&mut self, date: impl Into<Date>, cx: &mut ViewContext<Self>) { pub fn set_date(&mut self, date: impl Into<Date>, cx: &mut ViewContext<Self>) {
self.update_date(date.into(), cx); self.update_date(date.into(), false, cx);
} }
fn update_date(&mut self, date: Date, cx: &mut ViewContext<Self>) { fn update_date(&mut self, date: Date, emit: bool, cx: &mut ViewContext<Self>) {
self.date = date; self.date = date;
self.calendar.update(cx, |view, cx| { self.calendar.update(cx, |view, cx| {
view.set_date(date, cx); view.set_date(date, cx);
}); });
self.open = false; self.open = false;
cx.emit(DatePickerEvent::Change(date)); if emit {
cx.emit(DatePickerEvent::Change(date));
}
cx.notify(); cx.notify();
} }
@ -119,7 +142,14 @@ impl DatePicker {
} }
fn clean(&mut self, _: &gpui::ClickEvent, cx: &mut ViewContext<Self>) { fn clean(&mut self, _: &gpui::ClickEvent, cx: &mut ViewContext<Self>) {
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<Self>) { fn toggle_calendar(&mut self, _: &gpui::ClickEvent, cx: &mut ViewContext<Self>) {