@atlaskit/media-document-viewer 0.6.11 → 0.7.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @atlaskit/media-document-viewer
2
2
 
3
+ ## 0.7.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`2fe9a9909d2ac`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2fe9a9909d2ac) -
8
+ Enrol media packages into the React Compiler with platform gating via
9
+ isReactCompilerActivePlatform
10
+ - Updated dependencies
11
+
12
+ ## 0.7.0
13
+
14
+ ### Minor Changes
15
+
16
+ - [`34c40eb233aa4`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/34c40eb233aa4) -
17
+ isUxChange: true
18
+
19
+ Lazy-append document pages for MS Excel previews behind platform_media_excel_lazy_load gate to fix
20
+ initial-render freeze on very large documents
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies
25
+
3
26
  ## 0.6.11
4
27
 
5
28
  ### Patch Changes
@@ -20,7 +20,8 @@ var anchorStyles = {
20
20
  };
21
21
  var DocumentLink = function DocumentLink(_ref) {
22
22
  var link = _ref.link,
23
- dataTestId = _ref.dataTestId;
23
+ dataTestId = _ref.dataTestId,
24
+ appendUpTo = _ref.appendUpTo;
24
25
  return /*#__PURE__*/_react.default.createElement("foreignObject", {
25
26
  x: link.x,
26
27
  y: -link.y,
@@ -34,15 +35,20 @@ var DocumentLink = function DocumentLink(_ref) {
34
35
  style: anchorStyles
35
36
  })) : /*#__PURE__*/_react.default.createElement(_anchor.default, (0, _extends2.default)({}, foreignObjectProps, {
36
37
  href: "#page-".concat(link.p_num + 1),
37
- style: anchorStyles
38
+ style: anchorStyles,
39
+ onClick: appendUpTo ? function () {
40
+ return appendUpTo(link.p_num + 1);
41
+ } : undefined
38
42
  })));
39
43
  };
40
44
  var DocumentLinks = exports.DocumentLinks = function DocumentLinks(_ref2) {
41
- var links = _ref2.links;
45
+ var links = _ref2.links,
46
+ appendUpTo = _ref2.appendUpTo;
42
47
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, links.map(function (link, i) {
43
48
  return /*#__PURE__*/_react.default.createElement(DocumentLink, {
44
49
  link: link,
45
50
  dataTestId: "document-link-".concat(i),
51
+ appendUpTo: appendUpTo,
46
52
  key: i
47
53
  });
48
54
  }));
@@ -11,7 +11,9 @@ require("./documentViewer.compiled.css");
11
11
  var _react = _interopRequireWildcard(require("react"));
12
12
  var React = _react;
13
13
  var _runtime = require("@compiled/react/runtime");
14
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
14
15
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
16
+ var _browserApis = require("@atlaskit/browser-apis");
15
17
  var _mediaCommon = require("@atlaskit/media-common");
16
18
  var _page = require("./page");
17
19
  var _usePageContent2 = require("./usePageContent");
@@ -20,14 +22,173 @@ var _useCachedGetImage = require("./utils/useCachedGetImage");
20
22
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
21
23
  var documentViewerStyles = null;
22
24
  var DEFAULT_PAGINATION_SIZE = 50;
23
- var DocumentViewer = exports.DocumentViewer = function DocumentViewer(_ref) {
25
+ var INITIAL_PAGE_COUNT = 50;
26
+ var APPEND_STEP = 50;
27
+
28
+ /**
29
+ * TAIL-APPEND PATTERN FOR LAZY LOADING:
30
+ *
31
+ * The <Page> component has an `onVisible: () => void` prop that is called when the page
32
+ * enters the viewport (via useIntersectionObserver with a 300% rootMargin). This callback
33
+ * is currently used to load page content via `loadPageContent(i)`.
34
+ *
35
+ * For the LazyAppendPages feature (T2.3), the parent component can leverage this same
36
+ * mechanism by:
37
+ * 1. Rendering only a subset of pages (lazyPageCount instead of all documentMetadata.pageCount)
38
+ * 2. Passing onVisible={handleAppend} ONLY to the last rendered page (i === lazyPageCount - 1)
39
+ * 3. For all other pages, passing onVisible={() => loadPageContent(i)} as usual
40
+ *
41
+ * When the last page enters the viewport, handleAppend will be triggered, which can:
42
+ * - Fetch the next batch of pages
43
+ * - Append them to the rendered page list
44
+ * - This effectively creates a tail-append/infinite-scroll behavior without any changes to <Page>
45
+ *
46
+ * No changes to the <Page> signature are required. The onVisible callback is already
47
+ * properly wired and can be overridden by parent components for different behaviors.
48
+ */
49
+
50
+ var LegacyPages = function LegacyPages(_ref) {
24
51
  var _documentMetadata$pag;
25
- var onSuccess = _ref.onSuccess,
26
- getContent = _ref.getContent,
27
- getPageImageUrl = _ref.getPageImageUrl,
28
- _ref$paginationSize = _ref.paginationSize,
29
- paginationSize = _ref$paginationSize === void 0 ? DEFAULT_PAGINATION_SIZE : _ref$paginationSize,
30
- zoom = _ref.zoom;
52
+ var documentMetadata = _ref.documentMetadata,
53
+ getPageContent = _ref.getPageContent,
54
+ loadPageContent = _ref.loadPageContent,
55
+ getImageUrl = _ref.getImageUrl,
56
+ zoom = _ref.zoom,
57
+ onSuccess = _ref.onSuccess,
58
+ style = _ref.style,
59
+ onTouchStart = _ref.onTouchStart,
60
+ onTouchMove = _ref.onTouchMove,
61
+ onTouchEnd = _ref.onTouchEnd;
62
+ return /*#__PURE__*/React.createElement("div", {
63
+ "data-testid": "document-viewer",
64
+ style: style,
65
+ onTouchStart: onTouchStart,
66
+ onTouchMove: onTouchMove,
67
+ onTouchEnd: onTouchEnd,
68
+ className: (0, _runtime.ax)(["_zulputpp _1reo1wug _18m91wug _19pkxncg _1ul91osq _1e0c1txw _2lx21bp4 _1bsb1ris"])
69
+ }, (0, _toConsumableArray2.default)(Array((_documentMetadata$pag = documentMetadata.pageCount) !== null && _documentMetadata$pag !== void 0 ? _documentMetadata$pag : 4)).map(function (_, i) {
70
+ var _getPageContent = getPageContent(i),
71
+ page = _getPageContent.page,
72
+ fonts = _getPageContent.fonts;
73
+ return /*#__PURE__*/React.createElement(_page.Page, {
74
+ key: i,
75
+ getPageSrc: getImageUrl,
76
+ pageIndex: i,
77
+ zoom: zoom,
78
+ defaultDimensions: documentMetadata.defaultDimensions,
79
+ onVisible: loadPageContent,
80
+ onLoad: i === 0 ? onSuccess : undefined,
81
+ fonts: fonts,
82
+ content: page
83
+ });
84
+ }));
85
+ };
86
+ var LazyAppendPages = function LazyAppendPages(_ref2) {
87
+ var _documentMetadata$pag2;
88
+ var documentMetadata = _ref2.documentMetadata,
89
+ getPageContent = _ref2.getPageContent,
90
+ loadPageContent = _ref2.loadPageContent,
91
+ getImageUrl = _ref2.getImageUrl,
92
+ zoom = _ref2.zoom,
93
+ onSuccess = _ref2.onSuccess,
94
+ style = _ref2.style,
95
+ onTouchStart = _ref2.onTouchStart,
96
+ onTouchMove = _ref2.onTouchMove,
97
+ onTouchEnd = _ref2.onTouchEnd;
98
+ var totalPages = (_documentMetadata$pag2 = documentMetadata.pageCount) !== null && _documentMetadata$pag2 !== void 0 ? _documentMetadata$pag2 : 4;
99
+ var _useState = (0, _react.useState)(function () {
100
+ return Math.min(INITIAL_PAGE_COUNT, totalPages);
101
+ }),
102
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
103
+ lazyPageCount = _useState2[0],
104
+ setLazyPageCount = _useState2[1];
105
+
106
+ // lastAppendTriggerIndex deduplicates: only append when a strictly-larger
107
+ // tail page fires onVisible. This prevents double-append on scroll-up-then-down.
108
+ var lastAppendTriggerIndex = (0, _react.useRef)(-1);
109
+
110
+ // Handle #page-N URL hash on first load: fast-forward lazyPageCount to include the target page.
111
+ // Capture totalPages in a ref so the one-shot effect can read it without being re-run when
112
+ // totalPages changes (the effect must only fire once, on mount).
113
+ var totalPagesRef = (0, _react.useRef)(totalPages);
114
+ (0, _react.useEffect)(function () {
115
+ var total = totalPagesRef.current;
116
+ var hash = window.location.hash;
117
+ var match = hash.match(/^#page-(\d+)$/);
118
+ if (match) {
119
+ var targetPage = parseInt(match[1], 10);
120
+ if (targetPage >= 1 && targetPage <= total) {
121
+ // Update dedup ref BEFORE setLazyPageCount so handleAppend does not
122
+ // cascade when the new tail page enters the viewport via IntersectionObserver.
123
+ lastAppendTriggerIndex.current = targetPage - 1;
124
+ // Fast-forward lazyPageCount to include the target page
125
+ setLazyPageCount(function (prev) {
126
+ return Math.max(prev, targetPage);
127
+ });
128
+ // After the pages are mounted (next animation frame), scroll to the target
129
+ requestAnimationFrame(function () {
130
+ var _getDocument;
131
+ var el = (_getDocument = (0, _browserApis.getDocument)()) === null || _getDocument === void 0 ? void 0 : _getDocument.getElementById("page-".concat(targetPage));
132
+ if (el) {
133
+ el.scrollIntoView();
134
+ }
135
+ });
136
+ }
137
+ }
138
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps -- intentionally one-shot; totalPages read via ref
139
+
140
+ var handleAppendAndLoadPageContent = (0, _react.useCallback)(function (pageIndex) {
141
+ if (pageIndex > lastAppendTriggerIndex.current) {
142
+ lastAppendTriggerIndex.current = pageIndex;
143
+ setLazyPageCount(function (c) {
144
+ return Math.min(c + APPEND_STEP, totalPages);
145
+ });
146
+ }
147
+ loadPageContent(pageIndex);
148
+ }, [totalPages, loadPageContent]);
149
+ var appendUpTo = (0, _react.useCallback)(function (targetPage) {
150
+ var clamped = Math.min(Math.max(targetPage, 0), totalPages);
151
+ if (clamped > lastAppendTriggerIndex.current) {
152
+ lastAppendTriggerIndex.current = clamped - 1;
153
+ setLazyPageCount(function (prev) {
154
+ return Math.max(prev, clamped);
155
+ });
156
+ }
157
+ }, [totalPages]);
158
+ return /*#__PURE__*/React.createElement("div", {
159
+ "data-testid": "document-viewer",
160
+ style: style,
161
+ onTouchStart: onTouchStart,
162
+ onTouchMove: onTouchMove,
163
+ onTouchEnd: onTouchEnd,
164
+ className: (0, _runtime.ax)(["_zulputpp _1reo1wug _18m91wug _19pkxncg _1ul91osq _1e0c1txw _2lx21bp4 _1bsb1ris"])
165
+ }, (0, _toConsumableArray2.default)(Array(lazyPageCount)).map(function (_, i) {
166
+ var _getPageContent2 = getPageContent(i),
167
+ page = _getPageContent2.page,
168
+ fonts = _getPageContent2.fonts;
169
+ return /*#__PURE__*/React.createElement(_page.Page, {
170
+ key: i,
171
+ getPageSrc: getImageUrl,
172
+ pageIndex: i,
173
+ zoom: zoom,
174
+ defaultDimensions: documentMetadata.defaultDimensions,
175
+ onVisible: i === lazyPageCount - 1 ? handleAppendAndLoadPageContent : loadPageContent,
176
+ onLoad: i === 0 ? onSuccess : undefined,
177
+ fonts: fonts,
178
+ content: page,
179
+ appendUpTo: appendUpTo
180
+ });
181
+ }));
182
+ };
183
+ var DocumentViewer = exports.DocumentViewer = function DocumentViewer(_ref3) {
184
+ var onSuccess = _ref3.onSuccess,
185
+ getContent = _ref3.getContent,
186
+ getPageImageUrl = _ref3.getPageImageUrl,
187
+ _ref3$paginationSize = _ref3.paginationSize,
188
+ paginationSize = _ref3$paginationSize === void 0 ? DEFAULT_PAGINATION_SIZE : _ref3$paginationSize,
189
+ zoom = _ref3.zoom,
190
+ _ref3$enableLazyPageR = _ref3.enableLazyPageRendering,
191
+ enableLazyPageRendering = _ref3$enableLazyPageR === void 0 ? false : _ref3$enableLazyPageR;
31
192
  var _usePageContent = (0, _usePageContent2.usePageContent)(getContent, paginationSize),
32
193
  getPageContent = _usePageContent.getPageContent,
33
194
  loadPageContent = _usePageContent.loadPageContent,
@@ -102,29 +263,17 @@ var DocumentViewer = exports.DocumentViewer = function DocumentViewer(_ref) {
102
263
  var onTouchEnd = (0, _react.useCallback)(function () {
103
264
  touchStartRef.current = null;
104
265
  }, []);
105
- return /*#__PURE__*/React.createElement("div", {
106
- "data-testid": "document-viewer",
266
+ var sharedProps = {
267
+ documentMetadata: documentMetadata,
268
+ getPageContent: getPageContent,
269
+ loadPageContent: loadPageContent,
270
+ getImageUrl: getImageUrl,
271
+ zoom: zoom,
272
+ onSuccess: onSuccess,
107
273
  style: style,
108
274
  onTouchStart: onTouchStart,
109
275
  onTouchMove: onTouchMove,
110
- onTouchEnd: onTouchEnd,
111
- className: (0, _runtime.ax)(["_zulputpp _1reo1wug _18m91wug _19pkxncg _1ul91osq _1e0c1txw _2lx21bp4 _1bsb1ris"])
112
- }, (0, _toConsumableArray2.default)(Array((_documentMetadata$pag = documentMetadata.pageCount) !== null && _documentMetadata$pag !== void 0 ? _documentMetadata$pag : 4)).map(function (_, i) {
113
- var _getPageContent = getPageContent(i),
114
- page = _getPageContent.page,
115
- fonts = _getPageContent.fonts;
116
- return /*#__PURE__*/React.createElement(_page.Page, {
117
- key: i,
118
- getPageSrc: getImageUrl,
119
- pageIndex: i,
120
- zoom: zoom,
121
- defaultDimensions: documentMetadata.defaultDimensions,
122
- onVisible: function onVisible() {
123
- return loadPageContent(i);
124
- },
125
- onLoad: i === 0 ? onSuccess : undefined,
126
- fonts: fonts,
127
- content: page
128
- });
129
- }));
276
+ onTouchEnd: onTouchEnd
277
+ };
278
+ return enableLazyPageRendering ? /*#__PURE__*/React.createElement(LazyAppendPages, sharedProps) : /*#__PURE__*/React.createElement(LegacyPages, sharedProps);
130
279
  };
package/dist/cjs/page.js CHANGED
@@ -81,7 +81,8 @@ var PageView = /*#__PURE__*/(0, _react.forwardRef)(function (_ref4, ref) {
81
81
  fonts = _ref4.fonts,
82
82
  pageIndex = _ref4.pageIndex,
83
83
  zoom = _ref4.zoom,
84
- onImageLoad = _ref4.onImageLoad;
84
+ onImageLoad = _ref4.onImageLoad,
85
+ appendUpTo = _ref4.appendUpTo;
85
86
  var style = {};
86
87
  if (dimensions) {
87
88
  // contents endpoint has loaded so dimensions are available
@@ -130,7 +131,8 @@ var PageView = /*#__PURE__*/(0, _react.forwardRef)(function (_ref4, ref) {
130
131
  }), content.annotations && /*#__PURE__*/React.createElement(_annotations.Annotations, {
131
132
  annotations: content.annotations
132
133
  }), content.links && /*#__PURE__*/React.createElement(_documentLinks.DocumentLinks, {
133
- links: content.links
134
+ links: content.links,
135
+ appendUpTo: appendUpTo
134
136
  })));
135
137
  });
136
138
  var Page = exports.Page = function Page(_ref5) {
@@ -142,7 +144,8 @@ var Page = exports.Page = function Page(_ref5) {
142
144
  zoom = _ref5.zoom,
143
145
  defaultDimensions = _ref5.defaultDimensions,
144
146
  onVisible = _ref5.onVisible,
145
- onLoad = _ref5.onLoad;
147
+ onLoad = _ref5.onLoad,
148
+ appendUpTo = _ref5.appendUpTo;
146
149
  var _useState = (0, _react.useState)(),
147
150
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
148
151
  imageSrc = _useState2[0],
@@ -154,7 +157,7 @@ var Page = exports.Page = function Page(_ref5) {
154
157
  rootMargin: '300%',
155
158
  threshold: 0.1
156
159
  }, function () {
157
- onVisible();
160
+ onVisible(pageIndex);
158
161
  getPageSrc(pageIndex, zoom).then(setImageSrc);
159
162
  }),
160
163
  observedRef = _useIntersectionObser.observedRef,
@@ -190,6 +193,7 @@ var Page = exports.Page = function Page(_ref5) {
190
193
  fonts: fonts,
191
194
  pageIndex: pageIndex,
192
195
  zoom: zoom,
193
- onImageLoad: onImageLoad
196
+ onImageLoad: onImageLoad,
197
+ appendUpTo: appendUpTo
194
198
  });
195
199
  };
@@ -12,7 +12,8 @@ const anchorStyles = {
12
12
  };
13
13
  const DocumentLink = ({
14
14
  link,
15
- dataTestId
15
+ dataTestId,
16
+ appendUpTo
16
17
  }) => {
17
18
  return /*#__PURE__*/React.createElement("foreignObject", {
18
19
  x: link.x,
@@ -27,15 +28,18 @@ const DocumentLink = ({
27
28
  style: anchorStyles
28
29
  })) : /*#__PURE__*/React.createElement(Anchor, _extends({}, foreignObjectProps, {
29
30
  href: `#page-${link.p_num + 1}`,
30
- style: anchorStyles
31
+ style: anchorStyles,
32
+ onClick: appendUpTo ? () => appendUpTo(link.p_num + 1) : undefined
31
33
  })));
32
34
  };
33
35
  export const DocumentLinks = ({
34
- links
36
+ links,
37
+ appendUpTo
35
38
  }) => {
36
39
  return /*#__PURE__*/React.createElement(React.Fragment, null, links.map((link, i) => /*#__PURE__*/React.createElement(DocumentLink, {
37
40
  link: link,
38
41
  dataTestId: `document-link-${i}`,
42
+ appendUpTo: appendUpTo,
39
43
  key: i
40
44
  })));
41
45
  };
@@ -2,7 +2,8 @@
2
2
  import "./documentViewer.compiled.css";
3
3
  import * as React from 'react';
4
4
  import { ax, ix } from "@compiled/react/runtime";
5
- import { useCallback, useLayoutEffect, useRef } from 'react';
5
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
6
+ import { getDocument } from '@atlaskit/browser-apis';
6
7
  import { useStaticCallback } from '@atlaskit/media-common';
7
8
  import { Page } from './page';
8
9
  import { usePageContent } from './usePageContent';
@@ -10,14 +11,165 @@ import { getScrollElement } from './utils/getDocumentRoot';
10
11
  import { useCachedGetImage } from './utils/useCachedGetImage';
11
12
  const documentViewerStyles = null;
12
13
  const DEFAULT_PAGINATION_SIZE = 50;
14
+ const INITIAL_PAGE_COUNT = 50;
15
+ const APPEND_STEP = 50;
16
+
17
+ /**
18
+ * TAIL-APPEND PATTERN FOR LAZY LOADING:
19
+ *
20
+ * The <Page> component has an `onVisible: () => void` prop that is called when the page
21
+ * enters the viewport (via useIntersectionObserver with a 300% rootMargin). This callback
22
+ * is currently used to load page content via `loadPageContent(i)`.
23
+ *
24
+ * For the LazyAppendPages feature (T2.3), the parent component can leverage this same
25
+ * mechanism by:
26
+ * 1. Rendering only a subset of pages (lazyPageCount instead of all documentMetadata.pageCount)
27
+ * 2. Passing onVisible={handleAppend} ONLY to the last rendered page (i === lazyPageCount - 1)
28
+ * 3. For all other pages, passing onVisible={() => loadPageContent(i)} as usual
29
+ *
30
+ * When the last page enters the viewport, handleAppend will be triggered, which can:
31
+ * - Fetch the next batch of pages
32
+ * - Append them to the rendered page list
33
+ * - This effectively creates a tail-append/infinite-scroll behavior without any changes to <Page>
34
+ *
35
+ * No changes to the <Page> signature are required. The onVisible callback is already
36
+ * properly wired and can be overridden by parent components for different behaviors.
37
+ */
38
+
39
+ const LegacyPages = ({
40
+ documentMetadata,
41
+ getPageContent,
42
+ loadPageContent,
43
+ getImageUrl,
44
+ zoom,
45
+ onSuccess,
46
+ style,
47
+ onTouchStart,
48
+ onTouchMove,
49
+ onTouchEnd
50
+ }) => {
51
+ var _documentMetadata$pag;
52
+ return /*#__PURE__*/React.createElement("div", {
53
+ "data-testid": "document-viewer",
54
+ style: style,
55
+ onTouchStart: onTouchStart,
56
+ onTouchMove: onTouchMove,
57
+ onTouchEnd: onTouchEnd,
58
+ className: ax(["_zulputpp _1reo1wug _18m91wug _19pkxncg _1ul91osq _1e0c1txw _2lx21bp4 _1bsb1ris"])
59
+ }, [...Array((_documentMetadata$pag = documentMetadata.pageCount) !== null && _documentMetadata$pag !== void 0 ? _documentMetadata$pag : 4)].map((_, i) => {
60
+ const {
61
+ page,
62
+ fonts
63
+ } = getPageContent(i);
64
+ return /*#__PURE__*/React.createElement(Page, {
65
+ key: i,
66
+ getPageSrc: getImageUrl,
67
+ pageIndex: i,
68
+ zoom: zoom,
69
+ defaultDimensions: documentMetadata.defaultDimensions,
70
+ onVisible: loadPageContent,
71
+ onLoad: i === 0 ? onSuccess : undefined,
72
+ fonts: fonts,
73
+ content: page
74
+ });
75
+ }));
76
+ };
77
+ const LazyAppendPages = ({
78
+ documentMetadata,
79
+ getPageContent,
80
+ loadPageContent,
81
+ getImageUrl,
82
+ zoom,
83
+ onSuccess,
84
+ style,
85
+ onTouchStart,
86
+ onTouchMove,
87
+ onTouchEnd
88
+ }) => {
89
+ var _documentMetadata$pag2;
90
+ const totalPages = (_documentMetadata$pag2 = documentMetadata.pageCount) !== null && _documentMetadata$pag2 !== void 0 ? _documentMetadata$pag2 : 4;
91
+ const [lazyPageCount, setLazyPageCount] = useState(() => Math.min(INITIAL_PAGE_COUNT, totalPages));
92
+
93
+ // lastAppendTriggerIndex deduplicates: only append when a strictly-larger
94
+ // tail page fires onVisible. This prevents double-append on scroll-up-then-down.
95
+ const lastAppendTriggerIndex = useRef(-1);
96
+
97
+ // Handle #page-N URL hash on first load: fast-forward lazyPageCount to include the target page.
98
+ // Capture totalPages in a ref so the one-shot effect can read it without being re-run when
99
+ // totalPages changes (the effect must only fire once, on mount).
100
+ const totalPagesRef = useRef(totalPages);
101
+ useEffect(() => {
102
+ const total = totalPagesRef.current;
103
+ const hash = window.location.hash;
104
+ const match = hash.match(/^#page-(\d+)$/);
105
+ if (match) {
106
+ const targetPage = parseInt(match[1], 10);
107
+ if (targetPage >= 1 && targetPage <= total) {
108
+ // Update dedup ref BEFORE setLazyPageCount so handleAppend does not
109
+ // cascade when the new tail page enters the viewport via IntersectionObserver.
110
+ lastAppendTriggerIndex.current = targetPage - 1;
111
+ // Fast-forward lazyPageCount to include the target page
112
+ setLazyPageCount(prev => Math.max(prev, targetPage));
113
+ // After the pages are mounted (next animation frame), scroll to the target
114
+ requestAnimationFrame(() => {
115
+ var _getDocument;
116
+ const el = (_getDocument = getDocument()) === null || _getDocument === void 0 ? void 0 : _getDocument.getElementById(`page-${targetPage}`);
117
+ if (el) {
118
+ el.scrollIntoView();
119
+ }
120
+ });
121
+ }
122
+ }
123
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps -- intentionally one-shot; totalPages read via ref
124
+
125
+ const handleAppendAndLoadPageContent = useCallback(pageIndex => {
126
+ if (pageIndex > lastAppendTriggerIndex.current) {
127
+ lastAppendTriggerIndex.current = pageIndex;
128
+ setLazyPageCount(c => Math.min(c + APPEND_STEP, totalPages));
129
+ }
130
+ loadPageContent(pageIndex);
131
+ }, [totalPages, loadPageContent]);
132
+ const appendUpTo = useCallback(targetPage => {
133
+ const clamped = Math.min(Math.max(targetPage, 0), totalPages);
134
+ if (clamped > lastAppendTriggerIndex.current) {
135
+ lastAppendTriggerIndex.current = clamped - 1;
136
+ setLazyPageCount(prev => Math.max(prev, clamped));
137
+ }
138
+ }, [totalPages]);
139
+ return /*#__PURE__*/React.createElement("div", {
140
+ "data-testid": "document-viewer",
141
+ style: style,
142
+ onTouchStart: onTouchStart,
143
+ onTouchMove: onTouchMove,
144
+ onTouchEnd: onTouchEnd,
145
+ className: ax(["_zulputpp _1reo1wug _18m91wug _19pkxncg _1ul91osq _1e0c1txw _2lx21bp4 _1bsb1ris"])
146
+ }, [...Array(lazyPageCount)].map((_, i) => {
147
+ const {
148
+ page,
149
+ fonts
150
+ } = getPageContent(i);
151
+ return /*#__PURE__*/React.createElement(Page, {
152
+ key: i,
153
+ getPageSrc: getImageUrl,
154
+ pageIndex: i,
155
+ zoom: zoom,
156
+ defaultDimensions: documentMetadata.defaultDimensions,
157
+ onVisible: i === lazyPageCount - 1 ? handleAppendAndLoadPageContent : loadPageContent,
158
+ onLoad: i === 0 ? onSuccess : undefined,
159
+ fonts: fonts,
160
+ content: page,
161
+ appendUpTo: appendUpTo
162
+ });
163
+ }));
164
+ };
13
165
  export const DocumentViewer = ({
14
166
  onSuccess,
15
167
  getContent,
16
168
  getPageImageUrl,
17
169
  paginationSize = DEFAULT_PAGINATION_SIZE,
18
- zoom
170
+ zoom,
171
+ enableLazyPageRendering = false
19
172
  }) => {
20
- var _documentMetadata$pag;
21
173
  const {
22
174
  getPageContent,
23
175
  loadPageContent,
@@ -93,28 +245,17 @@ export const DocumentViewer = ({
93
245
  const onTouchEnd = useCallback(() => {
94
246
  touchStartRef.current = null;
95
247
  }, []);
96
- return /*#__PURE__*/React.createElement("div", {
97
- "data-testid": "document-viewer",
98
- style: style,
99
- onTouchStart: onTouchStart,
100
- onTouchMove: onTouchMove,
101
- onTouchEnd: onTouchEnd,
102
- className: ax(["_zulputpp _1reo1wug _18m91wug _19pkxncg _1ul91osq _1e0c1txw _2lx21bp4 _1bsb1ris"])
103
- }, [...Array((_documentMetadata$pag = documentMetadata.pageCount) !== null && _documentMetadata$pag !== void 0 ? _documentMetadata$pag : 4)].map((_, i) => {
104
- const {
105
- page,
106
- fonts
107
- } = getPageContent(i);
108
- return /*#__PURE__*/React.createElement(Page, {
109
- key: i,
110
- getPageSrc: getImageUrl,
111
- pageIndex: i,
112
- zoom: zoom,
113
- defaultDimensions: documentMetadata.defaultDimensions,
114
- onVisible: () => loadPageContent(i),
115
- onLoad: i === 0 ? onSuccess : undefined,
116
- fonts: fonts,
117
- content: page
118
- });
119
- }));
248
+ const sharedProps = {
249
+ documentMetadata,
250
+ getPageContent,
251
+ loadPageContent,
252
+ getImageUrl,
253
+ zoom,
254
+ onSuccess,
255
+ style,
256
+ onTouchStart,
257
+ onTouchMove,
258
+ onTouchEnd
259
+ };
260
+ return enableLazyPageRendering ? /*#__PURE__*/React.createElement(LazyAppendPages, sharedProps) : /*#__PURE__*/React.createElement(LegacyPages, sharedProps);
120
261
  };
@@ -70,7 +70,8 @@ const PageView = /*#__PURE__*/forwardRef(({
70
70
  fonts,
71
71
  pageIndex,
72
72
  zoom,
73
- onImageLoad
73
+ onImageLoad,
74
+ appendUpTo
74
75
  }, ref) => {
75
76
  const style = {};
76
77
  if (dimensions) {
@@ -118,7 +119,8 @@ const PageView = /*#__PURE__*/forwardRef(({
118
119
  })), content.annotations && /*#__PURE__*/React.createElement(Annotations, {
119
120
  annotations: content.annotations
120
121
  }), content.links && /*#__PURE__*/React.createElement(DocumentLinks, {
121
- links: content.links
122
+ links: content.links,
123
+ appendUpTo: appendUpTo
122
124
  })));
123
125
  });
124
126
  export const Page = ({
@@ -129,7 +131,8 @@ export const Page = ({
129
131
  zoom,
130
132
  defaultDimensions,
131
133
  onVisible,
132
- onLoad
134
+ onLoad,
135
+ appendUpTo
133
136
  }) => {
134
137
  var _ref;
135
138
  const [imageSrc, setImageSrc] = useState();
@@ -143,7 +146,7 @@ export const Page = ({
143
146
  rootMargin: '300%',
144
147
  threshold: 0.1
145
148
  }, () => {
146
- onVisible();
149
+ onVisible(pageIndex);
147
150
  getPageSrc(pageIndex, zoom).then(setImageSrc);
148
151
  });
149
152
  const [dimensions, setDimensions] = useState();
@@ -174,6 +177,7 @@ export const Page = ({
174
177
  fonts: fonts,
175
178
  pageIndex: pageIndex,
176
179
  zoom: zoom,
177
- onImageLoad: onImageLoad
180
+ onImageLoad: onImageLoad,
181
+ appendUpTo: appendUpTo
178
182
  });
179
183
  };
@@ -12,7 +12,8 @@ var anchorStyles = {
12
12
  };
13
13
  var DocumentLink = function DocumentLink(_ref) {
14
14
  var link = _ref.link,
15
- dataTestId = _ref.dataTestId;
15
+ dataTestId = _ref.dataTestId,
16
+ appendUpTo = _ref.appendUpTo;
16
17
  return /*#__PURE__*/React.createElement("foreignObject", {
17
18
  x: link.x,
18
19
  y: -link.y,
@@ -26,15 +27,20 @@ var DocumentLink = function DocumentLink(_ref) {
26
27
  style: anchorStyles
27
28
  })) : /*#__PURE__*/React.createElement(Anchor, _extends({}, foreignObjectProps, {
28
29
  href: "#page-".concat(link.p_num + 1),
29
- style: anchorStyles
30
+ style: anchorStyles,
31
+ onClick: appendUpTo ? function () {
32
+ return appendUpTo(link.p_num + 1);
33
+ } : undefined
30
34
  })));
31
35
  };
32
36
  export var DocumentLinks = function DocumentLinks(_ref2) {
33
- var links = _ref2.links;
37
+ var links = _ref2.links,
38
+ appendUpTo = _ref2.appendUpTo;
34
39
  return /*#__PURE__*/React.createElement(React.Fragment, null, links.map(function (link, i) {
35
40
  return /*#__PURE__*/React.createElement(DocumentLink, {
36
41
  link: link,
37
42
  dataTestId: "document-link-".concat(i),
43
+ appendUpTo: appendUpTo,
38
44
  key: i
39
45
  });
40
46
  }));
@@ -1,9 +1,11 @@
1
1
  /* documentViewer.tsx generated by @compiled/babel-plugin v0.39.1 */
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
3
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
4
  import "./documentViewer.compiled.css";
4
5
  import * as React from 'react';
5
6
  import { ax, ix } from "@compiled/react/runtime";
6
- import { useCallback, useLayoutEffect, useRef } from 'react';
7
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
8
+ import { getDocument } from '@atlaskit/browser-apis';
7
9
  import { useStaticCallback } from '@atlaskit/media-common';
8
10
  import { Page } from './page';
9
11
  import { usePageContent } from './usePageContent';
@@ -11,14 +13,173 @@ import { getScrollElement } from './utils/getDocumentRoot';
11
13
  import { useCachedGetImage } from './utils/useCachedGetImage';
12
14
  var documentViewerStyles = null;
13
15
  var DEFAULT_PAGINATION_SIZE = 50;
14
- export var DocumentViewer = function DocumentViewer(_ref) {
16
+ var INITIAL_PAGE_COUNT = 50;
17
+ var APPEND_STEP = 50;
18
+
19
+ /**
20
+ * TAIL-APPEND PATTERN FOR LAZY LOADING:
21
+ *
22
+ * The <Page> component has an `onVisible: () => void` prop that is called when the page
23
+ * enters the viewport (via useIntersectionObserver with a 300% rootMargin). This callback
24
+ * is currently used to load page content via `loadPageContent(i)`.
25
+ *
26
+ * For the LazyAppendPages feature (T2.3), the parent component can leverage this same
27
+ * mechanism by:
28
+ * 1. Rendering only a subset of pages (lazyPageCount instead of all documentMetadata.pageCount)
29
+ * 2. Passing onVisible={handleAppend} ONLY to the last rendered page (i === lazyPageCount - 1)
30
+ * 3. For all other pages, passing onVisible={() => loadPageContent(i)} as usual
31
+ *
32
+ * When the last page enters the viewport, handleAppend will be triggered, which can:
33
+ * - Fetch the next batch of pages
34
+ * - Append them to the rendered page list
35
+ * - This effectively creates a tail-append/infinite-scroll behavior without any changes to <Page>
36
+ *
37
+ * No changes to the <Page> signature are required. The onVisible callback is already
38
+ * properly wired and can be overridden by parent components for different behaviors.
39
+ */
40
+
41
+ var LegacyPages = function LegacyPages(_ref) {
15
42
  var _documentMetadata$pag;
16
- var onSuccess = _ref.onSuccess,
17
- getContent = _ref.getContent,
18
- getPageImageUrl = _ref.getPageImageUrl,
19
- _ref$paginationSize = _ref.paginationSize,
20
- paginationSize = _ref$paginationSize === void 0 ? DEFAULT_PAGINATION_SIZE : _ref$paginationSize,
21
- zoom = _ref.zoom;
43
+ var documentMetadata = _ref.documentMetadata,
44
+ getPageContent = _ref.getPageContent,
45
+ loadPageContent = _ref.loadPageContent,
46
+ getImageUrl = _ref.getImageUrl,
47
+ zoom = _ref.zoom,
48
+ onSuccess = _ref.onSuccess,
49
+ style = _ref.style,
50
+ onTouchStart = _ref.onTouchStart,
51
+ onTouchMove = _ref.onTouchMove,
52
+ onTouchEnd = _ref.onTouchEnd;
53
+ return /*#__PURE__*/React.createElement("div", {
54
+ "data-testid": "document-viewer",
55
+ style: style,
56
+ onTouchStart: onTouchStart,
57
+ onTouchMove: onTouchMove,
58
+ onTouchEnd: onTouchEnd,
59
+ className: ax(["_zulputpp _1reo1wug _18m91wug _19pkxncg _1ul91osq _1e0c1txw _2lx21bp4 _1bsb1ris"])
60
+ }, _toConsumableArray(Array((_documentMetadata$pag = documentMetadata.pageCount) !== null && _documentMetadata$pag !== void 0 ? _documentMetadata$pag : 4)).map(function (_, i) {
61
+ var _getPageContent = getPageContent(i),
62
+ page = _getPageContent.page,
63
+ fonts = _getPageContent.fonts;
64
+ return /*#__PURE__*/React.createElement(Page, {
65
+ key: i,
66
+ getPageSrc: getImageUrl,
67
+ pageIndex: i,
68
+ zoom: zoom,
69
+ defaultDimensions: documentMetadata.defaultDimensions,
70
+ onVisible: loadPageContent,
71
+ onLoad: i === 0 ? onSuccess : undefined,
72
+ fonts: fonts,
73
+ content: page
74
+ });
75
+ }));
76
+ };
77
+ var LazyAppendPages = function LazyAppendPages(_ref2) {
78
+ var _documentMetadata$pag2;
79
+ var documentMetadata = _ref2.documentMetadata,
80
+ getPageContent = _ref2.getPageContent,
81
+ loadPageContent = _ref2.loadPageContent,
82
+ getImageUrl = _ref2.getImageUrl,
83
+ zoom = _ref2.zoom,
84
+ onSuccess = _ref2.onSuccess,
85
+ style = _ref2.style,
86
+ onTouchStart = _ref2.onTouchStart,
87
+ onTouchMove = _ref2.onTouchMove,
88
+ onTouchEnd = _ref2.onTouchEnd;
89
+ var totalPages = (_documentMetadata$pag2 = documentMetadata.pageCount) !== null && _documentMetadata$pag2 !== void 0 ? _documentMetadata$pag2 : 4;
90
+ var _useState = useState(function () {
91
+ return Math.min(INITIAL_PAGE_COUNT, totalPages);
92
+ }),
93
+ _useState2 = _slicedToArray(_useState, 2),
94
+ lazyPageCount = _useState2[0],
95
+ setLazyPageCount = _useState2[1];
96
+
97
+ // lastAppendTriggerIndex deduplicates: only append when a strictly-larger
98
+ // tail page fires onVisible. This prevents double-append on scroll-up-then-down.
99
+ var lastAppendTriggerIndex = useRef(-1);
100
+
101
+ // Handle #page-N URL hash on first load: fast-forward lazyPageCount to include the target page.
102
+ // Capture totalPages in a ref so the one-shot effect can read it without being re-run when
103
+ // totalPages changes (the effect must only fire once, on mount).
104
+ var totalPagesRef = useRef(totalPages);
105
+ useEffect(function () {
106
+ var total = totalPagesRef.current;
107
+ var hash = window.location.hash;
108
+ var match = hash.match(/^#page-(\d+)$/);
109
+ if (match) {
110
+ var targetPage = parseInt(match[1], 10);
111
+ if (targetPage >= 1 && targetPage <= total) {
112
+ // Update dedup ref BEFORE setLazyPageCount so handleAppend does not
113
+ // cascade when the new tail page enters the viewport via IntersectionObserver.
114
+ lastAppendTriggerIndex.current = targetPage - 1;
115
+ // Fast-forward lazyPageCount to include the target page
116
+ setLazyPageCount(function (prev) {
117
+ return Math.max(prev, targetPage);
118
+ });
119
+ // After the pages are mounted (next animation frame), scroll to the target
120
+ requestAnimationFrame(function () {
121
+ var _getDocument;
122
+ var el = (_getDocument = getDocument()) === null || _getDocument === void 0 ? void 0 : _getDocument.getElementById("page-".concat(targetPage));
123
+ if (el) {
124
+ el.scrollIntoView();
125
+ }
126
+ });
127
+ }
128
+ }
129
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps -- intentionally one-shot; totalPages read via ref
130
+
131
+ var handleAppendAndLoadPageContent = useCallback(function (pageIndex) {
132
+ if (pageIndex > lastAppendTriggerIndex.current) {
133
+ lastAppendTriggerIndex.current = pageIndex;
134
+ setLazyPageCount(function (c) {
135
+ return Math.min(c + APPEND_STEP, totalPages);
136
+ });
137
+ }
138
+ loadPageContent(pageIndex);
139
+ }, [totalPages, loadPageContent]);
140
+ var appendUpTo = useCallback(function (targetPage) {
141
+ var clamped = Math.min(Math.max(targetPage, 0), totalPages);
142
+ if (clamped > lastAppendTriggerIndex.current) {
143
+ lastAppendTriggerIndex.current = clamped - 1;
144
+ setLazyPageCount(function (prev) {
145
+ return Math.max(prev, clamped);
146
+ });
147
+ }
148
+ }, [totalPages]);
149
+ return /*#__PURE__*/React.createElement("div", {
150
+ "data-testid": "document-viewer",
151
+ style: style,
152
+ onTouchStart: onTouchStart,
153
+ onTouchMove: onTouchMove,
154
+ onTouchEnd: onTouchEnd,
155
+ className: ax(["_zulputpp _1reo1wug _18m91wug _19pkxncg _1ul91osq _1e0c1txw _2lx21bp4 _1bsb1ris"])
156
+ }, _toConsumableArray(Array(lazyPageCount)).map(function (_, i) {
157
+ var _getPageContent2 = getPageContent(i),
158
+ page = _getPageContent2.page,
159
+ fonts = _getPageContent2.fonts;
160
+ return /*#__PURE__*/React.createElement(Page, {
161
+ key: i,
162
+ getPageSrc: getImageUrl,
163
+ pageIndex: i,
164
+ zoom: zoom,
165
+ defaultDimensions: documentMetadata.defaultDimensions,
166
+ onVisible: i === lazyPageCount - 1 ? handleAppendAndLoadPageContent : loadPageContent,
167
+ onLoad: i === 0 ? onSuccess : undefined,
168
+ fonts: fonts,
169
+ content: page,
170
+ appendUpTo: appendUpTo
171
+ });
172
+ }));
173
+ };
174
+ export var DocumentViewer = function DocumentViewer(_ref3) {
175
+ var onSuccess = _ref3.onSuccess,
176
+ getContent = _ref3.getContent,
177
+ getPageImageUrl = _ref3.getPageImageUrl,
178
+ _ref3$paginationSize = _ref3.paginationSize,
179
+ paginationSize = _ref3$paginationSize === void 0 ? DEFAULT_PAGINATION_SIZE : _ref3$paginationSize,
180
+ zoom = _ref3.zoom,
181
+ _ref3$enableLazyPageR = _ref3.enableLazyPageRendering,
182
+ enableLazyPageRendering = _ref3$enableLazyPageR === void 0 ? false : _ref3$enableLazyPageR;
22
183
  var _usePageContent = usePageContent(getContent, paginationSize),
23
184
  getPageContent = _usePageContent.getPageContent,
24
185
  loadPageContent = _usePageContent.loadPageContent,
@@ -93,29 +254,17 @@ export var DocumentViewer = function DocumentViewer(_ref) {
93
254
  var onTouchEnd = useCallback(function () {
94
255
  touchStartRef.current = null;
95
256
  }, []);
96
- return /*#__PURE__*/React.createElement("div", {
97
- "data-testid": "document-viewer",
257
+ var sharedProps = {
258
+ documentMetadata: documentMetadata,
259
+ getPageContent: getPageContent,
260
+ loadPageContent: loadPageContent,
261
+ getImageUrl: getImageUrl,
262
+ zoom: zoom,
263
+ onSuccess: onSuccess,
98
264
  style: style,
99
265
  onTouchStart: onTouchStart,
100
266
  onTouchMove: onTouchMove,
101
- onTouchEnd: onTouchEnd,
102
- className: ax(["_zulputpp _1reo1wug _18m91wug _19pkxncg _1ul91osq _1e0c1txw _2lx21bp4 _1bsb1ris"])
103
- }, _toConsumableArray(Array((_documentMetadata$pag = documentMetadata.pageCount) !== null && _documentMetadata$pag !== void 0 ? _documentMetadata$pag : 4)).map(function (_, i) {
104
- var _getPageContent = getPageContent(i),
105
- page = _getPageContent.page,
106
- fonts = _getPageContent.fonts;
107
- return /*#__PURE__*/React.createElement(Page, {
108
- key: i,
109
- getPageSrc: getImageUrl,
110
- pageIndex: i,
111
- zoom: zoom,
112
- defaultDimensions: documentMetadata.defaultDimensions,
113
- onVisible: function onVisible() {
114
- return loadPageContent(i);
115
- },
116
- onLoad: i === 0 ? onSuccess : undefined,
117
- fonts: fonts,
118
- content: page
119
- });
120
- }));
267
+ onTouchEnd: onTouchEnd
268
+ };
269
+ return enableLazyPageRendering ? /*#__PURE__*/React.createElement(LazyAppendPages, sharedProps) : /*#__PURE__*/React.createElement(LegacyPages, sharedProps);
121
270
  };
package/dist/esm/page.js CHANGED
@@ -72,7 +72,8 @@ var PageView = /*#__PURE__*/forwardRef(function (_ref4, ref) {
72
72
  fonts = _ref4.fonts,
73
73
  pageIndex = _ref4.pageIndex,
74
74
  zoom = _ref4.zoom,
75
- onImageLoad = _ref4.onImageLoad;
75
+ onImageLoad = _ref4.onImageLoad,
76
+ appendUpTo = _ref4.appendUpTo;
76
77
  var style = {};
77
78
  if (dimensions) {
78
79
  // contents endpoint has loaded so dimensions are available
@@ -121,7 +122,8 @@ var PageView = /*#__PURE__*/forwardRef(function (_ref4, ref) {
121
122
  }), content.annotations && /*#__PURE__*/React.createElement(Annotations, {
122
123
  annotations: content.annotations
123
124
  }), content.links && /*#__PURE__*/React.createElement(DocumentLinks, {
124
- links: content.links
125
+ links: content.links,
126
+ appendUpTo: appendUpTo
125
127
  })));
126
128
  });
127
129
  export var Page = function Page(_ref5) {
@@ -133,7 +135,8 @@ export var Page = function Page(_ref5) {
133
135
  zoom = _ref5.zoom,
134
136
  defaultDimensions = _ref5.defaultDimensions,
135
137
  onVisible = _ref5.onVisible,
136
- onLoad = _ref5.onLoad;
138
+ onLoad = _ref5.onLoad,
139
+ appendUpTo = _ref5.appendUpTo;
137
140
  var _useState = useState(),
138
141
  _useState2 = _slicedToArray(_useState, 2),
139
142
  imageSrc = _useState2[0],
@@ -145,7 +148,7 @@ export var Page = function Page(_ref5) {
145
148
  rootMargin: '300%',
146
149
  threshold: 0.1
147
150
  }, function () {
148
- onVisible();
151
+ onVisible(pageIndex);
149
152
  getPageSrc(pageIndex, zoom).then(setImageSrc);
150
153
  }),
151
154
  observedRef = _useIntersectionObser.observedRef,
@@ -181,6 +184,7 @@ export var Page = function Page(_ref5) {
181
184
  fonts: fonts,
182
185
  pageIndex: pageIndex,
183
186
  zoom: zoom,
184
- onImageLoad: onImageLoad
187
+ onImageLoad: onImageLoad,
188
+ appendUpTo: appendUpTo
185
189
  });
186
190
  };
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { type Link } from './types';
3
- export declare const DocumentLinks: ({ links }: {
3
+ export declare const DocumentLinks: ({ links, appendUpTo, }: {
4
4
  links: readonly Link[];
5
+ appendUpTo?: (n: number) => void;
5
6
  }) => React.JSX.Element;
@@ -13,5 +13,11 @@ export type DocumentViewerProps = {
13
13
  maxPageImageZoom?: number;
14
14
  zoom: number;
15
15
  onSuccess?: () => void;
16
+ /**
17
+ * When true, renders an initial batch of pages and appends more as the user scrolls.
18
+ * Intended for large documents (e.g. large Excel previews).
19
+ * Default: false.
20
+ */
21
+ enableLazyPageRendering?: boolean;
16
22
  };
17
- export declare const DocumentViewer: ({ onSuccess, getContent, getPageImageUrl, paginationSize, zoom, }: DocumentViewerProps) => JSX.Element;
23
+ export declare const DocumentViewer: ({ onSuccess, getContent, getPageImageUrl, paginationSize, zoom, enableLazyPageRendering, }: DocumentViewerProps) => JSX.Element;
@@ -9,8 +9,15 @@ type PageProps = {
9
9
  width: number;
10
10
  height: number;
11
11
  };
12
- onVisible: () => void;
12
+ onVisible: (pageIndex: number) => void;
13
13
  onLoad?: () => void;
14
+ /**
15
+ * Called when a local `#page-N` anchor inside this page is clicked.
16
+ * Fast-forwards the lazy page count so the target page exists in the DOM
17
+ * before the browser performs the native anchor scroll.
18
+ * Only provided when `enableLazyPageRendering` is true.
19
+ */
20
+ appendUpTo?: (n: number) => void;
14
21
  };
15
- export declare const Page: ({ getPageSrc, content, fonts, pageIndex, zoom, defaultDimensions, onVisible, onLoad, }: PageProps) => JSX.Element;
22
+ export declare const Page: ({ getPageSrc, content, fonts, pageIndex, zoom, defaultDimensions, onVisible, onLoad, appendUpTo, }: PageProps) => JSX.Element;
16
23
  export {};
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { type Link } from './types';
3
- export declare const DocumentLinks: ({ links }: {
3
+ export declare const DocumentLinks: ({ links, appendUpTo, }: {
4
4
  links: readonly Link[];
5
+ appendUpTo?: (n: number) => void;
5
6
  }) => React.JSX.Element;
@@ -13,5 +13,11 @@ export type DocumentViewerProps = {
13
13
  maxPageImageZoom?: number;
14
14
  zoom: number;
15
15
  onSuccess?: () => void;
16
+ /**
17
+ * When true, renders an initial batch of pages and appends more as the user scrolls.
18
+ * Intended for large documents (e.g. large Excel previews).
19
+ * Default: false.
20
+ */
21
+ enableLazyPageRendering?: boolean;
16
22
  };
17
- export declare const DocumentViewer: ({ onSuccess, getContent, getPageImageUrl, paginationSize, zoom, }: DocumentViewerProps) => JSX.Element;
23
+ export declare const DocumentViewer: ({ onSuccess, getContent, getPageImageUrl, paginationSize, zoom, enableLazyPageRendering, }: DocumentViewerProps) => JSX.Element;
@@ -9,8 +9,15 @@ type PageProps = {
9
9
  width: number;
10
10
  height: number;
11
11
  };
12
- onVisible: () => void;
12
+ onVisible: (pageIndex: number) => void;
13
13
  onLoad?: () => void;
14
+ /**
15
+ * Called when a local `#page-N` anchor inside this page is clicked.
16
+ * Fast-forwards the lazy page count so the target page exists in the DOM
17
+ * before the browser performs the native anchor scroll.
18
+ * Only provided when `enableLazyPageRendering` is true.
19
+ */
20
+ appendUpTo?: (n: number) => void;
14
21
  };
15
- export declare const Page: ({ getPageSrc, content, fonts, pageIndex, zoom, defaultDimensions, onVisible, onLoad, }: PageProps) => JSX.Element;
22
+ export declare const Page: ({ getPageSrc, content, fonts, pageIndex, zoom, defaultDimensions, onVisible, onLoad, appendUpTo, }: PageProps) => JSX.Element;
16
23
  export {};
package/package.json CHANGED
@@ -1,5 +1,12 @@
1
1
  {
2
2
  "atlassian": {
3
+ "react-compiler": {
4
+ "enabled": true,
5
+ "gating": {
6
+ "source": "@atlassian/react-compiler-gating",
7
+ "importSpecifierName": "isReactCompilerActivePlatform"
8
+ }
9
+ },
3
10
  "team": "Media Exif",
4
11
  "website": {
5
12
  "name": "MediaDocumentViewer",
@@ -26,7 +33,7 @@
26
33
  "dependencies": {
27
34
  "@atlaskit/browser-apis": "^0.0.1",
28
35
  "@atlaskit/css": "^0.19.0",
29
- "@atlaskit/media-common": "^13.0.0",
36
+ "@atlaskit/media-common": "^13.3.0",
30
37
  "@atlaskit/primitives": "^19.0.0",
31
38
  "@atlaskit/spinner": "^19.1.0",
32
39
  "@atlaskit/tokens": "^13.0.0",
@@ -41,7 +48,8 @@
41
48
  "@af/visual-regression": "workspace:^",
42
49
  "@atlaskit/ssr": "workspace:^",
43
50
  "@atlassian/a11y-jest-testing": "^0.11.0",
44
- "@atlassian/feature-flags-test-utils": "^1.0.0",
51
+ "@atlassian/feature-flags-test-utils": "^1.1.0",
52
+ "@atlassian/react-compiler-gating": "workspace:^",
45
53
  "@testing-library/react": "^16.3.0",
46
54
  "@testing-library/user-event": "^14.4.3",
47
55
  "react-dom": "^18.2.0"
@@ -82,7 +90,7 @@
82
90
  }
83
91
  },
84
92
  "name": "@atlaskit/media-document-viewer",
85
- "version": "0.6.11",
93
+ "version": "0.7.1",
86
94
  "description": "Modern and fast document viewer",
87
95
  "author": "Atlassian Pty Ltd",
88
96
  "license": "Apache-2.0",