type MultiSelectStateLike = { isSelecting: boolean; startX: number; startY: number; currentX: number; currentY: number; selectedAllocationIds: string[]; selectedResourceIds: string[]; dateRange: { start: Date; end: Date } | null; multiDragDaysDelta: number; isMultiDragging: boolean; multiDragMode: string; }; export function createMultiSelectState( currentX: number, currentY: number, defaults: Pick< TState, | "selectedAllocationIds" | "selectedResourceIds" | "dateRange" | "multiDragDaysDelta" | "isMultiDragging" | "multiDragMode" >, ): TState { return { isSelecting: true, startX: currentX, startY: currentY, currentX, currentY, ...defaults, } as TState; } export function updateMultiSelectDraft( state: TState, currentX: number, currentY: number, ): TState { return { ...state, currentX, currentY, }; } export function finalizeMultiSelectDraft( state: TState, currentX: number, currentY: number, minDistancePx = 5, ): TState | null { const distance = Math.hypot(currentX - state.startX, currentY - state.startY); if (distance < minDistancePx) { return null; } return { ...state, isSelecting: false, currentX, currentY, }; } export function completeMultiSelectDraft( state: TState, currentX: number, currentY: number, emptyState: TState, minDistancePx = 5, ): { nextState: TState; shouldClear: boolean } { const finished = finalizeMultiSelectDraft(state, currentX, currentY, minDistancePx); if (!finished) { return { nextState: emptyState, shouldClear: true, }; } return { nextState: finished, shouldClear: false, }; }