Files
CapaKraken/apps/web/src/hooks/timelineMultiSelect.ts
T

89 lines
1.8 KiB
TypeScript

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<TState extends MultiSelectStateLike>(
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<TState extends MultiSelectStateLike>(
state: TState,
currentX: number,
currentY: number,
): TState {
return {
...state,
currentX,
currentY,
};
}
export function finalizeMultiSelectDraft<TState extends MultiSelectStateLike>(
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<TState extends MultiSelectStateLike>(
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,
};
}