@papyrus-sdk/ui-react-native 0.2.18-beta.6 → 0.2.18-beta.8

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../gesture/pinchZoom.ts"],"sourcesContent":["export type PinchTouchPoint = {\n pageX: number;\n pageY: number;\n};\n\nexport type PinchSession = {\n initialDistance: number;\n initialZoom: number;\n};\n\nexport type PinchZoomBounds = {\n minZoom: number;\n maxZoom: number;\n};\n\nexport type AnchoredViewportOffsetInput = {\n viewportOffset: number;\n startScrollOffset: number;\n startItemOffset: number;\n startItemLength: number;\n endItemOffset: number;\n endItemLength: number;\n viewportLength: number;\n endContentLength: number;\n};\n\nexport type AnchoredDocumentOffsetInput = {\n viewportOffset: number;\n startScrollOffset: number;\n startContentLength: number;\n endContentLength: number;\n viewportLength: number;\n};\n\nexport type DocumentSurfaceWidthInput = {\n viewportWidth: number;\n contentWidth: number;\n horizontalPadding: number;\n};\n\nexport type GlobalHorizontalOffsetInput = {\n offsetX: number;\n surfaceWidth: number;\n viewportWidth: number;\n};\n\nexport type AnchoredHorizontalSurfaceOffsetInput = {\n focalViewportX: number;\n startSurfaceScrollX: number;\n startSurfaceWidth: number;\n endSurfaceWidth: number;\n viewportWidth: number;\n};\n\nexport type CenteredContentInsetInput = {\n viewportLength: number;\n contentLength: number;\n};\n\nexport const DEFAULT_PINCH_ZOOM_BOUNDS: PinchZoomBounds = {\n minZoom: 0.5,\n maxZoom: 4,\n};\nexport const PINCH_PRESS_SUPPRESSION_MS = 120;\n\nconst clamp = (value: number, min: number, max: number) =>\n Math.min(max, Math.max(min, value));\n\nexport const getTouchDistance = (touches: PinchTouchPoint[]): number => {\n if (touches.length < 2) return 0;\n const [first, second] = touches;\n return Math.hypot(second.pageX - first.pageX, second.pageY - first.pageY);\n};\n\nexport const isPinchTouchList = (touches: PinchTouchPoint[]): boolean =>\n touches.length === 2 && getTouchDistance(touches) > 0;\n\nexport const createPinchSession = (\n touches: PinchTouchPoint[],\n zoom: number,\n bounds: PinchZoomBounds = DEFAULT_PINCH_ZOOM_BOUNDS\n): PinchSession => ({\n initialDistance: Math.max(1, getTouchDistance(touches)),\n initialZoom: clamp(zoom, bounds.minZoom, bounds.maxZoom),\n});\n\nexport const resolvePinchZoomChange = (\n session: PinchSession,\n touches: PinchTouchPoint[],\n bounds: PinchZoomBounds = DEFAULT_PINCH_ZOOM_BOUNDS\n): number => {\n const distance = getTouchDistance(touches);\n if (distance <= 0) {\n return clamp(session.initialZoom, bounds.minZoom, bounds.maxZoom);\n }\n\n return clamp(\n session.initialZoom * (distance / session.initialDistance),\n bounds.minZoom,\n bounds.maxZoom\n );\n};\n\nexport const resolvePinchPreviewScale = (\n startZoom: number,\n previewZoom: number\n): number => {\n const safeStartZoom = Math.max(0.0001, Math.abs(startZoom));\n return previewZoom / safeStartZoom;\n};\n\nexport const sanitizePinchPreviewScale = (value: number): number => {\n if (!Number.isFinite(value) || value <= 0) {\n return 1;\n }\n return value;\n};\n\nexport const resolvePinchGestureZoom = (\n startZoom: number,\n scaleFactor: number,\n bounds: PinchZoomBounds = DEFAULT_PINCH_ZOOM_BOUNDS\n): number =>\n clamp(\n (Number.isFinite(startZoom) && startZoom > 0 ? startZoom : 1) *\n (Number.isFinite(scaleFactor) && scaleFactor > 0 ? scaleFactor : 1),\n bounds.minZoom,\n bounds.maxZoom\n );\n\nexport const resolveAnchoredViewportOffset = ({\n viewportOffset,\n startScrollOffset,\n startItemOffset,\n startItemLength,\n endItemOffset,\n endItemLength,\n viewportLength,\n endContentLength,\n}: AnchoredViewportOffsetInput): number => {\n const safeViewportOffset = Number.isFinite(viewportOffset)\n ? viewportOffset\n : 0;\n const safeStartScrollOffset = Number.isFinite(startScrollOffset)\n ? startScrollOffset\n : 0;\n const safeStartItemOffset = Number.isFinite(startItemOffset)\n ? startItemOffset\n : 0;\n const safeStartItemLength =\n Number.isFinite(startItemLength) && startItemLength > 0\n ? startItemLength\n : 1;\n const safeEndItemOffset = Number.isFinite(endItemOffset) ? endItemOffset : 0;\n const safeEndItemLength =\n Number.isFinite(endItemLength) && endItemLength > 0 ? endItemLength : 1;\n const safeViewportLength =\n Number.isFinite(viewportLength) && viewportLength > 0 ? viewportLength : 0;\n const safeEndContentLength =\n Number.isFinite(endContentLength) && endContentLength > 0\n ? endContentLength\n : safeEndItemOffset + safeEndItemLength;\n\n const contentPoint =\n safeStartScrollOffset + safeViewportOffset - safeStartItemOffset;\n const normalizedPoint = clamp(contentPoint / safeStartItemLength, 0, 1);\n const anchoredContentPoint =\n safeEndItemOffset + normalizedPoint * safeEndItemLength;\n return clamp(\n anchoredContentPoint - safeViewportOffset,\n 0,\n Math.max(0, safeEndContentLength - safeViewportLength)\n );\n};\n\nexport const resolveAnchoredDocumentOffset = ({\n viewportOffset,\n startScrollOffset,\n startContentLength,\n endContentLength,\n viewportLength,\n}: AnchoredDocumentOffsetInput): number => {\n const safeViewportOffset = Number.isFinite(viewportOffset)\n ? viewportOffset\n : 0;\n const safeStartScrollOffset = Number.isFinite(startScrollOffset)\n ? startScrollOffset\n : 0;\n const safeStartContentLength =\n Number.isFinite(startContentLength) && startContentLength > 0\n ? startContentLength\n : 1;\n const safeEndContentLength =\n Number.isFinite(endContentLength) && endContentLength > 0\n ? endContentLength\n : 0;\n const safeViewportLength =\n Number.isFinite(viewportLength) && viewportLength > 0 ? viewportLength : 0;\n\n const anchoredRatio = clamp(\n (safeStartScrollOffset + safeViewportOffset) / safeStartContentLength,\n 0,\n 1\n );\n\n return resolveClampedScrollOffset(\n anchoredRatio * safeEndContentLength - safeViewportOffset,\n safeEndContentLength,\n safeViewportLength\n );\n};\n\nexport const resolveClampedScrollOffset = (\n offset: number,\n contentLength: number,\n viewportLength: number\n): number => {\n const safeOffset = Number.isFinite(offset) ? offset : 0;\n const safeContentLength =\n Number.isFinite(contentLength) && contentLength > 0 ? contentLength : 0;\n const safeViewportLength =\n Number.isFinite(viewportLength) && viewportLength > 0 ? viewportLength : 0;\n return clamp(\n safeOffset,\n 0,\n Math.max(0, safeContentLength - safeViewportLength)\n );\n};\n\nexport const resolveDocumentSurfaceWidth = ({\n viewportWidth,\n contentWidth,\n horizontalPadding,\n}: DocumentSurfaceWidthInput): number => {\n const safeViewportWidth =\n Number.isFinite(viewportWidth) && viewportWidth > 0 ? viewportWidth : 0;\n const safeContentWidth =\n Number.isFinite(contentWidth) && contentWidth > 0 ? contentWidth : 0;\n const safeHorizontalPadding =\n Number.isFinite(horizontalPadding) && horizontalPadding > 0\n ? horizontalPadding\n : 0;\n\n return Math.max(\n safeViewportWidth,\n safeContentWidth + safeHorizontalPadding * 2\n );\n};\n\nexport const resolveGlobalHorizontalOffset = ({\n offsetX,\n surfaceWidth,\n viewportWidth,\n}: GlobalHorizontalOffsetInput): number =>\n resolveClampedScrollOffset(offsetX, surfaceWidth, viewportWidth);\n\nexport const resolveAnchoredHorizontalSurfaceOffset = ({\n focalViewportX,\n startSurfaceScrollX,\n startSurfaceWidth,\n endSurfaceWidth,\n viewportWidth,\n}: AnchoredHorizontalSurfaceOffsetInput): number => {\n const safeFocalViewportX = Number.isFinite(focalViewportX)\n ? focalViewportX\n : 0;\n const safeStartSurfaceScrollX = Number.isFinite(startSurfaceScrollX)\n ? startSurfaceScrollX\n : 0;\n const safeStartSurfaceWidth =\n Number.isFinite(startSurfaceWidth) && startSurfaceWidth > 0\n ? startSurfaceWidth\n : 1;\n const safeEndSurfaceWidth =\n Number.isFinite(endSurfaceWidth) && endSurfaceWidth > 0\n ? endSurfaceWidth\n : 0;\n const safeViewportWidth =\n Number.isFinite(viewportWidth) && viewportWidth > 0 ? viewportWidth : 0;\n\n const anchoredRatio = clamp(\n (safeStartSurfaceScrollX + safeFocalViewportX) / safeStartSurfaceWidth,\n 0,\n 1\n );\n\n return resolveGlobalHorizontalOffset({\n offsetX: anchoredRatio * safeEndSurfaceWidth - safeFocalViewportX,\n surfaceWidth: safeEndSurfaceWidth,\n viewportWidth: safeViewportWidth,\n });\n};\n\nexport const resolveCenteredContentInset = ({\n viewportLength,\n contentLength,\n}: CenteredContentInsetInput): number => {\n const safeViewportLength =\n Number.isFinite(viewportLength) && viewportLength > 0 ? viewportLength : 0;\n const safeContentLength =\n Number.isFinite(contentLength) && contentLength > 0 ? contentLength : 0;\n return Math.max(0, (safeViewportLength - safeContentLength) / 2);\n};\n\nexport const shouldSuppressPressAfterPinch = (\n lastPinchEndedAt: number | null | undefined,\n now = Date.now(),\n windowMs = PINCH_PRESS_SUPPRESSION_MS\n): boolean => {\n if (typeof lastPinchEndedAt !== \"number\") return false;\n const elapsedMs = now - lastPinchEndedAt;\n return elapsedMs >= 0 && elapsedMs < windowMs;\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,40 @@
1
+ import {
2
+ DEFAULT_PINCH_ZOOM_BOUNDS,
3
+ PINCH_PRESS_SUPPRESSION_MS,
4
+ createPinchSession,
5
+ getTouchDistance,
6
+ isPinchTouchList,
7
+ resolveAnchoredDocumentOffset,
8
+ resolveAnchoredHorizontalSurfaceOffset,
9
+ resolveAnchoredViewportOffset,
10
+ resolveCenteredContentInset,
11
+ resolveClampedScrollOffset,
12
+ resolveDocumentSurfaceWidth,
13
+ resolveGlobalHorizontalOffset,
14
+ resolvePinchGestureZoom,
15
+ resolvePinchPreviewScale,
16
+ resolvePinchZoomChange,
17
+ sanitizePinchPreviewScale,
18
+ shouldSuppressPressAfterPinch
19
+ } from "../chunk-B36LWZCX.mjs";
20
+ import "../chunk-ZD7AOCMD.mjs";
21
+ export {
22
+ DEFAULT_PINCH_ZOOM_BOUNDS,
23
+ PINCH_PRESS_SUPPRESSION_MS,
24
+ createPinchSession,
25
+ getTouchDistance,
26
+ isPinchTouchList,
27
+ resolveAnchoredDocumentOffset,
28
+ resolveAnchoredHorizontalSurfaceOffset,
29
+ resolveAnchoredViewportOffset,
30
+ resolveCenteredContentInset,
31
+ resolveClampedScrollOffset,
32
+ resolveDocumentSurfaceWidth,
33
+ resolveGlobalHorizontalOffset,
34
+ resolvePinchGestureZoom,
35
+ resolvePinchPreviewScale,
36
+ resolvePinchZoomChange,
37
+ sanitizePinchPreviewScale,
38
+ shouldSuppressPressAfterPinch
39
+ };
40
+ //# sourceMappingURL=pinchZoom.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,35 @@
1
+ type ViewerScrollState = {
2
+ selectionDragActive: boolean;
3
+ gestureScrollLockActive?: boolean;
4
+ };
5
+ type SelectionGestureTool = "select" | "highlight" | "underline" | "squiggly" | "strikeout" | "text" | "comment" | "ink";
6
+ type SelectionInteractionMode = "pan" | "select";
7
+ type SelectionGestureActivationInput = {
8
+ activeTool: SelectionGestureTool;
9
+ interactionMode: SelectionInteractionMode;
10
+ };
11
+ type ToolDockSelectionState = SelectionGestureActivationInput & {
12
+ toolId: SelectionGestureTool;
13
+ };
14
+ type ToolDockDismissState = SelectionGestureActivationInput & {
15
+ toolDockOpen: boolean;
16
+ };
17
+ type SelectionEdgeAutoscrollInput = {
18
+ x: number;
19
+ y: number;
20
+ width: number;
21
+ height: number;
22
+ threshold: number;
23
+ maxStep: number;
24
+ };
25
+ type SelectionEdgeAutoscroll = {
26
+ dx: number;
27
+ dy: number;
28
+ };
29
+ declare const shouldEnableViewerScroll: ({ selectionDragActive, gestureScrollLockActive, }: ViewerScrollState) => boolean;
30
+ declare const shouldEnableSelectionDrag: ({ activeTool, interactionMode, }: SelectionGestureActivationInput) => boolean;
31
+ declare const isToolDockToolSelected: ({ activeTool, interactionMode, toolId, }: ToolDockSelectionState) => boolean;
32
+ declare const getToolDockDismissState: ({ activeTool: _activeTool, interactionMode: _interactionMode, }: SelectionGestureActivationInput) => ToolDockDismissState;
33
+ declare const getSelectionEdgeAutoscroll: ({ x, y, width, height, threshold, maxStep, }: SelectionEdgeAutoscrollInput) => SelectionEdgeAutoscroll;
34
+
35
+ export { type SelectionEdgeAutoscroll, type SelectionEdgeAutoscrollInput, type SelectionGestureActivationInput, type SelectionGestureTool, type SelectionInteractionMode, type ToolDockDismissState, type ToolDockSelectionState, type ViewerScrollState, getSelectionEdgeAutoscroll, getToolDockDismissState, isToolDockToolSelected, shouldEnableSelectionDrag, shouldEnableViewerScroll };
@@ -0,0 +1,35 @@
1
+ type ViewerScrollState = {
2
+ selectionDragActive: boolean;
3
+ gestureScrollLockActive?: boolean;
4
+ };
5
+ type SelectionGestureTool = "select" | "highlight" | "underline" | "squiggly" | "strikeout" | "text" | "comment" | "ink";
6
+ type SelectionInteractionMode = "pan" | "select";
7
+ type SelectionGestureActivationInput = {
8
+ activeTool: SelectionGestureTool;
9
+ interactionMode: SelectionInteractionMode;
10
+ };
11
+ type ToolDockSelectionState = SelectionGestureActivationInput & {
12
+ toolId: SelectionGestureTool;
13
+ };
14
+ type ToolDockDismissState = SelectionGestureActivationInput & {
15
+ toolDockOpen: boolean;
16
+ };
17
+ type SelectionEdgeAutoscrollInput = {
18
+ x: number;
19
+ y: number;
20
+ width: number;
21
+ height: number;
22
+ threshold: number;
23
+ maxStep: number;
24
+ };
25
+ type SelectionEdgeAutoscroll = {
26
+ dx: number;
27
+ dy: number;
28
+ };
29
+ declare const shouldEnableViewerScroll: ({ selectionDragActive, gestureScrollLockActive, }: ViewerScrollState) => boolean;
30
+ declare const shouldEnableSelectionDrag: ({ activeTool, interactionMode, }: SelectionGestureActivationInput) => boolean;
31
+ declare const isToolDockToolSelected: ({ activeTool, interactionMode, toolId, }: ToolDockSelectionState) => boolean;
32
+ declare const getToolDockDismissState: ({ activeTool: _activeTool, interactionMode: _interactionMode, }: SelectionGestureActivationInput) => ToolDockDismissState;
33
+ declare const getSelectionEdgeAutoscroll: ({ x, y, width, height, threshold, maxStep, }: SelectionEdgeAutoscrollInput) => SelectionEdgeAutoscroll;
34
+
35
+ export { type SelectionEdgeAutoscroll, type SelectionEdgeAutoscrollInput, type SelectionGestureActivationInput, type SelectionGestureTool, type SelectionInteractionMode, type ToolDockDismissState, type ToolDockSelectionState, type ViewerScrollState, getSelectionEdgeAutoscroll, getToolDockDismissState, isToolDockToolSelected, shouldEnableSelectionDrag, shouldEnableViewerScroll };
@@ -0,0 +1,90 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // gesture/selectionInteraction.ts
20
+ var selectionInteraction_exports = {};
21
+ __export(selectionInteraction_exports, {
22
+ getSelectionEdgeAutoscroll: () => getSelectionEdgeAutoscroll,
23
+ getToolDockDismissState: () => getToolDockDismissState,
24
+ isToolDockToolSelected: () => isToolDockToolSelected,
25
+ shouldEnableSelectionDrag: () => shouldEnableSelectionDrag,
26
+ shouldEnableViewerScroll: () => shouldEnableViewerScroll
27
+ });
28
+ module.exports = __toCommonJS(selectionInteraction_exports);
29
+ var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
30
+ var DRAG_SELECTION_TOOLS = /* @__PURE__ */ new Set([
31
+ "highlight",
32
+ "underline",
33
+ "squiggly",
34
+ "strikeout"
35
+ ]);
36
+ var resolveAxisAutoscroll = (coordinate, size, threshold, maxStep) => {
37
+ if (size <= 0 || threshold <= 0 || maxStep <= 0) return 0;
38
+ const startDistance = clamp(coordinate, 0, size);
39
+ if (startDistance < threshold) {
40
+ const intensity = 1 - startDistance / threshold;
41
+ return -Math.round(maxStep * intensity);
42
+ }
43
+ const endDistance = clamp(size - coordinate, 0, size);
44
+ if (endDistance < threshold) {
45
+ const intensity = 1 - endDistance / threshold;
46
+ return Math.round(maxStep * intensity);
47
+ }
48
+ return 0;
49
+ };
50
+ var shouldEnableViewerScroll = ({
51
+ selectionDragActive,
52
+ gestureScrollLockActive = false
53
+ }) => !selectionDragActive && !gestureScrollLockActive;
54
+ var shouldEnableSelectionDrag = ({
55
+ activeTool,
56
+ interactionMode
57
+ }) => DRAG_SELECTION_TOOLS.has(activeTool) || activeTool === "select" && interactionMode === "select";
58
+ var isToolDockToolSelected = ({
59
+ activeTool,
60
+ interactionMode,
61
+ toolId
62
+ }) => toolId === "select" ? activeTool === "select" && interactionMode === "select" : activeTool === toolId;
63
+ var getToolDockDismissState = ({
64
+ activeTool: _activeTool,
65
+ interactionMode: _interactionMode
66
+ }) => ({
67
+ toolDockOpen: false,
68
+ activeTool: "select",
69
+ interactionMode: "pan"
70
+ });
71
+ var getSelectionEdgeAutoscroll = ({
72
+ x,
73
+ y,
74
+ width,
75
+ height,
76
+ threshold,
77
+ maxStep
78
+ }) => ({
79
+ dx: resolveAxisAutoscroll(x, width, threshold, maxStep),
80
+ dy: resolveAxisAutoscroll(y, height, threshold, maxStep)
81
+ });
82
+ // Annotate the CommonJS export names for ESM import in node:
83
+ 0 && (module.exports = {
84
+ getSelectionEdgeAutoscroll,
85
+ getToolDockDismissState,
86
+ isToolDockToolSelected,
87
+ shouldEnableSelectionDrag,
88
+ shouldEnableViewerScroll
89
+ });
90
+ //# sourceMappingURL=selectionInteraction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../gesture/selectionInteraction.ts"],"sourcesContent":["export type ViewerScrollState = {\n selectionDragActive: boolean;\n gestureScrollLockActive?: boolean;\n};\n\nexport type SelectionGestureTool =\n | \"select\"\n | \"highlight\"\n | \"underline\"\n | \"squiggly\"\n | \"strikeout\"\n | \"text\"\n | \"comment\"\n | \"ink\";\n\nexport type SelectionInteractionMode = \"pan\" | \"select\";\n\nexport type SelectionGestureActivationInput = {\n activeTool: SelectionGestureTool;\n interactionMode: SelectionInteractionMode;\n};\n\nexport type ToolDockSelectionState = SelectionGestureActivationInput & {\n toolId: SelectionGestureTool;\n};\n\nexport type ToolDockDismissState = SelectionGestureActivationInput & {\n toolDockOpen: boolean;\n};\n\nexport type SelectionEdgeAutoscrollInput = {\n x: number;\n y: number;\n width: number;\n height: number;\n threshold: number;\n maxStep: number;\n};\n\nexport type SelectionEdgeAutoscroll = {\n dx: number;\n dy: number;\n};\n\nconst clamp = (value: number, min: number, max: number) =>\n Math.min(max, Math.max(min, value));\n\nconst DRAG_SELECTION_TOOLS = new Set<SelectionGestureTool>([\n \"highlight\",\n \"underline\",\n \"squiggly\",\n \"strikeout\",\n]);\n\nconst resolveAxisAutoscroll = (\n coordinate: number,\n size: number,\n threshold: number,\n maxStep: number\n) => {\n if (size <= 0 || threshold <= 0 || maxStep <= 0) return 0;\n\n const startDistance = clamp(coordinate, 0, size);\n if (startDistance < threshold) {\n const intensity = 1 - startDistance / threshold;\n return -Math.round(maxStep * intensity);\n }\n\n const endDistance = clamp(size - coordinate, 0, size);\n if (endDistance < threshold) {\n const intensity = 1 - endDistance / threshold;\n return Math.round(maxStep * intensity);\n }\n\n return 0;\n};\n\nexport const shouldEnableViewerScroll = ({\n selectionDragActive,\n gestureScrollLockActive = false,\n}: ViewerScrollState) => !selectionDragActive && !gestureScrollLockActive;\n\nexport const shouldEnableSelectionDrag = ({\n activeTool,\n interactionMode,\n}: SelectionGestureActivationInput) =>\n DRAG_SELECTION_TOOLS.has(activeTool) ||\n (activeTool === \"select\" && interactionMode === \"select\");\n\nexport const isToolDockToolSelected = ({\n activeTool,\n interactionMode,\n toolId,\n}: ToolDockSelectionState) =>\n toolId === \"select\"\n ? activeTool === \"select\" && interactionMode === \"select\"\n : activeTool === toolId;\n\nexport const getToolDockDismissState = ({\n activeTool: _activeTool,\n interactionMode: _interactionMode,\n}: SelectionGestureActivationInput): ToolDockDismissState => ({\n toolDockOpen: false,\n activeTool: \"select\",\n interactionMode: \"pan\",\n});\n\nexport const getSelectionEdgeAutoscroll = ({\n x,\n y,\n width,\n height,\n threshold,\n maxStep,\n}: SelectionEdgeAutoscrollInput): SelectionEdgeAutoscroll => ({\n dx: resolveAxisAutoscroll(x, width, threshold, maxStep),\n dy: resolveAxisAutoscroll(y, height, threshold, maxStep),\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4CA,IAAM,QAAQ,CAAC,OAAe,KAAa,QACzC,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAEpC,IAAM,uBAAuB,oBAAI,IAA0B;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,wBAAwB,CAC5B,YACA,MACA,WACA,YACG;AACH,MAAI,QAAQ,KAAK,aAAa,KAAK,WAAW,EAAG,QAAO;AAExD,QAAM,gBAAgB,MAAM,YAAY,GAAG,IAAI;AAC/C,MAAI,gBAAgB,WAAW;AAC7B,UAAM,YAAY,IAAI,gBAAgB;AACtC,WAAO,CAAC,KAAK,MAAM,UAAU,SAAS;AAAA,EACxC;AAEA,QAAM,cAAc,MAAM,OAAO,YAAY,GAAG,IAAI;AACpD,MAAI,cAAc,WAAW;AAC3B,UAAM,YAAY,IAAI,cAAc;AACpC,WAAO,KAAK,MAAM,UAAU,SAAS;AAAA,EACvC;AAEA,SAAO;AACT;AAEO,IAAM,2BAA2B,CAAC;AAAA,EACvC;AAAA,EACA,0BAA0B;AAC5B,MAAyB,CAAC,uBAAuB,CAAC;AAE3C,IAAM,4BAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AACF,MACE,qBAAqB,IAAI,UAAU,KAClC,eAAe,YAAY,oBAAoB;AAE3C,IAAM,yBAAyB,CAAC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF,MACE,WAAW,WACP,eAAe,YAAY,oBAAoB,WAC/C,eAAe;AAEd,IAAM,0BAA0B,CAAC;AAAA,EACtC,YAAY;AAAA,EACZ,iBAAiB;AACnB,OAA8D;AAAA,EAC5D,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,iBAAiB;AACnB;AAEO,IAAM,6BAA6B,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,OAA8D;AAAA,EAC5D,IAAI,sBAAsB,GAAG,OAAO,WAAW,OAAO;AAAA,EACtD,IAAI,sBAAsB,GAAG,QAAQ,WAAW,OAAO;AACzD;","names":[]}
@@ -0,0 +1,16 @@
1
+ import {
2
+ getSelectionEdgeAutoscroll,
3
+ getToolDockDismissState,
4
+ isToolDockToolSelected,
5
+ shouldEnableSelectionDrag,
6
+ shouldEnableViewerScroll
7
+ } from "../chunk-KXNP73MZ.mjs";
8
+ import "../chunk-ZD7AOCMD.mjs";
9
+ export {
10
+ getSelectionEdgeAutoscroll,
11
+ getToolDockDismissState,
12
+ isToolDockToolSelected,
13
+ shouldEnableSelectionDrag,
14
+ shouldEnableViewerScroll
15
+ };
16
+ //# sourceMappingURL=selectionInteraction.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { DocumentEngine, DocumentType, MobilePrimaryDestination, DocumentSource } from '@papyrus-sdk/types';
2
+ import { DocumentEngine, PdfViewerMode, DocumentType, MobilePrimaryDestination, DocumentSource } from '@papyrus-sdk/types';
3
3
  import { PapyrusPageViewProps } from '@papyrus-sdk/engine-native';
4
4
  import { StyleProp, ViewStyle } from 'react-native';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
@@ -10,6 +10,7 @@ interface ViewerProps {
10
10
  maxToRenderPerBatch?: number;
11
11
  removeClippedSubviews?: boolean;
12
12
  useDedicatedAndroidPdfViewer?: boolean;
13
+ viewerMode?: PdfViewerMode;
13
14
  }
14
15
  declare const Viewer: React.FC<ViewerProps>;
15
16
 
@@ -98,6 +99,11 @@ type ReadingShellProps = {
98
99
  };
99
100
  declare function ReadingShell({ engine, title, documentType, thumbsInitialCount, viewerProps, }: ReadingShellProps): react_jsx_runtime.JSX.Element;
100
101
 
102
+ type DedicatedAndroidPdfViewerProps = {
103
+ engine: DocumentEngine;
104
+ };
105
+ declare function DedicatedAndroidPdfViewer({ engine, }: DedicatedAndroidPdfViewerProps): react_jsx_runtime.JSX.Element;
106
+
101
107
  type OverflowSheetProps = {
102
108
  visible: boolean;
103
109
  onClose: () => void;
@@ -159,4 +165,4 @@ declare const MOBILE_CHROME_METRICS: {
159
165
  readonly bottomBarItemPaddingVertical: 3;
160
166
  };
161
167
 
162
- export { AnnotationEditor, BottomBar, CoverPreview, DocumentActionsSheet, InfoSheet, MOBILE_CHROME_METRICS, OverflowSheet, _default as PageRenderer, ProgressPill, ReadingShell, RightSheet, SearchOverlay, SearchResultsSheet, SettingsSheet, ToolDock, Topbar, Viewer };
168
+ export { AnnotationEditor, BottomBar, CoverPreview, DocumentActionsSheet, InfoSheet, MOBILE_CHROME_METRICS, DedicatedAndroidPdfViewer as NativePdfDocumentViewer, OverflowSheet, _default as PageRenderer, ProgressPill, ReadingShell, RightSheet, SearchOverlay, SearchResultsSheet, SettingsSheet, ToolDock, Topbar, Viewer };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { DocumentEngine, DocumentType, MobilePrimaryDestination, DocumentSource } from '@papyrus-sdk/types';
2
+ import { DocumentEngine, PdfViewerMode, DocumentType, MobilePrimaryDestination, DocumentSource } from '@papyrus-sdk/types';
3
3
  import { PapyrusPageViewProps } from '@papyrus-sdk/engine-native';
4
4
  import { StyleProp, ViewStyle } from 'react-native';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
@@ -10,6 +10,7 @@ interface ViewerProps {
10
10
  maxToRenderPerBatch?: number;
11
11
  removeClippedSubviews?: boolean;
12
12
  useDedicatedAndroidPdfViewer?: boolean;
13
+ viewerMode?: PdfViewerMode;
13
14
  }
14
15
  declare const Viewer: React.FC<ViewerProps>;
15
16
 
@@ -98,6 +99,11 @@ type ReadingShellProps = {
98
99
  };
99
100
  declare function ReadingShell({ engine, title, documentType, thumbsInitialCount, viewerProps, }: ReadingShellProps): react_jsx_runtime.JSX.Element;
100
101
 
102
+ type DedicatedAndroidPdfViewerProps = {
103
+ engine: DocumentEngine;
104
+ };
105
+ declare function DedicatedAndroidPdfViewer({ engine, }: DedicatedAndroidPdfViewerProps): react_jsx_runtime.JSX.Element;
106
+
101
107
  type OverflowSheetProps = {
102
108
  visible: boolean;
103
109
  onClose: () => void;
@@ -159,4 +165,4 @@ declare const MOBILE_CHROME_METRICS: {
159
165
  readonly bottomBarItemPaddingVertical: 3;
160
166
  };
161
167
 
162
- export { AnnotationEditor, BottomBar, CoverPreview, DocumentActionsSheet, InfoSheet, MOBILE_CHROME_METRICS, OverflowSheet, _default as PageRenderer, ProgressPill, ReadingShell, RightSheet, SearchOverlay, SearchResultsSheet, SettingsSheet, ToolDock, Topbar, Viewer };
168
+ export { AnnotationEditor, BottomBar, CoverPreview, DocumentActionsSheet, InfoSheet, MOBILE_CHROME_METRICS, DedicatedAndroidPdfViewer as NativePdfDocumentViewer, OverflowSheet, _default as PageRenderer, ProgressPill, ReadingShell, RightSheet, SearchOverlay, SearchResultsSheet, SettingsSheet, ToolDock, Topbar, Viewer };
package/dist/index.js CHANGED
@@ -21024,6 +21024,7 @@ __export(ui_react_native_exports, {
21024
21024
  DocumentActionsSheet: () => DocumentActionsSheet,
21025
21025
  InfoSheet: () => InfoSheet,
21026
21026
  MOBILE_CHROME_METRICS: () => MOBILE_CHROME_METRICS,
21027
+ NativePdfDocumentViewer: () => DedicatedAndroidPdfViewer,
21027
21028
  OverflowSheet: () => OverflowSheet,
21028
21029
  PageRenderer: () => PageRenderer_default,
21029
21030
  ProgressPill: () => ProgressPill,
@@ -23949,12 +23950,14 @@ function DedicatedAndroidPdfViewer({
23949
23950
  const searchResults = (0, import_core3.useViewerStore)((state) => state.searchResults);
23950
23951
  const annotations = (0, import_core3.useViewerStore)((state) => state.annotations);
23951
23952
  const viewMode = (0, import_core3.useViewerStore)((state) => state.viewMode);
23953
+ const nativeViewMode = viewMode === "single" ? "single" : "continuous";
23952
23954
  const setDocumentState = (0, import_core3.useViewerStore)((state) => state.setDocumentState);
23953
23955
  const addAnnotation = (0, import_core3.useViewerStore)((state) => state.addAnnotation);
23954
23956
  const setSelectedAnnotation = (0, import_core3.useViewerStore)((state) => state.setSelectedAnnotation);
23955
23957
  const engineId = getDedicatedAndroidPdfEngineId(engine);
23956
23958
  const [selection, setSelection] = (0, import_react3.useState)(null);
23957
23959
  const selectionRef = (0, import_react3.useRef)(null);
23960
+ const lastVisiblePagesKeyRef = (0, import_react3.useRef)("");
23958
23961
  const lastScrollOffsetYRef = (0, import_react3.useRef)(0);
23959
23962
  const scrollDownAccumRef = (0, import_react3.useRef)(0);
23960
23963
  const scrollUpAccumRef = (0, import_react3.useRef)(0);
@@ -24043,7 +24046,7 @@ function DedicatedAndroidPdfViewer({
24043
24046
  }, []);
24044
24047
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native3.View, { style: styles3.container, children: [
24045
24048
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
24046
- import_engine_native2.PapyrusPdfViewerView,
24049
+ import_engine_native2.PapyrusPdfDocumentView,
24047
24050
  {
24048
24051
  style: styles3.viewer,
24049
24052
  engineId,
@@ -24057,13 +24060,30 @@ function DedicatedAndroidPdfViewer({
24057
24060
  searchResults,
24058
24061
  annotations,
24059
24062
  selectionActive: !!selection,
24060
- viewMode,
24061
- onPageChanged: (event) => {
24063
+ viewMode: nativeViewMode,
24064
+ onPageChange: (event) => {
24062
24065
  setDocumentState({ currentPage: event.nativeEvent.page });
24063
24066
  },
24064
- onZoomChanged: (event) => {
24067
+ onZoomChange: (event) => {
24065
24068
  setDocumentState({ zoom: event.nativeEvent.zoom });
24066
24069
  },
24070
+ onVisiblePagesChange: (event) => {
24071
+ const pages = event.nativeEvent.pages ?? [];
24072
+ const stablePages = pages.filter(
24073
+ (page) => page.visibleRatio >= 0.03
24074
+ );
24075
+ if (stablePages.length === 0) {
24076
+ return;
24077
+ }
24078
+ const key = stablePages.map(
24079
+ (page) => `${page.pageIndex}:${Math.round(page.visibleRatio * 100)}`
24080
+ ).join("|");
24081
+ if (key === lastVisiblePagesKeyRef.current) {
24082
+ return;
24083
+ }
24084
+ lastVisiblePagesKeyRef.current = key;
24085
+ setDocumentState({ visiblePages: stablePages });
24086
+ },
24067
24087
  onAnnotationCreated: (event) => {
24068
24088
  addAnnotation(event.nativeEvent);
24069
24089
  },
@@ -24193,6 +24213,14 @@ var styles3 = import_react_native3.StyleSheet.create({
24193
24213
  }
24194
24214
  });
24195
24215
 
24216
+ // components/nativePdfViewerMode.ts
24217
+ var shouldUseNativePdfViewer = ({
24218
+ viewerMode,
24219
+ pageCount,
24220
+ isWebView,
24221
+ nativeEngineId
24222
+ }) => viewerMode === "native" && pageCount > 0 && !isWebView && !!nativeEngineId;
24223
+
24196
24224
  // components/Viewer.tsx
24197
24225
  var import_jsx_runtime5 = require("react/jsx-runtime");
24198
24226
  var LIST_TOP_PADDING = 18;
@@ -24222,7 +24250,8 @@ var Viewer = ({
24222
24250
  virtualWindowSize,
24223
24251
  maxToRenderPerBatch,
24224
24252
  removeClippedSubviews,
24225
- useDedicatedAndroidPdfViewer
24253
+ useDedicatedAndroidPdfViewer,
24254
+ viewerMode
24226
24255
  }) => {
24227
24256
  const pageCount = (0, import_core4.useViewerStore)((state) => state.pageCount);
24228
24257
  const currentPage = (0, import_core4.useViewerStore)((state) => state.currentPage);
@@ -24236,6 +24265,7 @@ var Viewer = ({
24236
24265
  const uiTheme = (0, import_core4.useViewerStore)((state) => state.uiTheme);
24237
24266
  const viewMode = (0, import_core4.useViewerStore)((state) => state.viewMode);
24238
24267
  const zoom = (0, import_core4.useViewerStore)((state) => state.zoom);
24268
+ const storeViewerMode = (0, import_core4.useViewerStore)((state) => state.viewerMode);
24239
24269
  const listRef = (0, import_react4.useRef)(null);
24240
24270
  const horizontalScrollRef = (0, import_react4.useRef)(null);
24241
24271
  const isDark = uiTheme === "dark";
@@ -24244,7 +24274,14 @@ var Viewer = ({
24244
24274
  const isSingle = viewMode === "single";
24245
24275
  const renderTargetType = engine.getRenderTargetType?.() ?? "canvas";
24246
24276
  const isWebView = renderTargetType === "webview";
24247
- const isDedicatedAndroidPdfViewer = import_react_native4.Platform.OS === "android" && !!useDedicatedAndroidPdfViewer && pageCount > 0 && !isWebView && !!getDedicatedAndroidPdfEngineId(engine);
24277
+ const resolvedViewerMode = viewerMode ?? (useDedicatedAndroidPdfViewer ? "native" : storeViewerMode);
24278
+ const nativeEngineId = getDedicatedAndroidPdfEngineId(engine);
24279
+ const isNativePdfViewer = shouldUseNativePdfViewer({
24280
+ viewerMode: resolvedViewerMode,
24281
+ pageCount,
24282
+ isWebView,
24283
+ nativeEngineId
24284
+ });
24248
24285
  const perfEnabled = isMobilePerfEnabled();
24249
24286
  const mountedAtRef = (0, import_react4.useRef)(perfNow());
24250
24287
  const readyLoggedRef = (0, import_react4.useRef)(false);
@@ -25398,7 +25435,7 @@ var Viewer = ({
25398
25435
  if (isWebView) {
25399
25436
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native4.View, { style: [styles4.container, isDark && styles4.containerDark], children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(WebViewViewer_default, { engine }) });
25400
25437
  }
25401
- if (isDedicatedAndroidPdfViewer) {
25438
+ if (isNativePdfViewer) {
25402
25439
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native4.View, { style: [styles4.container, isDark && styles4.containerDark], children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DedicatedAndroidPdfViewer, { engine }) });
25403
25440
  }
25404
25441
  if (isSingle) {
@@ -30610,6 +30647,7 @@ var styles19 = import_react_native19.StyleSheet.create({
30610
30647
  DocumentActionsSheet,
30611
30648
  InfoSheet,
30612
30649
  MOBILE_CHROME_METRICS,
30650
+ NativePdfDocumentViewer,
30613
30651
  OverflowSheet,
30614
30652
  PageRenderer,
30615
30653
  ProgressPill,