@embedpdf/utils 1.1.1 → 1.2.0

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.
Files changed (37) hide show
  1. package/dist/preact/adapter.d.ts +1 -0
  2. package/dist/preact/index.cjs +1 -1
  3. package/dist/preact/index.cjs.map +1 -1
  4. package/dist/preact/index.js +683 -2
  5. package/dist/preact/index.js.map +1 -1
  6. package/dist/react/adapter.d.ts +1 -0
  7. package/dist/react/index.cjs +1 -1
  8. package/dist/react/index.cjs.map +1 -1
  9. package/dist/react/index.js +683 -2
  10. package/dist/react/index.js.map +1 -1
  11. package/dist/shared-preact/hooks/index.d.ts +3 -0
  12. package/dist/shared-preact/hooks/use-double-press-props.d.ts +11 -0
  13. package/dist/shared-preact/hooks/use-drag-resize.d.ts +27 -0
  14. package/dist/shared-preact/hooks/use-interaction-handles.d.ts +33 -0
  15. package/dist/shared-preact/index.d.ts +1 -0
  16. package/dist/shared-preact/plugin-interaction-primitives/drag-resize-controller.d.ts +68 -0
  17. package/dist/shared-preact/plugin-interaction-primitives/index.d.ts +2 -0
  18. package/dist/shared-preact/plugin-interaction-primitives/utils.d.ts +22 -0
  19. package/dist/shared-react/hooks/index.d.ts +3 -0
  20. package/dist/shared-react/hooks/use-double-press-props.d.ts +11 -0
  21. package/dist/shared-react/hooks/use-drag-resize.d.ts +27 -0
  22. package/dist/shared-react/hooks/use-interaction-handles.d.ts +33 -0
  23. package/dist/shared-react/index.d.ts +1 -0
  24. package/dist/shared-react/plugin-interaction-primitives/drag-resize-controller.d.ts +68 -0
  25. package/dist/shared-react/plugin-interaction-primitives/index.d.ts +2 -0
  26. package/dist/shared-react/plugin-interaction-primitives/utils.d.ts +22 -0
  27. package/dist/shared-vue/plugin-interaction-primitives/drag-resize-controller.d.ts +68 -0
  28. package/dist/shared-vue/plugin-interaction-primitives/index.d.ts +2 -0
  29. package/dist/shared-vue/plugin-interaction-primitives/utils.d.ts +22 -0
  30. package/dist/vue/hooks/index.d.ts +1 -0
  31. package/dist/vue/hooks/use-drag-resize.d.ts +24 -0
  32. package/dist/vue/index.cjs +1 -1
  33. package/dist/vue/index.cjs.map +1 -1
  34. package/dist/vue/index.d.ts +1 -0
  35. package/dist/vue/index.js +478 -2
  36. package/dist/vue/index.js.map +1 -1
  37. package/package.json +2 -2
@@ -1,6 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { getCounterRotation } from "@embedpdf/utils";
3
- import { Fragment } from "react";
3
+ import { Fragment, useRef, useEffect, useCallback, useMemo } from "react";
4
+ const dblClickProp = "onDoubleClick";
4
5
  function CounterRotate({ children, ...props }) {
5
6
  const { rect, rotation } = props;
6
7
  const { matrix, width, height } = getCounterRotation(rect, rotation);
@@ -29,7 +30,687 @@ function CounterRotate({ children, ...props }) {
29
30
  }
30
31
  }) });
31
32
  }
33
+ class DragResizeController {
34
+ constructor(config, onUpdate) {
35
+ this.config = config;
36
+ this.onUpdate = onUpdate;
37
+ this.state = "idle";
38
+ this.startPoint = null;
39
+ this.startElement = null;
40
+ this.activeHandle = null;
41
+ this.currentPosition = null;
42
+ this.activeVertexIndex = null;
43
+ this.startVertices = [];
44
+ this.currentVertices = [];
45
+ this.currentVertices = config.vertices || [];
46
+ }
47
+ updateConfig(config) {
48
+ this.config = { ...this.config, ...config };
49
+ this.currentVertices = config.vertices || [];
50
+ }
51
+ startDrag(clientX, clientY) {
52
+ this.state = "dragging";
53
+ this.startPoint = { x: clientX, y: clientY };
54
+ this.startElement = { ...this.config.element };
55
+ this.currentPosition = { ...this.config.element };
56
+ this.onUpdate({
57
+ state: "start",
58
+ transformData: {
59
+ type: "move",
60
+ changes: {
61
+ rect: this.startElement
62
+ }
63
+ }
64
+ });
65
+ }
66
+ startResize(handle, clientX, clientY) {
67
+ this.state = "resizing";
68
+ this.activeHandle = handle;
69
+ this.startPoint = { x: clientX, y: clientY };
70
+ this.startElement = { ...this.config.element };
71
+ this.currentPosition = { ...this.config.element };
72
+ this.onUpdate({
73
+ state: "start",
74
+ transformData: {
75
+ type: "resize",
76
+ changes: {
77
+ rect: this.startElement
78
+ },
79
+ metadata: {
80
+ handle: this.activeHandle,
81
+ maintainAspectRatio: this.config.maintainAspectRatio
82
+ }
83
+ }
84
+ });
85
+ }
86
+ startVertexEdit(vertexIndex, clientX, clientY) {
87
+ this.currentVertices = [...this.config.vertices ?? this.currentVertices];
88
+ if (vertexIndex < 0 || vertexIndex >= this.currentVertices.length) return;
89
+ this.state = "vertex-editing";
90
+ this.activeVertexIndex = vertexIndex;
91
+ this.startPoint = { x: clientX, y: clientY };
92
+ this.startVertices = [...this.currentVertices];
93
+ this.onUpdate({
94
+ state: "start",
95
+ transformData: {
96
+ type: "vertex-edit",
97
+ changes: {
98
+ vertices: this.startVertices
99
+ },
100
+ metadata: {
101
+ vertexIndex
102
+ }
103
+ }
104
+ });
105
+ }
106
+ move(clientX, clientY) {
107
+ if (this.state === "idle" || !this.startPoint) return;
108
+ if (this.state === "dragging" && this.startElement) {
109
+ const delta = this.calculateDelta(clientX, clientY);
110
+ const position = this.calculateDragPosition(delta);
111
+ this.currentPosition = position;
112
+ this.onUpdate({
113
+ state: "move",
114
+ transformData: {
115
+ type: "move",
116
+ changes: {
117
+ rect: position
118
+ }
119
+ }
120
+ });
121
+ } else if (this.state === "resizing" && this.activeHandle && this.startElement) {
122
+ const delta = this.calculateDelta(clientX, clientY);
123
+ const position = this.calculateResizePosition(delta, this.activeHandle);
124
+ this.currentPosition = position;
125
+ this.onUpdate({
126
+ state: "move",
127
+ transformData: {
128
+ type: "resize",
129
+ changes: {
130
+ rect: position
131
+ },
132
+ metadata: {
133
+ handle: this.activeHandle,
134
+ maintainAspectRatio: this.config.maintainAspectRatio
135
+ }
136
+ }
137
+ });
138
+ } else if (this.state === "vertex-editing" && this.activeVertexIndex !== null) {
139
+ const vertices = this.calculateVertexPosition(clientX, clientY);
140
+ this.currentVertices = vertices;
141
+ this.onUpdate({
142
+ state: "move",
143
+ transformData: {
144
+ type: "vertex-edit",
145
+ changes: {
146
+ vertices
147
+ },
148
+ metadata: {
149
+ vertexIndex: this.activeVertexIndex
150
+ }
151
+ }
152
+ });
153
+ }
154
+ }
155
+ end() {
156
+ if (this.state === "idle") return;
157
+ const wasState = this.state;
158
+ const handle = this.activeHandle;
159
+ const vertexIndex = this.activeVertexIndex;
160
+ if (wasState === "vertex-editing") {
161
+ this.onUpdate({
162
+ state: "end",
163
+ transformData: {
164
+ type: "vertex-edit",
165
+ changes: {
166
+ vertices: this.currentVertices
167
+ },
168
+ metadata: {
169
+ vertexIndex: vertexIndex || void 0
170
+ }
171
+ }
172
+ });
173
+ } else {
174
+ const finalPosition = this.getCurrentPosition();
175
+ this.onUpdate({
176
+ state: "end",
177
+ transformData: {
178
+ type: wasState === "dragging" ? "move" : "resize",
179
+ changes: {
180
+ rect: finalPosition
181
+ },
182
+ metadata: wasState === "dragging" ? void 0 : {
183
+ handle: handle || void 0,
184
+ maintainAspectRatio: this.config.maintainAspectRatio
185
+ }
186
+ }
187
+ });
188
+ }
189
+ this.reset();
190
+ }
191
+ cancel() {
192
+ if (this.state === "idle") return;
193
+ if (this.state === "vertex-editing") {
194
+ this.onUpdate({
195
+ state: "end",
196
+ transformData: {
197
+ type: "vertex-edit",
198
+ changes: {
199
+ vertices: this.startVertices
200
+ },
201
+ metadata: {
202
+ vertexIndex: this.activeVertexIndex || void 0
203
+ }
204
+ }
205
+ });
206
+ } else if (this.startElement) {
207
+ this.onUpdate({
208
+ state: "end",
209
+ transformData: {
210
+ type: this.state === "dragging" ? "move" : "resize",
211
+ changes: {
212
+ rect: this.startElement
213
+ },
214
+ metadata: this.state === "dragging" ? void 0 : {
215
+ handle: this.activeHandle || void 0,
216
+ maintainAspectRatio: this.config.maintainAspectRatio
217
+ }
218
+ }
219
+ });
220
+ }
221
+ this.reset();
222
+ }
223
+ reset() {
224
+ this.state = "idle";
225
+ this.startPoint = null;
226
+ this.startElement = null;
227
+ this.activeHandle = null;
228
+ this.currentPosition = null;
229
+ this.activeVertexIndex = null;
230
+ this.startVertices = [];
231
+ }
232
+ getCurrentPosition() {
233
+ return this.currentPosition || this.config.element;
234
+ }
235
+ calculateDelta(clientX, clientY) {
236
+ if (!this.startPoint) return { x: 0, y: 0 };
237
+ const rawDelta = {
238
+ x: clientX - this.startPoint.x,
239
+ y: clientY - this.startPoint.y
240
+ };
241
+ return this.transformDelta(rawDelta);
242
+ }
243
+ transformDelta(delta) {
244
+ const { pageRotation = 0, scale = 1 } = this.config;
245
+ const rad = pageRotation * Math.PI / 2;
246
+ const cos = Math.cos(rad);
247
+ const sin = Math.sin(rad);
248
+ const scaledX = delta.x / scale;
249
+ const scaledY = delta.y / scale;
250
+ return {
251
+ x: cos * scaledX + sin * scaledY,
252
+ y: -sin * scaledX + cos * scaledY
253
+ };
254
+ }
255
+ clampPoint(p) {
256
+ var _a;
257
+ const bbox = (_a = this.config.constraints) == null ? void 0 : _a.boundingBox;
258
+ if (!bbox) return p;
259
+ return {
260
+ x: Math.max(0, Math.min(p.x, bbox.width)),
261
+ y: Math.max(0, Math.min(p.y, bbox.height))
262
+ };
263
+ }
264
+ calculateVertexPosition(clientX, clientY) {
265
+ if (this.activeVertexIndex === null) return this.startVertices;
266
+ const delta = this.calculateDelta(clientX, clientY);
267
+ const newVertices = [...this.startVertices];
268
+ const currentVertex = newVertices[this.activeVertexIndex];
269
+ const moved = {
270
+ x: currentVertex.x + delta.x,
271
+ y: currentVertex.y + delta.y
272
+ };
273
+ newVertices[this.activeVertexIndex] = this.clampPoint(moved);
274
+ return newVertices;
275
+ }
276
+ calculateDragPosition(delta) {
277
+ if (!this.startElement) return this.config.element;
278
+ const position = {
279
+ origin: {
280
+ x: this.startElement.origin.x + delta.x,
281
+ y: this.startElement.origin.y + delta.y
282
+ },
283
+ size: {
284
+ width: this.startElement.size.width,
285
+ height: this.startElement.size.height
286
+ }
287
+ };
288
+ return this.applyConstraints(position);
289
+ }
290
+ calculateResizePosition(delta, handle) {
291
+ var _a;
292
+ if (!this.startElement) return this.config.element;
293
+ let {
294
+ origin: { x, y },
295
+ size: { width, height }
296
+ } = this.startElement;
297
+ switch (handle) {
298
+ case "se":
299
+ width += delta.x;
300
+ height += delta.y;
301
+ break;
302
+ case "sw":
303
+ x += delta.x;
304
+ width -= delta.x;
305
+ height += delta.y;
306
+ break;
307
+ case "ne":
308
+ width += delta.x;
309
+ y += delta.y;
310
+ height -= delta.y;
311
+ break;
312
+ case "nw":
313
+ x += delta.x;
314
+ width -= delta.x;
315
+ y += delta.y;
316
+ height -= delta.y;
317
+ break;
318
+ case "n":
319
+ y += delta.y;
320
+ height -= delta.y;
321
+ break;
322
+ case "s":
323
+ height += delta.y;
324
+ break;
325
+ case "e":
326
+ width += delta.x;
327
+ break;
328
+ case "w":
329
+ x += delta.x;
330
+ width -= delta.x;
331
+ break;
332
+ }
333
+ if (this.config.maintainAspectRatio && this.startElement) {
334
+ const aspectRatio = this.startElement.size.width / this.startElement.size.height;
335
+ if (["n", "s", "e", "w"].includes(handle)) {
336
+ if (handle === "n" || handle === "s") {
337
+ const newWidth = height * aspectRatio;
338
+ const widthDiff = newWidth - width;
339
+ width = newWidth;
340
+ x -= widthDiff / 2;
341
+ } else {
342
+ const newHeight = width / aspectRatio;
343
+ const heightDiff = newHeight - height;
344
+ height = newHeight;
345
+ if (handle === "w") {
346
+ x = this.startElement.origin.x + this.startElement.size.width - width;
347
+ }
348
+ y -= heightDiff / 2;
349
+ }
350
+ } else {
351
+ const widthChange = Math.abs(width - this.startElement.size.width);
352
+ const heightChange = Math.abs(height - this.startElement.size.height);
353
+ if (widthChange > heightChange) {
354
+ height = width / aspectRatio;
355
+ } else {
356
+ width = height * aspectRatio;
357
+ }
358
+ if (handle.includes("w")) {
359
+ x = this.startElement.origin.x + this.startElement.size.width - width;
360
+ }
361
+ if (handle.includes("n")) {
362
+ y = this.startElement.origin.y + this.startElement.size.height - height;
363
+ }
364
+ }
365
+ }
366
+ const bbox = (_a = this.config.constraints) == null ? void 0 : _a.boundingBox;
367
+ if (bbox) {
368
+ switch (handle) {
369
+ case "e":
370
+ width = Math.min(width, bbox.width - x);
371
+ break;
372
+ case "s":
373
+ height = Math.min(height, bbox.height - y);
374
+ break;
375
+ case "se":
376
+ width = Math.min(width, bbox.width - x);
377
+ height = Math.min(height, bbox.height - y);
378
+ break;
379
+ case "w":
380
+ if (x < 0) {
381
+ width += x;
382
+ x = 0;
383
+ }
384
+ break;
385
+ case "n":
386
+ if (y < 0) {
387
+ height += y;
388
+ y = 0;
389
+ }
390
+ break;
391
+ case "sw":
392
+ if (x < 0) {
393
+ width += x;
394
+ x = 0;
395
+ }
396
+ height = Math.min(height, bbox.height - y);
397
+ break;
398
+ case "nw":
399
+ if (x < 0) {
400
+ width += x;
401
+ x = 0;
402
+ }
403
+ if (y < 0) {
404
+ height += y;
405
+ y = 0;
406
+ }
407
+ break;
408
+ case "ne":
409
+ width = Math.min(width, bbox.width - x);
410
+ if (y < 0) {
411
+ height += y;
412
+ y = 0;
413
+ }
414
+ break;
415
+ }
416
+ }
417
+ return this.applyConstraints({ origin: { x, y }, size: { width, height } });
418
+ }
419
+ applyConstraints(position) {
420
+ const { constraints } = this.config;
421
+ if (!constraints) return position;
422
+ let {
423
+ origin: { x, y },
424
+ size: { width, height }
425
+ } = position;
426
+ width = Math.max(constraints.minWidth || 1, width);
427
+ height = Math.max(constraints.minHeight || 1, height);
428
+ if (constraints.maxWidth) width = Math.min(constraints.maxWidth, width);
429
+ if (constraints.maxHeight) height = Math.min(constraints.maxHeight, height);
430
+ if (constraints.boundingBox) {
431
+ x = Math.max(0, Math.min(x, constraints.boundingBox.width - width));
432
+ y = Math.max(0, Math.min(y, constraints.boundingBox.height - height));
433
+ }
434
+ return { origin: { x, y }, size: { width, height } };
435
+ }
436
+ }
437
+ function diagonalCursor(handle, rot) {
438
+ const diag0 = {
439
+ nw: "nwse-resize",
440
+ ne: "nesw-resize",
441
+ sw: "nesw-resize",
442
+ se: "nwse-resize"
443
+ };
444
+ if (handle === "n" || handle === "s") return "ns-resize";
445
+ if (handle === "e" || handle === "w") return "ew-resize";
446
+ if (rot % 2 === 0) return diag0[handle];
447
+ return { nw: "nesw-resize", ne: "nwse-resize", sw: "nwse-resize", se: "nesw-resize" }[handle];
448
+ }
449
+ function edgeOffset(k, spacing, mode) {
450
+ const base = -k / 2;
451
+ if (mode === "center") return base;
452
+ return mode === "outside" ? base - spacing : base + spacing;
453
+ }
454
+ function describeResizeFromConfig(cfg, ui = {}) {
455
+ const {
456
+ handleSize = 8,
457
+ spacing = 1,
458
+ offsetMode = "outside",
459
+ includeSides = false,
460
+ zIndex = 3,
461
+ rotationAwareCursor = true
462
+ } = ui;
463
+ const rotation = (cfg.pageRotation ?? 0) % 4;
464
+ const off = (edge) => ({
465
+ [edge]: edgeOffset(handleSize, spacing, offsetMode)
466
+ });
467
+ const corners = [
468
+ ["nw", { ...off("top"), ...off("left") }],
469
+ ["ne", { ...off("top"), ...off("right") }],
470
+ ["sw", { ...off("bottom"), ...off("left") }],
471
+ ["se", { ...off("bottom"), ...off("right") }]
472
+ ];
473
+ const sides = includeSides ? [
474
+ ["n", { ...off("top"), left: `calc(50% - ${handleSize / 2}px)` }],
475
+ ["s", { ...off("bottom"), left: `calc(50% - ${handleSize / 2}px)` }],
476
+ ["w", { ...off("left"), top: `calc(50% - ${handleSize / 2}px)` }],
477
+ ["e", { ...off("right"), top: `calc(50% - ${handleSize / 2}px)` }]
478
+ ] : [];
479
+ const all = [...corners, ...sides];
480
+ return all.map(([handle, pos]) => ({
481
+ handle,
482
+ style: {
483
+ position: "absolute",
484
+ width: handleSize,
485
+ height: handleSize,
486
+ borderRadius: "50%",
487
+ zIndex,
488
+ cursor: rotationAwareCursor ? diagonalCursor(handle, rotation) : "default",
489
+ touchAction: "none",
490
+ ...pos
491
+ },
492
+ attrs: { "data-epdf-handle": handle }
493
+ }));
494
+ }
495
+ function describeVerticesFromConfig(cfg, ui = {}, liveVertices) {
496
+ const { vertexSize = 12, zIndex = 4 } = ui;
497
+ const rect = cfg.element;
498
+ const scale = cfg.scale ?? 1;
499
+ const verts = liveVertices ?? cfg.vertices ?? [];
500
+ return verts.map((v, i) => {
501
+ const left = (v.x - rect.origin.x) * scale - vertexSize / 2;
502
+ const top = (v.y - rect.origin.y) * scale - vertexSize / 2;
503
+ return {
504
+ handle: "nw",
505
+ // not used; kept for type
506
+ style: {
507
+ position: "absolute",
508
+ left,
509
+ top,
510
+ width: vertexSize,
511
+ height: vertexSize,
512
+ borderRadius: "50%",
513
+ cursor: "pointer",
514
+ zIndex,
515
+ touchAction: "none"
516
+ },
517
+ attrs: { "data-epdf-vertex": i }
518
+ };
519
+ });
520
+ }
521
+ function useDragResize(options) {
522
+ const { onUpdate, enabled = true, ...config } = options;
523
+ const controllerRef = useRef(null);
524
+ const onUpdateRef = useRef(onUpdate);
525
+ useEffect(() => {
526
+ onUpdateRef.current = onUpdate;
527
+ }, [onUpdate]);
528
+ useEffect(() => {
529
+ if (!controllerRef.current) {
530
+ controllerRef.current = new DragResizeController(
531
+ config,
532
+ (event) => {
533
+ var _a;
534
+ return (_a = onUpdateRef.current) == null ? void 0 : _a.call(onUpdateRef, event);
535
+ }
536
+ );
537
+ } else {
538
+ controllerRef.current.updateConfig(config);
539
+ }
540
+ }, [
541
+ config.element,
542
+ config.constraints,
543
+ config.maintainAspectRatio,
544
+ config.pageRotation,
545
+ config.scale,
546
+ config.vertices
547
+ ]);
548
+ const handleDragStart = useCallback(
549
+ (e) => {
550
+ var _a;
551
+ if (!enabled) return;
552
+ e.preventDefault();
553
+ e.stopPropagation();
554
+ (_a = controllerRef.current) == null ? void 0 : _a.startDrag(e.clientX, e.clientY);
555
+ e.currentTarget.setPointerCapture(e.pointerId);
556
+ },
557
+ [enabled]
558
+ );
559
+ const handleMove = useCallback((e) => {
560
+ var _a;
561
+ e.preventDefault();
562
+ e.stopPropagation();
563
+ (_a = controllerRef.current) == null ? void 0 : _a.move(e.clientX, e.clientY);
564
+ }, []);
565
+ const handleEnd = useCallback((e) => {
566
+ var _a, _b, _c;
567
+ e.preventDefault();
568
+ e.stopPropagation();
569
+ (_a = controllerRef.current) == null ? void 0 : _a.end();
570
+ (_c = (_b = e.currentTarget).releasePointerCapture) == null ? void 0 : _c.call(_b, e.pointerId);
571
+ }, []);
572
+ const createResizeHandler = useCallback(
573
+ (handle) => ({
574
+ onPointerDown: (e) => {
575
+ var _a;
576
+ if (!enabled) return;
577
+ e.preventDefault();
578
+ e.stopPropagation();
579
+ (_a = controllerRef.current) == null ? void 0 : _a.startResize(handle, e.clientX, e.clientY);
580
+ e.currentTarget.setPointerCapture(e.pointerId);
581
+ },
582
+ onPointerMove: handleMove,
583
+ onPointerUp: handleEnd,
584
+ onPointerCancel: handleEnd
585
+ }),
586
+ [enabled, handleMove, handleEnd]
587
+ );
588
+ const createVertexHandler = useCallback(
589
+ (vertexIndex) => ({
590
+ onPointerDown: (e) => {
591
+ var _a;
592
+ if (!enabled) return;
593
+ e.preventDefault();
594
+ e.stopPropagation();
595
+ (_a = controllerRef.current) == null ? void 0 : _a.startVertexEdit(vertexIndex, e.clientX, e.clientY);
596
+ e.currentTarget.setPointerCapture(e.pointerId);
597
+ },
598
+ onPointerMove: handleMove,
599
+ onPointerUp: handleEnd,
600
+ onPointerCancel: handleEnd
601
+ }),
602
+ [enabled, handleMove, handleEnd]
603
+ );
604
+ return {
605
+ dragProps: enabled ? {
606
+ onPointerDown: handleDragStart,
607
+ onPointerMove: handleMove,
608
+ onPointerUp: handleEnd,
609
+ onPointerCancel: handleEnd
610
+ } : {},
611
+ createResizeProps: createResizeHandler,
612
+ createVertexProps: createVertexHandler
613
+ };
614
+ }
615
+ function useInteractionHandles(opts) {
616
+ const {
617
+ controller,
618
+ resizeUI,
619
+ vertexUI,
620
+ includeVertices = false,
621
+ handleAttrs,
622
+ vertexAttrs
623
+ } = opts;
624
+ const { dragProps, createResizeProps, createVertexProps } = useDragResize(controller);
625
+ const resize = useMemo(() => {
626
+ const desc = describeResizeFromConfig(controller, resizeUI);
627
+ return desc.map((d) => {
628
+ var _a;
629
+ return {
630
+ key: (_a = d.attrs) == null ? void 0 : _a["data-epdf-handle"],
631
+ style: d.style,
632
+ ...createResizeProps(d.handle),
633
+ ...d.attrs ?? {},
634
+ ...(handleAttrs == null ? void 0 : handleAttrs(d.handle)) ?? {}
635
+ };
636
+ });
637
+ }, [
638
+ controller.element.origin.x,
639
+ controller.element.origin.y,
640
+ controller.element.size.width,
641
+ controller.element.size.height,
642
+ controller.scale,
643
+ controller.pageRotation,
644
+ controller.maintainAspectRatio,
645
+ resizeUI == null ? void 0 : resizeUI.handleSize,
646
+ resizeUI == null ? void 0 : resizeUI.spacing,
647
+ resizeUI == null ? void 0 : resizeUI.offsetMode,
648
+ resizeUI == null ? void 0 : resizeUI.includeSides,
649
+ resizeUI == null ? void 0 : resizeUI.zIndex,
650
+ resizeUI == null ? void 0 : resizeUI.rotationAwareCursor,
651
+ createResizeProps,
652
+ handleAttrs
653
+ ]);
654
+ const vertices = useMemo(() => {
655
+ if (!includeVertices) return [];
656
+ const desc = describeVerticesFromConfig(controller, vertexUI, controller.vertices);
657
+ return desc.map((d, i) => ({
658
+ key: i,
659
+ style: d.style,
660
+ ...createVertexProps(i),
661
+ ...d.attrs ?? {},
662
+ ...(vertexAttrs == null ? void 0 : vertexAttrs(i)) ?? {}
663
+ }));
664
+ }, [
665
+ includeVertices,
666
+ controller.element.origin.x,
667
+ controller.element.origin.y,
668
+ controller.element.size.width,
669
+ controller.element.size.height,
670
+ controller.scale,
671
+ controller.vertices,
672
+ // identity/content drives recalculation
673
+ vertexUI == null ? void 0 : vertexUI.vertexSize,
674
+ vertexUI == null ? void 0 : vertexUI.zIndex,
675
+ createVertexProps,
676
+ vertexAttrs
677
+ ]);
678
+ return { dragProps, resize, vertices };
679
+ }
680
+ function useDoublePressProps(onDouble, { delay = 300, tolerancePx = 18 } = {}) {
681
+ const last = useRef({ t: 0, x: 0, y: 0 });
682
+ const handlePointerUp = useCallback(
683
+ (e) => {
684
+ if (!onDouble) return;
685
+ if (e.pointerType === "mouse" || e.isPrimary === false) return;
686
+ const now = performance.now();
687
+ const x = e.clientX;
688
+ const y = e.clientY;
689
+ const withinTime = now - last.current.t <= delay;
690
+ const dx = x - last.current.x;
691
+ const dy = y - last.current.y;
692
+ const withinDist = dx * dx + dy * dy <= tolerancePx * tolerancePx;
693
+ if (withinTime && withinDist) onDouble == null ? void 0 : onDouble(e);
694
+ last.current = { t: now, x, y };
695
+ },
696
+ [onDouble, delay, tolerancePx]
697
+ );
698
+ const handleDouble = useCallback(
699
+ (e) => {
700
+ onDouble == null ? void 0 : onDouble(e);
701
+ },
702
+ [onDouble]
703
+ );
704
+ return onDouble ? {
705
+ // Computed property uses the framework’s name ('onDoubleClick' or 'onDblClick')
706
+ [dblClickProp]: handleDouble,
707
+ onPointerUpCapture: handlePointerUp
708
+ } : {};
709
+ }
32
710
  export {
33
- CounterRotate
711
+ CounterRotate,
712
+ useDoublePressProps,
713
+ useDragResize,
714
+ useInteractionHandles
34
715
  };
35
716
  //# sourceMappingURL=index.js.map