@embedpdf/plugin-annotation 2.9.0 → 2.10.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 (77) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +3082 -2656
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/actions.d.ts +25 -6
  6. package/dist/lib/annotation-plugin.d.ts +15 -12
  7. package/dist/lib/handlers/index.d.ts +1 -0
  8. package/dist/lib/handlers/link.handler.d.ts +3 -0
  9. package/dist/lib/handlers/types.d.ts +9 -1
  10. package/dist/lib/helpers.d.ts +12 -5
  11. package/dist/lib/index.d.ts +4 -0
  12. package/dist/lib/reducer.d.ts +1 -1
  13. package/dist/lib/tools/default-tools.d.ts +149 -299
  14. package/dist/lib/tools/tools-utils.d.ts +448 -22
  15. package/dist/lib/tools/types.d.ts +37 -2
  16. package/dist/lib/types.d.ts +108 -24
  17. package/dist/preact/index.cjs +1 -1
  18. package/dist/preact/index.cjs.map +1 -1
  19. package/dist/preact/index.js +213 -92
  20. package/dist/preact/index.js.map +1 -1
  21. package/dist/react/index.cjs +1 -1
  22. package/dist/react/index.cjs.map +1 -1
  23. package/dist/react/index.js +213 -92
  24. package/dist/react/index.js.map +1 -1
  25. package/dist/shared/components/annotation-navigation-handler.d.ts +1 -0
  26. package/dist/shared/components/annotations/link-locked.d.ts +3 -0
  27. package/dist/shared/components/annotations/stamp.d.ts +1 -1
  28. package/dist/shared/components/preview-renderer.d.ts +4 -3
  29. package/dist/shared/components/types.d.ts +21 -4
  30. package/dist/shared/hooks/index.d.ts +1 -0
  31. package/dist/shared/hooks/use-annotation.d.ts +2 -2
  32. package/dist/shared/hooks/use-ios-zoom-prevention.d.ts +16 -0
  33. package/dist/shared-preact/components/annotation-navigation-handler.d.ts +1 -0
  34. package/dist/shared-preact/components/annotations/link-locked.d.ts +3 -0
  35. package/dist/shared-preact/components/annotations/stamp.d.ts +1 -1
  36. package/dist/shared-preact/components/preview-renderer.d.ts +4 -3
  37. package/dist/shared-preact/components/types.d.ts +21 -4
  38. package/dist/shared-preact/hooks/index.d.ts +1 -0
  39. package/dist/shared-preact/hooks/use-annotation.d.ts +2 -2
  40. package/dist/shared-preact/hooks/use-ios-zoom-prevention.d.ts +15 -0
  41. package/dist/shared-react/components/annotation-navigation-handler.d.ts +1 -0
  42. package/dist/shared-react/components/annotations/link-locked.d.ts +3 -0
  43. package/dist/shared-react/components/annotations/stamp.d.ts +1 -1
  44. package/dist/shared-react/components/preview-renderer.d.ts +4 -3
  45. package/dist/shared-react/components/types.d.ts +21 -4
  46. package/dist/shared-react/hooks/index.d.ts +1 -0
  47. package/dist/shared-react/hooks/use-annotation.d.ts +2 -2
  48. package/dist/shared-react/hooks/use-ios-zoom-prevention.d.ts +16 -0
  49. package/dist/svelte/components/AnnotationNavigationHandler.svelte.d.ts +3 -0
  50. package/dist/svelte/components/PreviewRenderer.svelte.d.ts +3 -2
  51. package/dist/svelte/components/annotations/LinkLockedMode.svelte.d.ts +5 -0
  52. package/dist/svelte/components/annotations/LinkPreview.svelte.d.ts +10 -0
  53. package/dist/svelte/components/annotations/Stamp.svelte.d.ts +1 -1
  54. package/dist/svelte/context/renderer-registry.svelte.d.ts +1 -1
  55. package/dist/svelte/context/types.d.ts +20 -3
  56. package/dist/svelte/hooks/index.d.ts +1 -0
  57. package/dist/svelte/hooks/use-annotation.svelte.d.ts +1 -1
  58. package/dist/svelte/hooks/use-ios-zoom-prevention.svelte.d.ts +6 -0
  59. package/dist/svelte/index.cjs +1 -1
  60. package/dist/svelte/index.cjs.map +1 -1
  61. package/dist/svelte/index.js +422 -234
  62. package/dist/svelte/index.js.map +1 -1
  63. package/dist/vue/components/annotation-navigation-handler.vue.d.ts +3 -0
  64. package/dist/vue/components/annotations/link-locked.vue.d.ts +5 -0
  65. package/dist/vue/components/annotations/link-preview.vue.d.ts +10 -0
  66. package/dist/vue/components/annotations/stamp.vue.d.ts +2 -2
  67. package/dist/vue/components/preview-renderer.vue.d.ts +3 -2
  68. package/dist/vue/context/renderer-registry.d.ts +1 -1
  69. package/dist/vue/context/types.d.ts +20 -3
  70. package/dist/vue/hooks/index.d.ts +1 -0
  71. package/dist/vue/hooks/use-annotation.d.ts +24 -2
  72. package/dist/vue/hooks/use-ios-zoom-prevention.d.ts +7 -0
  73. package/dist/vue/index.cjs +1 -1
  74. package/dist/vue/index.cjs.map +1 -1
  75. package/dist/vue/index.js +433 -277
  76. package/dist/vue/index.js.map +1 -1
  77. package/package.json +12 -10
@@ -1,11 +1,11 @@
1
1
  import { createPluginPackage } from "@embedpdf/core";
2
- import { initialDocumentState, AnnotationPlugin, generateCloudyRectanglePath, generateCloudyEllipsePath, patching, generateCloudyPolygonPath, getAnnotationsByPageIndex, getSelectedAnnotationIds, resolveInteractionProp, AnnotationPluginPackage as AnnotationPluginPackage$1 } from "@embedpdf/plugin-annotation";
2
+ import { AnnotationPlugin, initialDocumentState, generateCloudyRectanglePath, generateCloudyEllipsePath, patching, generateCloudyPolygonPath, LockModeType, getAnnotationsByPageIndex, getSelectedAnnotationIds, resolveInteractionProp, getAnnotationCategories, hasLockedFlag, isCategoryLocked, AnnotationPluginPackage as AnnotationPluginPackage$1 } from "@embedpdf/plugin-annotation";
3
3
  export * from "@embedpdf/plugin-annotation";
4
4
  import { jsx, jsxs, Fragment } from "preact/jsx-runtime";
5
5
  import { createContext, Fragment as Fragment$1 } from "preact";
6
- import { useState, useCallback, useContext, useRef, useEffect, useMemo, useLayoutEffect } from "preact/hooks";
6
+ import { useState, useCallback, useContext, useRef, useEffect, useMemo } from "preact/hooks";
7
7
  import { createPortal } from "preact/compat";
8
- import { useCapability, usePlugin, useDocumentPermissions, useDocumentState } from "@embedpdf/core/preact";
8
+ import { usePlugin, useCapability, useDocumentPermissions, useDocumentState } from "@embedpdf/core/preact";
9
9
  import { inferRotationCenterFromRects, boundingRectOrEmpty, PdfAnnotationBorderStyle, getContrastStrokeColor, PdfVerticalAlignment, textAlignmentToCss, standardFontCssProperties, ignore, PdfErrorCode, PdfBlendMode, PdfAnnotationSubtype, blendModeToCss } from "@embedpdf/models";
10
10
  import { usePointerHandlers } from "@embedpdf/plugin-interaction-manager/preact";
11
11
  import { useSelectionCapability } from "@embedpdf/plugin-selection/preact";
@@ -60,6 +60,50 @@ const useAnnotation = (documentId) => {
60
60
  provides: (provides == null ? void 0 : provides.forDocument(documentId)) ?? null
61
61
  };
62
62
  };
63
+ function AnnotationNavigationHandler() {
64
+ const { plugin } = useAnnotationPlugin();
65
+ const { provides } = useAnnotationCapability();
66
+ useEffect(() => {
67
+ if (!provides || !plugin) return;
68
+ return provides.onNavigate((event) => {
69
+ if (event.result.outcome === "uri" && plugin.config.autoOpenLinks !== false) {
70
+ window.open(event.result.uri, "_blank", "noopener,noreferrer");
71
+ }
72
+ });
73
+ }, [provides, plugin]);
74
+ return null;
75
+ }
76
+ const MIN_IOS_FOCUS_FONT_PX = 16;
77
+ function detectIOS() {
78
+ try {
79
+ const nav = navigator;
80
+ return /iPad|iPhone|iPod/.test(navigator.userAgent) || navigator.platform === "MacIntel" && (nav == null ? void 0 : nav.maxTouchPoints) > 1;
81
+ } catch {
82
+ return false;
83
+ }
84
+ }
85
+ let _isIOS;
86
+ function getIsIOS() {
87
+ if (_isIOS === void 0) {
88
+ _isIOS = detectIOS();
89
+ }
90
+ return _isIOS;
91
+ }
92
+ function useIOSZoomPrevention(computedFontPx, active) {
93
+ const isIOS = getIsIOS();
94
+ return useMemo(() => {
95
+ const needsComp = isIOS && active && computedFontPx > 0 && computedFontPx < MIN_IOS_FOCUS_FONT_PX;
96
+ const adjustedFontPx = needsComp ? MIN_IOS_FOCUS_FONT_PX : computedFontPx;
97
+ const scaleComp = needsComp ? computedFontPx / MIN_IOS_FOCUS_FONT_PX : 1;
98
+ const wrapperStyle = needsComp ? {
99
+ width: `${100 / scaleComp}%`,
100
+ height: `${100 / scaleComp}%`,
101
+ transform: `scale(${scaleComp})`,
102
+ transformOrigin: "top left"
103
+ } : void 0;
104
+ return { needsComp, adjustedFontPx, scaleComp, wrapperStyle };
105
+ }, [isIOS, active, computedFontPx]);
106
+ }
63
107
  function AppearanceImage({ appearance, style }) {
64
108
  const [imageUrl, setImageUrl] = useState(null);
65
109
  const urlRef = useRef(null);
@@ -403,7 +447,7 @@ function AnnotationContainer({
403
447
  ...blendMode && { mixBlendMode: blendMode },
404
448
  ...style
405
449
  },
406
- children: /* @__PURE__ */ jsxs("div", { style: { ...innerDivBaseStyle, pointerEvents: "none" }, children: [
450
+ children: /* @__PURE__ */ jsxs("div", { style: { ...innerDivBaseStyle, pointerEvents: isEditing ? "auto" : "none" }, children: [
407
451
  (() => {
408
452
  const childrenRender = typeof children === "function" ? children(childObject, { appearanceActive: apActive }) : children;
409
453
  const customRender = customAnnotationRenderer == null ? void 0 : customAnnotationRenderer({
@@ -578,7 +622,7 @@ function AnnotationContainer({
578
622
  ...innerDivBaseStyle,
579
623
  outline: showOutline ? `${outlineWidth}px ${outlineStyle} ${outlineColor}` : "none",
580
624
  outlineOffset: showOutline ? `${outlineOff}px` : "0px",
581
- pointerEvents: isSelected && !isMultiSelected ? "auto" : "none",
625
+ pointerEvents: isSelected && !isMultiSelected && !isEditing ? "auto" : "none",
582
626
  touchAction: "none",
583
627
  cursor: isSelected && effectiveIsDraggable ? "move" : "default"
584
628
  },
@@ -1214,6 +1258,7 @@ function createRenderer(entry) {
1214
1258
  id: entry.id,
1215
1259
  matches: (annotation) => entry.matches(annotation),
1216
1260
  render: (props) => entry.render(props),
1261
+ renderPreview: entry.renderPreview ? (props) => entry.renderPreview(props) : void 0,
1217
1262
  vertexConfig: entry.vertexConfig,
1218
1263
  zIndex: entry.zIndex,
1219
1264
  defaultBlendMode: entry.defaultBlendMode,
@@ -1223,7 +1268,9 @@ function createRenderer(entry) {
1223
1268
  isDraggable: entry.isDraggable,
1224
1269
  onDoubleClick: entry.onDoubleClick,
1225
1270
  selectOverride: entry.selectOverride,
1226
- hideSelectionMenu: entry.hideSelectionMenu
1271
+ hideSelectionMenu: entry.hideSelectionMenu,
1272
+ hiddenWhenLocked: entry.hiddenWhenLocked,
1273
+ renderLocked: entry.renderLocked ? (props) => entry.renderLocked(props) : void 0
1227
1274
  };
1228
1275
  }
1229
1276
  const MIN_HIT_AREA_SCREEN_PX$5 = 20;
@@ -1277,8 +1324,8 @@ function Ink({
1277
1324
  strokeWidth: hitStrokeWidth,
1278
1325
  onPointerDown: onClick,
1279
1326
  style: {
1280
- cursor: isSelected ? "move" : "pointer",
1281
- pointerEvents: isSelected ? "none" : "visibleStroke",
1327
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1328
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : "visibleStroke",
1282
1329
  strokeLinecap: "round",
1283
1330
  strokeLinejoin: "round"
1284
1331
  }
@@ -1370,8 +1417,8 @@ function Square({
1370
1417
  strokeWidth: hitStrokeWidth,
1371
1418
  onPointerDown: onClick,
1372
1419
  style: {
1373
- cursor: isSelected ? "move" : "pointer",
1374
- pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1420
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1421
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1375
1422
  }
1376
1423
  }
1377
1424
  ) : /* @__PURE__ */ jsx(
@@ -1386,8 +1433,8 @@ function Square({
1386
1433
  strokeWidth: hitStrokeWidth,
1387
1434
  onPointerDown: onClick,
1388
1435
  style: {
1389
- cursor: isSelected ? "move" : "pointer",
1390
- pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1436
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1437
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1391
1438
  }
1392
1439
  }
1393
1440
  ),
@@ -1494,8 +1541,8 @@ function Circle({
1494
1541
  strokeWidth: hitStrokeWidth,
1495
1542
  onPointerDown: onClick,
1496
1543
  style: {
1497
- cursor: isSelected ? "move" : "pointer",
1498
- pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1544
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1545
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1499
1546
  }
1500
1547
  }
1501
1548
  ) : /* @__PURE__ */ jsx(
@@ -1510,8 +1557,8 @@ function Circle({
1510
1557
  strokeWidth: hitStrokeWidth,
1511
1558
  onPointerDown: onClick,
1512
1559
  style: {
1513
- cursor: isSelected ? "move" : "pointer",
1514
- pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1560
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1561
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1515
1562
  }
1516
1563
  }
1517
1564
  ),
@@ -1611,8 +1658,8 @@ function Line({
1611
1658
  strokeWidth: hitStrokeWidth,
1612
1659
  onPointerDown: onClick,
1613
1660
  style: {
1614
- cursor: isSelected ? "move" : "pointer",
1615
- pointerEvents: isSelected ? "none" : "visibleStroke",
1661
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1662
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : "visibleStroke",
1616
1663
  strokeLinecap: "butt"
1617
1664
  }
1618
1665
  }
@@ -1627,8 +1674,8 @@ function Line({
1627
1674
  strokeWidth: hitStrokeWidth,
1628
1675
  onPointerDown: onClick,
1629
1676
  style: {
1630
- cursor: isSelected ? "move" : "pointer",
1631
- pointerEvents: isSelected ? "none" : endings.start.filled ? "visible" : "visibleStroke",
1677
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1678
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : endings.start.filled ? "visible" : "visibleStroke",
1632
1679
  strokeLinecap: "butt"
1633
1680
  }
1634
1681
  }
@@ -1643,8 +1690,8 @@ function Line({
1643
1690
  strokeWidth: hitStrokeWidth,
1644
1691
  onPointerDown: onClick,
1645
1692
  style: {
1646
- cursor: isSelected ? "move" : "pointer",
1647
- pointerEvents: isSelected ? "none" : endings.end.filled ? "visible" : "visibleStroke",
1693
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1694
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : endings.end.filled ? "visible" : "visibleStroke",
1648
1695
  strokeLinecap: "butt"
1649
1696
  }
1650
1697
  }
@@ -1781,8 +1828,8 @@ function Polyline({
1781
1828
  strokeWidth: hitStrokeWidth,
1782
1829
  onPointerDown: onClick,
1783
1830
  style: {
1784
- cursor: isSelected ? "move" : "pointer",
1785
- pointerEvents: isSelected ? "none" : "visibleStroke",
1831
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1832
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : "visibleStroke",
1786
1833
  strokeLinecap: "butt",
1787
1834
  strokeLinejoin: "miter"
1788
1835
  }
@@ -1798,8 +1845,8 @@ function Polyline({
1798
1845
  strokeWidth: hitStrokeWidth,
1799
1846
  onPointerDown: onClick,
1800
1847
  style: {
1801
- cursor: isSelected ? "move" : "pointer",
1802
- pointerEvents: isSelected ? "none" : endings.start.filled ? "visible" : "visibleStroke",
1848
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1849
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : endings.start.filled ? "visible" : "visibleStroke",
1803
1850
  strokeLinecap: "butt"
1804
1851
  }
1805
1852
  }
@@ -1814,8 +1861,8 @@ function Polyline({
1814
1861
  strokeWidth: hitStrokeWidth,
1815
1862
  onPointerDown: onClick,
1816
1863
  style: {
1817
- cursor: isSelected ? "move" : "pointer",
1818
- pointerEvents: isSelected ? "none" : endings.end.filled ? "visible" : "visibleStroke",
1864
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1865
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : endings.end.filled ? "visible" : "visibleStroke",
1819
1866
  strokeLinecap: "butt"
1820
1867
  }
1821
1868
  }
@@ -1940,8 +1987,8 @@ function Polygon({
1940
1987
  strokeWidth: hitStrokeWidth,
1941
1988
  onPointerDown: onClick,
1942
1989
  style: {
1943
- cursor: isSelected ? "move" : "pointer",
1944
- pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible",
1990
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
1991
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible",
1945
1992
  strokeLinecap: "butt",
1946
1993
  strokeLinejoin: "miter"
1947
1994
  }
@@ -2027,8 +2074,8 @@ function Text({
2027
2074
  position: "absolute",
2028
2075
  inset: 0,
2029
2076
  zIndex: 2,
2030
- pointerEvents: isSelected ? "none" : "auto",
2031
- cursor: isSelected ? "move" : "pointer"
2077
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : "auto",
2078
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default"
2032
2079
  },
2033
2080
  onPointerDown: onClick,
2034
2081
  children: !appearanceActive && /* @__PURE__ */ jsxs(
@@ -2077,46 +2124,39 @@ function FreeText({
2077
2124
  const editingRef = useRef(false);
2078
2125
  const { provides: annotationCapability } = useAnnotationCapability();
2079
2126
  const annotationProvides = (annotationCapability == null ? void 0 : annotationCapability.forDocument(documentId)) ?? null;
2080
- const [isIOS, setIsIOS] = useState(false);
2127
+ const { adjustedFontPx, wrapperStyle } = useIOSZoomPrevention(
2128
+ annotation.object.fontSize * scale,
2129
+ isEditing
2130
+ );
2081
2131
  useEffect(() => {
2132
+ var _a;
2082
2133
  if (isEditing && editorRef.current) {
2083
2134
  editingRef.current = true;
2084
2135
  const editor = editorRef.current;
2085
2136
  editor.focus();
2137
+ const tool = annotationProvides == null ? void 0 : annotationProvides.findToolForAnnotation(annotation.object);
2138
+ const isDefaultContent = ((_a = tool == null ? void 0 : tool.defaults) == null ? void 0 : _a.contents) != null && annotation.object.contents === tool.defaults.contents;
2086
2139
  const selection = window.getSelection();
2087
2140
  if (selection) {
2088
2141
  const range = document.createRange();
2089
2142
  range.selectNodeContents(editor);
2090
- range.collapse(false);
2143
+ if (!isDefaultContent) {
2144
+ range.collapse(false);
2145
+ }
2091
2146
  selection.removeAllRanges();
2092
2147
  selection.addRange(range);
2093
2148
  }
2094
2149
  }
2095
2150
  }, [isEditing]);
2096
- useLayoutEffect(() => {
2097
- try {
2098
- const nav = navigator;
2099
- const ios = /iPad|iPhone|iPod/.test(navigator.userAgent) || navigator.platform === "MacIntel" && (nav == null ? void 0 : nav.maxTouchPoints) > 1;
2100
- setIsIOS(ios);
2101
- } catch {
2102
- setIsIOS(false);
2103
- }
2104
- }, []);
2105
2151
  const handleBlur = () => {
2106
2152
  if (!editingRef.current) return;
2107
2153
  editingRef.current = false;
2108
2154
  if (!annotationProvides) return;
2109
2155
  if (!editorRef.current) return;
2110
2156
  annotationProvides.updateAnnotation(pageIndex, annotation.object.id, {
2111
- contents: editorRef.current.innerText
2157
+ contents: editorRef.current.innerText.replace(/\u00A0/g, " ")
2112
2158
  });
2113
2159
  };
2114
- const computedFontPx = annotation.object.fontSize * scale;
2115
- const MIN_IOS_FOCUS_FONT_PX = 16;
2116
- const needsComp = isIOS && isEditing && computedFontPx > 0 && computedFontPx < MIN_IOS_FOCUS_FONT_PX;
2117
- const adjustedFontPx = needsComp ? MIN_IOS_FOCUS_FONT_PX : computedFontPx;
2118
- const scaleComp = needsComp ? computedFontPx / MIN_IOS_FOCUS_FONT_PX : 1;
2119
- const invScalePercent = needsComp ? 100 / scaleComp : 100;
2120
2160
  return /* @__PURE__ */ jsx(
2121
2161
  "div",
2122
2162
  {
@@ -2125,7 +2165,7 @@ function FreeText({
2125
2165
  width: annotation.object.rect.size.width * scale,
2126
2166
  height: annotation.object.rect.size.height * scale,
2127
2167
  cursor: isSelected && !isEditing ? "move" : "default",
2128
- pointerEvents: isSelected && !isEditing ? "none" : "auto",
2168
+ pointerEvents: !onClick ? "none" : isSelected && !isEditing ? "none" : "auto",
2129
2169
  zIndex: 2,
2130
2170
  opacity: appearanceActive ? 0 : 1
2131
2171
  },
@@ -2146,14 +2186,13 @@ function FreeText({
2146
2186
  display: "flex",
2147
2187
  backgroundColor: annotation.object.color ?? annotation.object.backgroundColor,
2148
2188
  opacity: annotation.object.opacity,
2149
- width: needsComp ? `${invScalePercent}%` : "100%",
2150
- height: needsComp ? `${invScalePercent}%` : "100%",
2189
+ width: "100%",
2190
+ height: "100%",
2151
2191
  lineHeight: "1.18",
2152
2192
  overflow: "hidden",
2153
- cursor: isEditing ? "text" : "pointer",
2193
+ cursor: isEditing ? "text" : onClick ? "pointer" : "default",
2154
2194
  outline: "none",
2155
- transform: needsComp ? `scale(${scaleComp})` : void 0,
2156
- transformOrigin: "top left"
2195
+ ...wrapperStyle
2157
2196
  },
2158
2197
  contentEditable: isEditing,
2159
2198
  ...suppressContentEditableWarningProps,
@@ -2252,8 +2291,8 @@ function Stamp({
2252
2291
  width: "100%",
2253
2292
  height: "100%",
2254
2293
  zIndex: 2,
2255
- pointerEvents: isSelected ? "none" : "auto",
2256
- cursor: "pointer"
2294
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : "auto",
2295
+ cursor: onClick ? "pointer" : "default"
2257
2296
  },
2258
2297
  onPointerDown: onClick,
2259
2298
  children: /* @__PURE__ */ jsx(
@@ -2319,8 +2358,8 @@ function Link({
2319
2358
  fill: "transparent",
2320
2359
  onPointerDown: hasIRT ? void 0 : onClick,
2321
2360
  style: {
2322
- cursor: hasIRT ? "default" : isSelected ? "move" : "pointer",
2323
- pointerEvents: hasIRT ? "none" : isSelected ? "none" : "visible"
2361
+ cursor: hasIRT || !onClick ? "default" : isSelected ? "move" : "pointer",
2362
+ pointerEvents: hasIRT || !onClick ? "none" : isSelected ? "none" : "visible"
2324
2363
  }
2325
2364
  }
2326
2365
  ),
@@ -2593,8 +2632,8 @@ function Caret({
2593
2632
  strokeWidth: 4,
2594
2633
  onPointerDown: onClick,
2595
2634
  style: {
2596
- cursor: isSelected ? "move" : "pointer",
2597
- pointerEvents: isSelected ? "none" : "visible"
2635
+ cursor: isSelected ? "move" : onClick ? "pointer" : "default",
2636
+ pointerEvents: !onClick ? "none" : isSelected ? "none" : "visible"
2598
2637
  }
2599
2638
  }
2600
2639
  ),
@@ -2614,6 +2653,29 @@ function Caret({
2614
2653
  }
2615
2654
  );
2616
2655
  }
2656
+ function LinkLockedMode({
2657
+ annotation,
2658
+ documentId
2659
+ }) {
2660
+ const { provides } = useAnnotationCapability();
2661
+ const handleClick = useCallback(() => {
2662
+ const target = annotation.object.target;
2663
+ if (!target || !provides) return;
2664
+ provides.forDocument(documentId).navigateTarget(target);
2665
+ }, [annotation.object.target, provides, documentId]);
2666
+ return /* @__PURE__ */ jsx(
2667
+ "div",
2668
+ {
2669
+ onClick: handleClick,
2670
+ style: {
2671
+ width: "100%",
2672
+ height: "100%",
2673
+ cursor: "pointer",
2674
+ pointerEvents: "auto"
2675
+ }
2676
+ }
2677
+ );
2678
+ }
2617
2679
  const builtInRenderers = [
2618
2680
  // --- Drawing ---
2619
2681
  createRenderer({
@@ -2880,9 +2942,24 @@ const builtInRenderers = [
2880
2942
  hasIRT: !!currentObject.inReplyToId
2881
2943
  }
2882
2944
  ),
2945
+ renderPreview: ({ data, bounds, scale }) => /* @__PURE__ */ jsx(
2946
+ "div",
2947
+ {
2948
+ style: {
2949
+ position: "absolute",
2950
+ left: 0,
2951
+ top: 0,
2952
+ width: bounds.size.width * scale,
2953
+ height: bounds.size.height * scale,
2954
+ borderBottom: `${data.strokeWidth * scale}px solid ${data.strokeColor}`,
2955
+ backgroundColor: "rgba(0, 0, 255, 0.05)",
2956
+ boxSizing: "border-box"
2957
+ }
2958
+ }
2959
+ ),
2883
2960
  interactionDefaults: {
2884
- isDraggable: false,
2885
- isResizable: false,
2961
+ isDraggable: true,
2962
+ isResizable: true,
2886
2963
  isRotatable: false
2887
2964
  },
2888
2965
  useAppearanceStream: false,
@@ -2900,7 +2977,8 @@ const builtInRenderers = [
2900
2977
  }
2901
2978
  helpers.selectAnnotation(helpers.pageIndex, annotation.object.id);
2902
2979
  },
2903
- hideSelectionMenu: (a) => !!a.inReplyToId
2980
+ hideSelectionMenu: (a) => !!a.inReplyToId,
2981
+ renderLocked: (props) => /* @__PURE__ */ jsx(LinkLockedMode, { ...props })
2904
2982
  })
2905
2983
  ];
2906
2984
  function Annotations(annotationsProps) {
@@ -2912,6 +2990,7 @@ function Annotations(annotationsProps) {
2912
2990
  const [allSelectedIds, setAllSelectedIds] = useState([]);
2913
2991
  const [editingId, setEditingId] = useState(null);
2914
2992
  const [appearanceMap, setAppearanceMap] = useState({});
2993
+ const [lockedMode, setLockedMode] = useState({ type: LockModeType.None });
2915
2994
  const prevScaleRef = useRef(scale);
2916
2995
  const annotationProvides = useMemo(
2917
2996
  () => annotationCapability ? annotationCapability.forDocument(documentId) : null,
@@ -2923,12 +3002,22 @@ function Annotations(annotationsProps) {
2923
3002
  const currentState = annotationProvides.getState();
2924
3003
  setAnnotations(getAnnotationsByPageIndex(currentState, pageIndex));
2925
3004
  setAllSelectedIds(getSelectedAnnotationIds(currentState));
3005
+ setLockedMode(currentState.locked);
2926
3006
  return annotationProvides.onStateChange((state) => {
2927
3007
  setAnnotations(getAnnotationsByPageIndex(state, pageIndex));
2928
3008
  setAllSelectedIds(getSelectedAnnotationIds(state));
3009
+ setLockedMode(state.locked);
2929
3010
  });
2930
3011
  }
2931
3012
  }, [annotationProvides, pageIndex]);
3013
+ useEffect(() => {
3014
+ if (!annotationProvides) return;
3015
+ return annotationProvides.onAnnotationEvent((event) => {
3016
+ if (event.type === "create" && event.editAfterCreate) {
3017
+ setEditingId(event.annotation.id);
3018
+ }
3019
+ });
3020
+ }, [annotationProvides]);
2932
3021
  useEffect(() => {
2933
3022
  if (!annotationProvides) return;
2934
3023
  if (prevScaleRef.current !== scale) {
@@ -2948,12 +3037,15 @@ function Annotations(annotationsProps) {
2948
3037
  () => ({
2949
3038
  onPointerDown: (_, pe) => {
2950
3039
  if (pe.target === pe.currentTarget && annotationProvides) {
3040
+ if (editingId && annotations.some((a) => a.object.id === editingId)) {
3041
+ pe.stopImmediatePropagation();
3042
+ }
2951
3043
  annotationProvides.deselectAnnotation();
2952
3044
  setEditingId(null);
2953
3045
  }
2954
3046
  }
2955
3047
  }),
2956
- [annotationProvides]
3048
+ [annotationProvides, editingId, annotations]
2957
3049
  );
2958
3050
  const handleClick = useCallback(
2959
3051
  (e, annotation) => {
@@ -3088,27 +3180,35 @@ function Annotations(annotationsProps) {
3088
3180
  var _a, _b, _c;
3089
3181
  const renderer = resolveRenderer(annotation);
3090
3182
  if (!renderer) return null;
3091
- const tool = annotationProvides == null ? void 0 : annotationProvides.findToolForAnnotation(annotation.object);
3092
- const isSelected = allSelectedIds.includes(annotation.object.id);
3093
- const isEditing = editingId === annotation.object.id;
3183
+ const tool = (annotationProvides == null ? void 0 : annotationProvides.findToolForAnnotation(annotation.object)) ?? null;
3184
+ const categories = getAnnotationCategories(tool);
3185
+ const locked = hasLockedFlag(annotation.object) || isCategoryLocked(categories, lockedMode);
3186
+ if (locked && renderer.hiddenWhenLocked) return null;
3187
+ const hasRenderLocked = locked && !!renderer.renderLocked;
3188
+ const isSelected = locked ? false : allSelectedIds.includes(annotation.object.id);
3189
+ const isEditing = locked ? false : editingId === annotation.object.id;
3094
3190
  const defaults = renderer.interactionDefaults;
3095
3191
  const resolvedDraggable = resolveInteractionProp(
3096
3192
  tool == null ? void 0 : tool.interaction.isDraggable,
3097
3193
  annotation.object,
3098
3194
  (defaults == null ? void 0 : defaults.isDraggable) ?? true
3099
3195
  );
3100
- const finalDraggable = renderer.isDraggable ? renderer.isDraggable(resolvedDraggable, { isEditing }) : resolvedDraggable;
3196
+ const finalDraggable = locked ? false : renderer.isDraggable ? renderer.isDraggable(resolvedDraggable, { isEditing }) : resolvedDraggable;
3101
3197
  const useAP = ((_a = tool == null ? void 0 : tool.behavior) == null ? void 0 : _a.useAppearanceStream) ?? renderer.useAppearanceStream ?? true;
3102
- const onSelect = renderer.selectOverride ? (e) => renderer.selectOverride(e, annotation, selectHelpers) : (e) => handleClick(e, annotation);
3198
+ const appearance = hasRenderLocked ? void 0 : useAP ? getAppearanceForAnnotation(annotation) : void 0;
3199
+ const noopSelect = (e) => {
3200
+ e.stopPropagation();
3201
+ };
3202
+ const onSelect = locked ? noopSelect : renderer.selectOverride ? (e) => renderer.selectOverride(e, annotation, selectHelpers) : (e) => handleClick(e, annotation);
3103
3203
  return /* @__PURE__ */ jsx(
3104
3204
  AnnotationContainer,
3105
3205
  {
3106
3206
  trackedAnnotation: annotation,
3107
3207
  isSelected,
3108
3208
  isEditing,
3109
- isMultiSelected,
3209
+ isMultiSelected: locked ? false : isMultiSelected,
3110
3210
  isDraggable: finalDraggable,
3111
- isResizable: resolveInteractionProp(
3211
+ isResizable: locked ? false : resolveInteractionProp(
3112
3212
  tool == null ? void 0 : tool.interaction.isResizable,
3113
3213
  annotation.object,
3114
3214
  (defaults == null ? void 0 : defaults.isResizable) ?? false
@@ -3118,15 +3218,15 @@ function Annotations(annotationsProps) {
3118
3218
  annotation.object,
3119
3219
  (defaults == null ? void 0 : defaults.lockAspectRatio) ?? false
3120
3220
  ),
3121
- isRotatable: resolveInteractionProp(
3221
+ isRotatable: locked ? false : resolveInteractionProp(
3122
3222
  tool == null ? void 0 : tool.interaction.isRotatable,
3123
3223
  annotation.object,
3124
3224
  (defaults == null ? void 0 : defaults.isRotatable) ?? false
3125
3225
  ),
3126
- vertexConfig: renderer.vertexConfig,
3127
- selectionMenu: ((_b = renderer.hideSelectionMenu) == null ? void 0 : _b.call(renderer, annotation.object)) ? void 0 : selectionMenu,
3226
+ vertexConfig: locked ? void 0 : renderer.vertexConfig,
3227
+ selectionMenu: locked ? void 0 : ((_b = renderer.hideSelectionMenu) == null ? void 0 : _b.call(renderer, annotation.object)) ? void 0 : selectionMenu,
3128
3228
  onSelect,
3129
- onDoubleClick: renderer.onDoubleClick ? (e) => {
3229
+ onDoubleClick: locked ? void 0 : renderer.onDoubleClick ? (e) => {
3130
3230
  e.stopPropagation();
3131
3231
  renderer.onDoubleClick(annotation.object.id, setEditingId);
3132
3232
  } : void 0,
@@ -3135,19 +3235,34 @@ function Annotations(annotationsProps) {
3135
3235
  annotation.object.blendMode ?? renderer.defaultBlendMode ?? PdfBlendMode.Normal
3136
3236
  ),
3137
3237
  style: (_c = renderer.containerStyle) == null ? void 0 : _c.call(renderer, annotation.object),
3138
- appearance: useAP ? getAppearanceForAnnotation(annotation) : void 0,
3238
+ appearance,
3139
3239
  ...annotationsProps,
3140
- children: (currentObject, { appearanceActive }) => renderer.render({
3141
- annotation,
3142
- currentObject,
3143
- isSelected,
3144
- isEditing,
3145
- scale,
3146
- pageIndex,
3147
- documentId,
3148
- onClick: onSelect,
3149
- appearanceActive
3150
- })
3240
+ children: (currentObject, { appearanceActive }) => {
3241
+ if (hasRenderLocked) {
3242
+ return renderer.renderLocked({
3243
+ annotation,
3244
+ currentObject,
3245
+ isSelected: false,
3246
+ isEditing: false,
3247
+ scale,
3248
+ pageIndex,
3249
+ documentId,
3250
+ onClick: void 0,
3251
+ appearanceActive
3252
+ });
3253
+ }
3254
+ return renderer.render({
3255
+ annotation,
3256
+ currentObject,
3257
+ isSelected,
3258
+ isEditing,
3259
+ scale,
3260
+ pageIndex,
3261
+ documentId,
3262
+ onClick: locked ? void 0 : onSelect,
3263
+ appearanceActive
3264
+ });
3265
+ }
3151
3266
  },
3152
3267
  annotation.object.id
3153
3268
  );
@@ -3287,8 +3402,9 @@ function TextMarkup({ documentId, pageIndex, scale }) {
3287
3402
  return null;
3288
3403
  }
3289
3404
  }
3290
- function PreviewRenderer({ preview, scale }) {
3405
+ function PreviewRenderer({ toolId, preview, scale }) {
3291
3406
  const { bounds } = preview;
3407
+ const registeredRenderers = useRegisteredRenderers();
3292
3408
  const style = {
3293
3409
  position: "absolute",
3294
3410
  left: bounds.origin.x * scale,
@@ -3338,6 +3454,10 @@ function PreviewRenderer({ preview, scale }) {
3338
3454
  }
3339
3455
  ) });
3340
3456
  }
3457
+ const match = registeredRenderers.find((r) => r.id === toolId && r.renderPreview);
3458
+ if (match == null ? void 0 : match.renderPreview) {
3459
+ return /* @__PURE__ */ jsx("div", { style, children: match.renderPreview({ data: preview.data, bounds: preview.bounds, scale }) });
3460
+ }
3341
3461
  return null;
3342
3462
  }
3343
3463
  function AnnotationPaintLayer({ documentId, pageIndex, scale }) {
@@ -3407,7 +3527,7 @@ function AnnotationPaintLayer({ documentId, pageIndex, scale }) {
3407
3527
  return /* @__PURE__ */ jsxs(Fragment, { children: [
3408
3528
  /* @__PURE__ */ jsx("input", { ref: fileInputRef, type: "file", style: { display: "none" } }),
3409
3529
  /* @__PURE__ */ jsx("canvas", { ref: canvasRef, style: { display: "none" } }),
3410
- Array.from(previews.entries()).map(([toolId, preview]) => /* @__PURE__ */ jsx(PreviewRenderer, { preview, scale }, toolId))
3530
+ Array.from(previews.entries()).map(([toolId, preview]) => /* @__PURE__ */ jsx(PreviewRenderer, { toolId, preview, scale }, toolId))
3411
3531
  ] });
3412
3532
  }
3413
3533
  function AnnotationLayer({
@@ -3488,7 +3608,7 @@ function AnnotationLayer({
3488
3608
  }
3489
3609
  );
3490
3610
  }
3491
- const AnnotationPluginPackage = createPluginPackage(AnnotationPluginPackage$1).addWrapper(AnnotationRendererProvider).build();
3611
+ const AnnotationPluginPackage = createPluginPackage(AnnotationPluginPackage$1).addWrapper(AnnotationRendererProvider).addUtility(AnnotationNavigationHandler).build();
3492
3612
  export {
3493
3613
  AnnotationLayer,
3494
3614
  AnnotationPluginPackage,
@@ -3498,6 +3618,7 @@ export {
3498
3618
  useAnnotation,
3499
3619
  useAnnotationCapability,
3500
3620
  useAnnotationPlugin,
3621
+ useIOSZoomPrevention,
3501
3622
  useRegisterRenderers,
3502
3623
  useRegisteredRenderers,
3503
3624
  useRendererRegistry