@reekon-tools/boldr-utils 1.6.12 → 1.6.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/annotation/canvas/AnnotationCanvas.native.d.ts +2 -2
- package/dist/annotation/canvas/AnnotationCanvasInner.d.ts +5 -2
- package/dist/annotation/canvas/AnnotationCanvasInner.js +58 -6
- package/dist/annotation/canvas/AnnotationCanvasInner.native.d.ts +5 -2
- package/dist/annotation/canvas/AnnotationCanvasInner.native.js +514 -59
- package/dist/annotation/canvas/AnnotationCanvasSkia.d.ts +31 -1
- package/dist/annotation/canvas/AnnotationCanvasSkia.js +38 -9
- package/dist/annotation/canvas/Tool.d.ts +27 -0
- package/dist/annotation/canvas/elements/BackgroundImageElement.js +4 -1
- package/dist/annotation/canvas/elements/ShapeElement.js +68 -9
- package/dist/annotation/canvas/elements/StrokeElement.js +8 -3
- package/dist/annotation/canvas/measurementGeometry.d.ts +21 -0
- package/dist/annotation/canvas/measurementGeometry.js +98 -3
- package/dist/annotation/canvas/shapeGeometry.d.ts +5 -0
- package/dist/annotation/canvas/shapeGeometry.js +116 -0
- package/dist/annotation/canvas/strokeGeometry.d.ts +1 -0
- package/dist/annotation/canvas/strokeGeometry.js +8 -0
- package/dist/annotation/canvas/textGeometry.d.ts +24 -0
- package/dist/annotation/canvas/textGeometry.js +110 -0
- package/dist/annotation/canvas/tools/panTool.d.ts +1 -0
- package/dist/annotation/canvas/tools/panTool.js +38 -5
- package/dist/annotation/canvas/tools/penTool.d.ts +1 -0
- package/dist/annotation/canvas/tools/penTool.js +8 -2
- package/dist/annotation/canvas/tools/polygonTool.d.ts +11 -0
- package/dist/annotation/canvas/tools/polygonTool.js +162 -0
- package/dist/annotation/canvas/tools/selectTool.js +148 -51
- package/dist/annotation/canvas/tools/shapeTool.d.ts +25 -0
- package/dist/annotation/canvas/tools/shapeTool.js +111 -0
- package/dist/annotation/canvas/tools/textTool.d.ts +12 -0
- package/dist/annotation/canvas/tools/textTool.js +78 -0
- package/dist/annotation/canvas/useAnnotationCanvasState.d.ts +2 -1
- package/dist/annotation/canvas/useAnnotationCanvasState.js +56 -6
- package/dist/annotation/data/coalescedRunner.d.ts +1 -0
- package/dist/annotation/data/coalescedRunner.js +48 -0
- package/dist/annotation/data/hooks/useAnnotationCanvasDoc.js +118 -38
- package/dist/exports.d.ts +9 -4
- package/dist/exports.js +8 -3
- package/dist/formulas/calculateFormula.js +1 -3
- package/dist/types/annotation.d.ts +9 -0
- package/dist/types/firestore.d.ts +4 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AnnotationCanvasInnerProps } from './AnnotationCanvasInner.native.js';
|
|
2
|
-
export type { AnnotationCanvasHandle
|
|
3
|
-
export type { GestureConfig, PanTrigger
|
|
2
|
+
export type { AnnotationCanvasHandle } from './useAnnotationCanvasState.js';
|
|
3
|
+
export type { GestureConfig, PanTrigger } from './AnnotationCanvasInner.js';
|
|
4
4
|
export type AnnotationCanvasProps = AnnotationCanvasInnerProps & {
|
|
5
5
|
fallback?: unknown;
|
|
6
6
|
canvasKitOpts?: unknown;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type CSSProperties, type MutableRefObject } from 'react';
|
|
2
2
|
import type { DecimalTolerance, FractionalTolerance, Measurement, Units } from '../../types/firestore.js';
|
|
3
|
-
import type { AnnotationCanvasState, AnnotationDocumentPatch, Selection } from '../../types/annotation.js';
|
|
3
|
+
import type { AnnotationCanvasState, AnnotationDocumentPatch, PlacedMeasurementRef, Selection } from '../../types/annotation.js';
|
|
4
4
|
import type { MeasurementRef } from './measurementPicker.js';
|
|
5
|
-
import type { Tool } from './Tool.js';
|
|
5
|
+
import type { RequestTextInput, Tool } from './Tool.js';
|
|
6
6
|
import { type AnnotationCanvasHandle } from './useAnnotationCanvasState.js';
|
|
7
7
|
import { type ViewportState } from './viewport.js';
|
|
8
8
|
import type { RenderMeasurementStamp } from './measurementStampOverlay.js';
|
|
@@ -20,7 +20,10 @@ export interface AnnotationCanvasInnerProps {
|
|
|
20
20
|
decimalTolerance?: DecimalTolerance;
|
|
21
21
|
resolveImageUrl?: (storagePath: string) => Promise<string>;
|
|
22
22
|
pickMeasurement?: () => Promise<MeasurementRef | null>;
|
|
23
|
+
requestTextInput?: RequestTextInput;
|
|
23
24
|
renderMeasurementStamp?: RenderMeasurementStamp;
|
|
25
|
+
onMeasurementStampPress?: (placed: PlacedMeasurementRef) => void;
|
|
26
|
+
onMeasurementStampLongPress?: (placed: PlacedMeasurementRef) => void;
|
|
24
27
|
stampFontSource?: unknown;
|
|
25
28
|
stampValueFontSize?: number;
|
|
26
29
|
stampLabelFontSize?: number;
|
|
@@ -55,7 +55,10 @@ export const AnnotationCanvasInner = (props) => {
|
|
|
55
55
|
y: event.clientY - (rect?.top ?? 0),
|
|
56
56
|
};
|
|
57
57
|
if (isPanTriggerDown(event)) {
|
|
58
|
-
panGestureRef.current = {
|
|
58
|
+
panGestureRef.current = {
|
|
59
|
+
pointerId: event.pointerId,
|
|
60
|
+
lastScreen: screen,
|
|
61
|
+
};
|
|
59
62
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
60
63
|
event.preventDefault();
|
|
61
64
|
return;
|
|
@@ -75,7 +78,10 @@ export const AnnotationCanvasInner = (props) => {
|
|
|
75
78
|
x: screen.x - pan.lastScreen.x,
|
|
76
79
|
y: screen.y - pan.lastScreen.y,
|
|
77
80
|
});
|
|
78
|
-
panGestureRef.current = {
|
|
81
|
+
panGestureRef.current = {
|
|
82
|
+
pointerId: pan.pointerId,
|
|
83
|
+
lastScreen: screen,
|
|
84
|
+
};
|
|
79
85
|
return;
|
|
80
86
|
}
|
|
81
87
|
state.dispatchPointerMove(toCanvasPointer(event));
|
|
@@ -165,7 +171,7 @@ export const AnnotationCanvasInner = (props) => {
|
|
|
165
171
|
...style,
|
|
166
172
|
};
|
|
167
173
|
const customPreview = activeTool?.renderPreview?.(state.customPreviewState, state.ctx);
|
|
168
|
-
const { renderMeasurementStamp, selection } = props;
|
|
174
|
+
const { renderMeasurementStamp, onMeasurementStampPress, onMeasurementStampLongPress, selection, } = props;
|
|
169
175
|
return (_jsxs("div", { ref: containerRef, style: containerStyle, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp, onPointerCancel: handlePointerCancel, onWheel: handleWheel, onContextMenu: handleContextMenu, children: [AnnotationCanvasSkia({
|
|
170
176
|
width,
|
|
171
177
|
height,
|
|
@@ -177,8 +183,13 @@ export const AnnotationCanvasInner = (props) => {
|
|
|
177
183
|
// Endpoint handles on the selected line annotation. Web drives endpoint
|
|
178
184
|
// drag through selectTool's pointer handlers (preview patches update the
|
|
179
185
|
// line, so the handles follow via re-render); no live geometry needed.
|
|
186
|
+
// Handles are drag affordances — suppressed unless the active tool can
|
|
187
|
+
// act on them (view mode's pan tool selects measurements but must not
|
|
188
|
+
// advertise draggability).
|
|
180
189
|
selectedId: selection?.ids[0] ?? null,
|
|
181
|
-
handleRadius:
|
|
190
|
+
handleRadius: activeTool?.dragSelection
|
|
191
|
+
? HANDLE_PX / state.viewport.zoom
|
|
192
|
+
: undefined,
|
|
182
193
|
customPreview,
|
|
183
194
|
}), renderMeasurementStamp && (_jsx("div", { style: {
|
|
184
195
|
position: 'absolute',
|
|
@@ -190,7 +201,7 @@ export const AnnotationCanvasInner = (props) => {
|
|
|
190
201
|
const cy = (placed.anchor.y - state.viewport.pan.y) * state.viewport.zoom;
|
|
191
202
|
const isSelected = selection?.ids.includes(placed.id) ?? false;
|
|
192
203
|
const measurement = placed.measurementId
|
|
193
|
-
? state.measurementsById.get(placed.measurementId) ?? null
|
|
204
|
+
? (state.measurementsById.get(placed.measurementId) ?? null)
|
|
194
205
|
: null;
|
|
195
206
|
return (_jsxs("div", { style: {
|
|
196
207
|
position: 'absolute',
|
|
@@ -205,7 +216,9 @@ export const AnnotationCanvasInner = (props) => {
|
|
|
205
216
|
selected: isSelected,
|
|
206
217
|
size,
|
|
207
218
|
zoom: state.viewport.zoom,
|
|
208
|
-
}),
|
|
219
|
+
}), onMeasurementStampPress && (_jsx(StampPressTarget, { onPress: () => onMeasurementStampPress(placed), onLongPress: onMeasurementStampLongPress
|
|
220
|
+
? () => onMeasurementStampLongPress(placed)
|
|
221
|
+
: undefined })), isSelected && measurement && (_jsx("div", { role: "button", "aria-label": "Remove measurement", onPointerDown: (e) => {
|
|
209
222
|
e.stopPropagation();
|
|
210
223
|
const { ops, keepSelection } = buildRemoveMeasurementOps(placed);
|
|
211
224
|
state.ctx.commit({ ops });
|
|
@@ -222,3 +235,42 @@ export const AnnotationCanvasInner = (props) => {
|
|
|
222
235
|
} }))] }, placed.id));
|
|
223
236
|
}) }))] }));
|
|
224
237
|
};
|
|
238
|
+
// Whole-tile press target for the stamp overlay. The DOM has no native
|
|
239
|
+
// long-press, so it's derived: pointerdown arms a timer; if it fires before
|
|
240
|
+
// the pointer lifts (or leaves/cancels), the long-press callback runs and the
|
|
241
|
+
// trailing click is swallowed. Mirrors the native overlay's TouchableOpacity
|
|
242
|
+
// onPress/onLongPress semantics (500ms, RN's default delayLongPress).
|
|
243
|
+
const LONG_PRESS_MS = 500;
|
|
244
|
+
const StampPressTarget = ({ onPress, onLongPress, }) => {
|
|
245
|
+
const timerRef = useRef(null);
|
|
246
|
+
const longPressFiredRef = useRef(false);
|
|
247
|
+
const clearTimer = () => {
|
|
248
|
+
if (timerRef.current != null) {
|
|
249
|
+
clearTimeout(timerRef.current);
|
|
250
|
+
timerRef.current = null;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
return (_jsx("button", { "aria-label": "Open measurement", onPointerDown: (e) => {
|
|
254
|
+
e.stopPropagation();
|
|
255
|
+
longPressFiredRef.current = false;
|
|
256
|
+
if (onLongPress) {
|
|
257
|
+
clearTimer();
|
|
258
|
+
timerRef.current = setTimeout(() => {
|
|
259
|
+
timerRef.current = null;
|
|
260
|
+
longPressFiredRef.current = true;
|
|
261
|
+
onLongPress();
|
|
262
|
+
}, LONG_PRESS_MS);
|
|
263
|
+
}
|
|
264
|
+
}, onPointerUp: clearTimer, onPointerLeave: clearTimer, onPointerCancel: clearTimer, onClick: () => {
|
|
265
|
+
if (!longPressFiredRef.current)
|
|
266
|
+
onPress();
|
|
267
|
+
}, style: {
|
|
268
|
+
position: 'absolute',
|
|
269
|
+
inset: 0,
|
|
270
|
+
pointerEvents: 'auto',
|
|
271
|
+
cursor: 'pointer',
|
|
272
|
+
background: 'transparent',
|
|
273
|
+
border: 'none',
|
|
274
|
+
padding: 0,
|
|
275
|
+
} }));
|
|
276
|
+
};
|
|
@@ -2,9 +2,9 @@ import { type MutableRefObject } from 'react';
|
|
|
2
2
|
import { type ViewStyle } from 'react-native';
|
|
3
3
|
import type { RenderMeasurementStamp } from './measurementStampOverlay.js';
|
|
4
4
|
import type { DecimalTolerance, FractionalTolerance, Measurement, Units } from '../../types/firestore.js';
|
|
5
|
-
import { type AnnotationCanvasState, type AnnotationDocumentPatch, type Selection } from '../../types/annotation.js';
|
|
5
|
+
import { type AnnotationCanvasState, type AnnotationDocumentPatch, type PlacedMeasurementRef, type Selection } from '../../types/annotation.js';
|
|
6
6
|
import type { MeasurementRef } from './measurementPicker.js';
|
|
7
|
-
import type { Tool } from './Tool.js';
|
|
7
|
+
import type { RequestTextInput, Tool } from './Tool.js';
|
|
8
8
|
import { type AnnotationCanvasHandle } from './useAnnotationCanvasState.js';
|
|
9
9
|
import type { ViewportState } from './viewport.js';
|
|
10
10
|
export type { AnnotationCanvasHandle };
|
|
@@ -21,7 +21,10 @@ export interface AnnotationCanvasInnerProps {
|
|
|
21
21
|
decimalTolerance?: DecimalTolerance;
|
|
22
22
|
resolveImageUrl?: (storagePath: string) => Promise<string>;
|
|
23
23
|
pickMeasurement?: () => Promise<MeasurementRef | null>;
|
|
24
|
+
requestTextInput?: RequestTextInput;
|
|
24
25
|
renderMeasurementStamp?: RenderMeasurementStamp;
|
|
26
|
+
onMeasurementStampPress?: (placed: PlacedMeasurementRef) => void;
|
|
27
|
+
onMeasurementStampLongPress?: (placed: PlacedMeasurementRef) => void;
|
|
25
28
|
stampFontSource?: unknown;
|
|
26
29
|
stampValueFontSize?: number;
|
|
27
30
|
stampLabelFontSize?: number;
|