@hypercard-ai/hyper-jump 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -31,28 +31,60 @@ function App() {
31
31
  }
32
32
  ```
33
33
 
34
- ### Jump to a specific page
34
+ ### Open a PDF at a specific page
35
35
 
36
- Pass a zero-indexed `page` prop to scroll directly to a page:
36
+ Pass a zero-indexed `initialPage` to start at a specific page when the document loads:
37
37
 
38
38
  ```tsx
39
- <HyperJumpViewer url="/path/to/document.pdf" page={3} />
39
+ <HyperJumpViewer url="/path/to/document.pdf" initialPage={3} />
40
+ ```
41
+
42
+ ### Jump to a page imperatively
43
+
44
+ Use a ref to jump to any page at any time — ideal for navigating to RAG citations:
45
+
46
+ ```tsx
47
+ import { useRef } from "react";
48
+ import { HyperJumpViewer, type HyperJumpViewerAPI } from "@hypercard-ai/hyper-jump";
49
+ import "@hypercard-ai/hyper-jump/styles.css";
50
+
51
+ function App() {
52
+ const viewerRef = useRef<HyperJumpViewerAPI>(null);
53
+
54
+ return (
55
+ <>
56
+ <button onClick={() => viewerRef.current?.jumpToPage(5)}>
57
+ Go to page 6
58
+ </button>
59
+ <HyperJumpViewer url="/path/to/document.pdf" ref={viewerRef} />
60
+ </>
61
+ );
62
+ }
40
63
  ```
41
64
 
42
65
  ## API
43
66
 
44
67
  ### `<HyperJumpViewer />`
45
68
 
46
- | Prop | Type | Required | Description |
47
- | ------ | -------- | -------- | ----------------------------------- |
48
- | `url` | `string` | Yes | URL or path to the PDF file |
49
- | `page` | `number` | No | Zero-indexed page to scroll to |
69
+ | Prop | Type | Required | Description |
70
+ | -------------- | ----------------------------- | -------- | -------------------------------------------------- |
71
+ | `url` | `string` | Yes | URL or path to the PDF file |
72
+ | `initialPage` | `number` | No | Zero-indexed page to show when the document loads |
73
+ | `onPageChange` | `(page: number) => void` | No | Called when the visible page changes (zero-indexed) |
74
+ | `ref` | `Ref<HyperJumpViewerAPI>` | No | Ref exposing imperative `jumpToPage` method |
75
+
76
+ ### `HyperJumpViewerAPI`
77
+
78
+ | Method | Description |
79
+ | --------------------------- | ---------------------------------------------------- |
80
+ | `jumpToPage(page: number)` | Scroll to a zero-indexed page. Clamps to valid range.|
50
81
 
51
82
  ### Exports
52
83
 
53
84
  | Export | Type | Description |
54
85
  | ----------------------- | --------- | ------------------------------------ |
55
86
  | `HyperJumpViewer` | Component | The PDF viewer component |
87
+ | `HyperJumpViewerAPI` | Type | Imperative API exposed via ref |
56
88
  | `HyperJumpViewerProps` | Type | Props for the viewer component |
57
89
  | `ZoomConfig` | Type | Zoom configuration interface |
58
90
 
package/dist/index.css CHANGED
@@ -21,8 +21,9 @@
21
21
  display: flex;
22
22
  align-items: center;
23
23
  justify-content: center;
24
+ width: 100%;
25
+ height: 100%;
24
26
  background: #fff;
25
- position: relative;
26
27
  }
27
28
  .hj-spinner {
28
29
  width: 32px;
@@ -41,6 +42,8 @@
41
42
  display: flex;
42
43
  align-items: center;
43
44
  justify-content: center;
45
+ width: 100%;
46
+ height: 100%;
44
47
  background: #fff;
45
48
  color: #495057;
46
49
  font-size: 14px;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/styles.css"],"sourcesContent":["/* HyperJump PDF Viewer Styles */\n\n.hj-viewer {\n\tposition: relative;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\theight: 100%;\n\twidth: 100%;\n\toverflow: hidden;\n}\n\n.hj-viewer .react-pdf__Document {\n\theight: 100%;\n\twidth: 100%;\n}\n\n/* Page renderer */\n.hj-page {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n/* Loading page */\n.hj-loading {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground: #fff;\n\tposition: relative;\n}\n\n.hj-spinner {\n\twidth: 32px;\n\theight: 32px;\n\tborder: 3px solid #e9ecef;\n\tborder-top-color: #228be6;\n\tborder-radius: 50%;\n\tanimation: hj-spin 0.6s linear infinite;\n}\n\n@keyframes hj-spin {\n\tto {\n\t\ttransform: rotate(360deg);\n\t}\n}\n\n/* Error page */\n.hj-error {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground: #fff;\n\tcolor: #495057;\n\tfont-size: 14px;\n}\n\n/* Controls */\n.hj-controls {\n\tposition: absolute;\n\tbottom: 12px;\n\tleft: 12px;\n\tright: 12px;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tz-index: 10;\n}\n\n.hj-controls-bar {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tpadding: 6px 12px;\n\tbackground: #fff;\n\tborder: 1px solid #dee2e6;\n\tborder-radius: 8px;\n\tbox-shadow:\n\t\t0 1px 3px rgba(0, 0, 0, 0.1),\n\t\t0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n.hj-controls-group {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n}\n\n.hj-divider {\n\twidth: 1px;\n\theight: 24px;\n\tbackground: #dee2e6;\n}\n\n.hj-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 4px 12px;\n\tfont-size: 13px;\n\tfont-family: inherit;\n\tline-height: 1.4;\n\tborder: 1px solid #dee2e6;\n\tborder-radius: 4px;\n\tbackground: #fff;\n\tcolor: #212529;\n\tcursor: pointer;\n\tuser-select: none;\n\twhite-space: nowrap;\n}\n\n.hj-btn:hover:not(:disabled) {\n\tbackground: #f8f9fa;\n}\n\n.hj-btn:disabled {\n\topacity: 0.5;\n\tcursor: not-allowed;\n}\n\n.hj-icon-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 28px;\n\theight: 28px;\n\tpadding: 0;\n\tborder: 1px solid #dee2e6;\n\tborder-radius: 4px;\n\tbackground: #fff;\n\tcolor: #212529;\n\tcursor: pointer;\n}\n\n.hj-icon-btn:hover:not(:disabled) {\n\tbackground: #f8f9fa;\n}\n\n.hj-icon-btn:disabled {\n\topacity: 0.5;\n\tcursor: not-allowed;\n}\n\n.hj-page-indicator {\n\tfont-size: 13px;\n\tmin-width: 50px;\n\ttext-align: center;\n\tcolor: #212529;\n\tuser-select: none;\n}\n\n.hj-select {\n\tfont-size: 13px;\n\tfont-family: inherit;\n\tpadding: 4px 8px;\n\tborder: 1px solid #dee2e6;\n\tborder-radius: 4px;\n\tbackground: #fff;\n\tcolor: #212529;\n\tcursor: pointer;\n\tmin-width: 120px;\n}\n\n.hj-select:focus {\n\toutline: 2px solid #228be6;\n\toutline-offset: -1px;\n}\n"],"mappings":";AAEA,CAAC;AACA,YAAU;AACV,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,UAAQ;AACR,SAAO;AACP,YAAU;AACX;AAEA,CAVC,UAUU,CAAC;AACX,UAAQ;AACR,SAAO;AACR;AAGA,CAAC;AACA,WAAS;AACT,eAAa;AACb,mBAAiB;AAClB;AAGA,CAAC;AACA,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,cAAY;AACZ,YAAU;AACX;AAEA,CAAC;AACA,SAAO;AACP,UAAQ;AACR,UAAQ,IAAI,MAAM;AAClB,oBAAkB;AAClB,iBAAe;AACf,aAAW,QAAQ,KAAK,OAAO;AAChC;AAEA,WAHY;AAIX;AACC,eAAW,OAAO;AACnB;AACD;AAGA,CAAC;AACA,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,cAAY;AACZ,SAAO;AACP,aAAW;AACZ;AAGA,CAAC;AACA,YAAU;AACV,UAAQ;AACR,QAAM;AACN,SAAO;AACP,WAAS;AACT,mBAAiB;AACjB,eAAa;AACb,WAAS;AACV;AAEA,CAAC;AACA,WAAS;AACT,eAAa;AACb,OAAK;AACL,WAAS,IAAI;AACb,cAAY;AACZ,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACf,cACC,EAAE,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAC5B,EAAE,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAC1B;AAEA,CAAC;AACA,WAAS;AACT,eAAa;AACb,OAAK;AACN;AAEA,CAAC;AACA,SAAO;AACP,UAAQ;AACR,cAAY;AACb;AAEA,CAAC;AACA,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,eAAa;AACb,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACf,cAAY;AACZ,SAAO;AACP,UAAQ;AACR,eAAa;AACb,eAAa;AACd;AAEA,CAjBC,MAiBM,MAAM,KAAK;AACjB,cAAY;AACb;AAEA,CArBC,MAqBM;AACN,WAAS;AACT,UAAQ;AACT;AAEA,CAAC;AACA,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,SAAO;AACP,UAAQ;AACR,WAAS;AACT,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACf,cAAY;AACZ,SAAO;AACP,UAAQ;AACT;AAEA,CAdC,WAcW,MAAM,KAAK;AACtB,cAAY;AACb;AAEA,CAlBC,WAkBW;AACX,WAAS;AACT,UAAQ;AACT;AAEA,CAAC;AACA,aAAW;AACX,aAAW;AACX,cAAY;AACZ,SAAO;AACP,eAAa;AACd;AAEA,CAAC;AACA,aAAW;AACX,eAAa;AACb,WAAS,IAAI;AACb,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACf,cAAY;AACZ,SAAO;AACP,UAAQ;AACR,aAAW;AACZ;AAEA,CAZC,SAYS;AACT,WAAS,IAAI,MAAM;AACnB,kBAAgB;AACjB;","names":[]}
1
+ {"version":3,"sources":["../src/styles.css"],"sourcesContent":["/* HyperJump PDF Viewer Styles */\n\n.hj-viewer {\n\tposition: relative;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\theight: 100%;\n\twidth: 100%;\n\toverflow: hidden;\n}\n\n.hj-viewer .react-pdf__Document {\n\theight: 100%;\n\twidth: 100%;\n}\n\n/* Page renderer */\n.hj-page {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n/* Loading page */\n.hj-loading {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 100%;\n\theight: 100%;\n\tbackground: #fff;\n}\n\n.hj-spinner {\n\twidth: 32px;\n\theight: 32px;\n\tborder: 3px solid #e9ecef;\n\tborder-top-color: #228be6;\n\tborder-radius: 50%;\n\tanimation: hj-spin 0.6s linear infinite;\n}\n\n@keyframes hj-spin {\n\tto {\n\t\ttransform: rotate(360deg);\n\t}\n}\n\n/* Error page */\n.hj-error {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 100%;\n\theight: 100%;\n\tbackground: #fff;\n\tcolor: #495057;\n\tfont-size: 14px;\n}\n\n/* Controls */\n.hj-controls {\n\tposition: absolute;\n\tbottom: 12px;\n\tleft: 12px;\n\tright: 12px;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tz-index: 10;\n}\n\n.hj-controls-bar {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tpadding: 6px 12px;\n\tbackground: #fff;\n\tborder: 1px solid #dee2e6;\n\tborder-radius: 8px;\n\tbox-shadow:\n\t\t0 1px 3px rgba(0, 0, 0, 0.1),\n\t\t0 1px 2px rgba(0, 0, 0, 0.06);\n}\n\n.hj-controls-group {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n}\n\n.hj-divider {\n\twidth: 1px;\n\theight: 24px;\n\tbackground: #dee2e6;\n}\n\n.hj-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 4px 12px;\n\tfont-size: 13px;\n\tfont-family: inherit;\n\tline-height: 1.4;\n\tborder: 1px solid #dee2e6;\n\tborder-radius: 4px;\n\tbackground: #fff;\n\tcolor: #212529;\n\tcursor: pointer;\n\tuser-select: none;\n\twhite-space: nowrap;\n}\n\n.hj-btn:hover:not(:disabled) {\n\tbackground: #f8f9fa;\n}\n\n.hj-btn:disabled {\n\topacity: 0.5;\n\tcursor: not-allowed;\n}\n\n.hj-icon-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 28px;\n\theight: 28px;\n\tpadding: 0;\n\tborder: 1px solid #dee2e6;\n\tborder-radius: 4px;\n\tbackground: #fff;\n\tcolor: #212529;\n\tcursor: pointer;\n}\n\n.hj-icon-btn:hover:not(:disabled) {\n\tbackground: #f8f9fa;\n}\n\n.hj-icon-btn:disabled {\n\topacity: 0.5;\n\tcursor: not-allowed;\n}\n\n.hj-page-indicator {\n\tfont-size: 13px;\n\tmin-width: 50px;\n\ttext-align: center;\n\tcolor: #212529;\n\tuser-select: none;\n}\n\n.hj-select {\n\tfont-size: 13px;\n\tfont-family: inherit;\n\tpadding: 4px 8px;\n\tborder: 1px solid #dee2e6;\n\tborder-radius: 4px;\n\tbackground: #fff;\n\tcolor: #212529;\n\tcursor: pointer;\n\tmin-width: 120px;\n}\n\n.hj-select:focus {\n\toutline: 2px solid #228be6;\n\toutline-offset: -1px;\n}\n"],"mappings":";AAEA,CAAC;AACA,YAAU;AACV,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,UAAQ;AACR,SAAO;AACP,YAAU;AACX;AAEA,CAVC,UAUU,CAAC;AACX,UAAQ;AACR,SAAO;AACR;AAGA,CAAC;AACA,WAAS;AACT,eAAa;AACb,mBAAiB;AAClB;AAGA,CAAC;AACA,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,SAAO;AACP,UAAQ;AACR,cAAY;AACb;AAEA,CAAC;AACA,SAAO;AACP,UAAQ;AACR,UAAQ,IAAI,MAAM;AAClB,oBAAkB;AAClB,iBAAe;AACf,aAAW,QAAQ,KAAK,OAAO;AAChC;AAEA,WAHY;AAIX;AACC,eAAW,OAAO;AACnB;AACD;AAGA,CAAC;AACA,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,SAAO;AACP,UAAQ;AACR,cAAY;AACZ,SAAO;AACP,aAAW;AACZ;AAGA,CAAC;AACA,YAAU;AACV,UAAQ;AACR,QAAM;AACN,SAAO;AACP,WAAS;AACT,mBAAiB;AACjB,eAAa;AACb,WAAS;AACV;AAEA,CAAC;AACA,WAAS;AACT,eAAa;AACb,OAAK;AACL,WAAS,IAAI;AACb,cAAY;AACZ,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACf,cACC,EAAE,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAC5B,EAAE,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AAC1B;AAEA,CAAC;AACA,WAAS;AACT,eAAa;AACb,OAAK;AACN;AAEA,CAAC;AACA,SAAO;AACP,UAAQ;AACR,cAAY;AACb;AAEA,CAAC;AACA,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,WAAS,IAAI;AACb,aAAW;AACX,eAAa;AACb,eAAa;AACb,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACf,cAAY;AACZ,SAAO;AACP,UAAQ;AACR,eAAa;AACb,eAAa;AACd;AAEA,CAjBC,MAiBM,MAAM,KAAK;AACjB,cAAY;AACb;AAEA,CArBC,MAqBM;AACN,WAAS;AACT,UAAQ;AACT;AAEA,CAAC;AACA,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,SAAO;AACP,UAAQ;AACR,WAAS;AACT,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACf,cAAY;AACZ,SAAO;AACP,UAAQ;AACT;AAEA,CAdC,WAcW,MAAM,KAAK;AACtB,cAAY;AACb;AAEA,CAlBC,WAkBW;AACX,WAAS;AACT,UAAQ;AACT;AAEA,CAAC;AACA,aAAW;AACX,aAAW;AACX,cAAY;AACZ,SAAO;AACP,eAAa;AACd;AAEA,CAAC;AACA,aAAW;AACX,eAAa;AACb,WAAS,IAAI;AACb,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACf,cAAY;AACZ,SAAO;AACP,UAAQ;AACR,aAAW;AACZ;AAEA,CAZC,SAYS;AACT,WAAS,IAAI,MAAM;AACnB,kBAAgB;AACjB;","names":[]}
package/dist/index.d.ts CHANGED
@@ -6,14 +6,20 @@ interface ZoomConfig {
6
6
  value: number;
7
7
  }
8
8
 
9
+ interface HyperJumpViewerAPI {
10
+ /** Imperatively scroll to a page (0-indexed). Clamps to valid range. */
11
+ jumpToPage: (page: number) => void;
12
+ }
9
13
  interface HyperJumpViewerProps {
10
14
  /** URL of the PDF file to display */
11
15
  url: string;
12
- /** Page number to jump to (0-indexed) */
13
- page?: number;
16
+ /** Page to show when the document first loads (0-indexed) */
17
+ initialPage?: number;
14
18
  /** Called when the visible page changes (0-indexed) */
15
19
  onPageChange?: (page: number) => void;
20
+ /** Ref exposing imperative jumpToPage method */
21
+ ref?: React.Ref<HyperJumpViewerAPI>;
16
22
  }
17
23
  declare function HyperJumpViewer(props: HyperJumpViewerProps): react_jsx_runtime.JSX.Element;
18
24
 
19
- export { HyperJumpViewer, type HyperJumpViewerProps, type ZoomConfig };
25
+ export { HyperJumpViewer, type HyperJumpViewerAPI, type HyperJumpViewerProps, type ZoomConfig };
package/dist/index.js CHANGED
@@ -1,7 +1,14 @@
1
1
  import "./index.css";
2
2
 
3
3
  // src/viewer.tsx
4
- import { useCallback as useCallback2, useEffect, useMemo, useRef as useRef2, useState as useState2 } from "react";
4
+ import {
5
+ useCallback as useCallback2,
6
+ useEffect,
7
+ useImperativeHandle,
8
+ useMemo,
9
+ useRef as useRef2,
10
+ useState as useState2
11
+ } from "react";
5
12
  import { Document, pdfjs } from "react-pdf";
6
13
  import "react-pdf/dist/Page/AnnotationLayer.css";
7
14
  import "react-pdf/dist/Page/TextLayer.css";
@@ -112,34 +119,16 @@ function PDFViewerControls(props) {
112
119
  ] }) });
113
120
  }
114
121
 
115
- // src/constants.ts
116
- var PAGE_HEIGHT = 842;
117
- var PAGE_WIDTH = 595;
118
-
119
122
  // src/error-page.tsx
120
123
  import { jsx as jsx2 } from "react/jsx-runtime";
121
124
  function PDFErrorPage() {
122
- return /* @__PURE__ */ jsx2(
123
- "div",
124
- {
125
- className: "hj-error",
126
- style: { width: PAGE_WIDTH, height: PAGE_HEIGHT },
127
- children: "Error loading file"
128
- }
129
- );
125
+ return /* @__PURE__ */ jsx2("div", { className: "hj-error", children: "Error loading file" });
130
126
  }
131
127
 
132
128
  // src/loading-page.tsx
133
129
  import { jsx as jsx3 } from "react/jsx-runtime";
134
130
  function PDFLoadingPage() {
135
- return /* @__PURE__ */ jsx3(
136
- "div",
137
- {
138
- className: "hj-loading",
139
- style: { width: PAGE_WIDTH, height: PAGE_HEIGHT },
140
- children: /* @__PURE__ */ jsx3("div", { className: "hj-spinner" })
141
- }
142
- );
131
+ return /* @__PURE__ */ jsx3("div", { className: "hj-loading", children: /* @__PURE__ */ jsx3("div", { className: "hj-spinner" }) });
143
132
  }
144
133
 
145
134
  // src/renderer.tsx
@@ -175,6 +164,10 @@ function useElementSize() {
175
164
  return { ref, width: size.width, height: size.height };
176
165
  }
177
166
 
167
+ // src/constants.ts
168
+ var PAGE_HEIGHT = 842;
169
+ var PAGE_WIDTH = 595;
170
+
178
171
  // src/utils.ts
179
172
  async function getPageDimensions(document, scale) {
180
173
  const dims = [];
@@ -203,7 +196,7 @@ pdfjs.GlobalWorkerOptions.workerSrc = new URL(
203
196
  ).toString();
204
197
  var PAGE_MARGIN = 12;
205
198
  function HyperJumpViewer(props) {
206
- const { url, page, onPageChange } = props;
199
+ const { url, initialPage, onPageChange, ref } = props;
207
200
  const [document, setDocument] = useState2();
208
201
  const [pageIndex, setPageIndex] = useState2(0);
209
202
  const [pageDimensions, setPageDimensions] = useState2([]);
@@ -224,18 +217,29 @@ function HyperJumpViewer(props) {
224
217
  });
225
218
  }
226
219
  }, [document, zoomConfig]);
227
- const scrollToPage = useCallback2((index) => {
228
- listRef.current?.scrollToRow({ index, align: "start" });
229
- setPageIndex(index);
230
- }, []);
220
+ const scrollToPage = useCallback2(
221
+ (target) => {
222
+ if (numPages === 0 || pageDimensions.length !== numPages) return;
223
+ const clamped = Math.max(0, Math.min(Math.floor(target), numPages - 1));
224
+ listRef.current?.scrollToRow({ index: clamped, align: "start" });
225
+ setPageIndex(clamped);
226
+ },
227
+ [numPages, pageDimensions]
228
+ );
229
+ useImperativeHandle(ref, () => ({ jumpToPage: scrollToPage }), [
230
+ scrollToPage
231
+ ]);
232
+ const hasAppliedInitialPage = useRef2(false);
231
233
  const onLoadSuccess = useCallback2((response) => {
234
+ hasAppliedInitialPage.current = false;
232
235
  setDocument(response);
233
236
  }, []);
234
237
  useEffect(() => {
235
- if (page !== void 0 && pageDimensions.length === numPages && numPages > 0) {
236
- scrollToPage(page);
238
+ if (!hasAppliedInitialPage.current && initialPage !== void 0 && pageDimensions.length === numPages && numPages > 0) {
239
+ hasAppliedInitialPage.current = true;
240
+ scrollToPage(initialPage);
237
241
  }
238
- }, [page, pageDimensions, numPages, scrollToPage]);
242
+ }, [initialPage, pageDimensions, numPages, scrollToPage]);
239
243
  const file = useMemo(() => {
240
244
  return { url };
241
245
  }, [url]);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/viewer.tsx","../src/controls.tsx","../src/constants.ts","../src/error-page.tsx","../src/loading-page.tsx","../src/renderer.tsx","../src/use-element-size.ts","../src/utils.ts"],"sourcesContent":["import type { PDFDocumentProxy } from \"pdfjs-dist\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { Document, pdfjs } from \"react-pdf\";\nimport \"react-pdf/dist/Page/AnnotationLayer.css\";\nimport \"react-pdf/dist/Page/TextLayer.css\";\nimport type { OnDocumentLoadSuccess } from \"react-pdf/dist/shared/types.js\";\nimport { List, type ListImperativeAPI } from \"react-window\";\nimport PDFViewerControls from \"./controls\";\nimport PDFErrorPage from \"./error-page\";\nimport PDFLoadingPage from \"./loading-page\";\nimport PDFPageRenderer from \"./renderer\";\nimport \"./styles.css\";\nimport type { ZoomConfig } from \"./types\";\nimport { useElementSize } from \"./use-element-size\";\nimport { getPageDimensions } from \"./utils\";\n\npdfjs.GlobalWorkerOptions.workerSrc = new URL(\n\t\"pdfjs-dist/build/pdf.worker.min.mjs\",\n\timport.meta.url,\n).toString();\n\nconst PAGE_MARGIN = 12;\n\nexport interface HyperJumpViewerProps {\n\t/** URL of the PDF file to display */\n\turl: string;\n\t/** Page number to jump to (0-indexed) */\n\tpage?: number;\n\t/** Called when the visible page changes (0-indexed) */\n\tonPageChange?: (page: number) => void;\n}\n\nexport function HyperJumpViewer(props: HyperJumpViewerProps) {\n\tconst { url, page, onPageChange } = props;\n\tconst [document, setDocument] = useState<PDFDocumentProxy>();\n\tconst [pageIndex, setPageIndex] = useState(0);\n\tconst [pageDimensions, setPageDimensions] = useState<\n\t\t{ width: number; height: number }[]\n\t>([]);\n\tconst [zoomConfig, setZoomConfig] = useState<ZoomConfig>({\n\t\tmode: \"automatic\",\n\t\tvalue: 1,\n\t});\n\tconst scrollPageRef = useRef(0);\n\n\tconst { ref: containerRef } = useElementSize();\n\tconst listRef = useRef<ListImperativeAPI>(null);\n\n\tconst numPages = useMemo(() => {\n\t\treturn document?.numPages || 0;\n\t}, [document]);\n\n\tuseEffect(() => {\n\t\tif (document) {\n\t\t\tgetPageDimensions(document, zoomConfig.value).then((value) => {\n\t\t\t\tsetPageDimensions(value);\n\t\t\t});\n\t\t}\n\t}, [document, zoomConfig]);\n\n\tconst scrollToPage = useCallback((index: number) => {\n\t\tlistRef.current?.scrollToRow({ index, align: \"start\" });\n\t\tsetPageIndex(index);\n\t}, []);\n\n\tconst onLoadSuccess: OnDocumentLoadSuccess = useCallback((response) => {\n\t\tsetDocument(response);\n\t}, []);\n\n\tuseEffect(() => {\n\t\tif (\n\t\t\tpage !== undefined &&\n\t\t\tpageDimensions.length === numPages &&\n\t\t\tnumPages > 0\n\t\t) {\n\t\t\tscrollToPage(page);\n\t\t}\n\t}, [page, pageDimensions, numPages, scrollToPage]);\n\n\tconst file = useMemo(() => {\n\t\treturn { url };\n\t}, [url]);\n\n\tconst onPrevPage = useCallback(() => {\n\t\tif (pageIndex > 0) {\n\t\t\tconst newPageIndex = pageIndex - 1;\n\t\t\tlistRef.current?.scrollToRow({ index: newPageIndex, align: \"start\" });\n\t\t\tsetPageIndex(newPageIndex);\n\t\t}\n\t}, [pageIndex]);\n\n\tconst onNextPage = useCallback(() => {\n\t\tif (pageIndex < numPages - 1) {\n\t\t\tconst newPageIndex = pageIndex + 1;\n\t\t\tlistRef.current?.scrollToRow({ index: newPageIndex, align: \"start\" });\n\t\t\tsetPageIndex(newPageIndex);\n\t\t}\n\t}, [pageIndex, numPages]);\n\n\tconst onChangeZoom = useCallback((value: string) => {\n\t\tif (value === \"automatic\") {\n\t\t\tsetZoomConfig({ mode: \"automatic\", value: 1 });\n\t\t} else {\n\t\t\tsetZoomConfig({ mode: \"manual\", value: Number.parseFloat(value) });\n\t\t}\n\t}, []);\n\n\tconst getItemSize = useCallback(\n\t\t(index: number) => {\n\t\t\tif (pageDimensions[index]) {\n\t\t\t\treturn pageDimensions[index].height + PAGE_MARGIN;\n\t\t\t}\n\t\t\treturn 0;\n\t\t},\n\t\t[pageDimensions],\n\t);\n\n\tconst onRowsRendered = useCallback(\n\t\t(visibleRows: { startIndex: number; stopIndex: number }) => {\n\t\t\tconst prev = scrollPageRef.current;\n\t\t\tscrollPageRef.current = visibleRows.startIndex;\n\t\t\tif (visibleRows.startIndex !== prev) {\n\t\t\t\tsetPageIndex(visibleRows.startIndex);\n\t\t\t\tonPageChange?.(visibleRows.startIndex);\n\t\t\t}\n\t\t},\n\t\t[onPageChange],\n\t);\n\n\treturn (\n\t\t<div className=\"hj-viewer\" ref={containerRef}>\n\t\t\t{file ? (\n\t\t\t\t<Document\n\t\t\t\t\tfile={file}\n\t\t\t\t\tonLoadSuccess={onLoadSuccess}\n\t\t\t\t\terror={PDFErrorPage}\n\t\t\t\t\tloading={PDFLoadingPage}\n\t\t\t\t>\n\t\t\t\t\t{pageDimensions.length > 0 && pageDimensions.length === numPages && (\n\t\t\t\t\t\t<List\n\t\t\t\t\t\t\tlistRef={listRef}\n\t\t\t\t\t\t\trowCount={numPages}\n\t\t\t\t\t\t\trowHeight={getItemSize}\n\t\t\t\t\t\t\tonRowsRendered={onRowsRendered}\n\t\t\t\t\t\t\trowProps={{ scale: zoomConfig.value }}\n\t\t\t\t\t\t\trowComponent={PDFPageRenderer}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</Document>\n\t\t\t) : (\n\t\t\t\t<PDFLoadingPage />\n\t\t\t)}\n\t\t\t<PDFViewerControls\n\t\t\t\tpageIndex={pageIndex}\n\t\t\t\tnumPages={numPages}\n\t\t\t\tonPrevPage={onPrevPage}\n\t\t\t\tonNextPage={onNextPage}\n\t\t\t\tzoomConfig={zoomConfig}\n\t\t\t\tonChangeZoom={onChangeZoom}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","import type { ZoomConfig } from \"./types\";\n\nconst ZOOM_OPTIONS = [\n\t{ label: \"Auto Width\", value: \"automatic\" },\n\t{ label: \"50%\", value: \"0.5\" },\n\t{ label: \"75%\", value: \"0.75\" },\n\t{ label: \"100%\", value: \"1\" },\n\t{ label: \"125%\", value: \"1.25\" },\n\t{ label: \"150%\", value: \"1.5\" },\n\t{ label: \"200%\", value: \"2\" },\n\t{ label: \"300%\", value: \"3\" },\n\t{ label: \"400%\", value: \"4\" },\n];\n\ninterface IProps {\n\tonChangeZoom(value: string): void;\n\tpageIndex: number;\n\tnumPages: number;\n\tzoomConfig: ZoomConfig;\n\tonNextPage(): void;\n\tonPrevPage(): void;\n}\n\nfunction ChevronLeft() {\n\treturn (\n\t\t<svg\n\t\t\twidth=\"16\"\n\t\t\theight=\"16\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"2\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t>\n\t\t\t<title>Previous Page</title>\n\t\t\t<path d=\"M15 18l-6-6 6-6\" />\n\t\t</svg>\n\t);\n}\n\nfunction ChevronRight() {\n\treturn (\n\t\t<svg\n\t\t\twidth=\"16\"\n\t\t\theight=\"16\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"2\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t>\n\t\t\t<title>Next Page</title>\n\t\t\t<path d=\"M9 18l6-6-6 6\" />\n\t\t</svg>\n\t);\n}\n\nexport default function PDFViewerControls(props: IProps) {\n\tconst {\n\t\tonChangeZoom,\n\t\tpageIndex,\n\t\tnumPages,\n\t\tzoomConfig,\n\t\tonNextPage,\n\t\tonPrevPage,\n\t} = props;\n\n\tconst zoomValue =\n\t\tzoomConfig.mode === \"automatic\" || zoomConfig.mode === \"page-width\"\n\t\t\t? zoomConfig.mode\n\t\t\t: zoomConfig.value.toString();\n\n\treturn (\n\t\t<div className=\"hj-controls\">\n\t\t\t<div className=\"hj-controls-bar\">\n\t\t\t\t<div className=\"hj-controls-group\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"hj-icon-btn\"\n\t\t\t\t\t\tonClick={onPrevPage}\n\t\t\t\t\t\tdisabled={pageIndex <= 0}\n\t\t\t\t\t\taria-label=\"Previous Page\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<ChevronLeft />\n\t\t\t\t\t</button>\n\t\t\t\t\t<span className=\"hj-page-indicator\">\n\t\t\t\t\t\t{pageIndex + 1} / {numPages}\n\t\t\t\t\t</span>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"hj-icon-btn\"\n\t\t\t\t\t\tonClick={onNextPage}\n\t\t\t\t\t\tdisabled={pageIndex >= numPages - 1}\n\t\t\t\t\t\taria-label=\"Next Page\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<ChevronRight />\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"hj-divider\" />\n\t\t\t\t<select\n\t\t\t\t\tclassName=\"hj-select\"\n\t\t\t\t\tvalue={zoomValue}\n\t\t\t\t\tonChange={(e) => onChangeZoom(e.target.value)}\n\t\t\t\t\taria-label=\"Zoom Level\"\n\t\t\t\t>\n\t\t\t\t\t{ZOOM_OPTIONS.map((opt) => (\n\t\t\t\t\t\t<option key={opt.value} value={opt.value}>\n\t\t\t\t\t\t\t{opt.label}\n\t\t\t\t\t\t</option>\n\t\t\t\t\t))}\n\t\t\t\t</select>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","export const PAGE_HEIGHT = 842;\nexport const PAGE_WIDTH = 595;\n","import { PAGE_HEIGHT, PAGE_WIDTH } from \"./constants\";\n\nexport default function PDFErrorPage() {\n\treturn (\n\t\t<div\n\t\t\tclassName=\"hj-error\"\n\t\t\tstyle={{ width: PAGE_WIDTH, height: PAGE_HEIGHT }}\n\t\t>\n\t\t\tError loading file\n\t\t</div>\n\t);\n}\n","import { PAGE_HEIGHT, PAGE_WIDTH } from \"./constants\";\n\nexport default function PDFLoadingPage() {\n\treturn (\n\t\t<div\n\t\t\tclassName=\"hj-loading\"\n\t\t\tstyle={{ width: PAGE_WIDTH, height: PAGE_HEIGHT }}\n\t\t>\n\t\t\t<div className=\"hj-spinner\" />\n\t\t</div>\n\t);\n}\n","import { Page } from \"react-pdf\";\nimport type { RowComponentProps } from \"react-window\";\nimport PDFLoadingPage from \"./loading-page\";\n\ninterface RowProps {\n\tscale: number;\n}\n\nexport default function PDFPageRenderer(props: RowComponentProps<RowProps>) {\n\tconst { index, style, scale } = props;\n\treturn (\n\t\t<div className=\"hj-page\" style={style}>\n\t\t\t<Page pageIndex={index} scale={scale} loading={PDFLoadingPage} />\n\t\t</div>\n\t);\n}\n","import { useCallback, useRef, useState } from \"react\";\n\nexport function useElementSize<T extends HTMLElement = HTMLDivElement>() {\n\tconst [size, setSize] = useState({ width: 0, height: 0 });\n\tconst observerRef = useRef<ResizeObserver | null>(null);\n\n\tconst ref = useCallback((node: T | null) => {\n\t\tif (observerRef.current) {\n\t\t\tobserverRef.current.disconnect();\n\t\t\tobserverRef.current = null;\n\t\t}\n\n\t\tif (node) {\n\t\t\tconst observer = new ResizeObserver(([entry]) => {\n\t\t\t\tconst { width, height } = entry.contentRect;\n\t\t\t\tsetSize((prev) => {\n\t\t\t\t\tif (prev.width === width && prev.height === height) return prev;\n\t\t\t\t\treturn { width, height };\n\t\t\t\t});\n\t\t\t});\n\t\t\tobserver.observe(node);\n\t\t\tobserverRef.current = observer;\n\t\t}\n\t}, []);\n\n\treturn { ref, width: size.width, height: size.height };\n}\n","import type { PDFDocumentProxy } from \"pdfjs-dist\";\nimport { PAGE_HEIGHT, PAGE_WIDTH } from \"./constants\";\n\nexport async function getPageDimensions(\n\tdocument: PDFDocumentProxy,\n\tscale: number,\n) {\n\tconst dims = [];\n\tfor (let i = 1; i <= document.numPages; i++) {\n\t\ttry {\n\t\t\tconst page = await document.getPage(i);\n\t\t\tconst viewport = page.getViewport({ scale });\n\t\t\tconst { height, width } = viewport;\n\t\t\tdims.push({ height, width });\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to get page dimensions\", error);\n\t\t\tdims.push({\n\t\t\t\twidth: PAGE_WIDTH,\n\t\t\t\theight: PAGE_HEIGHT,\n\t\t\t});\n\t\t}\n\t}\n\treturn dims;\n}\n"],"mappings":"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","names":["useCallback","useRef","useState","jsx","jsx","jsx","jsx","jsxs","useState","useRef","useCallback"]}
1
+ {"version":3,"sources":["../src/viewer.tsx","../src/controls.tsx","../src/error-page.tsx","../src/loading-page.tsx","../src/renderer.tsx","../src/use-element-size.ts","../src/constants.ts","../src/utils.ts"],"sourcesContent":["import type { PDFDocumentProxy } from \"pdfjs-dist\";\nimport {\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { Document, pdfjs } from \"react-pdf\";\nimport \"react-pdf/dist/Page/AnnotationLayer.css\";\nimport \"react-pdf/dist/Page/TextLayer.css\";\nimport type { OnDocumentLoadSuccess } from \"react-pdf/dist/shared/types.js\";\nimport { List, type ListImperativeAPI } from \"react-window\";\nimport PDFViewerControls from \"./controls\";\nimport PDFErrorPage from \"./error-page\";\nimport PDFLoadingPage from \"./loading-page\";\nimport PDFPageRenderer from \"./renderer\";\nimport \"./styles.css\";\nimport type { ZoomConfig } from \"./types\";\nimport { useElementSize } from \"./use-element-size\";\nimport { getPageDimensions } from \"./utils\";\n\npdfjs.GlobalWorkerOptions.workerSrc = new URL(\n\t\"pdfjs-dist/build/pdf.worker.min.mjs\",\n\timport.meta.url,\n).toString();\n\nconst PAGE_MARGIN = 12;\n\nexport interface HyperJumpViewerAPI {\n\t/** Imperatively scroll to a page (0-indexed). Clamps to valid range. */\n\tjumpToPage: (page: number) => void;\n}\n\nexport interface HyperJumpViewerProps {\n\t/** URL of the PDF file to display */\n\turl: string;\n\t/** Page to show when the document first loads (0-indexed) */\n\tinitialPage?: number;\n\t/** Called when the visible page changes (0-indexed) */\n\tonPageChange?: (page: number) => void;\n\t/** Ref exposing imperative jumpToPage method */\n\tref?: React.Ref<HyperJumpViewerAPI>;\n}\n\nexport function HyperJumpViewer(props: HyperJumpViewerProps) {\n\tconst { url, initialPage, onPageChange, ref } = props;\n\tconst [document, setDocument] = useState<PDFDocumentProxy>();\n\tconst [pageIndex, setPageIndex] = useState(0);\n\tconst [pageDimensions, setPageDimensions] = useState<\n\t\t{ width: number; height: number }[]\n\t>([]);\n\tconst [zoomConfig, setZoomConfig] = useState<ZoomConfig>({\n\t\tmode: \"automatic\",\n\t\tvalue: 1,\n\t});\n\tconst scrollPageRef = useRef(0);\n\n\tconst { ref: containerRef } = useElementSize();\n\tconst listRef = useRef<ListImperativeAPI>(null);\n\n\tconst numPages = useMemo(() => {\n\t\treturn document?.numPages || 0;\n\t}, [document]);\n\n\tuseEffect(() => {\n\t\tif (document) {\n\t\t\tgetPageDimensions(document, zoomConfig.value).then((value) => {\n\t\t\t\tsetPageDimensions(value);\n\t\t\t});\n\t\t}\n\t}, [document, zoomConfig]);\n\n\tconst scrollToPage = useCallback(\n\t\t(target: number) => {\n\t\t\tif (numPages === 0 || pageDimensions.length !== numPages) return;\n\t\t\tconst clamped = Math.max(0, Math.min(Math.floor(target), numPages - 1));\n\t\t\tlistRef.current?.scrollToRow({ index: clamped, align: \"start\" });\n\t\t\tsetPageIndex(clamped);\n\t\t},\n\t\t[numPages, pageDimensions],\n\t);\n\n\tuseImperativeHandle(ref, () => ({ jumpToPage: scrollToPage }), [\n\t\tscrollToPage,\n\t]);\n\n\tconst hasAppliedInitialPage = useRef(false);\n\n\tconst onLoadSuccess: OnDocumentLoadSuccess = useCallback((response) => {\n\t\thasAppliedInitialPage.current = false;\n\t\tsetDocument(response);\n\t}, []);\n\n\t// Scroll to initialPage once when dimensions are first available\n\tuseEffect(() => {\n\t\tif (\n\t\t\t!hasAppliedInitialPage.current &&\n\t\t\tinitialPage !== undefined &&\n\t\t\tpageDimensions.length === numPages &&\n\t\t\tnumPages > 0\n\t\t) {\n\t\t\thasAppliedInitialPage.current = true;\n\t\t\tscrollToPage(initialPage);\n\t\t}\n\t}, [initialPage, pageDimensions, numPages, scrollToPage]);\n\n\tconst file = useMemo(() => {\n\t\treturn { url };\n\t}, [url]);\n\n\tconst onPrevPage = useCallback(() => {\n\t\tif (pageIndex > 0) {\n\t\t\tconst newPageIndex = pageIndex - 1;\n\t\t\tlistRef.current?.scrollToRow({ index: newPageIndex, align: \"start\" });\n\t\t\tsetPageIndex(newPageIndex);\n\t\t}\n\t}, [pageIndex]);\n\n\tconst onNextPage = useCallback(() => {\n\t\tif (pageIndex < numPages - 1) {\n\t\t\tconst newPageIndex = pageIndex + 1;\n\t\t\tlistRef.current?.scrollToRow({ index: newPageIndex, align: \"start\" });\n\t\t\tsetPageIndex(newPageIndex);\n\t\t}\n\t}, [pageIndex, numPages]);\n\n\tconst onChangeZoom = useCallback((value: string) => {\n\t\tif (value === \"automatic\") {\n\t\t\tsetZoomConfig({ mode: \"automatic\", value: 1 });\n\t\t} else {\n\t\t\tsetZoomConfig({ mode: \"manual\", value: Number.parseFloat(value) });\n\t\t}\n\t}, []);\n\n\tconst getItemSize = useCallback(\n\t\t(index: number) => {\n\t\t\tif (pageDimensions[index]) {\n\t\t\t\treturn pageDimensions[index].height + PAGE_MARGIN;\n\t\t\t}\n\t\t\treturn 0;\n\t\t},\n\t\t[pageDimensions],\n\t);\n\n\tconst onRowsRendered = useCallback(\n\t\t(visibleRows: { startIndex: number; stopIndex: number }) => {\n\t\t\tconst prev = scrollPageRef.current;\n\t\t\tscrollPageRef.current = visibleRows.startIndex;\n\t\t\tif (visibleRows.startIndex !== prev) {\n\t\t\t\tsetPageIndex(visibleRows.startIndex);\n\t\t\t\tonPageChange?.(visibleRows.startIndex);\n\t\t\t}\n\t\t},\n\t\t[onPageChange],\n\t);\n\n\treturn (\n\t\t<div className=\"hj-viewer\" ref={containerRef}>\n\t\t\t{file ? (\n\t\t\t\t<Document\n\t\t\t\t\tfile={file}\n\t\t\t\t\tonLoadSuccess={onLoadSuccess}\n\t\t\t\t\terror={PDFErrorPage}\n\t\t\t\t\tloading={PDFLoadingPage}\n\t\t\t\t>\n\t\t\t\t\t{pageDimensions.length > 0 && pageDimensions.length === numPages && (\n\t\t\t\t\t\t<List\n\t\t\t\t\t\t\tlistRef={listRef}\n\t\t\t\t\t\t\trowCount={numPages}\n\t\t\t\t\t\t\trowHeight={getItemSize}\n\t\t\t\t\t\t\tonRowsRendered={onRowsRendered}\n\t\t\t\t\t\t\trowProps={{ scale: zoomConfig.value }}\n\t\t\t\t\t\t\trowComponent={PDFPageRenderer}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</Document>\n\t\t\t) : (\n\t\t\t\t<PDFLoadingPage />\n\t\t\t)}\n\t\t\t<PDFViewerControls\n\t\t\t\tpageIndex={pageIndex}\n\t\t\t\tnumPages={numPages}\n\t\t\t\tonPrevPage={onPrevPage}\n\t\t\t\tonNextPage={onNextPage}\n\t\t\t\tzoomConfig={zoomConfig}\n\t\t\t\tonChangeZoom={onChangeZoom}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","import type { ZoomConfig } from \"./types\";\n\nconst ZOOM_OPTIONS = [\n\t{ label: \"Auto Width\", value: \"automatic\" },\n\t{ label: \"50%\", value: \"0.5\" },\n\t{ label: \"75%\", value: \"0.75\" },\n\t{ label: \"100%\", value: \"1\" },\n\t{ label: \"125%\", value: \"1.25\" },\n\t{ label: \"150%\", value: \"1.5\" },\n\t{ label: \"200%\", value: \"2\" },\n\t{ label: \"300%\", value: \"3\" },\n\t{ label: \"400%\", value: \"4\" },\n];\n\ninterface IProps {\n\tonChangeZoom(value: string): void;\n\tpageIndex: number;\n\tnumPages: number;\n\tzoomConfig: ZoomConfig;\n\tonNextPage(): void;\n\tonPrevPage(): void;\n}\n\nfunction ChevronLeft() {\n\treturn (\n\t\t<svg\n\t\t\twidth=\"16\"\n\t\t\theight=\"16\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"2\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t>\n\t\t\t<title>Previous Page</title>\n\t\t\t<path d=\"M15 18l-6-6 6-6\" />\n\t\t</svg>\n\t);\n}\n\nfunction ChevronRight() {\n\treturn (\n\t\t<svg\n\t\t\twidth=\"16\"\n\t\t\theight=\"16\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"2\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t>\n\t\t\t<title>Next Page</title>\n\t\t\t<path d=\"M9 18l6-6-6 6\" />\n\t\t</svg>\n\t);\n}\n\nexport default function PDFViewerControls(props: IProps) {\n\tconst {\n\t\tonChangeZoom,\n\t\tpageIndex,\n\t\tnumPages,\n\t\tzoomConfig,\n\t\tonNextPage,\n\t\tonPrevPage,\n\t} = props;\n\n\tconst zoomValue =\n\t\tzoomConfig.mode === \"automatic\" || zoomConfig.mode === \"page-width\"\n\t\t\t? zoomConfig.mode\n\t\t\t: zoomConfig.value.toString();\n\n\treturn (\n\t\t<div className=\"hj-controls\">\n\t\t\t<div className=\"hj-controls-bar\">\n\t\t\t\t<div className=\"hj-controls-group\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"hj-icon-btn\"\n\t\t\t\t\t\tonClick={onPrevPage}\n\t\t\t\t\t\tdisabled={pageIndex <= 0}\n\t\t\t\t\t\taria-label=\"Previous Page\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<ChevronLeft />\n\t\t\t\t\t</button>\n\t\t\t\t\t<span className=\"hj-page-indicator\">\n\t\t\t\t\t\t{pageIndex + 1} / {numPages}\n\t\t\t\t\t</span>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"hj-icon-btn\"\n\t\t\t\t\t\tonClick={onNextPage}\n\t\t\t\t\t\tdisabled={pageIndex >= numPages - 1}\n\t\t\t\t\t\taria-label=\"Next Page\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<ChevronRight />\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"hj-divider\" />\n\t\t\t\t<select\n\t\t\t\t\tclassName=\"hj-select\"\n\t\t\t\t\tvalue={zoomValue}\n\t\t\t\t\tonChange={(e) => onChangeZoom(e.target.value)}\n\t\t\t\t\taria-label=\"Zoom Level\"\n\t\t\t\t>\n\t\t\t\t\t{ZOOM_OPTIONS.map((opt) => (\n\t\t\t\t\t\t<option key={opt.value} value={opt.value}>\n\t\t\t\t\t\t\t{opt.label}\n\t\t\t\t\t\t</option>\n\t\t\t\t\t))}\n\t\t\t\t</select>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","export default function PDFErrorPage() {\n\treturn <div className=\"hj-error\">Error loading file</div>;\n}\n","export default function PDFLoadingPage() {\n\treturn (\n\t\t<div className=\"hj-loading\">\n\t\t\t<div className=\"hj-spinner\" />\n\t\t</div>\n\t);\n}\n","import { Page } from \"react-pdf\";\nimport type { RowComponentProps } from \"react-window\";\nimport PDFLoadingPage from \"./loading-page\";\n\ninterface RowProps {\n\tscale: number;\n}\n\nexport default function PDFPageRenderer(props: RowComponentProps<RowProps>) {\n\tconst { index, style, scale } = props;\n\treturn (\n\t\t<div className=\"hj-page\" style={style}>\n\t\t\t<Page pageIndex={index} scale={scale} loading={PDFLoadingPage} />\n\t\t</div>\n\t);\n}\n","import { useCallback, useRef, useState } from \"react\";\n\nexport function useElementSize<T extends HTMLElement = HTMLDivElement>() {\n\tconst [size, setSize] = useState({ width: 0, height: 0 });\n\tconst observerRef = useRef<ResizeObserver | null>(null);\n\n\tconst ref = useCallback((node: T | null) => {\n\t\tif (observerRef.current) {\n\t\t\tobserverRef.current.disconnect();\n\t\t\tobserverRef.current = null;\n\t\t}\n\n\t\tif (node) {\n\t\t\tconst observer = new ResizeObserver(([entry]) => {\n\t\t\t\tconst { width, height } = entry.contentRect;\n\t\t\t\tsetSize((prev) => {\n\t\t\t\t\tif (prev.width === width && prev.height === height) return prev;\n\t\t\t\t\treturn { width, height };\n\t\t\t\t});\n\t\t\t});\n\t\t\tobserver.observe(node);\n\t\t\tobserverRef.current = observer;\n\t\t}\n\t}, []);\n\n\treturn { ref, width: size.width, height: size.height };\n}\n","export const PAGE_HEIGHT = 842;\nexport const PAGE_WIDTH = 595;\n","import type { PDFDocumentProxy } from \"pdfjs-dist\";\nimport { PAGE_HEIGHT, PAGE_WIDTH } from \"./constants\";\n\nexport async function getPageDimensions(\n\tdocument: PDFDocumentProxy,\n\tscale: number,\n) {\n\tconst dims = [];\n\tfor (let i = 1; i <= document.numPages; i++) {\n\t\ttry {\n\t\t\tconst page = await document.getPage(i);\n\t\t\tconst viewport = page.getViewport({ scale });\n\t\t\tconst { height, width } = viewport;\n\t\t\tdims.push({ height, width });\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to get page dimensions\", error);\n\t\t\tdims.push({\n\t\t\t\twidth: PAGE_WIDTH,\n\t\t\t\theight: PAGE_HEIGHT,\n\t\t\t});\n\t\t}\n\t}\n\treturn dims;\n}\n"],"mappings":";;;AACA;AAAA,EACC,eAAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OACM;AACP,SAAS,UAAU,aAAa;AAChC,OAAO;AACP,OAAO;AAEP,SAAS,YAAoC;;;ACY3C,SAUC,KAVD;AAvBF,IAAM,eAAe;AAAA,EACpB,EAAE,OAAO,cAAc,OAAO,YAAY;AAAA,EAC1C,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,EAC7B,EAAE,OAAO,OAAO,OAAO,OAAO;AAAA,EAC9B,EAAE,OAAO,QAAQ,OAAO,IAAI;AAAA,EAC5B,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,EAC/B,EAAE,OAAO,QAAQ,OAAO,MAAM;AAAA,EAC9B,EAAE,OAAO,QAAQ,OAAO,IAAI;AAAA,EAC5B,EAAE,OAAO,QAAQ,OAAO,IAAI;AAAA,EAC5B,EAAE,OAAO,QAAQ,OAAO,IAAI;AAC7B;AAWA,SAAS,cAAc;AACtB,SACC;AAAA,IAAC;AAAA;AAAA,MACA,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MAEf;AAAA,4BAAC,WAAM,2BAAa;AAAA,QACpB,oBAAC,UAAK,GAAE,mBAAkB;AAAA;AAAA;AAAA,EAC3B;AAEF;AAEA,SAAS,eAAe;AACvB,SACC;AAAA,IAAC;AAAA;AAAA,MACA,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MAEf;AAAA,4BAAC,WAAM,uBAAS;AAAA,QAChB,oBAAC,UAAK,GAAE,iBAAgB;AAAA;AAAA;AAAA,EACzB;AAEF;AAEe,SAAR,kBAAmC,OAAe;AACxD,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI;AAEJ,QAAM,YACL,WAAW,SAAS,eAAe,WAAW,SAAS,eACpD,WAAW,OACX,WAAW,MAAM,SAAS;AAE9B,SACC,oBAAC,SAAI,WAAU,eACd,+BAAC,SAAI,WAAU,mBACd;AAAA,yBAAC,SAAI,WAAU,qBACd;AAAA;AAAA,QAAC;AAAA;AAAA,UACA,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS;AAAA,UACT,UAAU,aAAa;AAAA,UACvB,cAAW;AAAA,UAEX,8BAAC,eAAY;AAAA;AAAA,MACd;AAAA,MACA,qBAAC,UAAK,WAAU,qBACd;AAAA,oBAAY;AAAA,QAAE;AAAA,QAAI;AAAA,SACpB;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACA,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS;AAAA,UACT,UAAU,aAAa,WAAW;AAAA,UAClC,cAAW;AAAA,UAEX,8BAAC,gBAAa;AAAA;AAAA,MACf;AAAA,OACD;AAAA,IACA,oBAAC,SAAI,WAAU,cAAa;AAAA,IAC5B;AAAA,MAAC;AAAA;AAAA,QACA,WAAU;AAAA,QACV,OAAO;AAAA,QACP,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK;AAAA,QAC5C,cAAW;AAAA,QAEV,uBAAa,IAAI,CAAC,QAClB,oBAAC,YAAuB,OAAO,IAAI,OACjC,cAAI,SADO,IAAI,KAEjB,CACA;AAAA;AAAA,IACF;AAAA,KACD,GACD;AAEF;;;ACnHQ,gBAAAC,YAAA;AADO,SAAR,eAAgC;AACtC,SAAO,gBAAAA,KAAC,SAAI,WAAU,YAAW,gCAAkB;AACpD;;;ACCG,gBAAAC,YAAA;AAHY,SAAR,iBAAkC;AACxC,SACC,gBAAAA,KAAC,SAAI,WAAU,cACd,0BAAAA,KAAC,SAAI,WAAU,cAAa,GAC7B;AAEF;;;ACNA,SAAS,YAAY;AAYlB,gBAAAC,YAAA;AAJY,SAAR,gBAAiC,OAAoC;AAC3E,QAAM,EAAE,OAAO,OAAO,MAAM,IAAI;AAChC,SACC,gBAAAA,KAAC,SAAI,WAAU,WAAU,OACxB,0BAAAA,KAAC,QAAK,WAAW,OAAO,OAAc,SAAS,gBAAgB,GAChE;AAEF;;;ACfA,SAAS,aAAa,QAAQ,gBAAgB;AAEvC,SAAS,iBAAyD;AACxE,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC;AACxD,QAAM,cAAc,OAA8B,IAAI;AAEtD,QAAM,MAAM,YAAY,CAAC,SAAmB;AAC3C,QAAI,YAAY,SAAS;AACxB,kBAAY,QAAQ,WAAW;AAC/B,kBAAY,UAAU;AAAA,IACvB;AAEA,QAAI,MAAM;AACT,YAAM,WAAW,IAAI,eAAe,CAAC,CAAC,KAAK,MAAM;AAChD,cAAM,EAAE,OAAO,OAAO,IAAI,MAAM;AAChC,gBAAQ,CAAC,SAAS;AACjB,cAAI,KAAK,UAAU,SAAS,KAAK,WAAW,OAAQ,QAAO;AAC3D,iBAAO,EAAE,OAAO,OAAO;AAAA,QACxB,CAAC;AAAA,MACF,CAAC;AACD,eAAS,QAAQ,IAAI;AACrB,kBAAY,UAAU;AAAA,IACvB;AAAA,EACD,GAAG,CAAC,CAAC;AAEL,SAAO,EAAE,KAAK,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO;AACtD;;;AC1BO,IAAM,cAAc;AACpB,IAAM,aAAa;;;ACE1B,eAAsB,kBACrB,UACA,OACC;AACD,QAAM,OAAO,CAAC;AACd,WAAS,IAAI,GAAG,KAAK,SAAS,UAAU,KAAK;AAC5C,QAAI;AACH,YAAM,OAAO,MAAM,SAAS,QAAQ,CAAC;AACrC,YAAM,WAAW,KAAK,YAAY,EAAE,MAAM,CAAC;AAC3C,YAAM,EAAE,QAAQ,MAAM,IAAI;AAC1B,WAAK,KAAK,EAAE,QAAQ,MAAM,CAAC;AAAA,IAC5B,SAAS,OAAO;AACf,cAAQ,MAAM,iCAAiC,KAAK;AACpD,WAAK,KAAK;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,MACT,CAAC;AAAA,IACF;AAAA,EACD;AACA,SAAO;AACR;;;APwIE,SASI,OAAAC,MATJ,QAAAC,aAAA;AAxIF,MAAM,oBAAoB,YAAY,IAAI;AAAA,EACzC;AAAA,EACA,YAAY;AACb,EAAE,SAAS;AAEX,IAAM,cAAc;AAkBb,SAAS,gBAAgB,OAA6B;AAC5D,QAAM,EAAE,KAAK,aAAa,cAAc,IAAI,IAAI;AAChD,QAAM,CAAC,UAAU,WAAW,IAAIC,UAA2B;AAC3D,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,CAAC;AAC5C,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAE1C,CAAC,CAAC;AACJ,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAqB;AAAA,IACxD,MAAM;AAAA,IACN,OAAO;AAAA,EACR,CAAC;AACD,QAAM,gBAAgBC,QAAO,CAAC;AAE9B,QAAM,EAAE,KAAK,aAAa,IAAI,eAAe;AAC7C,QAAM,UAAUA,QAA0B,IAAI;AAE9C,QAAM,WAAW,QAAQ,MAAM;AAC9B,WAAO,UAAU,YAAY;AAAA,EAC9B,GAAG,CAAC,QAAQ,CAAC;AAEb,YAAU,MAAM;AACf,QAAI,UAAU;AACb,wBAAkB,UAAU,WAAW,KAAK,EAAE,KAAK,CAAC,UAAU;AAC7D,0BAAkB,KAAK;AAAA,MACxB,CAAC;AAAA,IACF;AAAA,EACD,GAAG,CAAC,UAAU,UAAU,CAAC;AAEzB,QAAM,eAAeC;AAAA,IACpB,CAAC,WAAmB;AACnB,UAAI,aAAa,KAAK,eAAe,WAAW,SAAU;AAC1D,YAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC;AACtE,cAAQ,SAAS,YAAY,EAAE,OAAO,SAAS,OAAO,QAAQ,CAAC;AAC/D,mBAAa,OAAO;AAAA,IACrB;AAAA,IACA,CAAC,UAAU,cAAc;AAAA,EAC1B;AAEA,sBAAoB,KAAK,OAAO,EAAE,YAAY,aAAa,IAAI;AAAA,IAC9D;AAAA,EACD,CAAC;AAED,QAAM,wBAAwBD,QAAO,KAAK;AAE1C,QAAM,gBAAuCC,aAAY,CAAC,aAAa;AACtE,0BAAsB,UAAU;AAChC,gBAAY,QAAQ;AAAA,EACrB,GAAG,CAAC,CAAC;AAGL,YAAU,MAAM;AACf,QACC,CAAC,sBAAsB,WACvB,gBAAgB,UAChB,eAAe,WAAW,YAC1B,WAAW,GACV;AACD,4BAAsB,UAAU;AAChC,mBAAa,WAAW;AAAA,IACzB;AAAA,EACD,GAAG,CAAC,aAAa,gBAAgB,UAAU,YAAY,CAAC;AAExD,QAAM,OAAO,QAAQ,MAAM;AAC1B,WAAO,EAAE,IAAI;AAAA,EACd,GAAG,CAAC,GAAG,CAAC;AAER,QAAM,aAAaA,aAAY,MAAM;AACpC,QAAI,YAAY,GAAG;AAClB,YAAM,eAAe,YAAY;AACjC,cAAQ,SAAS,YAAY,EAAE,OAAO,cAAc,OAAO,QAAQ,CAAC;AACpE,mBAAa,YAAY;AAAA,IAC1B;AAAA,EACD,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,aAAaA,aAAY,MAAM;AACpC,QAAI,YAAY,WAAW,GAAG;AAC7B,YAAM,eAAe,YAAY;AACjC,cAAQ,SAAS,YAAY,EAAE,OAAO,cAAc,OAAO,QAAQ,CAAC;AACpE,mBAAa,YAAY;AAAA,IAC1B;AAAA,EACD,GAAG,CAAC,WAAW,QAAQ,CAAC;AAExB,QAAM,eAAeA,aAAY,CAAC,UAAkB;AACnD,QAAI,UAAU,aAAa;AAC1B,oBAAc,EAAE,MAAM,aAAa,OAAO,EAAE,CAAC;AAAA,IAC9C,OAAO;AACN,oBAAc,EAAE,MAAM,UAAU,OAAO,OAAO,WAAW,KAAK,EAAE,CAAC;AAAA,IAClE;AAAA,EACD,GAAG,CAAC,CAAC;AAEL,QAAM,cAAcA;AAAA,IACnB,CAAC,UAAkB;AAClB,UAAI,eAAe,KAAK,GAAG;AAC1B,eAAO,eAAe,KAAK,EAAE,SAAS;AAAA,MACvC;AACA,aAAO;AAAA,IACR;AAAA,IACA,CAAC,cAAc;AAAA,EAChB;AAEA,QAAM,iBAAiBA;AAAA,IACtB,CAAC,gBAA2D;AAC3D,YAAM,OAAO,cAAc;AAC3B,oBAAc,UAAU,YAAY;AACpC,UAAI,YAAY,eAAe,MAAM;AACpC,qBAAa,YAAY,UAAU;AACnC,uBAAe,YAAY,UAAU;AAAA,MACtC;AAAA,IACD;AAAA,IACA,CAAC,YAAY;AAAA,EACd;AAEA,SACC,gBAAAH,MAAC,SAAI,WAAU,aAAY,KAAK,cAC9B;AAAA,WACA,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,SAAS;AAAA,QAER,yBAAe,SAAS,KAAK,eAAe,WAAW,YACvD,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YACV,WAAW;AAAA,YACX;AAAA,YACA,UAAU,EAAE,OAAO,WAAW,MAAM;AAAA,YACpC,cAAc;AAAA;AAAA,QACf;AAAA;AAAA,IAEF,IAEA,gBAAAA,KAAC,kBAAe;AAAA,IAEjB,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACD;AAAA,KACD;AAEF;","names":["useCallback","useRef","useState","jsx","jsx","jsx","jsx","jsxs","useState","useRef","useCallback"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hypercard-ai/hyper-jump",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Document viewer built for RAG",
5
5
  "license": "MIT",
6
6
  "author": "HyperCard AI",