use std::rc::Rc; use gpui::{ Context, IntoElement, KeyUpEvent, Keystroke, Modifiers, ParentElement, Render, Styled, TestAppContext, Window, div, point, px, }; use jiff::civil::{Date, Time, date, time}; use super::setup; use crate::forms::{Calendar, DatePicker, DateRangePicker, TimePicker}; const TODAY: Date = date(2026, 9, 25); struct Day { value: Option, disabled: bool, } impl Render for Day { fn render(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { let view = cx.entity(); div().size_full().child( DatePicker::new("day", self.value) .today(TODAY) .disabled(self.disabled) .on_change(move |picked, _, cx| { view.update(cx, |view, cx| { view.value = Some(picked); cx.notify(); }) }), ) } } #[gpui::test] fn a_date_picker_opens_and_picks_from_the_keyboard(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Day { value: Some(date(2026, 9, 10)), disabled: false, }); cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("enter right enter"); assert_eq!( view.read_with(cx, |view, _| view.value), Some(date(2026, 9, 11)) ); } struct Span { value: Option<(Date, Date)>, } impl Render for Span { fn render(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { let view = cx.entity(); div().size_full().child( DateRangePicker::new("span", self.value) .today(TODAY) .on_change(move |picked, _, cx| { view.update(cx, |view, cx| { view.value = Some(picked); cx.notify(); }) }), ) } } #[gpui::test] fn a_range_picker_takes_two_picks_in_either_order(cx: &mut TestAppContext) { setup(cx); let (view, cx) = cx.add_window_view(|_, _| Span { value: None }); cx.update(|window, cx| window.focus_next(cx)); cx.simulate_keystrokes("enter enter left left enter"); assert_eq!( view.read_with(cx, |view, _| view.value), Some((date(2026, 9, 23), TODAY)) ); } struct Clock { value: Option