@@ -123,6 +123,22 @@ const createTimedEvent = (
123123 ...overrides ,
124124 } ) as Schema_Event ;
125125
126+ const createAllDayEvent = (
127+ overrides : Partial < Schema_Event > & {
128+ _id : string ;
129+ startDate : string ;
130+ endDate : string ;
131+ } ,
132+ ) : Schema_Event =>
133+ ( {
134+ isAllDay : true ,
135+ isSomeday : false ,
136+ recurrence : undefined ,
137+ title : overrides . _id ,
138+ user : "user" ,
139+ ...overrides ,
140+ } ) as Schema_Event ;
141+
126142const setDayEvents = ( events : Schema_Event [ ] ) => {
127143 store = createStoreWithEvents ( events ) ;
128144} ;
@@ -137,6 +153,18 @@ const setDraftEvent = (event: Schema_Event) => {
137153 store . dispatch ( draftSlice . actions . startGridClick ( event ) ) ;
138154} ;
139155
156+ const getDismissOptions = ( ) => {
157+ const [ , options ] = useDismissMock . mock . calls . at ( - 1 ) ?? [ ] ;
158+
159+ expect ( options ) . toBeDefined ( ) ;
160+
161+ return options as {
162+ enabled : boolean ;
163+ outsidePress ?: ( event : MouseEvent ) => boolean ;
164+ outsidePressEvent : string ;
165+ } ;
166+ } ;
167+
140168beforeEach ( ( ) => {
141169 store = createStoreWithEvents ( [ ] ) ;
142170 useDismissMock . mockClear ( ) ;
@@ -369,15 +397,43 @@ describe("DayCalendarGrid", () => {
369397 it ( "dismisses the floating form after empty agenda mouse handlers run" , ( ) => {
370398 renderDayCalendarGrid ( ) ;
371399
372- expect ( useDismissMock ) . toHaveBeenCalledWith (
373- expect . anything ( ) ,
400+ expect ( getDismissOptions ( ) ) . toEqual (
374401 expect . objectContaining ( {
375402 enabled : true ,
403+ outsidePress : expect . any ( Function ) ,
376404 outsidePressEvent : "click" ,
377405 } ) ,
378406 ) ;
379407 } ) ;
380408
409+ it ( "does not dismiss a new all-day draft from the click that created it" , async ( ) => {
410+ renderDayCalendarGrid ( ) ;
411+
412+ const allDayRegion = screen . getByRole ( "region" , { name : "All-day events" } ) ;
413+
414+ fireEvent . mouseDown ( allDayRegion , {
415+ button : 0 ,
416+ clientX : 100 ,
417+ clientY : 1 ,
418+ } ) ;
419+
420+ await waitFor ( ( ) => {
421+ expect ( getDraft ( ) ?. isAllDay ) . toBe ( true ) ;
422+ } ) ;
423+
424+ const outsidePress = getDismissOptions ( ) . outsidePress ;
425+ expect ( outsidePress ) . toBeDefined ( ) ;
426+
427+ const creationClick = new MouseEvent ( "click" , { bubbles : true } ) ;
428+ Object . defineProperty ( creationClick , "target" , {
429+ configurable : true ,
430+ value : allDayRegion ,
431+ } ) ;
432+
433+ expect ( outsidePress ?.( creationClick ) ) . toBe ( false ) ;
434+ expect ( outsidePress ?.( creationClick ) ) . toBe ( true ) ;
435+ } ) ;
436+
381437 it ( "dismisses an open draft when clicking empty Day all-day calendar space" , ( ) => {
382438 const existingDraft = createTimedEvent ( {
383439 _id : "open-all-day-draft" ,
@@ -401,6 +457,52 @@ describe("DayCalendarGrid", () => {
401457 expect ( getDraft ( ) ) . toBeNull ( ) ;
402458 } ) ;
403459
460+ it ( "places a new all-day draft below existing all-day events" , async ( ) => {
461+ setDayEvents ( [
462+ createAllDayEvent ( {
463+ _id : "first-all-day" ,
464+ endDate : "2026-05-21" ,
465+ startDate : "2026-05-20" ,
466+ title : "First all-day" ,
467+ } ) ,
468+ createAllDayEvent ( {
469+ _id : "second-all-day" ,
470+ endDate : "2026-05-21" ,
471+ startDate : "2026-05-20" ,
472+ title : "Second all-day" ,
473+ } ) ,
474+ ] ) ;
475+ renderDayCalendarGrid ( ) ;
476+
477+ fireEvent . mouseDown (
478+ screen . getByRole ( "region" , { name : "All-day events" } ) ,
479+ {
480+ button : 0 ,
481+ clientX : 100 ,
482+ clientY : 80 ,
483+ } ,
484+ ) ;
485+
486+ await waitFor ( ( ) => {
487+ const draft = screen . getByRole ( "button" , {
488+ name : / a l l - d a y e v e n t : u n t i t l e d e v e n t / i,
489+ } ) ;
490+ const first = screen . getByRole ( "button" , {
491+ name : / a l l - d a y e v e n t : f i r s t a l l - d a y / i,
492+ } ) ;
493+ const second = screen . getByRole ( "button" , {
494+ name : / a l l - d a y e v e n t : s e c o n d a l l - d a y / i,
495+ } ) ;
496+
497+ expect ( parseFloat ( draft . style . top ) ) . toBeGreaterThan (
498+ parseFloat ( first . style . top ) ,
499+ ) ;
500+ expect ( parseFloat ( draft . style . top ) ) . toBeGreaterThan (
501+ parseFloat ( second . style . top ) ,
502+ ) ;
503+ } ) ;
504+ } ) ;
505+
404506 it ( "scrolls the Day timed grid to now when the Day view requests it" , ( ) => {
405507 const scroll = mock ( ) ;
406508
0 commit comments