@@ -26,7 +26,7 @@ function getTimeSegments(getByTestId: (...args: any[]) => HTMLElement) {
2626 }
2727}
2828
29- function setup ( props : { datePickerProps ?: DatePickerRootProps , emits ?: { 'onUpdate:modelValue' ?: ( data : DateValue ) => void } } = { } ) {
29+ function setup ( props : { datePickerProps ?: DatePickerRootProps , emits ?: { 'onUpdate:modelValue' ?: ( data : DateValue | undefined ) => void } } = { } ) {
3030 const user = userEvent . setup ( )
3131 const returned = render ( DatePicker , { props } )
3232 const month = returned . getByTestId ( 'month' )
@@ -252,6 +252,128 @@ describe('datePicker', async () => {
252252 expect ( calendar . querySelector ( '[data-selected]' ) ) . not . toBeInTheDocument ( )
253253 } )
254254
255+ it ( 'resets stale placeholder time when selecting a date after the model value is cleared' , async ( ) => {
256+ const emittedValues : ( DateValue | undefined ) [ ] = [ ]
257+ const { user, trigger, getByTestId, rerender } = setup ( {
258+ datePickerProps : {
259+ modelValue : calendarDateTime ,
260+ granularity : 'minute' ,
261+ } ,
262+ emits : {
263+ 'onUpdate:modelValue' : value => emittedValues . push ( value ) ,
264+ } ,
265+ } )
266+
267+ await rerender ( {
268+ datePickerProps : {
269+ modelValue : undefined ,
270+ granularity : 'minute' ,
271+ } ,
272+ emits : {
273+ 'onUpdate:modelValue' : value => emittedValues . push ( value ) ,
274+ } ,
275+ } )
276+
277+ await user . click ( trigger )
278+ await user . click ( getByTestId ( 'date-1-1' ) )
279+
280+ const selectedValue = emittedValues . at ( - 1 )
281+ expect ( selectedValue ) . toBeInstanceOf ( CalendarDateTime )
282+ expect ( ( selectedValue as CalendarDateTime ) . hour ) . toBe ( 0 )
283+ expect ( ( selectedValue as CalendarDateTime ) . minute ) . toBe ( 0 )
284+ expect ( ( selectedValue as CalendarDateTime ) . second ) . toBe ( 0 )
285+ expect ( ( selectedValue as CalendarDateTime ) . millisecond ) . toBe ( 0 )
286+ } )
287+
288+ it ( 'resets stale ZonedDateTime placeholder time when selecting a date after the model value is cleared' , async ( ) => {
289+ const emittedValues : ( DateValue | undefined ) [ ] = [ ]
290+ const zonedValue = toZoned ( new CalendarDateTime ( 1980 , 1 , 20 , 12 , 30 , 45 , 123 ) , 'America/New_York' )
291+ const { user, trigger, getByTestId, rerender } = setup ( {
292+ datePickerProps : {
293+ modelValue : zonedValue ,
294+ granularity : 'second' ,
295+ } ,
296+ emits : {
297+ 'onUpdate:modelValue' : value => emittedValues . push ( value ) ,
298+ } ,
299+ } )
300+
301+ await rerender ( {
302+ datePickerProps : {
303+ modelValue : undefined ,
304+ granularity : 'second' ,
305+ } ,
306+ emits : {
307+ 'onUpdate:modelValue' : value => emittedValues . push ( value ) ,
308+ } ,
309+ } )
310+
311+ await user . click ( trigger )
312+ await user . click ( getByTestId ( 'date-1-1' ) )
313+
314+ const selectedValue = emittedValues . at ( - 1 )
315+ expect ( selectedValue ) . toHaveProperty ( 'timeZone' , 'America/New_York' )
316+ expect ( selectedValue ?. hour ) . toBe ( 0 )
317+ expect ( selectedValue ?. minute ) . toBe ( 0 )
318+ expect ( selectedValue ?. second ) . toBe ( 0 )
319+ expect ( selectedValue ?. millisecond ) . toBe ( 0 )
320+ } )
321+
322+ it ( 'preserves typed time when typing a date after the model value is cleared' , async ( ) => {
323+ const emittedValues : ( DateValue | undefined ) [ ] = [ ]
324+ let rerender : ReturnType < typeof setup > [ 'rerender' ]
325+ const handleUpdateModelValue = ( value : DateValue | undefined ) => {
326+ emittedValues . push ( value )
327+ return rerender ( {
328+ datePickerProps : {
329+ modelValue : value ,
330+ granularity : 'minute' ,
331+ } ,
332+ emits : {
333+ 'onUpdate:modelValue' : handleUpdateModelValue ,
334+ } ,
335+ } )
336+ }
337+
338+ const view = setup ( {
339+ datePickerProps : {
340+ modelValue : calendarDateTime ,
341+ granularity : 'minute' ,
342+ } ,
343+ emits : {
344+ 'onUpdate:modelValue' : handleUpdateModelValue ,
345+ } ,
346+ } )
347+ rerender = view . rerender
348+
349+ await rerender ( {
350+ datePickerProps : {
351+ modelValue : undefined ,
352+ granularity : 'minute' ,
353+ } ,
354+ emits : {
355+ 'onUpdate:modelValue' : handleUpdateModelValue ,
356+ } ,
357+ } )
358+
359+ await view . user . click ( view . month )
360+ await view . user . keyboard ( '{2}' )
361+ await view . user . click ( view . day )
362+ await view . user . keyboard ( '{3}' )
363+ await view . user . click ( view . year )
364+ await view . user . keyboard ( '{2020}' )
365+ await view . user . click ( view . getByTestId ( 'hour' ) )
366+ await view . user . keyboard ( '{9}' )
367+ await view . user . click ( view . getByTestId ( 'minute' ) )
368+ await view . user . keyboard ( '{45}' )
369+
370+ expect ( view . month ) . toHaveTextContent ( '2' )
371+ expect ( view . day ) . toHaveTextContent ( '3' )
372+ expect ( view . year ) . toHaveTextContent ( '2020' )
373+ expect ( view . getByTestId ( 'hour' ) ) . toHaveTextContent ( '9' )
374+ expect ( view . getByTestId ( 'minute' ) ) . toHaveTextContent ( '45' )
375+ } )
376+
255377 it ( 'should close the picker on select when `closeOnSelect` is true' , async ( ) => {
256378 const { user, trigger, getByTestId } = setup ( {
257379 datePickerProps : {
0 commit comments