-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseActions.ts
More file actions
106 lines (98 loc) · 3.23 KB
/
useActions.ts
File metadata and controls
106 lines (98 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { produce } from 'immer';
import type { KeyboardEvent as ReactKeyboardEvent } from 'react';
import { useMemo } from 'react';
import type {
CancelActionPayload,
ZoomIntoROIOptions,
} from '../context/roiReducer.js';
import { zoomAction } from '../context/updaters/zoom.js';
import type { CommittedRoi, CommittedRoiProperties } from '../index.js';
import type { UpdateRoiOptions } from '../types/actions.ts';
import type { RoiMode } from '../types/utils.js';
import type { Point } from '../utilities/point.js';
import useCallbacksRef from './useCallbacksRef.js';
import { useCurrentState } from './useCurrentState.js';
import { useRoiContainerRef } from './useRoiContainerRef.js';
import { useRoiDispatch } from './useRoiDispatch.js';
export type UpdateData<TData = unknown> = Partial<
Omit<CommittedRoiProperties<TData>, 'id'>
>;
export function useActions<TData = unknown>() {
const roiDispatch = useRoiDispatch();
const containerRef = useRoiContainerRef();
const callbacksRef = useCallbacksRef();
const stateRef = useCurrentState();
return useMemo(() => {
return {
cancelAction: (
event: KeyboardEvent | ReactKeyboardEvent,
options: CancelActionPayload,
) => {
event.preventDefault();
if (event.isTrusted) {
roiDispatch({
type: 'CANCEL_ACTION',
payload: options,
});
}
},
zoomIntoROI: (
roiOrPoints: CommittedRoi | Point[],
options: ZoomIntoROIOptions = { margin: 0.2 },
) => {
roiDispatch({
type: 'ZOOM_INTO_ROI',
payload: {
roiOrPoints,
options,
},
});
},
zoom: (factor: number) => {
if (!containerRef?.current) return;
const refBound = containerRef.current.getBoundingClientRect();
const zoomPayload = {
clientX: refBound.width / 2,
clientY: refBound.height / 2,
scale: factor,
containerBoundingRect: refBound,
};
roiDispatch({
type: 'ZOOM',
payload: zoomPayload,
});
if (stateRef.current && callbacksRef.current?.onZoom) {
const newState = produce(stateRef.current, (draft) =>
zoomAction(draft, zoomPayload),
);
callbacksRef.current.onZoom(newState.panZoom);
}
},
createRoi: (roi: CommittedRoiProperties<TData>) => {
roiDispatch({
type: 'CREATE_ROI',
payload: roi,
});
},
updateRoi: (
selectedRoi: string,
updatedData: UpdateData<TData>,
options?: UpdateRoiOptions,
) => {
roiDispatch({
type: 'UPDATE_ROI',
payload: { ...updatedData, id: selectedRoi, options },
});
},
removeRoi: (selectedRoi: string) => {
roiDispatch({ type: 'REMOVE_ROI', payload: selectedRoi });
},
selectRoi: (selectedRoi: string | null) => {
roiDispatch({ type: 'SELECT_ROI', payload: selectedRoi });
},
setMode: (mode: RoiMode) =>
roiDispatch({ type: 'SET_MODE', payload: mode }),
};
}, [roiDispatch, containerRef, stateRef, callbacksRef]);
}
export type Actions<TData = unknown> = ReturnType<typeof useActions<TData>>;