@hypercard-ai/hyper-jump 0.3.2 → 1.0.2
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 +135 -32
- package/dist/index.css +1 -139
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +4 -28
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -306
- package/dist/index.js.map +1 -1
- package/dist/lib/types.d.ts +31 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/use-element-size.d.ts +6 -0
- package/dist/lib/use-element-size.d.ts.map +1 -0
- package/dist/pdf/constants.d.ts +3 -0
- package/dist/pdf/constants.d.ts.map +1 -0
- package/dist/pdf/controls.d.ts +13 -0
- package/dist/pdf/controls.d.ts.map +1 -0
- package/dist/pdf/error-page.d.ts +3 -0
- package/dist/pdf/error-page.d.ts.map +1 -0
- package/dist/pdf/index.css +148 -0
- package/dist/pdf/index.css.map +1 -0
- package/dist/pdf/index.d.ts +3 -0
- package/dist/pdf/index.d.ts.map +1 -0
- package/dist/pdf/index.js +315 -0
- package/dist/pdf/index.js.map +1 -0
- package/dist/pdf/loading-page.d.ts +3 -0
- package/dist/pdf/loading-page.d.ts.map +1 -0
- package/dist/pdf/pdf-viewer.d.ts +13 -0
- package/dist/pdf/pdf-viewer.d.ts.map +1 -0
- package/dist/pdf/renderer.d.ts +8 -0
- package/dist/pdf/renderer.d.ts.map +1 -0
- package/dist/pdf/utils.d.ts +6 -0
- package/dist/pdf/utils.d.ts.map +1 -0
- package/dist/pdf/viewer.stories.d.ts +11 -0
- package/dist/pdf/viewer.stories.d.ts.map +1 -0
- package/dist/video/index.css +18 -0
- package/dist/video/index.css.map +1 -0
- package/dist/video/index.d.ts +3 -0
- package/dist/video/index.d.ts.map +1 -0
- package/dist/video/index.js +48 -0
- package/dist/video/index.js.map +1 -0
- package/dist/video/video-viewer.d.ts +10 -0
- package/dist/video/video-viewer.d.ts.map +1 -0
- package/dist/video/viewer.stories.d.ts +9 -0
- package/dist/video/viewer.stories.d.ts.map +1 -0
- package/dist/viewer/viewer.d.ts +20 -0
- package/dist/viewer/viewer.d.ts.map +1 -0
- package/package.json +26 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pdf/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,GACd,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
// src/pdf/pdf-viewer.tsx
|
|
2
|
+
import {
|
|
3
|
+
forwardRef,
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useImperativeHandle,
|
|
7
|
+
useMemo,
|
|
8
|
+
useRef,
|
|
9
|
+
useState
|
|
10
|
+
} from "react";
|
|
11
|
+
import { Document, pdfjs } from "react-pdf";
|
|
12
|
+
import "react-pdf/dist/Page/AnnotationLayer.css";
|
|
13
|
+
import "react-pdf/dist/Page/TextLayer.css";
|
|
14
|
+
import { List } from "react-window";
|
|
15
|
+
|
|
16
|
+
// src/pdf/controls.tsx
|
|
17
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
18
|
+
var ZOOM_OPTIONS = [
|
|
19
|
+
{ label: "Auto Width", value: "automatic" },
|
|
20
|
+
{ label: "50%", value: "0.5" },
|
|
21
|
+
{ label: "75%", value: "0.75" },
|
|
22
|
+
{ label: "100%", value: "1" },
|
|
23
|
+
{ label: "125%", value: "1.25" },
|
|
24
|
+
{ label: "150%", value: "1.5" },
|
|
25
|
+
{ label: "200%", value: "2" },
|
|
26
|
+
{ label: "300%", value: "3" },
|
|
27
|
+
{ label: "400%", value: "4" }
|
|
28
|
+
];
|
|
29
|
+
function ChevronLeft() {
|
|
30
|
+
return /* @__PURE__ */ jsxs(
|
|
31
|
+
"svg",
|
|
32
|
+
{
|
|
33
|
+
width: "16",
|
|
34
|
+
height: "16",
|
|
35
|
+
viewBox: "0 0 24 24",
|
|
36
|
+
fill: "none",
|
|
37
|
+
stroke: "currentColor",
|
|
38
|
+
strokeWidth: "2",
|
|
39
|
+
strokeLinecap: "round",
|
|
40
|
+
strokeLinejoin: "round",
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ jsx("title", { children: "Previous Page" }),
|
|
43
|
+
/* @__PURE__ */ jsx("path", { d: "M15 18l-6-6 6-6" })
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
function ChevronRight() {
|
|
49
|
+
return /* @__PURE__ */ jsxs(
|
|
50
|
+
"svg",
|
|
51
|
+
{
|
|
52
|
+
width: "16",
|
|
53
|
+
height: "16",
|
|
54
|
+
viewBox: "0 0 24 24",
|
|
55
|
+
fill: "none",
|
|
56
|
+
stroke: "currentColor",
|
|
57
|
+
strokeWidth: "2",
|
|
58
|
+
strokeLinecap: "round",
|
|
59
|
+
strokeLinejoin: "round",
|
|
60
|
+
children: [
|
|
61
|
+
/* @__PURE__ */ jsx("title", { children: "Next Page" }),
|
|
62
|
+
/* @__PURE__ */ jsx("path", { d: "M9 18l6-6-6 6" })
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
function PDFViewerControls(props) {
|
|
68
|
+
const {
|
|
69
|
+
onChangeZoom,
|
|
70
|
+
pageIndex,
|
|
71
|
+
numPages,
|
|
72
|
+
zoomConfig,
|
|
73
|
+
onNextPage,
|
|
74
|
+
onPrevPage
|
|
75
|
+
} = props;
|
|
76
|
+
const zoomValue = zoomConfig.mode === "automatic" || zoomConfig.mode === "page-width" ? zoomConfig.mode : zoomConfig.value.toString();
|
|
77
|
+
return /* @__PURE__ */ jsx("div", { className: "hj-controls", children: /* @__PURE__ */ jsxs("div", { className: "hj-controls-bar", children: [
|
|
78
|
+
/* @__PURE__ */ jsxs("div", { className: "hj-controls-group", children: [
|
|
79
|
+
/* @__PURE__ */ jsx(
|
|
80
|
+
"button",
|
|
81
|
+
{
|
|
82
|
+
type: "button",
|
|
83
|
+
className: "hj-icon-btn",
|
|
84
|
+
onClick: onPrevPage,
|
|
85
|
+
disabled: pageIndex <= 0,
|
|
86
|
+
"aria-label": "Previous Page",
|
|
87
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, {})
|
|
88
|
+
}
|
|
89
|
+
),
|
|
90
|
+
/* @__PURE__ */ jsxs("span", { className: "hj-page-indicator", children: [
|
|
91
|
+
pageIndex + 1,
|
|
92
|
+
" / ",
|
|
93
|
+
numPages
|
|
94
|
+
] }),
|
|
95
|
+
/* @__PURE__ */ jsx(
|
|
96
|
+
"button",
|
|
97
|
+
{
|
|
98
|
+
type: "button",
|
|
99
|
+
className: "hj-icon-btn",
|
|
100
|
+
onClick: onNextPage,
|
|
101
|
+
disabled: pageIndex >= numPages - 1,
|
|
102
|
+
"aria-label": "Next Page",
|
|
103
|
+
children: /* @__PURE__ */ jsx(ChevronRight, {})
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
] }),
|
|
107
|
+
/* @__PURE__ */ jsx("div", { className: "hj-divider" }),
|
|
108
|
+
/* @__PURE__ */ jsx(
|
|
109
|
+
"select",
|
|
110
|
+
{
|
|
111
|
+
className: "hj-select",
|
|
112
|
+
value: zoomValue,
|
|
113
|
+
onChange: (e) => onChangeZoom(e.target.value),
|
|
114
|
+
"aria-label": "Zoom Level",
|
|
115
|
+
children: ZOOM_OPTIONS.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
] }) });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/pdf/error-page.tsx
|
|
122
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
123
|
+
function PDFErrorPage() {
|
|
124
|
+
return /* @__PURE__ */ jsx2("div", { className: "hj-error", children: "Error loading file" });
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/pdf/loading-page.tsx
|
|
128
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
129
|
+
function PDFLoadingPage() {
|
|
130
|
+
return /* @__PURE__ */ jsx3("div", { className: "hj-loading", children: /* @__PURE__ */ jsx3("div", { className: "hj-spinner" }) });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/pdf/renderer.tsx
|
|
134
|
+
import { Page } from "react-pdf";
|
|
135
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
136
|
+
function PDFPageRenderer(props) {
|
|
137
|
+
const { index, style, scale } = props;
|
|
138
|
+
return /* @__PURE__ */ jsx4("div", { className: "hj-page", style, children: /* @__PURE__ */ jsx4(Page, { pageIndex: index, scale, loading: PDFLoadingPage }) });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// src/pdf/constants.ts
|
|
142
|
+
var PAGE_HEIGHT = 842;
|
|
143
|
+
var PAGE_WIDTH = 595;
|
|
144
|
+
|
|
145
|
+
// src/pdf/utils.ts
|
|
146
|
+
async function getPageDimensions(document, scale) {
|
|
147
|
+
const dims = [];
|
|
148
|
+
for (let i = 1; i <= document.numPages; i++) {
|
|
149
|
+
try {
|
|
150
|
+
const page = await document.getPage(i);
|
|
151
|
+
const viewport = page.getViewport({ scale });
|
|
152
|
+
const { height, width } = viewport;
|
|
153
|
+
dims.push({ height, width });
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.error("Failed to get page dimensions", error);
|
|
156
|
+
dims.push({
|
|
157
|
+
width: PAGE_WIDTH,
|
|
158
|
+
height: PAGE_HEIGHT
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return dims;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/pdf/pdf-viewer.tsx
|
|
166
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
167
|
+
pdfjs.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;
|
|
168
|
+
var PAGE_MARGIN = 12;
|
|
169
|
+
var PdfViewerComponent = forwardRef(function PdfViewerComponent2(props, ref) {
|
|
170
|
+
const {
|
|
171
|
+
url,
|
|
172
|
+
initialPosition,
|
|
173
|
+
onPositionChange,
|
|
174
|
+
scrollBehavior = "instant"
|
|
175
|
+
} = props;
|
|
176
|
+
const [document, setDocument] = useState();
|
|
177
|
+
const [pageIndex, setPageIndex] = useState(0);
|
|
178
|
+
const [pageDimensions, setPageDimensions] = useState([]);
|
|
179
|
+
const [zoomConfig, setZoomConfig] = useState({
|
|
180
|
+
mode: "automatic",
|
|
181
|
+
value: 1
|
|
182
|
+
});
|
|
183
|
+
const scrollPageRef = useRef(0);
|
|
184
|
+
const listRef = useRef(null);
|
|
185
|
+
const numPages = useMemo(() => {
|
|
186
|
+
return document?.numPages || 0;
|
|
187
|
+
}, [document]);
|
|
188
|
+
useEffect(() => {
|
|
189
|
+
if (document) {
|
|
190
|
+
getPageDimensions(document, zoomConfig.value).then((value) => {
|
|
191
|
+
setPageDimensions(value);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}, [document, zoomConfig]);
|
|
195
|
+
const scrollToPage = useCallback(
|
|
196
|
+
(target) => {
|
|
197
|
+
if (numPages === 0 || pageDimensions.length !== numPages) return;
|
|
198
|
+
const clamped = Math.max(0, Math.min(Math.floor(target), numPages - 1));
|
|
199
|
+
listRef.current?.scrollToRow({
|
|
200
|
+
index: clamped,
|
|
201
|
+
align: "start",
|
|
202
|
+
behavior: scrollBehavior
|
|
203
|
+
});
|
|
204
|
+
setPageIndex(clamped);
|
|
205
|
+
},
|
|
206
|
+
[numPages, pageDimensions, scrollBehavior]
|
|
207
|
+
);
|
|
208
|
+
useImperativeHandle(ref, () => ({ jump: scrollToPage }), [scrollToPage]);
|
|
209
|
+
const hasAppliedInitialPosition = useRef(false);
|
|
210
|
+
const onLoadSuccess = useCallback((response) => {
|
|
211
|
+
hasAppliedInitialPosition.current = false;
|
|
212
|
+
setDocument(response);
|
|
213
|
+
}, []);
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
if (!hasAppliedInitialPosition.current && initialPosition !== void 0 && pageDimensions.length === numPages && numPages > 0) {
|
|
216
|
+
hasAppliedInitialPosition.current = true;
|
|
217
|
+
const id = requestAnimationFrame(() => scrollToPage(initialPosition));
|
|
218
|
+
return () => cancelAnimationFrame(id);
|
|
219
|
+
}
|
|
220
|
+
}, [initialPosition, pageDimensions, numPages, scrollToPage]);
|
|
221
|
+
const file = useMemo(() => {
|
|
222
|
+
return { url };
|
|
223
|
+
}, [url]);
|
|
224
|
+
const onPrevPage = useCallback(() => {
|
|
225
|
+
if (pageIndex > 0) {
|
|
226
|
+
const newPageIndex = pageIndex - 1;
|
|
227
|
+
listRef.current?.scrollToRow({
|
|
228
|
+
index: newPageIndex,
|
|
229
|
+
align: "start",
|
|
230
|
+
behavior: scrollBehavior
|
|
231
|
+
});
|
|
232
|
+
setPageIndex(newPageIndex);
|
|
233
|
+
}
|
|
234
|
+
}, [pageIndex, scrollBehavior]);
|
|
235
|
+
const onNextPage = useCallback(() => {
|
|
236
|
+
if (pageIndex < numPages - 1) {
|
|
237
|
+
const newPageIndex = pageIndex + 1;
|
|
238
|
+
listRef.current?.scrollToRow({
|
|
239
|
+
index: newPageIndex,
|
|
240
|
+
align: "start",
|
|
241
|
+
behavior: scrollBehavior
|
|
242
|
+
});
|
|
243
|
+
setPageIndex(newPageIndex);
|
|
244
|
+
}
|
|
245
|
+
}, [pageIndex, numPages, scrollBehavior]);
|
|
246
|
+
const onChangeZoom = useCallback((value) => {
|
|
247
|
+
if (value === "automatic") {
|
|
248
|
+
setZoomConfig({ mode: "automatic", value: 1 });
|
|
249
|
+
} else {
|
|
250
|
+
setZoomConfig({ mode: "manual", value: Number.parseFloat(value) });
|
|
251
|
+
}
|
|
252
|
+
}, []);
|
|
253
|
+
const getItemSize = useCallback(
|
|
254
|
+
(index) => {
|
|
255
|
+
if (pageDimensions[index]) {
|
|
256
|
+
return pageDimensions[index].height + PAGE_MARGIN;
|
|
257
|
+
}
|
|
258
|
+
return 0;
|
|
259
|
+
},
|
|
260
|
+
[pageDimensions]
|
|
261
|
+
);
|
|
262
|
+
const onRowsRendered = useCallback(
|
|
263
|
+
(visibleRows) => {
|
|
264
|
+
const prev = scrollPageRef.current;
|
|
265
|
+
scrollPageRef.current = visibleRows.startIndex;
|
|
266
|
+
if (visibleRows.startIndex !== prev) {
|
|
267
|
+
setPageIndex(visibleRows.startIndex);
|
|
268
|
+
onPositionChange?.(visibleRows.startIndex);
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
[onPositionChange]
|
|
272
|
+
);
|
|
273
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
274
|
+
file ? /* @__PURE__ */ jsx5(
|
|
275
|
+
Document,
|
|
276
|
+
{
|
|
277
|
+
file,
|
|
278
|
+
onLoadSuccess,
|
|
279
|
+
error: PDFErrorPage,
|
|
280
|
+
loading: PDFLoadingPage,
|
|
281
|
+
children: pageDimensions.length > 0 && pageDimensions.length === numPages && /* @__PURE__ */ jsx5(
|
|
282
|
+
List,
|
|
283
|
+
{
|
|
284
|
+
listRef,
|
|
285
|
+
rowCount: numPages,
|
|
286
|
+
rowHeight: getItemSize,
|
|
287
|
+
onRowsRendered,
|
|
288
|
+
rowProps: { scale: zoomConfig.value },
|
|
289
|
+
rowComponent: PDFPageRenderer
|
|
290
|
+
}
|
|
291
|
+
)
|
|
292
|
+
}
|
|
293
|
+
) : /* @__PURE__ */ jsx5(PDFLoadingPage, {}),
|
|
294
|
+
/* @__PURE__ */ jsx5(
|
|
295
|
+
PDFViewerControls,
|
|
296
|
+
{
|
|
297
|
+
pageIndex,
|
|
298
|
+
numPages,
|
|
299
|
+
onPrevPage,
|
|
300
|
+
onNextPage,
|
|
301
|
+
zoomConfig,
|
|
302
|
+
onChangeZoom
|
|
303
|
+
}
|
|
304
|
+
)
|
|
305
|
+
] });
|
|
306
|
+
});
|
|
307
|
+
var PdfRenderer = {
|
|
308
|
+
type: "pdf",
|
|
309
|
+
extensions: ["pdf"],
|
|
310
|
+
Component: PdfViewerComponent
|
|
311
|
+
};
|
|
312
|
+
export {
|
|
313
|
+
PdfRenderer
|
|
314
|
+
};
|
|
315
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/pdf/pdf-viewer.tsx","../../src/pdf/controls.tsx","../../src/pdf/error-page.tsx","../../src/pdf/loading-page.tsx","../../src/pdf/renderer.tsx","../../src/pdf/constants.ts","../../src/pdf/utils.ts"],"sourcesContent":["import type { PDFDocumentProxy } from \"pdfjs-dist\";\nimport {\n\tforwardRef,\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 type {\n\tFileRenderer,\n\tHyperJumpAPI,\n\tRendererProps,\n\tZoomConfig,\n} from \"../lib/types\";\nimport PDFViewerControls from \"./controls\";\nimport PDFErrorPage from \"./error-page\";\nimport PDFLoadingPage from \"./loading-page\";\nimport \"./pdf-viewer.css\";\nimport PDFPageRenderer from \"./renderer\";\nimport { getPageDimensions } from \"./utils\";\n\npdfjs.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;\n\nconst PAGE_MARGIN = 12;\n\nexport type HyperJumpPdfViewerAPI = HyperJumpAPI;\n\nexport type ScrollBehavior = \"auto\" | \"instant\" | \"smooth\";\n\nexport interface HyperJumpPdfViewerProps extends RendererProps {\n\t/** Scroll behavior when navigating between pages (default: \"instant\") */\n\tscrollBehavior?: ScrollBehavior;\n}\n\nconst PdfViewerComponent = forwardRef<\n\tHyperJumpPdfViewerAPI,\n\tHyperJumpPdfViewerProps\n>(function PdfViewerComponent(props, ref) {\n\tconst {\n\t\turl,\n\t\tinitialPosition,\n\t\tonPositionChange,\n\t\tscrollBehavior = \"instant\",\n\t} = 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 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({\n\t\t\t\tindex: clamped,\n\t\t\t\talign: \"start\",\n\t\t\t\tbehavior: scrollBehavior,\n\t\t\t});\n\t\t\tsetPageIndex(clamped);\n\t\t},\n\t\t[numPages, pageDimensions, scrollBehavior],\n\t);\n\n\tuseImperativeHandle(ref, () => ({ jump: scrollToPage }), [scrollToPage]);\n\n\tconst hasAppliedInitialPosition = useRef(false);\n\n\tconst onLoadSuccess: OnDocumentLoadSuccess = useCallback((response) => {\n\t\thasAppliedInitialPosition.current = false;\n\t\tsetDocument(response);\n\t}, []);\n\n\t// Scroll to initialPosition once when dimensions are first available.\n\t// Deferred by a frame so the List's scroll container is fully initialized.\n\tuseEffect(() => {\n\t\tif (\n\t\t\t!hasAppliedInitialPosition.current &&\n\t\t\tinitialPosition !== undefined &&\n\t\t\tpageDimensions.length === numPages &&\n\t\t\tnumPages > 0\n\t\t) {\n\t\t\thasAppliedInitialPosition.current = true;\n\t\t\tconst id = requestAnimationFrame(() => scrollToPage(initialPosition));\n\t\t\treturn () => cancelAnimationFrame(id);\n\t\t}\n\t}, [initialPosition, 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({\n\t\t\t\tindex: newPageIndex,\n\t\t\t\talign: \"start\",\n\t\t\t\tbehavior: scrollBehavior,\n\t\t\t});\n\t\t\tsetPageIndex(newPageIndex);\n\t\t}\n\t}, [pageIndex, scrollBehavior]);\n\n\tconst onNextPage = useCallback(() => {\n\t\tif (pageIndex < numPages - 1) {\n\t\t\tconst newPageIndex = pageIndex + 1;\n\t\t\tlistRef.current?.scrollToRow({\n\t\t\t\tindex: newPageIndex,\n\t\t\t\talign: \"start\",\n\t\t\t\tbehavior: scrollBehavior,\n\t\t\t});\n\t\t\tsetPageIndex(newPageIndex);\n\t\t}\n\t}, [pageIndex, numPages, scrollBehavior]);\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\tonPositionChange?.(visibleRows.startIndex);\n\t\t\t}\n\t\t},\n\t\t[onPositionChange],\n\t);\n\n\treturn (\n\t\t<>\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</>\n\t);\n});\n\n/** Renderer descriptor for PDF files. Pass this to HyperJumpViewer's `renderers` prop. */\nexport const PdfRenderer: FileRenderer = {\n\ttype: \"pdf\",\n\textensions: [\"pdf\"],\n\tComponent: PdfViewerComponent as React.ComponentType<\n\t\tRendererProps & Record<string, unknown>\n\t>,\n};\n","import \"./controls.css\";\nimport type { ZoomConfig } from \"../lib/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","import \"./error-page.css\";\n\nexport default function PDFErrorPage() {\n\treturn <div className=\"hj-error\">Error loading file</div>;\n}\n","import \"./loading-page.css\";\n\nexport 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\";\nimport \"./renderer.css\";\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","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":"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","names":["jsx","jsx","jsx","jsx","jsxs","PdfViewerComponent"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loading-page.d.ts","sourceRoot":"","sources":["../../src/pdf/loading-page.tsx"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAC;AAE5B,MAAM,CAAC,OAAO,UAAU,cAAc,4CAMrC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import "react-pdf/dist/Page/AnnotationLayer.css";
|
|
2
|
+
import "react-pdf/dist/Page/TextLayer.css";
|
|
3
|
+
import type { FileRenderer, HyperJumpAPI, RendererProps } from "../lib/types";
|
|
4
|
+
import "./pdf-viewer.css";
|
|
5
|
+
export type HyperJumpPdfViewerAPI = HyperJumpAPI;
|
|
6
|
+
export type ScrollBehavior = "auto" | "instant" | "smooth";
|
|
7
|
+
export interface HyperJumpPdfViewerProps extends RendererProps {
|
|
8
|
+
/** Scroll behavior when navigating between pages (default: "instant") */
|
|
9
|
+
scrollBehavior?: ScrollBehavior;
|
|
10
|
+
}
|
|
11
|
+
/** Renderer descriptor for PDF files. Pass this to HyperJumpViewer's `renderers` prop. */
|
|
12
|
+
export declare const PdfRenderer: FileRenderer;
|
|
13
|
+
//# sourceMappingURL=pdf-viewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf-viewer.d.ts","sourceRoot":"","sources":["../../src/pdf/pdf-viewer.tsx"],"names":[],"mappings":"AAWA,OAAO,yCAAyC,CAAC;AACjD,OAAO,mCAAmC,CAAC;AAG3C,OAAO,KAAK,EACX,YAAY,EACZ,YAAY,EACZ,aAAa,EAEb,MAAM,cAAc,CAAC;AAItB,OAAO,kBAAkB,CAAC;AAQ1B,MAAM,MAAM,qBAAqB,GAAG,YAAY,CAAC;AAEjD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,uBAAwB,SAAQ,aAAa;IAC7D,yEAAyE;IACzE,cAAc,CAAC,EAAE,cAAc,CAAC;CAChC;AAwKD,0FAA0F;AAC1F,eAAO,MAAM,WAAW,EAAE,YAMzB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RowComponentProps } from "react-window";
|
|
2
|
+
import "./renderer.css";
|
|
3
|
+
interface RowProps {
|
|
4
|
+
scale: number;
|
|
5
|
+
}
|
|
6
|
+
export default function PDFPageRenderer(props: RowComponentProps<RowProps>): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/pdf/renderer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,gBAAgB,CAAC;AAExB,UAAU,QAAQ;IACjB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,KAAK,EAAE,iBAAiB,CAAC,QAAQ,CAAC,2CAOzE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/pdf/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,wBAAsB,iBAAiB,CACtC,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,MAAM;;;KAkBb"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { StoryObj } from "@storybook/react";
|
|
2
|
+
import { HyperJumpViewer } from "../viewer/viewer";
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof HyperJumpViewer;
|
|
6
|
+
};
|
|
7
|
+
export default meta;
|
|
8
|
+
export declare const CitationJumps: StoryObj<typeof meta>;
|
|
9
|
+
export declare const Loading: StoryObj<typeof meta>;
|
|
10
|
+
export declare const ErrorState: StoryObj<typeof meta>;
|
|
11
|
+
//# sourceMappingURL=viewer.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewer.stories.d.ts","sourceRoot":"","sources":["../../src/pdf/viewer.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAKnD,QAAA,MAAM,IAAI;;;CAG8B,CAAC;AAEzC,eAAe,IAAI,CAAC;AAwEpB,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,OAAO,IAAI,CAyL/C,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,CASzC,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,OAAO,IAAI,CAS5C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* src/video/video-viewer.css */
|
|
2
|
+
.hj-video {
|
|
3
|
+
position: relative;
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
height: 100%;
|
|
8
|
+
width: 100%;
|
|
9
|
+
padding: 16px;
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
}
|
|
13
|
+
.hj-video video {
|
|
14
|
+
max-width: 100%;
|
|
15
|
+
max-height: 100%;
|
|
16
|
+
object-fit: contain;
|
|
17
|
+
}
|
|
18
|
+
/*# sourceMappingURL=index.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/video/video-viewer.css"],"sourcesContent":[".hj-video {\n\tposition: relative;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\theight: 100%;\n\twidth: 100%;\n\tpadding: 16px;\n\tbox-sizing: border-box;\n\toverflow: hidden;\n}\n\n.hj-video video {\n\tmax-width: 100%;\n\tmax-height: 100%;\n\tobject-fit: contain;\n}\n"],"mappings":";AAAA,CAAC;AACA,YAAU;AACV,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,UAAQ;AACR,SAAO;AACP,WAAS;AACT,cAAY;AACZ,YAAU;AACX;AAEA,CAZC,SAYS;AACT,aAAW;AACX,cAAY;AACZ,cAAY;AACb;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/video/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,uBAAuB,EACvB,yBAAyB,GACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// src/video/video-viewer.tsx
|
|
2
|
+
import { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
var VideoViewerComponent = forwardRef(function VideoViewerComponent2(props, ref) {
|
|
5
|
+
const { url, autoPlay = false, initialPosition, onPositionChange } = props;
|
|
6
|
+
const videoRef = useRef(null);
|
|
7
|
+
const hasAppliedInitialPosition = useRef(false);
|
|
8
|
+
useImperativeHandle(
|
|
9
|
+
ref,
|
|
10
|
+
() => ({
|
|
11
|
+
jump: (position) => {
|
|
12
|
+
if (videoRef.current) {
|
|
13
|
+
videoRef.current.currentTime = position;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}),
|
|
17
|
+
[]
|
|
18
|
+
);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!hasAppliedInitialPosition.current && initialPosition !== void 0 && videoRef.current) {
|
|
21
|
+
hasAppliedInitialPosition.current = true;
|
|
22
|
+
videoRef.current.currentTime = initialPosition;
|
|
23
|
+
}
|
|
24
|
+
}, [initialPosition]);
|
|
25
|
+
return /* @__PURE__ */ jsx("div", { className: "hj-video", children: /* @__PURE__ */ jsx(
|
|
26
|
+
"video",
|
|
27
|
+
{
|
|
28
|
+
ref: videoRef,
|
|
29
|
+
src: url,
|
|
30
|
+
autoPlay,
|
|
31
|
+
controls: true,
|
|
32
|
+
onTimeUpdate: () => {
|
|
33
|
+
if (videoRef.current) {
|
|
34
|
+
onPositionChange?.(videoRef.current.currentTime);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
) });
|
|
39
|
+
});
|
|
40
|
+
var VideoRenderer = {
|
|
41
|
+
type: "video",
|
|
42
|
+
extensions: ["mp4", "mov", "webm", "ogg"],
|
|
43
|
+
Component: VideoViewerComponent
|
|
44
|
+
};
|
|
45
|
+
export {
|
|
46
|
+
VideoRenderer
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/video/video-viewer.tsx"],"sourcesContent":["import { forwardRef, useEffect, useImperativeHandle, useRef } from \"react\";\nimport type { FileRenderer, HyperJumpAPI, RendererProps } from \"../lib/types\";\nimport \"./video-viewer.css\";\n\nexport type HyperJumpVideoViewerAPI = HyperJumpAPI;\n\nexport interface HyperJumpVideoViewerProps extends RendererProps {\n\t/** Whether the video should autoplay (default: false). */\n\tautoPlay?: boolean;\n}\n\nconst VideoViewerComponent = forwardRef<\n\tHyperJumpVideoViewerAPI,\n\tHyperJumpVideoViewerProps\n>(function VideoViewerComponent(props, ref) {\n\tconst { url, autoPlay = false, initialPosition, onPositionChange } = props;\n\tconst videoRef = useRef<HTMLVideoElement>(null);\n\tconst hasAppliedInitialPosition = useRef(false);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\tjump: (position: number) => {\n\t\t\t\tif (videoRef.current) {\n\t\t\t\t\tvideoRef.current.currentTime = position;\n\t\t\t\t}\n\t\t\t},\n\t\t}),\n\t\t[],\n\t);\n\n\tuseEffect(() => {\n\t\tif (\n\t\t\t!hasAppliedInitialPosition.current &&\n\t\t\tinitialPosition !== undefined &&\n\t\t\tvideoRef.current\n\t\t) {\n\t\t\thasAppliedInitialPosition.current = true;\n\t\t\tvideoRef.current.currentTime = initialPosition;\n\t\t}\n\t}, [initialPosition]);\n\n\treturn (\n\t\t<div className=\"hj-video\">\n\t\t\t{/* biome-ignore lint/a11y/useMediaCaption: captions are the consumer's responsibility */}\n\t\t\t<video\n\t\t\t\tref={videoRef}\n\t\t\t\tsrc={url}\n\t\t\t\tautoPlay={autoPlay}\n\t\t\t\tcontrols\n\t\t\t\tonTimeUpdate={() => {\n\t\t\t\t\tif (videoRef.current) {\n\t\t\t\t\t\tonPositionChange?.(videoRef.current.currentTime);\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t/>\n\t\t</div>\n\t);\n});\n\n/** Renderer descriptor for video files. Pass this to HyperJumpViewer's `renderers` prop. */\nexport const VideoRenderer: FileRenderer = {\n\ttype: \"video\",\n\textensions: [\"mp4\", \"mov\", \"webm\", \"ogg\"],\n\tComponent: VideoViewerComponent as React.ComponentType<\n\t\tRendererProps & Record<string, unknown>\n\t>,\n};\n"],"mappings":";AAAA,SAAS,YAAY,WAAW,qBAAqB,cAAc;AA6ChE;AAlCH,IAAM,uBAAuB,WAG3B,SAASA,sBAAqB,OAAO,KAAK;AAC3C,QAAM,EAAE,KAAK,WAAW,OAAO,iBAAiB,iBAAiB,IAAI;AACrE,QAAM,WAAW,OAAyB,IAAI;AAC9C,QAAM,4BAA4B,OAAO,KAAK;AAE9C;AAAA,IACC;AAAA,IACA,OAAO;AAAA,MACN,MAAM,CAAC,aAAqB;AAC3B,YAAI,SAAS,SAAS;AACrB,mBAAS,QAAQ,cAAc;AAAA,QAChC;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAC;AAAA,EACF;AAEA,YAAU,MAAM;AACf,QACC,CAAC,0BAA0B,WAC3B,oBAAoB,UACpB,SAAS,SACR;AACD,gCAA0B,UAAU;AACpC,eAAS,QAAQ,cAAc;AAAA,IAChC;AAAA,EACD,GAAG,CAAC,eAAe,CAAC;AAEpB,SACC,oBAAC,SAAI,WAAU,YAEd;AAAA,IAAC;AAAA;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA,UAAQ;AAAA,MACR,cAAc,MAAM;AACnB,YAAI,SAAS,SAAS;AACrB,6BAAmB,SAAS,QAAQ,WAAW;AAAA,QAChD;AAAA,MACD;AAAA;AAAA,EACD,GACD;AAEF,CAAC;AAGM,IAAM,gBAA8B;AAAA,EAC1C,MAAM;AAAA,EACN,YAAY,CAAC,OAAO,OAAO,QAAQ,KAAK;AAAA,EACxC,WAAW;AAGZ;","names":["VideoViewerComponent"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FileRenderer, HyperJumpAPI, RendererProps } from "../lib/types";
|
|
2
|
+
import "./video-viewer.css";
|
|
3
|
+
export type HyperJumpVideoViewerAPI = HyperJumpAPI;
|
|
4
|
+
export interface HyperJumpVideoViewerProps extends RendererProps {
|
|
5
|
+
/** Whether the video should autoplay (default: false). */
|
|
6
|
+
autoPlay?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** Renderer descriptor for video files. Pass this to HyperJumpViewer's `renderers` prop. */
|
|
9
|
+
export declare const VideoRenderer: FileRenderer;
|
|
10
|
+
//# sourceMappingURL=video-viewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"video-viewer.d.ts","sourceRoot":"","sources":["../../src/video/video-viewer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,oBAAoB,CAAC;AAE5B,MAAM,MAAM,uBAAuB,GAAG,YAAY,CAAC;AAEnD,MAAM,WAAW,yBAA0B,SAAQ,aAAa;IAC/D,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAmDD,4FAA4F;AAC5F,eAAO,MAAM,aAAa,EAAE,YAM3B,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { StoryObj } from "@storybook/react";
|
|
2
|
+
import { HyperJumpViewer } from "../viewer/viewer";
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof HyperJumpViewer;
|
|
6
|
+
};
|
|
7
|
+
export default meta;
|
|
8
|
+
export declare const Playground: StoryObj<typeof meta>;
|
|
9
|
+
//# sourceMappingURL=viewer.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewer.stories.d.ts","sourceRoot":"","sources":["../../src/video/viewer.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGnD,QAAA,MAAM,IAAI;;;CAG8B,CAAC;AAEzC,eAAe,IAAI,CAAC;AAapB,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,OAAO,IAAI,CAyI5C,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { FileRenderer, HyperJumpAPI } from "../lib/types";
|
|
2
|
+
import "./viewer.css";
|
|
3
|
+
export interface HyperJumpViewerProps<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
4
|
+
/** URL of the file to display */
|
|
5
|
+
url: string;
|
|
6
|
+
/** Explicit file type override (e.g. "pdf", "video"). If omitted, detected from URL extension. */
|
|
7
|
+
type?: string;
|
|
8
|
+
/** Renderers that this viewer can use. The first matching renderer wins. */
|
|
9
|
+
renderers: FileRenderer[];
|
|
10
|
+
/** Ref forwarded to the active renderer (e.g. for imperative APIs like jump). */
|
|
11
|
+
ref?: React.Ref<HyperJumpAPI>;
|
|
12
|
+
/** Initial position to show when the content first loads. Meaning depends on renderer (page index for PDF, seconds for video). */
|
|
13
|
+
initialPosition?: number;
|
|
14
|
+
/** Called when the current position changes. Meaning depends on renderer (page index for PDF, seconds for video). */
|
|
15
|
+
onPositionChange?: (position: number) => void;
|
|
16
|
+
/** Additional props forwarded to the matched renderer. */
|
|
17
|
+
rendererProps?: T;
|
|
18
|
+
}
|
|
19
|
+
export declare function HyperJumpViewer<T extends Record<string, unknown> = Record<string, unknown>>(props: HyperJumpViewerProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=viewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewer.d.ts","sourceRoot":"","sources":["../../src/viewer/viewer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,cAAc,CAAC;AAEtB,MAAM,WAAW,oBAAoB,CACpC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAE3D,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,kGAAkG;IAClG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,iFAAiF;IACjF,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC9B,kIAAkI;IAClI,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qHAAqH;IACrH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,0DAA0D;IAC1D,aAAa,CAAC,EAAE,CAAC,CAAC;CAClB;AAaD,wBAAgB,eAAe,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1D,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,2CAwC/B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypercard-ai/hyper-jump",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Document viewer built for RAG",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "HyperCard AI",
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
16
16
|
"pdf",
|
|
17
|
+
"video",
|
|
17
18
|
"viewer",
|
|
18
19
|
"react",
|
|
19
20
|
"rag",
|
|
20
|
-
"virtualized"
|
|
21
|
-
"react-pdf"
|
|
21
|
+
"virtualized"
|
|
22
22
|
],
|
|
23
23
|
"type": "module",
|
|
24
24
|
"module": "./dist/index.js",
|
|
@@ -28,7 +28,17 @@
|
|
|
28
28
|
"types": "./dist/index.d.ts",
|
|
29
29
|
"default": "./dist/index.js"
|
|
30
30
|
},
|
|
31
|
-
"./
|
|
31
|
+
"./pdf": {
|
|
32
|
+
"types": "./dist/pdf/index.d.ts",
|
|
33
|
+
"default": "./dist/pdf/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./styles.css": "./dist/index.css",
|
|
36
|
+
"./pdf/styles.css": "./dist/pdf/index.css",
|
|
37
|
+
"./video": {
|
|
38
|
+
"types": "./dist/video/index.d.ts",
|
|
39
|
+
"default": "./dist/video/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./video/styles.css": "./dist/video/index.css"
|
|
32
42
|
},
|
|
33
43
|
"files": [
|
|
34
44
|
"dist",
|
|
@@ -42,7 +52,7 @@
|
|
|
42
52
|
"access": "public"
|
|
43
53
|
},
|
|
44
54
|
"scripts": {
|
|
45
|
-
"build": "tsup",
|
|
55
|
+
"build": "tsup && tsc --emitDeclarationOnly --outDir dist",
|
|
46
56
|
"dev": "tsup --watch",
|
|
47
57
|
"test": "vitest run",
|
|
48
58
|
"test:watch": "vitest",
|
|
@@ -56,7 +66,16 @@
|
|
|
56
66
|
"peerDependencies": {
|
|
57
67
|
"react": ">=19.0.0",
|
|
58
68
|
"react-dom": ">=19.0.0",
|
|
59
|
-
"react-pdf": ">=10.0.0"
|
|
69
|
+
"react-pdf": ">=10.0.0",
|
|
70
|
+
"react-window": ">=2.0.0"
|
|
71
|
+
},
|
|
72
|
+
"peerDependenciesMeta": {
|
|
73
|
+
"react-pdf": {
|
|
74
|
+
"optional": true
|
|
75
|
+
},
|
|
76
|
+
"react-window": {
|
|
77
|
+
"optional": true
|
|
78
|
+
}
|
|
60
79
|
},
|
|
61
80
|
"devDependencies": {
|
|
62
81
|
"@biomejs/biome": "2.3.15",
|
|
@@ -70,12 +89,10 @@
|
|
|
70
89
|
"react": "^19.2.4",
|
|
71
90
|
"react-dom": "^19.2.4",
|
|
72
91
|
"react-pdf": "10.3.0",
|
|
92
|
+
"react-window": "^2.2.7",
|
|
73
93
|
"storybook": "^10.2.8",
|
|
74
94
|
"tsup": "^8.5.1",
|
|
75
95
|
"typescript": "^5.9.3",
|
|
76
96
|
"vitest": "^4.0.18"
|
|
77
|
-
},
|
|
78
|
-
"dependencies": {
|
|
79
|
-
"react-window": "^2.2.7"
|
|
80
97
|
}
|
|
81
98
|
}
|