@hypercard-ai/hyper-jump 0.3.1 → 1.0.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/README.md CHANGED
@@ -4,12 +4,15 @@
4
4
  [![CI](https://github.com/hypercard-ai/hyper-jump/actions/workflows/ci.yml/badge.svg)](https://github.com/hypercard-ai/hyper-jump/actions/workflows/ci.yml)
5
5
  [![license](https://img.shields.io/npm/l/@hypercard-ai/hyper-jump)](./LICENSE)
6
6
 
7
- A React PDF viewer built for RAG (Retrieval-Augmented Generation). Originally developed as part of [HyperCard.AI](https://hypercard.ai)'s chatbot platform, hyper-jump provides fast page navigation that pairs with RAG citations to deliver an excellent document viewing experience.
7
+ A pluggable React document viewer built for RAG (Retrieval-Augmented Generation). Originally developed as part of [HyperCard.AI](https://hypercard.ai)'s chatbot platform, hyper-jump provides fast navigation that pairs with RAG citations to deliver an excellent document viewing experience.
8
+
9
+ Renderers are opt-in — only bundle what you use.
8
10
 
9
11
  ## Features
10
12
 
13
+ - **Pluggable renderers** — import only the file types you need (PDF, video, and more coming soon)
11
14
  - Virtualized rendering via `react-window` for smooth viewing of large PDFs
12
- - Jump-to-page navigation for instant access to cited content
15
+ - Unified `jump()` API for instant navigation to cited content across all file types
13
16
  - Zoom controls with preset levels and automatic fit-to-width
14
17
  - Responsive layout that adapts to container size
15
18
  - Lightweight, self-contained CSS with no external styling dependencies
@@ -17,46 +20,65 @@ A React PDF viewer built for RAG (Retrieval-Augmented Generation). Originally de
17
20
  ## Installation
18
21
 
19
22
  ```bash
20
- npm install @hypercard-ai/hyper-jump react-pdf
23
+ # Core + PDF renderer
24
+ npm install @hypercard-ai/hyper-jump react-pdf react-window
25
+
26
+ # Core + Video renderer (no extra dependencies needed)
27
+ npm install @hypercard-ai/hyper-jump
21
28
  ```
22
29
 
30
+ Renderer dependencies are optional peer dependencies — only install those needed by the renderers you use.
31
+
23
32
  ## Usage
24
33
 
25
34
  ```tsx
26
35
  import { HyperJumpViewer } from "@hypercard-ai/hyper-jump";
27
- import "@hypercard-ai/hyper-jump/styles.css";
36
+ import { PdfRenderer } from "@hypercard-ai/hyper-jump/pdf";
28
37
 
29
38
  function App() {
30
- return <HyperJumpViewer url="/path/to/document.pdf" />;
39
+ return (
40
+ <HyperJumpViewer
41
+ url="/path/to/document.pdf"
42
+ renderers={[PdfRenderer]}
43
+ />
44
+ );
31
45
  }
32
46
  ```
33
47
 
34
- ### Open a PDF at a specific page
48
+ ### Open at a specific position
35
49
 
36
- Pass a zero-indexed `initialPage` to start at a specific page when the document loads:
50
+ Pass `initialPosition` to start at a specific location when the file loads. The meaning depends on the renderer — page index for PDF, seconds for video:
37
51
 
38
52
  ```tsx
39
- <HyperJumpViewer url="/path/to/document.pdf" initialPage={3} />
53
+ // PDF: open at page 4 (0-indexed)
54
+ <HyperJumpViewer url="/doc.pdf" renderers={[PdfRenderer]} initialPosition={3} />
55
+
56
+ // Video: start at 30 seconds
57
+ <HyperJumpViewer url="/clip.mp4" renderers={[VideoRenderer]} initialPosition={30} />
40
58
  ```
41
59
 
42
- ### Jump to a page imperatively
60
+ ### Jump to a position imperatively
43
61
 
44
- Use a ref to jump to any page at any time — ideal for navigating to RAG citations:
62
+ Use a ref to jump to any position at any time — ideal for navigating to RAG citations. The `jump()` method works the same across all renderers:
45
63
 
46
64
  ```tsx
47
65
  import { useRef } from "react";
48
- import { HyperJumpViewer, type HyperJumpViewerAPI } from "@hypercard-ai/hyper-jump";
49
- import "@hypercard-ai/hyper-jump/styles.css";
66
+ import { HyperJumpViewer, type HyperJumpAPI } from "@hypercard-ai/hyper-jump";
67
+ import { PdfRenderer } from "@hypercard-ai/hyper-jump/pdf";
50
68
 
51
69
  function App() {
52
- const viewerRef = useRef<HyperJumpViewerAPI>(null);
70
+ const viewerRef = useRef<HyperJumpAPI>(null);
53
71
 
54
72
  return (
55
73
  <>
56
- <button onClick={() => viewerRef.current?.jumpToPage(5)}>
74
+ <button onClick={() => viewerRef.current?.jump(5)}>
57
75
  Go to page 6
58
76
  </button>
59
- <HyperJumpViewer url="/path/to/document.pdf" ref={viewerRef} />
77
+ <HyperJumpViewer
78
+ url="/path/to/document.pdf"
79
+ renderers={[PdfRenderer]}
80
+ ref={viewerRef}
81
+ />
60
82
  </>
61
83
  );
62
84
  }
@@ -66,32 +88,114 @@ function App() {
66
88
 
67
89
  ### `<HyperJumpViewer />`
68
90
 
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 |
91
+ The core component. It detects the file type from the URL extension (or an explicit `type` prop), picks the first matching renderer, and forwards all remaining props to it.
92
+
93
+ | Prop | Type | Required | Description |
94
+ | --- | --- | --- | --- |
95
+ | `url` | `string` | Yes | URL or path to the file |
96
+ | `renderers` | `FileRenderer[]` | Yes | Renderers the viewer can use (first match wins) |
97
+ | `type` | `string` | No | Explicit file type override (e.g. `"pdf"`). If omitted, detected from URL extension |
98
+ | `ref` | `Ref<HyperJumpAPI>` | No | Forwarded to the active renderer for the `jump()` API |
99
+ | `initialPosition` | `number` | No | Position to start at when the file loads (page index for PDF, seconds for video) |
100
+ | `onPositionChange` | `(position: number) => void` | No | Called when the current position changes |
101
+ | `rendererProps` | `T` | No | Additional props forwarded to the matched renderer (generic, typed per renderer) |
102
+
103
+ ### `HyperJumpAPI` (exposed via ref)
104
+
105
+ All renderers expose the same imperative API:
106
+
107
+ | Method | Description |
108
+ | --- | --- |
109
+ | `jump(position: number)` | Jump to a position. Page index for PDF (0-indexed, clamped), seconds for video. |
75
110
 
76
- ### `HyperJumpViewerAPI`
111
+ ### PDF Renderer
77
112
 
78
- | Method | Description |
79
- | --------------------------- | ---------------------------------------------------- |
80
- | `jumpToPage(page: number)` | Scroll to a zero-indexed page. Clamps to valid range.|
113
+ Imported from `@hypercard-ai/hyper-jump/pdf`. Requires `react-pdf` and `react-window` as peer dependencies.
114
+
115
+ #### PDF-specific props
116
+
117
+ | Prop | Type | Required | Description |
118
+ | --- | --- | --- | --- |
119
+ | `scrollBehavior` | `"auto" \| "instant" \| "smooth"` | No | Scroll behavior when navigating between pages (default: `"instant"`) |
120
+
121
+ ### Video Renderer
122
+
123
+ Imported from `@hypercard-ai/hyper-jump/video`. Uses the native HTML `<video>` element — no extra dependencies required.
124
+
125
+ ```tsx
126
+ import { HyperJumpViewer } from "@hypercard-ai/hyper-jump";
127
+ import { VideoRenderer } from "@hypercard-ai/hyper-jump/video";
128
+ import "@hypercard-ai/hyper-jump/video/styles.css";
129
+
130
+ function App() {
131
+ return (
132
+ <HyperJumpViewer
133
+ url="/path/to/video.mp4"
134
+ renderers={[VideoRenderer]}
135
+ />
136
+ );
137
+ }
138
+ ```
139
+
140
+ #### Video-specific props
141
+
142
+ | Prop | Type | Required | Description |
143
+ | --- | --- | --- | --- |
144
+ | `autoPlay` | `boolean` | No | Whether the video should autoplay (default: `false`) |
81
145
 
82
146
  ### Exports
83
147
 
84
- | Export | Type | Description |
85
- | ----------------------- | --------- | ------------------------------------ |
86
- | `HyperJumpViewer` | Component | The PDF viewer component |
87
- | `HyperJumpViewerAPI` | Type | Imperative API exposed via ref |
88
- | `HyperJumpViewerProps` | Type | Props for the viewer component |
89
- | `ZoomConfig` | Type | Zoom configuration interface |
148
+ #### `@hypercard-ai/hyper-jump` (core)
149
+
150
+ | Export | Type | Description |
151
+ | --- | --- | --- |
152
+ | `HyperJumpViewer` | Component | The core viewer component |
153
+ | `HyperJumpViewerProps` | Type | Props for the viewer component |
154
+ | `HyperJumpAPI` | Type | Shared imperative API (`jump`) exposed via ref |
155
+ | `FileRenderer` | Type | Renderer descriptor interface |
156
+ | `RendererProps` | Type | Base props every renderer receives |
157
+ | `ZoomConfig` | Type | Zoom configuration interface |
158
+
159
+ #### `@hypercard-ai/hyper-jump/pdf`
160
+
161
+ | Export | Type | Description |
162
+ | --- | --- | --- |
163
+ | `PdfRenderer` | `FileRenderer` | Renderer descriptor for PDF files |
164
+ | `HyperJumpPdfViewerAPI` | Type | Alias for `HyperJumpAPI` |
165
+ | `HyperJumpPdfViewerProps` | Type | Full props for the PDF renderer |
166
+ | `ScrollBehavior` | Type | Scroll behavior union type |
167
+
168
+ #### `@hypercard-ai/hyper-jump/video`
169
+
170
+ | Export | Type | Description |
171
+ | --- | --- | --- |
172
+ | `VideoRenderer` | `FileRenderer` | Renderer descriptor for video files |
173
+ | `HyperJumpVideoViewerAPI` | Type | Alias for `HyperJumpAPI` |
174
+ | `HyperJumpVideoViewerProps` | Type | Full props for the video renderer |
175
+
176
+ ### Creating a custom renderer
177
+
178
+ Implement the `FileRenderer` interface to add support for any file type:
179
+
180
+ ```tsx
181
+ import type { FileRenderer, RendererProps } from "@hypercard-ai/hyper-jump";
182
+
183
+ const MyVideoRenderer: FileRenderer = {
184
+ type: "video",
185
+ extensions: ["mp4", "webm", "mov"],
186
+ Component: ({ url, containerWidth, containerHeight, ...props }) => (
187
+ <video src={url} width={containerWidth} height={containerHeight} controls />
188
+ ),
189
+ };
190
+
191
+ <HyperJumpViewer url="/clip.mp4" renderers={[PdfRenderer, MyVideoRenderer]} />
192
+ ```
90
193
 
91
194
  ## Requirements
92
195
 
93
196
  - React 19+
94
- - react-pdf 10+
197
+ - react-pdf 10+ (when using `PdfRenderer`)
198
+ - react-window 2+ (when using `PdfRenderer`)
95
199
 
96
200
  ## Development
97
201
 
package/dist/index.css CHANGED
@@ -1,4 +1,4 @@
1
- /* src/styles.css */
1
+ /* src/viewer/viewer.css */
2
2
  .hj-viewer {
3
3
  position: relative;
4
4
  display: flex;
@@ -8,139 +8,4 @@
8
8
  width: 100%;
9
9
  overflow: hidden;
10
10
  }
11
- .hj-viewer .react-pdf__Document {
12
- height: 100%;
13
- width: 100%;
14
- }
15
- .hj-page {
16
- display: flex;
17
- align-items: center;
18
- justify-content: center;
19
- }
20
- .hj-loading {
21
- display: flex;
22
- align-items: center;
23
- justify-content: center;
24
- width: 100%;
25
- height: 100%;
26
- background: #fff;
27
- }
28
- .hj-spinner {
29
- width: 32px;
30
- height: 32px;
31
- border: 3px solid #e9ecef;
32
- border-top-color: #228be6;
33
- border-radius: 50%;
34
- animation: hj-spin 0.6s linear infinite;
35
- }
36
- @keyframes hj-spin {
37
- to {
38
- transform: rotate(360deg);
39
- }
40
- }
41
- .hj-error {
42
- display: flex;
43
- align-items: center;
44
- justify-content: center;
45
- width: 100%;
46
- height: 100%;
47
- background: #fff;
48
- color: #495057;
49
- font-size: 14px;
50
- }
51
- .hj-controls {
52
- position: absolute;
53
- bottom: 12px;
54
- left: 12px;
55
- right: 12px;
56
- display: flex;
57
- justify-content: center;
58
- align-items: center;
59
- z-index: 10;
60
- }
61
- .hj-controls-bar {
62
- display: flex;
63
- align-items: center;
64
- gap: 12px;
65
- padding: 6px 12px;
66
- background: #fff;
67
- border: 1px solid #dee2e6;
68
- border-radius: 8px;
69
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
70
- }
71
- .hj-controls-group {
72
- display: flex;
73
- align-items: center;
74
- gap: 6px;
75
- }
76
- .hj-divider {
77
- width: 1px;
78
- height: 24px;
79
- background: #dee2e6;
80
- }
81
- .hj-btn {
82
- display: inline-flex;
83
- align-items: center;
84
- justify-content: center;
85
- padding: 4px 12px;
86
- font-size: 13px;
87
- font-family: inherit;
88
- line-height: 1.4;
89
- border: 1px solid #dee2e6;
90
- border-radius: 4px;
91
- background: #fff;
92
- color: #212529;
93
- cursor: pointer;
94
- user-select: none;
95
- white-space: nowrap;
96
- }
97
- .hj-btn:hover:not(:disabled) {
98
- background: #f8f9fa;
99
- }
100
- .hj-btn:disabled {
101
- opacity: 0.5;
102
- cursor: not-allowed;
103
- }
104
- .hj-icon-btn {
105
- display: inline-flex;
106
- align-items: center;
107
- justify-content: center;
108
- width: 28px;
109
- height: 28px;
110
- padding: 0;
111
- border: 1px solid #dee2e6;
112
- border-radius: 4px;
113
- background: #fff;
114
- color: #212529;
115
- cursor: pointer;
116
- }
117
- .hj-icon-btn:hover:not(:disabled) {
118
- background: #f8f9fa;
119
- }
120
- .hj-icon-btn:disabled {
121
- opacity: 0.5;
122
- cursor: not-allowed;
123
- }
124
- .hj-page-indicator {
125
- font-size: 13px;
126
- min-width: 50px;
127
- text-align: center;
128
- color: #212529;
129
- user-select: none;
130
- }
131
- .hj-select {
132
- font-size: 13px;
133
- font-family: inherit;
134
- padding: 4px 8px;
135
- border: 1px solid #dee2e6;
136
- border-radius: 4px;
137
- background: #fff;
138
- color: #212529;
139
- cursor: pointer;
140
- min-width: 120px;
141
- }
142
- .hj-select:focus {
143
- outline: 2px solid #228be6;
144
- outline-offset: -1px;
145
- }
146
11
  /*# sourceMappingURL=index.css.map */
@@ -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\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":[]}
1
+ {"version":3,"sources":["../src/viewer/viewer.css"],"sourcesContent":["/* HyperJump Viewer */\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"],"mappings":";AAEA,CAAC;AACA,YAAU;AACV,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,UAAQ;AACR,SAAO;AACP,YAAU;AACX;","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,25 +1,23 @@
1
+ import { F as FileRenderer, H as HyperJumpAPI } from './types-Ce3M8ej7.js';
2
+ export { R as RendererProps, Z as ZoomConfig } from './types-Ce3M8ej7.js';
1
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
4
 
3
- type ZoomMode = "automatic" | "page-width" | "manual";
4
- interface ZoomConfig {
5
- mode: ZoomMode;
6
- value: number;
7
- }
8
-
9
- interface HyperJumpViewerAPI {
10
- /** Imperatively scroll to a page (0-indexed). Clamps to valid range. */
11
- jumpToPage: (page: number) => void;
12
- }
13
- interface HyperJumpViewerProps {
14
- /** URL of the PDF file to display */
5
+ interface HyperJumpViewerProps<T extends Record<string, unknown> = Record<string, unknown>> {
6
+ /** URL of the file to display */
15
7
  url: string;
16
- /** Page to show when the document first loads (0-indexed) */
17
- initialPage?: number;
18
- /** Called when the visible page changes (0-indexed) */
19
- onPageChange?: (page: number) => void;
20
- /** Ref exposing imperative jumpToPage method */
21
- ref?: React.Ref<HyperJumpViewerAPI>;
8
+ /** Explicit file type override (e.g. "pdf", "video"). If omitted, detected from URL extension. */
9
+ type?: string;
10
+ /** Renderers that this viewer can use. The first matching renderer wins. */
11
+ renderers: FileRenderer[];
12
+ /** Ref forwarded to the active renderer (e.g. for imperative APIs like jump). */
13
+ ref?: React.Ref<HyperJumpAPI>;
14
+ /** Initial position to show when the content first loads. Meaning depends on renderer (page index for PDF, seconds for video). */
15
+ initialPosition?: number;
16
+ /** Called when the current position changes. Meaning depends on renderer (page index for PDF, seconds for video). */
17
+ onPositionChange?: (position: number) => void;
18
+ /** Additional props forwarded to the matched renderer. */
19
+ rendererProps?: T;
22
20
  }
23
- declare function HyperJumpViewer(props: HyperJumpViewerProps): react_jsx_runtime.JSX.Element;
21
+ declare function HyperJumpViewer<T extends Record<string, unknown> = Record<string, unknown>>(props: HyperJumpViewerProps<T>): react_jsx_runtime.JSX.Element;
24
22
 
25
- export { HyperJumpViewer, type HyperJumpViewerAPI, type HyperJumpViewerProps, type ZoomConfig };
23
+ export { FileRenderer, HyperJumpAPI, HyperJumpViewer, type HyperJumpViewerProps };