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