@papyrus-sdk/ui-react-native 0.2.32 → 0.2.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  resolveAnchoredHorizontalSurfaceOffset,
5
5
  resolveAnchoredViewportOffset,
6
6
  resolveCenteredContentInset,
7
+ resolveClampedScrollOffset,
7
8
  resolveDocumentSurfaceWidth,
8
9
  resolveGlobalHorizontalOffset,
9
10
  resolvePinchGestureZoom,
@@ -23176,6 +23177,42 @@ var resolvePdfAnchoredScrollY = ({
23176
23177
  });
23177
23178
  };
23178
23179
  var resolvePdfAnchoredScrollX = (input) => resolveAnchoredHorizontalSurfaceOffset(input);
23180
+ var resolvePdfPageAnchoredScrollX = ({
23181
+ focalViewportX,
23182
+ startSurfaceScrollX,
23183
+ viewportWidth,
23184
+ endSurfaceWidth,
23185
+ startPageOffsetX,
23186
+ endPageOffsetX,
23187
+ startPageFrameWidth,
23188
+ endPageFrameWidth,
23189
+ startPageWidth,
23190
+ endPageWidth
23191
+ }) => {
23192
+ const safeStartPageWidth = Number.isFinite(startPageWidth) && startPageWidth > 0 ? startPageWidth : 0;
23193
+ const safeEndPageWidth = Number.isFinite(endPageWidth) && endPageWidth > 0 ? endPageWidth : 0;
23194
+ if (safeStartPageWidth === 0 || safeEndPageWidth === 0) return 0;
23195
+ const safeFocalX = Number.isFinite(focalViewportX) ? focalViewportX : 0;
23196
+ const safeStartScrollX = Number.isFinite(startSurfaceScrollX) ? startSurfaceScrollX : 0;
23197
+ const safeStartOffsetX = Number.isFinite(startPageOffsetX) ? startPageOffsetX : 0;
23198
+ const safeEndOffsetX = Number.isFinite(endPageOffsetX) ? endPageOffsetX : 0;
23199
+ const startInset = resolveCenteredContentInset({
23200
+ viewportLength: startPageFrameWidth,
23201
+ contentLength: safeStartPageWidth
23202
+ });
23203
+ const endInset = resolveCenteredContentInset({
23204
+ viewportLength: endPageFrameWidth,
23205
+ contentLength: safeEndPageWidth
23206
+ });
23207
+ const startPageContentX = safeFocalX + safeStartScrollX - safeStartOffsetX - startInset;
23208
+ const scaledPageContentX = startPageContentX / safeStartPageWidth * safeEndPageWidth;
23209
+ const targetContentX = safeEndOffsetX + endInset + scaledPageContentX;
23210
+ return resolveClampedScrollOffset(
23211
+ targetContentX - safeFocalX,
23212
+ endSurfaceWidth,
23213
+ viewportWidth
23214
+ );
23215
+ };
23179
23216
  var resolvePdfSurfaceWidth = (input) => resolveDocumentSurfaceWidth(input);
23180
23217
  var resolvePdfGlobalScrollX = ({
23181
23218
  startSurfaceScrollX,
@@ -23210,10 +23247,57 @@ var buildCommentTapGestureDeps = ({
23210
23247
  ];
23211
23248
 
23212
23249
  // components/pdfPageMetrics.ts
23250
+ var resolvePdfDoublePageContentWidth = ({
23251
+ currentPage,
23252
+ pageCount,
23253
+ columnGap,
23254
+ getPageWidthForZoom
23255
+ }) => {
23256
+ const safePageCount = Number.isFinite(pageCount) ? Math.trunc(pageCount) : 0;
23257
+ if (safePageCount <= 0) return 0;
23258
+ const safeCurrentPage = Number.isFinite(currentPage) ? Math.trunc(currentPage) : 1;
23259
+ const pageIndex = Math.max(
23260
+ 0,
23261
+ Math.min(safePageCount - 1, safeCurrentPage - 1)
23262
+ );
23263
+ const leftPageIndex = Math.floor(pageIndex / 2) * 2;
23264
+ const rightPageIndex = leftPageIndex + 1;
23265
+ const resolvePageWidth = (index) => {
23266
+ const width = getPageWidthForZoom(index);
23267
+ return Number.isFinite(width) && width > 0 ? width : 0;
23268
+ };
23269
+ const leftPageWidth = resolvePageWidth(leftPageIndex);
23270
+ const rightPageWidth = rightPageIndex < safePageCount ? resolvePageWidth(rightPageIndex) : leftPageWidth;
23271
+ const safeColumnGap = Number.isFinite(columnGap) && columnGap > 0 ? columnGap : 0;
23272
+ return leftPageWidth + rightPageWidth + safeColumnGap;
23273
+ };
23274
+ var resolveMaxPageWidth = (maxPageWidth) => typeof maxPageWidth === "number" && Number.isFinite(maxPageWidth) && maxPageWidth > 0 ? maxPageWidth : void 0;
23275
+ var resolvePdfFitPageHeight = (viewportHeight, verticalInset) => {
23276
+ if (!Number.isFinite(viewportHeight) || viewportHeight <= 0 || !Number.isFinite(verticalInset) || verticalInset < 0) {
23277
+ return void 0;
23278
+ }
23279
+ return Math.max(1, viewportHeight - verticalInset * 2);
23280
+ };
23213
23281
  var resolvePdfBasePageWidth = ({
23214
23282
  viewportWidth,
23215
- horizontalPadding
23216
- }) => Math.max(0, viewportWidth - horizontalPadding * 2);
23283
+ horizontalPadding,
23284
+ maxPageWidth,
23285
+ maxPageHeight,
23286
+ pageAspectRatio
23287
+ }) => {
23288
+ const availablePageWidth = Math.max(
23289
+ 0,
23290
+ viewportWidth - horizontalPadding * 2
23291
+ );
23292
+ const resolvedMaxPageWidth = resolveMaxPageWidth(maxPageWidth);
23293
+ const hasValidPageHeight = typeof maxPageHeight === "number" && Number.isFinite(maxPageHeight) && maxPageHeight > 0 && typeof pageAspectRatio === "number" && Number.isFinite(pageAspectRatio) && pageAspectRatio > 0;
23294
+ const widthForMaxHeight = hasValidPageHeight ? maxPageHeight * pageAspectRatio : Number.POSITIVE_INFINITY;
23295
+ return Math.min(
23296
+ availablePageWidth,
23297
+ resolvedMaxPageWidth ?? Number.POSITIVE_INFINITY,
23298
+ widthForMaxHeight
23299
+ );
23300
+ };
23217
23301
 
23218
23302
  // components/selectionContentInteraction.ts
23219
23303
  var shouldDismissSelectionOnContentInteraction = ({
@@ -23300,6 +23384,8 @@ var PageRenderer = ({
23300
23384
  pageAspectRatio,
23301
23385
  PageViewComponent = PapyrusPageView,
23302
23386
  availableWidth,
23387
+ maxPageWidth,
23388
+ maxPageHeight,
23303
23389
  pageViewportWidth: providedPageViewportWidth,
23304
23390
  horizontalPadding = 16,
23305
23391
  spacing = 24,
@@ -24403,7 +24489,10 @@ var PageRenderer = ({
24403
24489
  const containerWidth = availableWidth ?? windowWidth;
24404
24490
  const baseWidth = resolvePdfBasePageWidth({
24405
24491
  viewportWidth: containerWidth,
24406
- horizontalPadding
24492
+ horizontalPadding,
24493
+ maxPageWidth,
24494
+ maxPageHeight,
24495
+ pageAspectRatio: aspectRatio
24407
24496
  });
24408
24497
  const pageWidth = isNative ? baseWidth * zoom : baseWidth;
24409
24498
  const pageHeight = pageWidth / aspectRatio;
@@ -25143,7 +25232,7 @@ var styles = StyleSheet.create({
25143
25232
  borderRadius: 3
25144
25233
  }
25145
25234
  });
25146
- var arePageRendererPropsEqual = (previous, next) => previous.engine === next.engine && previous.pageIndex === next.pageIndex && previous.scale === next.scale && previous.PageViewComponent === next.PageViewComponent && previous.availableWidth === next.availableWidth && previous.pageViewportWidth === next.pageViewportWidth && previous.horizontalPadding === next.horizontalPadding && previous.spacing === next.spacing && previous.onSelectionDragActiveChange === next.onSelectionDragActiveChange && previous.gestureScrollLockActive === next.gestureScrollLockActive && previous.lastPinchEndedAt === next.lastPinchEndedAt && previous.requestSelectionVerticalAutoscroll === next.requestSelectionVerticalAutoscroll;
25235
+ var arePageRendererPropsEqual = (previous, next) => previous.engine === next.engine && previous.pageIndex === next.pageIndex && previous.scale === next.scale && previous.PageViewComponent === next.PageViewComponent && previous.availableWidth === next.availableWidth && previous.maxPageWidth === next.maxPageWidth && previous.maxPageHeight === next.maxPageHeight && previous.pageViewportWidth === next.pageViewportWidth && previous.horizontalPadding === next.horizontalPadding && previous.spacing === next.spacing && previous.onSelectionDragActiveChange === next.onSelectionDragActiveChange && previous.gestureScrollLockActive === next.gestureScrollLockActive && previous.lastPinchEndedAt === next.lastPinchEndedAt && previous.requestSelectionVerticalAutoscroll === next.requestSelectionVerticalAutoscroll;
25147
25236
  var PageRenderer_default = memo(PageRenderer, arePageRendererPropsEqual);
25148
25237
 
25149
25238
  // components/WebViewViewer.tsx
@@ -25216,6 +25305,7 @@ var resolveRuntimeSource = (asset) => {
25216
25305
  };
25217
25306
  var WebViewViewer = ({
25218
25307
  engine,
25308
+ maxPageWidth,
25219
25309
  onScrollOffset,
25220
25310
  onTap
25221
25311
  }) => {
@@ -25334,6 +25424,12 @@ var WebViewViewer = ({
25334
25424
  }
25335
25425
  return void 0;
25336
25426
  }, []);
25427
+ const resolvedMaxPageWidth = resolveMaxPageWidth(maxPageWidth);
25428
+ const cappedWebViewStyle = resolvedMaxPageWidth ? {
25429
+ width: "100%",
25430
+ maxWidth: resolvedMaxPageWidth,
25431
+ alignSelf: "center"
25432
+ } : void 0;
25337
25433
  return /* @__PURE__ */ jsxs3(View2, { style: styles2.container, children: [
25338
25434
  /* @__PURE__ */ jsx4(
25339
25435
  WebView,
@@ -25354,7 +25450,7 @@ var WebViewViewer = ({
25354
25450
  allowFileAccessFromFileURLs: true,
25355
25451
  allowUniversalAccessFromFileURLs: true,
25356
25452
  allowingReadAccessToURL,
25357
- style: styles2.webview
25453
+ style: [styles2.webview, cappedWebViewStyle]
25358
25454
  }
25359
25455
  ),
25360
25456
  /* @__PURE__ */ jsx4(
@@ -25427,7 +25523,8 @@ var getDedicatedAndroidPdfEngineId = (engine) => {
25427
25523
  return typeof engineId === "string" && engineId.length > 0 ? engineId : null;
25428
25524
  };
25429
25525
  function DedicatedAndroidPdfViewer({
25430
- engine
25526
+ engine,
25527
+ maxPageWidth
25431
25528
  }) {
25432
25529
  const pageTheme = useViewerStore3((state) => state.pageTheme);
25433
25530
  const zoom = useViewerStore3((state) => state.zoom);
@@ -25450,6 +25547,12 @@ function DedicatedAndroidPdfViewer({
25450
25547
  const addAnnotation = useViewerStore3((state) => state.addAnnotation);
25451
25548
  const setSelectedAnnotation = useViewerStore3((state) => state.setSelectedAnnotation);
25452
25549
  const engineId = getDedicatedAndroidPdfEngineId(engine);
25550
+ const resolvedMaxPageWidth = resolveMaxPageWidth(maxPageWidth);
25551
+ const cappedViewerStyle = resolvedMaxPageWidth ? {
25552
+ width: "100%",
25553
+ maxWidth: resolvedMaxPageWidth,
25554
+ alignSelf: "center"
25555
+ } : void 0;
25453
25556
  const [selection, setSelection] = useState3(null);
25454
25557
  const selectionRef = useRef3(null);
25455
25558
  const lastVisiblePagesKeyRef = useRef3("");
@@ -25551,7 +25654,7 @@ function DedicatedAndroidPdfViewer({
25551
25654
  /* @__PURE__ */ jsx5(
25552
25655
  PapyrusPdfDocumentView,
25553
25656
  {
25554
- style: styles3.viewer,
25657
+ style: [styles3.viewer, cappedViewerStyle],
25555
25658
  engineId,
25556
25659
  pageTheme,
25557
25660
  zoom,
@@ -25731,11 +25834,12 @@ var styles3 = StyleSheet3.create({
25731
25834
 
25732
25835
  // components/nativePdfViewerMode.ts
25733
25836
  var shouldUseNativePdfViewer = ({
25837
+ platform,
25734
25838
  viewerMode,
25735
25839
  pageCount,
25736
25840
  isWebView,
25737
25841
  nativeEngineId
25738
- }) => viewerMode === "native" && pageCount > 0 && !isWebView && !!nativeEngineId;
25842
+ }) => platform === "android" && viewerMode === "native" && pageCount > 0 && !isWebView && !!nativeEngineId;
25739
25843
 
25740
25844
  // perf/pinchPerfSession.ts
25741
25845
  var PINCH_EPSILON = 1e-3;
@@ -25997,6 +26101,14 @@ var resolveViewerScrollTarget = (pageIndex, isDouble) => ({
25997
26101
  var pageContainsScrollTarget = (row, pageIndex) => row.left === pageIndex || row.right === pageIndex;
25998
26102
 
25999
26103
  // components/viewerPerformance.ts
26104
+ var hasViewerViewportGeometryChanged = ({
26105
+ previous,
26106
+ next
26107
+ }) => {
26108
+ if (!previous) return false;
26109
+ if (previous.width !== next.width) return true;
26110
+ return typeof previous.pageFitHeight === "number" && typeof next.pageFitHeight === "number" && previous.pageFitHeight !== next.pageFitHeight;
26111
+ };
26000
26112
  var resolveOrientationScrollOffset = ({
26001
26113
  currentPage,
26002
26114
  pageCount,
@@ -26053,6 +26165,8 @@ var scrollViewerListToOffset = (list, offset, animated) => {
26053
26165
  };
26054
26166
  var Viewer = ({
26055
26167
  engine,
26168
+ maxPageWidth,
26169
+ fitPageToViewportHeight = false,
26056
26170
  virtualWindowSize,
26057
26171
  maxToRenderPerBatch,
26058
26172
  removeClippedSubviews,
@@ -26094,6 +26208,7 @@ var Viewer = ({
26094
26208
  }, [mobilePerf, resolvedViewerMode]);
26095
26209
  const nativeEngineId = getDedicatedAndroidPdfEngineId(engine);
26096
26210
  const isNativePdfViewer = shouldUseNativePdfViewer({
26211
+ platform: Platform2.OS,
26097
26212
  viewerMode: resolvedViewerMode,
26098
26213
  pageCount,
26099
26214
  isWebView,
@@ -26113,8 +26228,8 @@ var Viewer = ({
26113
26228
  const scrollPerfSession = useMemo3(() => createScrollPerfSession(), []);
26114
26229
  const dimensionsCacheRef = useRef4(/* @__PURE__ */ new Map());
26115
26230
  const dimensionsPendingRef = useRef4(/* @__PURE__ */ new Set());
26116
- const previousWindowWidthRef = useRef4(null);
26117
- const pendingOrientationRestoreWidthRef = useRef4(null);
26231
+ const previousViewportGeometryRef = useRef4(null);
26232
+ const pendingOrientationRestoreRef = useRef4(false);
26118
26233
  const layoutRefreshTimeoutRef = useRef4(
26119
26234
  null
26120
26235
  );
@@ -26161,6 +26276,7 @@ var Viewer = ({
26161
26276
  const committedPinchGestureIdRef = useRef4(null);
26162
26277
  const pinchAnchorRestoreFrameRef = useRef4(null);
26163
26278
  const viewerFrameRef = useRef4({ y: 0, height: 0 });
26279
+ const [viewerViewportHeight, setViewerViewportHeight] = useState4(0);
26164
26280
  const viewerContentHeightRef = useRef4(0);
26165
26281
  const listLayoutMetricsRef = useRef4(null);
26166
26282
  const resolvedWindowSize = useMemo3(
@@ -26449,16 +26565,27 @@ var Viewer = ({
26449
26565
  const columnGap = 12;
26450
26566
  const horizontalPadding = 16;
26451
26567
  const columnWidth = isDouble ? (windowWidth - horizontalPadding * 2 - columnGap) / 2 : windowWidth;
26568
+ const pageFitHeight = fitPageToViewportHeight ? resolvePdfFitPageHeight(viewerViewportHeight, LIST_TOP_PADDING) : void 0;
26452
26569
  const getPageWidthForZoom = useCallback3(
26453
26570
  (pageIndex, zoomValue) => {
26454
26571
  const safeZoom = Math.max(zoomValue, 0.25);
26455
26572
  const baseWidth = resolvePdfBasePageWidth({
26456
26573
  viewportWidth: isDouble ? columnWidth : windowWidth,
26457
- horizontalPadding: isDouble ? 8 : 16
26574
+ horizontalPadding: isDouble ? 8 : 16,
26575
+ maxPageWidth,
26576
+ maxPageHeight: pageFitHeight,
26577
+ pageAspectRatio: getPageAspectRatio(pageIndex)
26458
26578
  });
26459
26579
  return baseWidth * safeZoom;
26460
26580
  },
26461
- [columnWidth, isDouble, windowWidth]
26581
+ [
26582
+ columnWidth,
26583
+ getPageAspectRatio,
26584
+ isDouble,
26585
+ maxPageWidth,
26586
+ pageFitHeight,
26587
+ windowWidth
26588
+ ]
26462
26589
  );
26463
26590
  const getPageHeightForZoom = useCallback3(
26464
26591
  (pageIndex, zoomValue) => getPageWidthForZoom(pageIndex, zoomValue) / getPageAspectRatio(pageIndex),
@@ -26484,8 +26611,12 @@ var Viewer = ({
26484
26611
  );
26485
26612
  const documentSurfaceWidth = useMemo3(() => {
26486
26613
  if (isDouble) {
26487
- const leftPageWidth = getPageWidthForZoom(0, zoom);
26488
- const doubleContentWidth = leftPageWidth * 2 + columnGap;
26614
+ const doubleContentWidth = resolvePdfDoublePageContentWidth({
26615
+ currentPage,
26616
+ pageCount,
26617
+ columnGap,
26618
+ getPageWidthForZoom: (pageIndex) => getPageWidthForZoom(pageIndex, zoom)
26619
+ });
26489
26620
  return resolvePdfSurfaceWidth({
26490
26621
  viewportWidth: windowWidth,
26491
26622
  contentWidth: doubleContentWidth,
@@ -26503,6 +26634,8 @@ var Viewer = ({
26503
26634
  getPageWidthForZoom,
26504
26635
  horizontalPadding,
26505
26636
  isDouble,
26637
+ layoutRevision,
26638
+ pageCount,
26506
26639
  windowWidth,
26507
26640
  zoom
26508
26641
  ]);
@@ -26824,6 +26957,18 @@ var Viewer = ({
26824
26957
  horizontalPadding: pageHorizontalPadding,
26825
26958
  viewportOffsetX
26826
26959
  } = getPageViewportMetrics(anchorPageIndex);
26960
+ const availablePageWidth = Math.max(
26961
+ 0,
26962
+ pageViewportWidth - pageHorizontalPadding * 2
26963
+ );
26964
+ const basePageWidth = resolvePdfBasePageWidth({
26965
+ viewportWidth: pageViewportWidth,
26966
+ horizontalPadding: pageHorizontalPadding,
26967
+ maxPageWidth,
26968
+ maxPageHeight: pageFitHeight,
26969
+ pageAspectRatio: getPageAspectRatio(anchorPageIndex)
26970
+ });
26971
+ const startPageWidth = getPageWidthForZoom(anchorPageIndex, startZoom);
26827
26972
  const pageViewportContentWidth = Math.max(
26828
26973
  0,
26829
26974
  pageViewportWidth - pageHorizontalPadding * 2
@@ -26839,6 +26984,13 @@ var Viewer = ({
26839
26984
  usePageVerticalAnchor,
26840
26985
  startSurfaceScrollX: pinchStartSurfaceScrollXRef.current,
26841
26986
  startSurfaceWidth,
26987
+ usePageHorizontalAnchor: basePageWidth < availablePageWidth,
26988
+ startPageOffsetX: viewportOffsetX,
26989
+ startPageFrameWidth: isDouble ? Math.max(
26990
+ pageViewportWidth,
26991
+ startPageWidth + pageHorizontalPadding * 2
26992
+ ) : startSurfaceWidth,
26993
+ startPageWidth,
26842
26994
  pageViewportWidth,
26843
26995
  pageHorizontalPadding,
26844
26996
  pageViewportContentOffsetX: Math.max(
@@ -26877,8 +27029,13 @@ var Viewer = ({
26877
27029
  engine,
26878
27030
  documentSurfaceWidth,
26879
27031
  getPageLayoutForZoom,
27032
+ getPageWidthForZoom,
26880
27033
  getPageViewportMetrics,
26881
27034
  handleGestureScrollLockChange,
27035
+ isDouble,
27036
+ maxPageWidth,
27037
+ pageFitHeight,
27038
+ getPageAspectRatio,
26882
27039
  perfEnabled,
26883
27040
  pinchPerfMachine,
26884
27041
  resetViewerPinchPreview,
@@ -26963,7 +27120,7 @@ var Viewer = ({
26963
27120
  pageHeight: endPageHeight,
26964
27121
  totalContentHeight: endContentHeight
26965
27122
  } = getPageLayoutForZoom(pendingRestore.pageIndex, zoom);
26966
- const viewerViewportHeight = viewerFrameRef.current.height;
27123
+ const viewerViewportHeight2 = viewerFrameRef.current.height;
26967
27124
  const nextScrollY = resolvePdfAnchoredScrollY({
26968
27125
  mode: pendingRestore.usePageVerticalAnchor ? "page" : "document",
26969
27126
  focalY: pendingRestore.focalY,
@@ -26974,7 +27131,7 @@ var Viewer = ({
26974
27131
  endPageOffsetY,
26975
27132
  endPageHeight,
26976
27133
  endContentHeight,
26977
- viewportHeight: viewerViewportHeight
27134
+ viewportHeight: viewerViewportHeight2
26978
27135
  });
26979
27136
  if (isSingle) {
26980
27137
  listRef.current?.scrollTo?.({
@@ -26993,7 +27150,25 @@ var Viewer = ({
26993
27150
  0,
26994
27151
  pendingRestore.pageViewportWidth - pendingRestore.pageHorizontalPadding * 2
26995
27152
  );
26996
- const nextOffsetX = resolvePdfAnchoredScrollX({
27153
+ const nextPageWidth = getPageWidthForZoom(
27154
+ pendingRestore.pageIndex,
27155
+ pendingRestore.finalZoom
27156
+ );
27157
+ const nextOffsetX = pendingRestore.usePageHorizontalAnchor ? resolvePdfPageAnchoredScrollX({
27158
+ focalViewportX: pinchFocalPointRef.current.x,
27159
+ startSurfaceScrollX: pendingRestore.startSurfaceScrollX,
27160
+ viewportWidth: windowWidth,
27161
+ endSurfaceWidth,
27162
+ startPageOffsetX: pendingRestore.startPageOffsetX,
27163
+ endPageOffsetX: pendingRestore.startPageOffsetX,
27164
+ startPageFrameWidth: pendingRestore.startPageFrameWidth,
27165
+ endPageFrameWidth: isDouble ? Math.max(
27166
+ pendingRestore.pageViewportWidth,
27167
+ nextPageWidth + pendingRestore.pageHorizontalPadding * 2
27168
+ ) : endSurfaceWidth,
27169
+ startPageWidth: pendingRestore.startPageWidth,
27170
+ endPageWidth: nextPageWidth
27171
+ }) : resolvePdfAnchoredScrollX({
26997
27172
  focalViewportX: pendingRestore.pageViewportContentOffsetX,
26998
27173
  startSurfaceScrollX: pendingRestore.startSurfaceScrollX,
26999
27174
  startSurfaceWidth: pendingRestore.startSurfaceWidth,
@@ -27021,9 +27196,12 @@ var Viewer = ({
27021
27196
  }, [
27022
27197
  documentSurfaceWidth,
27023
27198
  getPageLayoutForZoom,
27199
+ getPageWidthForZoom,
27200
+ isDouble,
27024
27201
  isSingle,
27025
27202
  perfEnabled,
27026
27203
  scrollHorizontalSurfaceTo,
27204
+ windowWidth,
27027
27205
  zoom
27028
27206
  ]);
27029
27207
  useEffect4(() => {
@@ -27084,7 +27262,10 @@ var Viewer = ({
27084
27262
  if (isDouble) {
27085
27263
  const pageWidth2 = resolvePdfBasePageWidth({
27086
27264
  viewportWidth: columnWidth,
27087
- horizontalPadding: 8
27265
+ horizontalPadding: 8,
27266
+ maxPageWidth,
27267
+ maxPageHeight: pageFitHeight,
27268
+ pageAspectRatio: DEFAULT_PAGE_ASPECT_RATIO
27088
27269
  });
27089
27270
  return createPageLayoutMetrics({
27090
27271
  itemCount: rows.length,
@@ -27094,16 +27275,37 @@ var Viewer = ({
27094
27275
  estimatedLength: pageWidth2 / DEFAULT_PAGE_ASPECT_RATIO + DOUBLE_PAGE_SPACING,
27095
27276
  getBaseItemLength: (index) => {
27096
27277
  const row = rows[index];
27097
- if (!row) return pageWidth2 / DEFAULT_PAGE_ASPECT_RATIO + DOUBLE_PAGE_SPACING;
27098
- const leftHeight = pageWidth2 / getPageAspectRatio(row.left);
27099
- const rightHeight = row.right === null ? leftHeight : pageWidth2 / getPageAspectRatio(row.right);
27278
+ if (!row) {
27279
+ return pageWidth2 / DEFAULT_PAGE_ASPECT_RATIO + DOUBLE_PAGE_SPACING;
27280
+ }
27281
+ const leftAspectRatio = getPageAspectRatio(row.left);
27282
+ const leftPageWidth = resolvePdfBasePageWidth({
27283
+ viewportWidth: columnWidth,
27284
+ horizontalPadding: 8,
27285
+ maxPageWidth,
27286
+ maxPageHeight: pageFitHeight,
27287
+ pageAspectRatio: leftAspectRatio
27288
+ });
27289
+ const leftHeight = leftPageWidth / leftAspectRatio;
27290
+ const rightAspectRatio = row.right === null ? leftAspectRatio : getPageAspectRatio(row.right);
27291
+ const rightPageWidth = row.right === null ? leftPageWidth : resolvePdfBasePageWidth({
27292
+ viewportWidth: columnWidth,
27293
+ horizontalPadding: 8,
27294
+ maxPageWidth,
27295
+ maxPageHeight: pageFitHeight,
27296
+ pageAspectRatio: rightAspectRatio
27297
+ });
27298
+ const rightHeight = rightPageWidth / rightAspectRatio;
27100
27299
  return Math.max(leftHeight, rightHeight) + DOUBLE_PAGE_SPACING;
27101
27300
  }
27102
27301
  });
27103
27302
  }
27104
27303
  const pageWidth = resolvePdfBasePageWidth({
27105
27304
  viewportWidth: windowWidth,
27106
- horizontalPadding: 16
27305
+ horizontalPadding: 16,
27306
+ maxPageWidth,
27307
+ maxPageHeight: pageFitHeight,
27308
+ pageAspectRatio: DEFAULT_PAGE_ASPECT_RATIO
27107
27309
  });
27108
27310
  return createPageLayoutMetrics({
27109
27311
  itemCount: pageCount,
@@ -27111,13 +27313,25 @@ var Viewer = ({
27111
27313
  topPadding: LIST_TOP_PADDING,
27112
27314
  bottomPadding: LIST_BOTTOM_PADDING,
27113
27315
  estimatedLength: pageWidth / DEFAULT_PAGE_ASPECT_RATIO + CONTINUOUS_PAGE_SPACING,
27114
- getBaseItemLength: (index) => pageWidth / getPageAspectRatio(index) + CONTINUOUS_PAGE_SPACING
27316
+ getBaseItemLength: (index) => {
27317
+ const aspectRatio = getPageAspectRatio(index);
27318
+ const fittedPageWidth = resolvePdfBasePageWidth({
27319
+ viewportWidth: windowWidth,
27320
+ horizontalPadding: 16,
27321
+ maxPageWidth,
27322
+ maxPageHeight: pageFitHeight,
27323
+ pageAspectRatio: aspectRatio
27324
+ });
27325
+ return fittedPageWidth / aspectRatio + CONTINUOUS_PAGE_SPACING;
27326
+ }
27115
27327
  });
27116
27328
  }, [
27117
27329
  columnWidth,
27118
27330
  getPageAspectRatio,
27119
27331
  isDouble,
27120
27332
  layoutRevision,
27333
+ maxPageWidth,
27334
+ pageFitHeight,
27121
27335
  pageCount,
27122
27336
  rows,
27123
27337
  windowWidth
@@ -27154,7 +27368,7 @@ var Viewer = ({
27154
27368
  [getFallbackOffsetForIndex, setViewerScrollEnabledNative]
27155
27369
  );
27156
27370
  const restoreOrientationScrollOffset = useCallback3(() => {
27157
- if (pendingOrientationRestoreWidthRef.current !== windowWidth || pageCount <= 0 || isSingle || isWebView) {
27371
+ if (!pendingOrientationRestoreRef.current || fitPageToViewportHeight && pageFitHeight === void 0 || pageCount <= 0 || isSingle || isWebView) {
27158
27372
  return;
27159
27373
  }
27160
27374
  const offset = resolveOrientationScrollOffset({
@@ -27165,24 +27379,30 @@ var Viewer = ({
27165
27379
  });
27166
27380
  listRef.current?.scrollToOffset({ offset, animated: false });
27167
27381
  lastScrollOffsetYRef.current = offset;
27168
- pendingOrientationRestoreWidthRef.current = null;
27382
+ pendingOrientationRestoreRef.current = false;
27169
27383
  }, [
27170
27384
  currentPage,
27385
+ fitPageToViewportHeight,
27171
27386
  isDouble,
27172
27387
  isSingle,
27173
27388
  isWebView,
27174
27389
  pageCount,
27390
+ pageFitHeight,
27175
27391
  scaledListLayoutMetrics,
27176
27392
  windowWidth
27177
27393
  ]);
27178
27394
  useEffect4(() => {
27179
- const previousWindowWidth = previousWindowWidthRef.current;
27180
- previousWindowWidthRef.current = windowWidth;
27181
- if (previousWindowWidth !== null && previousWindowWidth !== windowWidth) {
27182
- pendingOrientationRestoreWidthRef.current = windowWidth;
27395
+ const nextGeometry = { width: windowWidth, pageFitHeight };
27396
+ const previousGeometry = previousViewportGeometryRef.current;
27397
+ previousViewportGeometryRef.current = nextGeometry;
27398
+ if (hasViewerViewportGeometryChanged({
27399
+ previous: previousGeometry,
27400
+ next: nextGeometry
27401
+ })) {
27402
+ pendingOrientationRestoreRef.current = true;
27183
27403
  }
27184
27404
  restoreOrientationScrollOffset();
27185
- }, [restoreOrientationScrollOffset, windowWidth]);
27405
+ }, [pageFitHeight, restoreOrientationScrollOffset, windowWidth]);
27186
27406
  useEffect4(() => {
27187
27407
  if (pendingScrollTargetRef.current !== null) {
27188
27408
  scrollToPendingTarget(false);
@@ -27434,6 +27654,8 @@ var Viewer = ({
27434
27654
  pageIndex: row.left,
27435
27655
  pageAspectRatio: getPageAspectRatio(row.left),
27436
27656
  availableWidth: columnWidth,
27657
+ maxPageWidth,
27658
+ maxPageHeight: pageFitHeight,
27437
27659
  horizontalPadding: 8,
27438
27660
  pageViewportWidth: columnWidth,
27439
27661
  spacing: DOUBLE_PAGE_SPACING,
@@ -27454,6 +27676,8 @@ var Viewer = ({
27454
27676
  pageIndex: row.right,
27455
27677
  pageAspectRatio: getPageAspectRatio(row.right),
27456
27678
  availableWidth: columnWidth,
27679
+ maxPageWidth,
27680
+ maxPageHeight: pageFitHeight,
27457
27681
  horizontalPadding: 8,
27458
27682
  pageViewportWidth: columnWidth,
27459
27683
  spacing: DOUBLE_PAGE_SPACING,
@@ -27478,6 +27702,8 @@ var Viewer = ({
27478
27702
  pageIndex: item,
27479
27703
  pageAspectRatio: getPageAspectRatio(item),
27480
27704
  availableWidth: windowWidth,
27705
+ maxPageWidth,
27706
+ maxPageHeight: pageFitHeight,
27481
27707
  pageViewportWidth: documentSurfaceWidth,
27482
27708
  spacing: CONTINUOUS_PAGE_SPACING,
27483
27709
  onSelectionDragActiveChange: setSelectionDragActive,
@@ -27503,6 +27729,8 @@ var Viewer = ({
27503
27729
  horizontalPadding,
27504
27730
  isDouble,
27505
27731
  lastPinchEndedAt,
27732
+ maxPageWidth,
27733
+ pageFitHeight,
27506
27734
  windowWidth
27507
27735
  ]
27508
27736
  );
@@ -27525,7 +27753,13 @@ var Viewer = ({
27525
27753
  onViewableItemsChanged,
27526
27754
  viewabilityConfig: { itemVisiblePercentThreshold: 60 },
27527
27755
  scrollEnabled: pageScrubResolvedScrollEnabled || programmaticScrollActive,
27528
- onLayout: () => {
27756
+ onLayout: (event) => {
27757
+ const nextHeight = event.nativeEvent.layout.height;
27758
+ if (fitPageToViewportHeight) {
27759
+ setViewerViewportHeight(
27760
+ (currentHeight) => currentHeight === nextHeight ? currentHeight : nextHeight
27761
+ );
27762
+ }
27529
27763
  captureViewerFrame(listRef.current);
27530
27764
  restoreOrientationScrollOffset();
27531
27765
  scrollToPendingTarget(false);
@@ -27594,13 +27828,14 @@ var Viewer = ({
27594
27828
  WebViewViewer_default,
27595
27829
  {
27596
27830
  engine,
27831
+ maxPageWidth,
27597
27832
  onScrollOffset: handleWebViewScroll,
27598
27833
  onTap: handleWebViewTap
27599
27834
  }
27600
27835
  ) });
27601
27836
  }
27602
27837
  if (isNativePdfViewer) {
27603
- return /* @__PURE__ */ jsx6(View4, { style: [styles4.container, isDark && styles4.containerDark], children: /* @__PURE__ */ jsx6(DedicatedAndroidPdfViewer, { engine }) });
27838
+ return /* @__PURE__ */ jsx6(View4, { style: [styles4.container, isDark && styles4.containerDark], children: /* @__PURE__ */ jsx6(DedicatedAndroidPdfViewer, { engine, maxPageWidth }) });
27604
27839
  }
27605
27840
  if (isSingle) {
27606
27841
  return /* @__PURE__ */ jsx6(View4, { style: [styles4.container, isDark && styles4.containerDark], children: /* @__PURE__ */ jsx6(GestureDetector2, { gesture: viewerPinchGesture, children: /* @__PURE__ */ jsx6(
@@ -27641,7 +27876,15 @@ var Viewer = ({
27641
27876
  contentContainerStyle: styles4.singleContent,
27642
27877
  showsVerticalScrollIndicator: false,
27643
27878
  scrollEnabled: pageScrubResolvedScrollEnabled,
27644
- onLayout: () => captureViewerFrame(listRef.current),
27879
+ onLayout: (event) => {
27880
+ const nextHeight = event.nativeEvent.layout.height;
27881
+ if (fitPageToViewportHeight) {
27882
+ setViewerViewportHeight(
27883
+ (currentHeight) => currentHeight === nextHeight ? currentHeight : nextHeight
27884
+ );
27885
+ }
27886
+ captureViewerFrame(listRef.current);
27887
+ },
27645
27888
  onContentSizeChange: (_, height) => {
27646
27889
  viewerContentHeightRef.current = height;
27647
27890
  },
@@ -27674,6 +27917,8 @@ var Viewer = ({
27674
27917
  Math.max(0, currentPage - 1)
27675
27918
  ),
27676
27919
  availableWidth: windowWidth,
27920
+ maxPageWidth,
27921
+ maxPageHeight: pageFitHeight,
27677
27922
  pageViewportWidth: documentSurfaceWidth,
27678
27923
  spacing: 32,
27679
27924
  onSelectionDragActiveChange: setSelectionDragActive,
@@ -27822,6 +28067,9 @@ import {
27822
28067
  } from "react-native";
27823
28068
 
27824
28069
  // components/nativeSheetLayout.ts
28070
+ var FLOATING_SHEET_MIN_WINDOW_WIDTH = 600;
28071
+ var FLOATING_SHEET_HORIZONTAL_GUTTER = 32;
28072
+ var FLOATING_SHEET_MAX_WIDTH = 640;
27825
28073
  var getNativeSheetSizeStyle = (maxHeight) => {
27826
28074
  if (!maxHeight) return null;
27827
28075
  return {
@@ -27829,6 +28077,32 @@ var getNativeSheetSizeStyle = (maxHeight) => {
27829
28077
  ...typeof maxHeight === "number" ? { height: maxHeight } : {}
27830
28078
  };
27831
28079
  };
28080
+ var getNativeSheetWidth = (windowWidth) => {
28081
+ if (!Number.isFinite(windowWidth) || windowWidth <= 0) return 0;
28082
+ if (windowWidth < FLOATING_SHEET_MIN_WINDOW_WIDTH) return windowWidth;
28083
+ return Math.min(
28084
+ FLOATING_SHEET_MAX_WIDTH,
28085
+ windowWidth - FLOATING_SHEET_HORIZONTAL_GUTTER * 2
28086
+ );
28087
+ };
28088
+ var getNativeSheetLayoutStyles = (windowWidth) => {
28089
+ if (!Number.isFinite(windowWidth) || windowWidth < FLOATING_SHEET_MIN_WINDOW_WIDTH) {
28090
+ return null;
28091
+ }
28092
+ return {
28093
+ root: {
28094
+ justifyContent: "center",
28095
+ paddingHorizontal: FLOATING_SHEET_HORIZONTAL_GUTTER,
28096
+ paddingVertical: 24
28097
+ },
28098
+ sheet: {
28099
+ width: getNativeSheetWidth(windowWidth),
28100
+ alignSelf: "center",
28101
+ borderRadius: 24,
28102
+ borderBottomWidth: 1
28103
+ }
28104
+ };
28105
+ };
27832
28106
 
27833
28107
  // components/PapyrusSafeArea.tsx
27834
28108
  import React6, { useContext as useContext2 } from "react";
@@ -27908,7 +28182,8 @@ function NativeSheet({
27908
28182
  }) {
27909
28183
  const insets = usePapyrusSafeAreaInsets();
27910
28184
  const palette = getNativeSheetPalette(Boolean(isDark));
27911
- const { height: windowHeight } = useWindowDimensions3();
28185
+ const { height: windowHeight, width: windowWidth } = useWindowDimensions3();
28186
+ const tabletLayout = getNativeSheetLayoutStyles(windowWidth);
27912
28187
  const [rendered, setRendered] = useState5(visible);
27913
28188
  const renderedRef = useRef5(visible);
27914
28189
  const motion = useRef5(new Animated2.Value(visible ? 0 : 1)).current;
@@ -27963,7 +28238,7 @@ function NativeSheet({
27963
28238
  transparent: true,
27964
28239
  visible: rendered,
27965
28240
  onRequestClose: onClose,
27966
- children: /* @__PURE__ */ jsxs6(View5, { style: styles5.root, children: [
28241
+ children: /* @__PURE__ */ jsxs6(View5, { style: [styles5.root, tabletLayout?.root], children: [
27967
28242
  /* @__PURE__ */ jsx8(Animated2.View, { style: [styles5.backdrop, { opacity: backdropOpacity }], children: /* @__PURE__ */ jsx8(
27968
28243
  Pressable3,
27969
28244
  {
@@ -27978,12 +28253,14 @@ function NativeSheet({
27978
28253
  {
27979
28254
  style: [
27980
28255
  styles5.sheet,
28256
+ tabletLayout?.sheet,
27981
28257
  isDark && styles5.sheetDark,
27982
28258
  getNativeSheetSizeStyle(maxHeight),
27983
28259
  { paddingBottom: insets.bottom },
27984
28260
  {
27985
28261
  backgroundColor: palette.backgroundColor,
27986
- borderTopColor: palette.borderColor
28262
+ borderTopColor: palette.borderColor,
28263
+ borderBottomColor: palette.borderColor
27987
28264
  },
27988
28265
  sheetStyle,
27989
28266
  {
@@ -28039,7 +28316,8 @@ function NativeSheetFlatList(props) {
28039
28316
  var styles5 = StyleSheet5.create({
28040
28317
  root: {
28041
28318
  flex: 1,
28042
- justifyContent: "flex-end"
28319
+ justifyContent: "flex-end",
28320
+ alignItems: "center"
28043
28321
  },
28044
28322
  backdrop: {
28045
28323
  ...StyleSheet5.absoluteFillObject,
@@ -28052,6 +28330,7 @@ var styles5 = StyleSheet5.create({
28052
28330
  borderTopRightRadius: 24,
28053
28331
  borderTopWidth: 1,
28054
28332
  borderTopColor: "#e5e7eb",
28333
+ borderBottomColor: "#e5e7eb",
28055
28334
  backgroundColor: "#ffffff"
28056
28335
  },
28057
28336
  sheetDark: {
@@ -29638,7 +29917,6 @@ import {
29638
29917
  useState as useState9
29639
29918
  } from "react";
29640
29919
  import {
29641
- Dimensions,
29642
29920
  Image as Image2,
29643
29921
  Platform as Platform3,
29644
29922
  Pressable as Pressable7,
@@ -29646,12 +29924,21 @@ import {
29646
29924
  Text as Text5,
29647
29925
  UIManager,
29648
29926
  View as View9,
29649
- findNodeHandle as findNodeHandle2
29927
+ findNodeHandle as findNodeHandle2,
29928
+ useWindowDimensions as useWindowDimensions6
29650
29929
  } from "react-native";
29651
29930
  import { useViewerStore as useViewerStore7 } from "@papyrus-sdk/core";
29652
29931
  import { PapyrusPageView as PapyrusPageView2 } from "@papyrus-sdk/engine-native";
29653
29932
 
29654
29933
  // components/rightSheetLayout.ts
29934
+ var getRightSheetThumbnailLayout = (sheetWidth) => {
29935
+ const availableWidth = Number.isFinite(sheetWidth) ? Math.max(0, sheetWidth - 32) : 0;
29936
+ const cardWidth = Math.max(0, (availableWidth - 12) / 2);
29937
+ return {
29938
+ cardWidth,
29939
+ frameWidth: Math.max(0, cardWidth - 16)
29940
+ };
29941
+ };
29655
29942
  var resolveRightSheetHeight = ({
29656
29943
  windowHeight,
29657
29944
  showingNotes
@@ -29853,6 +30140,7 @@ var RightSheet = ({
29853
30140
  locale,
29854
30141
  accentColor
29855
30142
  } = useViewerStore7();
30143
+ const { height: windowHeight, width: windowWidth } = useWindowDimensions6();
29856
30144
  const [pagesMode, setPagesMode] = useState9(
29857
30145
  documentType === "pdf" || documentType === "comic" ? "thumbnails" : "summary"
29858
30146
  );
@@ -29866,14 +30154,11 @@ var RightSheet = ({
29866
30154
  const t = getStrings(locale);
29867
30155
  const showingNotes = sidebarRightTab === "annotations";
29868
30156
  const sheetHeight = resolveRightSheetHeight({
29869
- windowHeight: Dimensions.get("window").height,
30157
+ windowHeight,
29870
30158
  showingNotes
29871
30159
  });
29872
- const windowWidth = Dimensions.get("window").width;
29873
- const gridGutter = 12;
29874
- const gridPadding = 16;
29875
- const cardWidth = (windowWidth - gridPadding * 2 - gridGutter) / 2;
29876
- const frameWidth = cardWidth - 16;
30160
+ const sheetWidth = getNativeSheetWidth(windowWidth);
30161
+ const { cardWidth, frameWidth } = getRightSheetThumbnailLayout(sheetWidth);
29877
30162
  const renderTarget = engine.getRenderTargetType?.();
29878
30163
  const hasNativePageView = Boolean(
29879
30164
  UIManager.getViewManagerConfig?.("PapyrusPageView")
@@ -30301,7 +30586,9 @@ var RightSheet = ({
30301
30586
  ] }),
30302
30587
  /* @__PURE__ */ jsx12(Text5, { style: [styles9.noteType, { color: accentColor }], children: getAnnotationKindLabel(ann.type, locale) }),
30303
30588
  ann.content ? (() => {
30304
- const parts = resolveNoteQuoteParts(ann.content ?? "");
30589
+ const parts = resolveNoteQuoteParts(
30590
+ ann.content ?? ""
30591
+ );
30305
30592
  return /* @__PURE__ */ jsxs10(View9, { style: styles9.noteQuoteRow, children: [
30306
30593
  /* @__PURE__ */ jsx12(
30307
30594
  View9,
@@ -30789,7 +31076,7 @@ var styles10 = StyleSheet10.create({
30789
31076
  var AnnotationEditor_default = AnnotationEditor;
30790
31077
 
30791
31078
  // components/BottomBar.tsx
30792
- import { View as View11, Pressable as Pressable9, StyleSheet as StyleSheet11, useWindowDimensions as useWindowDimensions6 } from "react-native";
31079
+ import { View as View11, Pressable as Pressable9, StyleSheet as StyleSheet11, useWindowDimensions as useWindowDimensions7 } from "react-native";
30793
31080
  import { useViewerStore as useViewerStore9 } from "@papyrus-sdk/core";
30794
31081
 
30795
31082
  // components/bottomBarModel.ts
@@ -30857,7 +31144,7 @@ var BottomBar = ({
30857
31144
  } = useViewerStore9();
30858
31145
  const isDark = uiTheme === "dark";
30859
31146
  const t = getStrings(locale);
30860
- const { width, height } = useWindowDimensions6();
31147
+ const { width, height } = useWindowDimensions7();
30861
31148
  const isLandscape = width > height;
30862
31149
  const offsets = resolveMobileChromeOffsets(usePapyrusSafeAreaInsets());
30863
31150
  const iconColor = (active) => {
@@ -31080,8 +31367,19 @@ var styles11 = StyleSheet11.create({
31080
31367
  var BottomBar_default = BottomBar;
31081
31368
 
31082
31369
  // components/SettingsSheet.tsx
31083
- import { Dimensions as Dimensions2, View as View12, Text as Text7, Pressable as Pressable10, StyleSheet as StyleSheet12 } from "react-native";
31370
+ import {
31371
+ View as View12,
31372
+ Text as Text7,
31373
+ Pressable as Pressable10,
31374
+ StyleSheet as StyleSheet12,
31375
+ useWindowDimensions as useWindowDimensions8
31376
+ } from "react-native";
31084
31377
  import { useViewerStore as useViewerStore10 } from "@papyrus-sdk/core";
31378
+
31379
+ // components/settingsSheetLayout.ts
31380
+ var getSettingsSheetMaxHeight = (windowHeight) => Math.min(640, Math.max(0, windowHeight) * 0.72);
31381
+
31382
+ // components/SettingsSheet.tsx
31085
31383
  import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
31086
31384
  var PAGE_THEME_OPTIONS = [
31087
31385
  { value: "normal", labelKey: "themeOriginal" },
@@ -31126,7 +31424,8 @@ var SettingsSheet = ({
31126
31424
  const isPaged = viewMode === "single";
31127
31425
  const isDouble = viewMode === "double";
31128
31426
  const t = getStrings(locale);
31129
- const sheetMaxHeight = Math.min(640, Dimensions2.get("window").height * 0.72);
31427
+ const { height: windowHeight } = useWindowDimensions8();
31428
+ const sheetMaxHeight = getSettingsSheetMaxHeight(windowHeight);
31130
31429
  const handleTransition = (mode) => {
31131
31430
  if (mode === "paged") {
31132
31431
  setDocumentState({ viewMode: "single" });
@@ -32198,7 +32497,7 @@ import {
32198
32497
  StyleSheet as StyleSheet17,
32199
32498
  Text as Text12,
32200
32499
  View as View17,
32201
- useWindowDimensions as useWindowDimensions7
32500
+ useWindowDimensions as useWindowDimensions9
32202
32501
  } from "react-native";
32203
32502
  import { useViewerStore as useViewerStore14 } from "@papyrus-sdk/core";
32204
32503
  import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
@@ -32220,7 +32519,7 @@ function ProgressPill({
32220
32519
  } = useViewerStore14();
32221
32520
  const isDark = uiTheme === "dark";
32222
32521
  const offsets = resolveMobileChromeOffsets(usePapyrusSafeAreaInsets());
32223
- const { height: windowHeight } = useWindowDimensions7();
32522
+ const { height: windowHeight } = useWindowDimensions9();
32224
32523
  const windowHeightRef = useRef9(windowHeight);
32225
32524
  windowHeightRef.current = windowHeight;
32226
32525
  const trackHeight = resolvePageScrubberTrackHeight({
@@ -32594,9 +32893,29 @@ import {
32594
32893
  StyleSheet as StyleSheet18,
32595
32894
  Text as Text13,
32596
32895
  TextInput as TextInput3,
32597
- View as View18
32896
+ View as View18,
32897
+ useWindowDimensions as useWindowDimensions10
32598
32898
  } from "react-native";
32599
32899
  import { SearchService, useViewerStore as useViewerStore15 } from "@papyrus-sdk/core";
32900
+
32901
+ // components/searchOverlayLayout.ts
32902
+ var getSearchOverlayLayout = (windowWidth) => {
32903
+ if (!Number.isFinite(windowWidth) || windowWidth <= 0) {
32904
+ return { frame: { paddingHorizontal: 12 }, card: null };
32905
+ }
32906
+ if (windowWidth < 768) {
32907
+ return { frame: { paddingHorizontal: 12 }, card: null };
32908
+ }
32909
+ return {
32910
+ frame: { paddingHorizontal: 24 },
32911
+ card: {
32912
+ width: Math.min(640, windowWidth - 48),
32913
+ alignSelf: "center"
32914
+ }
32915
+ };
32916
+ };
32917
+
32918
+ // components/SearchOverlay.tsx
32600
32919
  import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
32601
32920
  function SearchOverlay({
32602
32921
  engine,
@@ -32622,6 +32941,8 @@ function SearchOverlay({
32622
32941
  const [isSearching, setIsSearching] = useState13(false);
32623
32942
  const searchRequestIdRef = React15.useRef(0);
32624
32943
  const isDark = uiTheme === "dark";
32944
+ const { width: windowWidth } = useWindowDimensions10();
32945
+ const overlayLayout = getSearchOverlayLayout(windowWidth);
32625
32946
  const offsets = resolveMobileChromeOffsets(usePapyrusSafeAreaInsets());
32626
32947
  const t = getStrings(locale);
32627
32948
  const searchService = useMemo8(() => new SearchService(engine), [engine]);
@@ -32657,110 +32978,125 @@ function SearchOverlay({
32657
32978
  onClose();
32658
32979
  };
32659
32980
  if (!visible) return null;
32660
- return /* @__PURE__ */ jsx21(View18, { pointerEvents: "box-none", style: [styles18.frame, { bottom: offsets.search, paddingLeft: offsets.left, paddingRight: offsets.right }], children: /* @__PURE__ */ jsxs18(
32981
+ return /* @__PURE__ */ jsx21(
32661
32982
  View18,
32662
32983
  {
32663
- style: [styles18.card, isDark && styles18.cardDark],
32664
- testID: "papyrus-search-overlay",
32665
- children: [
32666
- /* @__PURE__ */ jsxs18(View18, { style: styles18.inputRow, children: [
32667
- /* @__PURE__ */ jsxs18(View18, { style: [styles18.searchInputWrap, isDark && styles18.searchInputWrapDark], children: [
32668
- /* @__PURE__ */ jsx21(IconSearch, { size: 16, color: isDark ? "#cbd5e1" : "#64748b" }),
32669
- /* @__PURE__ */ jsx21(
32670
- TextInput3,
32671
- {
32672
- value: draft,
32673
- onChangeText: setDraft,
32674
- placeholder: t.searchPlaceholder,
32675
- placeholderTextColor: isDark ? "#94a3b8" : "#6b7280",
32676
- style: [styles18.input, isDark && styles18.inputDark],
32677
- autoFocus: true,
32678
- returnKeyType: "search",
32679
- onSubmitEditing: handleSubmit,
32680
- accessibilityLabel: "Search text",
32681
- testID: "papyrus-search-input"
32682
- }
32683
- )
32684
- ] }),
32685
- /* @__PURE__ */ jsx21(
32686
- Pressable12,
32687
- {
32688
- onPress: handleClose,
32689
- style: [styles18.closeButton, isDark && styles18.closeButtonDark],
32690
- accessibilityLabel: "Close search",
32691
- children: /* @__PURE__ */ jsx21(Text13, { style: [styles18.closeText, isDark && styles18.closeTextDark], children: t.cancel })
32692
- }
32693
- )
32694
- ] }),
32695
- /* @__PURE__ */ jsxs18(View18, { style: styles18.metaRow, children: [
32696
- /* @__PURE__ */ jsx21(
32697
- Pressable12,
32698
- {
32699
- onPress: prevSearchResult,
32700
- disabled: searchResults.length === 0,
32701
- style: [
32702
- styles18.navButton,
32703
- isDark && styles18.navButtonDark,
32704
- searchResults.length === 0 && styles18.navButtonDisabled
32705
- ],
32706
- accessibilityLabel: "Previous result",
32707
- children: /* @__PURE__ */ jsx21(IconChevronLeft, { size: 16, color: isDark ? "#e5e7eb" : "#111827" })
32708
- }
32709
- ),
32710
- /* @__PURE__ */ jsx21(Text13, { style: [styles18.metaText, isDark && styles18.metaTextDark], children: isSearching ? t.searching : `${currentCount}/${searchResults.length} ${targetLabel}` }),
32711
- /* @__PURE__ */ jsx21(
32712
- Pressable12,
32713
- {
32714
- onPress: nextSearchResult,
32715
- disabled: searchResults.length === 0,
32716
- style: [
32717
- styles18.navButton,
32718
- isDark && styles18.navButtonDark,
32719
- searchResults.length === 0 && styles18.navButtonDisabled
32720
- ],
32721
- accessibilityLabel: "Next result",
32722
- children: /* @__PURE__ */ jsx21(IconChevronRight, { size: 16, color: isDark ? "#e5e7eb" : "#111827" })
32723
- }
32724
- )
32725
- ] }),
32726
- /* @__PURE__ */ jsxs18(View18, { style: styles18.actionsRow, children: [
32727
- /* @__PURE__ */ jsx21(
32728
- Pressable12,
32729
- {
32730
- onPress: handleSubmit,
32731
- style: [styles18.primaryAction, { backgroundColor: accentColor }],
32732
- accessibilityLabel: "Run search",
32733
- testID: "papyrus-search-run",
32734
- children: /* @__PURE__ */ jsx21(Text13, { style: styles18.primaryActionText, children: t.searchGo })
32735
- }
32736
- ),
32737
- /* @__PURE__ */ jsx21(
32738
- Pressable12,
32739
- {
32740
- onPress: onOpenResults,
32741
- disabled: searchResults.length === 0,
32742
- style: [
32743
- styles18.secondaryAction,
32744
- isDark && styles18.secondaryActionDark,
32745
- searchResults.length === 0 && styles18.navButtonDisabled
32746
- ],
32747
- accessibilityLabel: "Open all results",
32748
- children: /* @__PURE__ */ jsx21(
32749
- Text13,
32984
+ pointerEvents: "box-none",
32985
+ style: [
32986
+ styles18.frame,
32987
+ overlayLayout.frame,
32988
+ {
32989
+ bottom: offsets.search,
32990
+ paddingLeft: Math.max(overlayLayout.frame.paddingHorizontal, offsets.left),
32991
+ paddingRight: Math.max(overlayLayout.frame.paddingHorizontal, offsets.right)
32992
+ }
32993
+ ],
32994
+ children: /* @__PURE__ */ jsxs18(
32995
+ View18,
32996
+ {
32997
+ style: [styles18.card, overlayLayout.card, isDark && styles18.cardDark],
32998
+ testID: "papyrus-search-overlay",
32999
+ children: [
33000
+ /* @__PURE__ */ jsxs18(View18, { style: styles18.inputRow, children: [
33001
+ /* @__PURE__ */ jsxs18(View18, { style: [styles18.searchInputWrap, isDark && styles18.searchInputWrapDark], children: [
33002
+ /* @__PURE__ */ jsx21(IconSearch, { size: 16, color: isDark ? "#cbd5e1" : "#64748b" }),
33003
+ /* @__PURE__ */ jsx21(
33004
+ TextInput3,
33005
+ {
33006
+ value: draft,
33007
+ onChangeText: setDraft,
33008
+ placeholder: t.searchPlaceholder,
33009
+ placeholderTextColor: isDark ? "#94a3b8" : "#6b7280",
33010
+ style: [styles18.input, isDark && styles18.inputDark],
33011
+ autoFocus: true,
33012
+ returnKeyType: "search",
33013
+ onSubmitEditing: handleSubmit,
33014
+ accessibilityLabel: "Search text",
33015
+ testID: "papyrus-search-input"
33016
+ }
33017
+ )
33018
+ ] }),
33019
+ /* @__PURE__ */ jsx21(
33020
+ Pressable12,
32750
33021
  {
33022
+ onPress: handleClose,
33023
+ style: [styles18.closeButton, isDark && styles18.closeButtonDark],
33024
+ accessibilityLabel: "Close search",
33025
+ children: /* @__PURE__ */ jsx21(Text13, { style: [styles18.closeText, isDark && styles18.closeTextDark], children: t.cancel })
33026
+ }
33027
+ )
33028
+ ] }),
33029
+ /* @__PURE__ */ jsxs18(View18, { style: styles18.metaRow, children: [
33030
+ /* @__PURE__ */ jsx21(
33031
+ Pressable12,
33032
+ {
33033
+ onPress: prevSearchResult,
33034
+ disabled: searchResults.length === 0,
33035
+ style: [
33036
+ styles18.navButton,
33037
+ isDark && styles18.navButtonDark,
33038
+ searchResults.length === 0 && styles18.navButtonDisabled
33039
+ ],
33040
+ accessibilityLabel: "Previous result",
33041
+ children: /* @__PURE__ */ jsx21(IconChevronLeft, { size: 16, color: isDark ? "#e5e7eb" : "#111827" })
33042
+ }
33043
+ ),
33044
+ /* @__PURE__ */ jsx21(Text13, { style: [styles18.metaText, isDark && styles18.metaTextDark], children: isSearching ? t.searching : `${currentCount}/${searchResults.length} ${targetLabel}` }),
33045
+ /* @__PURE__ */ jsx21(
33046
+ Pressable12,
33047
+ {
33048
+ onPress: nextSearchResult,
33049
+ disabled: searchResults.length === 0,
32751
33050
  style: [
32752
- styles18.secondaryActionText,
32753
- isDark && styles18.secondaryActionTextDark
33051
+ styles18.navButton,
33052
+ isDark && styles18.navButtonDark,
33053
+ searchResults.length === 0 && styles18.navButtonDisabled
32754
33054
  ],
32755
- children: t.allResults
33055
+ accessibilityLabel: "Next result",
33056
+ children: /* @__PURE__ */ jsx21(IconChevronRight, { size: 16, color: isDark ? "#e5e7eb" : "#111827" })
32756
33057
  }
32757
33058
  )
32758
- }
32759
- )
32760
- ] })
32761
- ]
33059
+ ] }),
33060
+ /* @__PURE__ */ jsxs18(View18, { style: styles18.actionsRow, children: [
33061
+ /* @__PURE__ */ jsx21(
33062
+ Pressable12,
33063
+ {
33064
+ onPress: handleSubmit,
33065
+ style: [styles18.primaryAction, { backgroundColor: accentColor }],
33066
+ accessibilityLabel: "Run search",
33067
+ testID: "papyrus-search-run",
33068
+ children: /* @__PURE__ */ jsx21(Text13, { style: styles18.primaryActionText, children: t.searchGo })
33069
+ }
33070
+ ),
33071
+ /* @__PURE__ */ jsx21(
33072
+ Pressable12,
33073
+ {
33074
+ onPress: onOpenResults,
33075
+ disabled: searchResults.length === 0,
33076
+ style: [
33077
+ styles18.secondaryAction,
33078
+ isDark && styles18.secondaryActionDark,
33079
+ searchResults.length === 0 && styles18.navButtonDisabled
33080
+ ],
33081
+ accessibilityLabel: "Open all results",
33082
+ children: /* @__PURE__ */ jsx21(
33083
+ Text13,
33084
+ {
33085
+ style: [
33086
+ styles18.secondaryActionText,
33087
+ isDark && styles18.secondaryActionTextDark
33088
+ ],
33089
+ children: t.allResults
33090
+ }
33091
+ )
33092
+ }
33093
+ )
33094
+ ] })
33095
+ ]
33096
+ }
33097
+ )
32762
33098
  }
32763
- ) });
33099
+ );
32764
33100
  }
32765
33101
  var styles18 = StyleSheet18.create({
32766
33102
  frame: {