49 lines
1.1 KiB
TypeScript
49 lines
1.1 KiB
TypeScript
type MutableCurrent<T> = {
|
|
current: T;
|
|
};
|
|
|
|
type AttachDocumentMouseDrag = (
|
|
documentTarget: Document,
|
|
onMove: (event: MouseEvent) => void,
|
|
onUp: (event: MouseEvent) => void,
|
|
) => () => void;
|
|
|
|
type BeginProjectDragSessionParams<TState> = {
|
|
state: TState;
|
|
cleanupRef: MutableCurrent<(() => void) | null>;
|
|
stateRef: MutableCurrent<TState>;
|
|
setState: (state: TState) => void;
|
|
documentTarget: Document;
|
|
attachDrag: AttachDocumentMouseDrag;
|
|
updatePosition: (clientX: number) => void;
|
|
finalize: (clientX: number) => Promise<void> | void;
|
|
};
|
|
|
|
export function beginProjectDragSession<TState>({
|
|
state,
|
|
cleanupRef,
|
|
stateRef,
|
|
setState,
|
|
documentTarget,
|
|
attachDrag,
|
|
updatePosition,
|
|
finalize,
|
|
}: BeginProjectDragSessionParams<TState>) {
|
|
stateRef.current = state;
|
|
setState(state);
|
|
cleanupRef.current?.();
|
|
|
|
function handleMove(event: MouseEvent) {
|
|
updatePosition(event.clientX);
|
|
}
|
|
|
|
function handleUp(event: MouseEvent) {
|
|
cleanupRef.current?.();
|
|
cleanupRef.current = null;
|
|
void finalize(event.clientX);
|
|
event.preventDefault();
|
|
}
|
|
|
|
cleanupRef.current = attachDrag(documentTarget, handleMove, handleUp);
|
|
}
|