@peeekpage/viewer 0.3.13
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 +91 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +788 -0
- package/dist/peeekviewer.css +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# @peeekpage/viewer
|
|
2
|
+
|
|
3
|
+
Embeddable document viewers for [peeek.page](https://peeek.page). This package
|
|
4
|
+
ships **PeeekViewer**, an animated 3D flipbook React component. It reads the
|
|
5
|
+
preview manifest that the renderer writes to your bucket and renders the page
|
|
6
|
+
images. No telemetry, no runtime dependencies.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @peeekpage/viewer
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
React 18+ is a peer dependency.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { PeeekViewer } from '@peeekpage/viewer'
|
|
20
|
+
import '@peeekpage/viewer/styles.css'
|
|
21
|
+
|
|
22
|
+
export function Preview() {
|
|
23
|
+
return (
|
|
24
|
+
<PeeekViewer
|
|
25
|
+
src="https://your-bucket.example.com/previews/doc-123/manifest.json"
|
|
26
|
+
accentColor="#0362FC"
|
|
27
|
+
layout="double"
|
|
28
|
+
downloadUrl="https://your-bucket.example.com/originals/doc-123.pdf"
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### In-memory pages
|
|
35
|
+
|
|
36
|
+
When the host already holds the rendered page URLs (e.g. a live render it is
|
|
37
|
+
polling itself), pass them via `pages` instead of `src`. No fetch happens, and
|
|
38
|
+
the array can grow over time as a render streams in:
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
<PeeekViewer
|
|
42
|
+
mode="coverflow"
|
|
43
|
+
pages={pageUrls} // string[] of presigned image URLs
|
|
44
|
+
filename="report.pdf"
|
|
45
|
+
mimeType="application/pdf"
|
|
46
|
+
/>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Props
|
|
50
|
+
|
|
51
|
+
| Prop | Type | Default | Notes |
|
|
52
|
+
| --- | --- | --- | --- |
|
|
53
|
+
| `src` | `string` | - | Manifest `.json` URL. Required unless `pages` is given. |
|
|
54
|
+
| `pages` | `string[]` | - | In-memory page image URLs. When set, the viewer renders these directly and does not fetch `src`. URLs are sanitized like the manifest path. |
|
|
55
|
+
| `filename` | `string` | - | Header filename for the `pages` path (coverflow). |
|
|
56
|
+
| `mimeType` | `string` | - | Header type badge for the `pages` path (coverflow). |
|
|
57
|
+
| `mode` | `'flip' \| 'coverflow'` | `'flip'` | `flip` is the 3D page-turn book; `coverflow` is a peeking 3D carousel with a header and thumbnail strip. |
|
|
58
|
+
| `logo` | `string` | - | Logo image URL. |
|
|
59
|
+
| `logoLink` | `string` | - | Logo link (http/https only). |
|
|
60
|
+
| `accentColor` | `string` | `#6E79D6` | Hex or `rgb()`. |
|
|
61
|
+
| `background` | `'color' \| 'image' \| 'transparent'` | `'color'` | |
|
|
62
|
+
| `backgroundColor` | `string` | - | Solid or gradient CSS. |
|
|
63
|
+
| `backgroundImage` | `string` | - | Used when `background='image'`. |
|
|
64
|
+
| `layout` | `'single' \| 'double'` | `'double'` | |
|
|
65
|
+
| `pageShadows` | `boolean` | `true` | |
|
|
66
|
+
| `rtl` | `boolean` | `false` | |
|
|
67
|
+
| `animateInteractions` | `boolean` | `true` | |
|
|
68
|
+
| `skin` | `'classic' \| 'minimal'` | `'classic'` | |
|
|
69
|
+
| `language` | `'en' \| 'pt-BR'` | `'en'` | Tooltip language. |
|
|
70
|
+
| `autoTransition` | `boolean` | `false` | |
|
|
71
|
+
| `autoTransitionInterval` | `number` | `5000` | ms. |
|
|
72
|
+
| `navigationControls` | `boolean` | `true` | Master toolbar toggle. |
|
|
73
|
+
| `fullscreen` | `boolean` | `true` | |
|
|
74
|
+
| `arrows` | `boolean` | `true` | |
|
|
75
|
+
| `navigationBar` | `boolean` | `true` | |
|
|
76
|
+
| `pagesOverview` | `boolean` | `true` | Thumbnails. |
|
|
77
|
+
| `downloadUrl` | `string` | - | Shows a download button when set. |
|
|
78
|
+
| `pollInterval` | `number` | `2000` | ms between WIP polls. |
|
|
79
|
+
| `className` | `string` | - | Extra class on the root. |
|
|
80
|
+
|
|
81
|
+
`coverflow` mode honors `logo`/`accentColor`/`background`, `fullscreen`, `arrows`,
|
|
82
|
+
`pagesOverview` (thumbnails), `rtl`, `autoTransition`/`autoTransitionInterval`,
|
|
83
|
+
`downloadUrl` and `language`. The flip-only props (`layout`, `pageShadows`,
|
|
84
|
+
`navigationBar`) are ignored in `coverflow`.
|
|
85
|
+
|
|
86
|
+
## Security
|
|
87
|
+
|
|
88
|
+
All host-provided URLs (`logo`, `logoLink`, `backgroundImage`, `downloadUrl`,
|
|
89
|
+
and every page URL in the manifest) are validated against an http/https
|
|
90
|
+
allowlist before they reach the DOM. The component never injects raw HTML and
|
|
91
|
+
makes no network calls beyond fetching the manifest and loading page images.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { JSX as JSX_2 } from 'react';
|
|
2
|
+
|
|
3
|
+
export declare type Background = 'color' | 'image' | 'transparent';
|
|
4
|
+
|
|
5
|
+
export declare type Lang = (typeof LANGUAGES)[number];
|
|
6
|
+
|
|
7
|
+
declare const LANGUAGES: readonly ["en", "pt-BR"];
|
|
8
|
+
|
|
9
|
+
export declare type Layout = 'single' | 'double';
|
|
10
|
+
|
|
11
|
+
export declare type Mode = 'flip' | 'coverflow';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* PeeekViewer: embeddable document viewer. Reads the worker manifest at `src`
|
|
15
|
+
* (or host-provided `pages`) and renders its pages in the selected mode (flip
|
|
16
|
+
* or coverflow) with branding and a gated toolbar. Every host-provided URL is
|
|
17
|
+
* sanitized before it reaches the DOM.
|
|
18
|
+
*/
|
|
19
|
+
export declare function PeeekViewer(props: PeeekViewerProps): JSX_2.Element;
|
|
20
|
+
|
|
21
|
+
export declare interface PeeekViewerProps {
|
|
22
|
+
src?: string;
|
|
23
|
+
pages?: string[];
|
|
24
|
+
filename?: string;
|
|
25
|
+
mimeType?: string;
|
|
26
|
+
mode?: Mode;
|
|
27
|
+
logo?: string;
|
|
28
|
+
logoLink?: string;
|
|
29
|
+
accentColor?: string;
|
|
30
|
+
background?: Background;
|
|
31
|
+
backgroundColor?: string;
|
|
32
|
+
backgroundImage?: string;
|
|
33
|
+
layout?: Layout;
|
|
34
|
+
fillHeight?: boolean;
|
|
35
|
+
pageShadows?: boolean;
|
|
36
|
+
rtl?: boolean;
|
|
37
|
+
animateInteractions?: boolean;
|
|
38
|
+
skin?: Skin;
|
|
39
|
+
language?: Lang;
|
|
40
|
+
autoTransition?: boolean;
|
|
41
|
+
autoTransitionInterval?: number;
|
|
42
|
+
navigationControls?: boolean;
|
|
43
|
+
fullscreen?: boolean;
|
|
44
|
+
arrows?: boolean;
|
|
45
|
+
navigationBar?: boolean;
|
|
46
|
+
pagesOverview?: boolean;
|
|
47
|
+
downloadUrl?: string;
|
|
48
|
+
pollInterval?: number;
|
|
49
|
+
className?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export declare type Skin = 'classic' | 'minimal' | 'showcase';
|
|
53
|
+
|
|
54
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,788 @@
|
|
|
1
|
+
import { jsxs as v, jsx as o, Fragment as Ue } from "react/jsx-runtime";
|
|
2
|
+
import { useState as T, useRef as U, useEffect as $, useCallback as S, useMemo as Be } from "react";
|
|
3
|
+
const De = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
4
|
+
function Z(t) {
|
|
5
|
+
if (typeof t != "string") return null;
|
|
6
|
+
const e = t.trim();
|
|
7
|
+
if (e === "" || e.includes(" ")) return null;
|
|
8
|
+
const n = typeof window < "u" ? window.location.href : void 0;
|
|
9
|
+
let r;
|
|
10
|
+
try {
|
|
11
|
+
r = new URL(e, n);
|
|
12
|
+
} catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return De.has(r.protocol) ? r.href : null;
|
|
16
|
+
}
|
|
17
|
+
const je = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/, Xe = /^rgba?\([ \t]*\d{1,3}[ \t]*,[ \t]*\d{1,3}[ \t]*,[ \t]*\d{1,3}[ \t]*(?:,[ \t]*(?:0|1|0?\.\d+)[ \t]*)?\)$/;
|
|
18
|
+
function me(t) {
|
|
19
|
+
if (typeof t != "string") return null;
|
|
20
|
+
const e = t.trim();
|
|
21
|
+
return je.test(e) || Xe.test(e) ? e : null;
|
|
22
|
+
}
|
|
23
|
+
const He = /url\(|image\(|image-set\(|element\(|expression|@|\/\*|;|\{|\}|<|>|\\/i, Ge = /^(repeating-)?(linear|radial|conic)-gradient\([a-z0-9#.,%()\/\s-]*\)$/i, Ye = /^hsla?\([a-z0-9.,%\/\s-]*\)$/i;
|
|
24
|
+
function Ve(t) {
|
|
25
|
+
if (typeof t != "string") return null;
|
|
26
|
+
const e = t.trim();
|
|
27
|
+
if (e === "" || He.test(e)) return null;
|
|
28
|
+
const n = me(e);
|
|
29
|
+
return n !== null ? n : Ye.test(e) || Ge.test(e) ? e : null;
|
|
30
|
+
}
|
|
31
|
+
const We = ["en", "pt-BR"], ge = {
|
|
32
|
+
prev: "Previous page",
|
|
33
|
+
next: "Next page",
|
|
34
|
+
zoom: "Zoom level",
|
|
35
|
+
zoomIn: "Zoom in",
|
|
36
|
+
zoomOut: "Zoom out",
|
|
37
|
+
thumbnails: "Page thumbnails",
|
|
38
|
+
fullscreen: "Fullscreen",
|
|
39
|
+
openFullscreen: "View page fullscreen",
|
|
40
|
+
download: "Download",
|
|
41
|
+
page: "page",
|
|
42
|
+
pages: "pages",
|
|
43
|
+
loading: "Loading document…",
|
|
44
|
+
error: "Could not load this document."
|
|
45
|
+
}, qe = {
|
|
46
|
+
prev: "Página anterior",
|
|
47
|
+
next: "Próxima página",
|
|
48
|
+
zoom: "Nível de zoom",
|
|
49
|
+
zoomIn: "Ampliar",
|
|
50
|
+
zoomOut: "Reduzir",
|
|
51
|
+
thumbnails: "Miniaturas das páginas",
|
|
52
|
+
fullscreen: "Tela cheia",
|
|
53
|
+
openFullscreen: "Ver página em tela cheia",
|
|
54
|
+
download: "Baixar",
|
|
55
|
+
page: "página",
|
|
56
|
+
pages: "páginas",
|
|
57
|
+
loading: "Carregando documento…",
|
|
58
|
+
error: "Não foi possível carregar este documento."
|
|
59
|
+
}, Je = { en: ge, "pt-BR": qe };
|
|
60
|
+
function Ke(t) {
|
|
61
|
+
return Je[t] ?? ge;
|
|
62
|
+
}
|
|
63
|
+
const Qe = "#6E79D6";
|
|
64
|
+
function C(t, e) {
|
|
65
|
+
return typeof t == "boolean" ? t : e;
|
|
66
|
+
}
|
|
67
|
+
function j(t, e, n) {
|
|
68
|
+
return e.includes(t) ? t : n;
|
|
69
|
+
}
|
|
70
|
+
function et(t) {
|
|
71
|
+
return {
|
|
72
|
+
src: typeof t.src == "string" ? t.src : "",
|
|
73
|
+
mode: j(t.mode, ["flip", "coverflow"], "flip"),
|
|
74
|
+
logo: Z(t.logo),
|
|
75
|
+
logoLink: Z(t.logoLink),
|
|
76
|
+
accentColor: me(t.accentColor) ?? Qe,
|
|
77
|
+
background: j(t.background, ["color", "image", "transparent"], "color"),
|
|
78
|
+
backgroundColor: Ve(t.backgroundColor),
|
|
79
|
+
backgroundImage: Z(t.backgroundImage),
|
|
80
|
+
layout: j(t.layout, ["single", "double"], "double"),
|
|
81
|
+
fillHeight: C(t.fillHeight, !1),
|
|
82
|
+
pageShadows: C(t.pageShadows, !0),
|
|
83
|
+
rtl: C(t.rtl, !1),
|
|
84
|
+
animateInteractions: C(t.animateInteractions, !0),
|
|
85
|
+
skin: j(t.skin, ["classic", "minimal", "showcase"], "classic"),
|
|
86
|
+
language: j(t.language, We, "en"),
|
|
87
|
+
autoTransition: C(t.autoTransition, !1),
|
|
88
|
+
autoTransitionInterval: typeof t.autoTransitionInterval == "number" && t.autoTransitionInterval > 0 ? t.autoTransitionInterval : 5e3,
|
|
89
|
+
navigationControls: C(t.navigationControls, !0),
|
|
90
|
+
fullscreen: C(t.fullscreen, !0),
|
|
91
|
+
arrows: C(t.arrows, !0),
|
|
92
|
+
navigationBar: C(t.navigationBar, !0),
|
|
93
|
+
pagesOverview: C(t.pagesOverview, !0),
|
|
94
|
+
downloadUrl: Z(t.downloadUrl),
|
|
95
|
+
pollInterval: typeof t.pollInterval == "number" && t.pollInterval > 0 ? t.pollInterval : 2e3,
|
|
96
|
+
className: typeof t.className == "string" ? t.className : ""
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const ne = 5e3;
|
|
100
|
+
function X(t) {
|
|
101
|
+
return typeof t == "string" ? t : "";
|
|
102
|
+
}
|
|
103
|
+
function tt(t) {
|
|
104
|
+
if (t === null || typeof t != "object" || Array.isArray(t))
|
|
105
|
+
return { ok: !1, error: "manifest is not an object" };
|
|
106
|
+
const e = t;
|
|
107
|
+
if (!Array.isArray(e.pages))
|
|
108
|
+
return { ok: !1, error: "manifest.pages is missing or not an array" };
|
|
109
|
+
if (e.pages.length > ne)
|
|
110
|
+
return { ok: !1, error: "manifest.pages exceeds the maximum" };
|
|
111
|
+
const n = e.total_pages, r = typeof n == "number" && Number.isFinite(n) && n >= 0 ? n : e.pages.length;
|
|
112
|
+
if (r > ne)
|
|
113
|
+
return { ok: !1, error: "manifest.total_pages exceeds the maximum" };
|
|
114
|
+
const l = [];
|
|
115
|
+
for (const g of e.pages) {
|
|
116
|
+
if (g === null || typeof g != "object") continue;
|
|
117
|
+
const s = Z(g.url);
|
|
118
|
+
s && l.push(s);
|
|
119
|
+
}
|
|
120
|
+
if (l.length === 0)
|
|
121
|
+
return { ok: !1, error: "manifest has no usable pages" };
|
|
122
|
+
const c = e.status === "wip" ? "wip" : "done", f = e.metadata && typeof e.metadata == "object" ? e.metadata : {}, h = {
|
|
123
|
+
fileId: X(f.file_id),
|
|
124
|
+
filename: X(f.filename),
|
|
125
|
+
creationDate: X(f.creation_date),
|
|
126
|
+
fileSize: X(f.file_size),
|
|
127
|
+
mimeType: X(f.mime_type)
|
|
128
|
+
};
|
|
129
|
+
return {
|
|
130
|
+
ok: !0,
|
|
131
|
+
value: { status: c, totalPages: r, pages: l, metadata: h }
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function nt(t, e) {
|
|
135
|
+
if (!Array.isArray(t) || t.length > ne) return null;
|
|
136
|
+
const n = [];
|
|
137
|
+
for (const l of t) {
|
|
138
|
+
const c = Z(l);
|
|
139
|
+
c && n.push(c);
|
|
140
|
+
}
|
|
141
|
+
return n.length === 0 ? null : {
|
|
142
|
+
status: "done",
|
|
143
|
+
totalPages: typeof e.total == "number" && Number.isFinite(e.total) && e.total > n.length ? e.total : n.length,
|
|
144
|
+
pages: n,
|
|
145
|
+
metadata: {
|
|
146
|
+
fileId: "",
|
|
147
|
+
filename: typeof e.filename == "string" ? e.filename : "",
|
|
148
|
+
creationDate: "",
|
|
149
|
+
fileSize: "",
|
|
150
|
+
mimeType: typeof e.mimeType == "string" ? e.mimeType : ""
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function rt(t, e) {
|
|
155
|
+
const [n, r] = T("loading"), [l, c] = T(null), [f, h] = T(null), g = U(null);
|
|
156
|
+
return $(() => {
|
|
157
|
+
let s = !1;
|
|
158
|
+
if (r("loading"), c(null), h(null), !t) return;
|
|
159
|
+
const b = () => {
|
|
160
|
+
g.current !== null && (clearTimeout(g.current), g.current = null);
|
|
161
|
+
}, p = async () => {
|
|
162
|
+
let u;
|
|
163
|
+
try {
|
|
164
|
+
const _ = await fetch(t);
|
|
165
|
+
if (!_.ok) throw new Error(`HTTP ${_.status}`);
|
|
166
|
+
u = await _.json();
|
|
167
|
+
} catch (_) {
|
|
168
|
+
if (s) return;
|
|
169
|
+
h(_ instanceof Error ? _.message : "fetch failed"), r("error");
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (s) return;
|
|
173
|
+
const i = tt(u);
|
|
174
|
+
if (!i.ok) {
|
|
175
|
+
h(i.error), r("error");
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
c(i.value), r("ready"), i.value.status === "wip" && (g.current = setTimeout(p, e));
|
|
179
|
+
};
|
|
180
|
+
return p(), () => {
|
|
181
|
+
s = !0, b();
|
|
182
|
+
};
|
|
183
|
+
}, [t, e]), { state: n, manifest: l, error: f };
|
|
184
|
+
}
|
|
185
|
+
function at(t) {
|
|
186
|
+
const [e, n] = T(!1);
|
|
187
|
+
$(() => {
|
|
188
|
+
const l = () => n(document.fullscreenElement != null);
|
|
189
|
+
return document.addEventListener("fullscreenchange", l), () => document.removeEventListener("fullscreenchange", l);
|
|
190
|
+
}, []);
|
|
191
|
+
const r = S(async () => {
|
|
192
|
+
const l = t.current;
|
|
193
|
+
if (l)
|
|
194
|
+
try {
|
|
195
|
+
document.fullscreenElement ? await document.exitFullscreen() : await l.requestFullscreen();
|
|
196
|
+
} catch {
|
|
197
|
+
}
|
|
198
|
+
}, [t]);
|
|
199
|
+
return { isFullscreen: e, toggle: r };
|
|
200
|
+
}
|
|
201
|
+
const fe = "(prefers-reduced-motion: reduce)";
|
|
202
|
+
function pe() {
|
|
203
|
+
const [t, e] = T(() => {
|
|
204
|
+
var n;
|
|
205
|
+
return ((n = matchMedia == null ? void 0 : matchMedia(fe)) == null ? void 0 : n.matches) ?? !1;
|
|
206
|
+
});
|
|
207
|
+
return $(() => {
|
|
208
|
+
const n = typeof matchMedia == "function" ? matchMedia(fe) : void 0;
|
|
209
|
+
if (!(n != null && n.addEventListener)) return;
|
|
210
|
+
const r = () => e(n.matches);
|
|
211
|
+
return n.addEventListener("change", r), () => n.removeEventListener("change", r);
|
|
212
|
+
}, []), t;
|
|
213
|
+
}
|
|
214
|
+
function re(t, e) {
|
|
215
|
+
return t <= 0 ? 0 : e === "single" ? t : 1 + Math.ceil((t - 1) / 2);
|
|
216
|
+
}
|
|
217
|
+
function ot(t, e) {
|
|
218
|
+
return e === "single" ? t : t <= 0 ? 0 : Math.floor((t - 1) / 2) + 1;
|
|
219
|
+
}
|
|
220
|
+
function Y(t, e, n) {
|
|
221
|
+
if (e <= 0) return { left: -1, right: -1 };
|
|
222
|
+
if (n === "single")
|
|
223
|
+
return { left: -1, right: t >= 0 && t < e ? t : -1 };
|
|
224
|
+
if (t <= 0)
|
|
225
|
+
return { left: -1, right: 0 };
|
|
226
|
+
const r = 2 * t - 1, l = 2 * t;
|
|
227
|
+
return { left: r < e ? r : -1, right: l < e ? l : -1 };
|
|
228
|
+
}
|
|
229
|
+
function he(t, e, n) {
|
|
230
|
+
const { left: r, right: l } = Y(t, e, n), c = [];
|
|
231
|
+
return r >= 0 && c.push(r), l >= 0 && c.push(l), c;
|
|
232
|
+
}
|
|
233
|
+
function Q(t, e, n) {
|
|
234
|
+
const r = re(e, n) - 1;
|
|
235
|
+
return t < 0 ? 0 : t > r ? r : t;
|
|
236
|
+
}
|
|
237
|
+
function lt(t) {
|
|
238
|
+
const {
|
|
239
|
+
strings: e,
|
|
240
|
+
label: n,
|
|
241
|
+
progress: r,
|
|
242
|
+
zoom: l,
|
|
243
|
+
minZoom: c,
|
|
244
|
+
maxZoom: f,
|
|
245
|
+
thumbsOpen: h,
|
|
246
|
+
isFullscreen: g,
|
|
247
|
+
downloadUrl: s,
|
|
248
|
+
show: b,
|
|
249
|
+
onZoomIn: p,
|
|
250
|
+
onZoomOut: u,
|
|
251
|
+
onZoomSet: i,
|
|
252
|
+
onToggleThumbs: _,
|
|
253
|
+
onToggleFullscreen: L
|
|
254
|
+
} = t;
|
|
255
|
+
return /* @__PURE__ */ v("div", { className: "peeek__toolbar", children: [
|
|
256
|
+
/* @__PURE__ */ o("span", { className: "peeek__label", children: n }),
|
|
257
|
+
b.bar && /* @__PURE__ */ o("div", { className: "peeek__scrubber", "aria-hidden": !0, children: /* @__PURE__ */ o("div", { className: "peeek__scrubber-fill", style: { width: `${r}%` } }) }),
|
|
258
|
+
/* @__PURE__ */ o(
|
|
259
|
+
"button",
|
|
260
|
+
{
|
|
261
|
+
type: "button",
|
|
262
|
+
className: "peeek__btn",
|
|
263
|
+
"aria-label": e.zoomOut,
|
|
264
|
+
disabled: l <= c,
|
|
265
|
+
onClick: u,
|
|
266
|
+
children: "−"
|
|
267
|
+
}
|
|
268
|
+
),
|
|
269
|
+
/* @__PURE__ */ o(
|
|
270
|
+
"input",
|
|
271
|
+
{
|
|
272
|
+
type: "range",
|
|
273
|
+
"aria-label": e.zoom,
|
|
274
|
+
min: c,
|
|
275
|
+
max: f,
|
|
276
|
+
step: 0.25,
|
|
277
|
+
value: l,
|
|
278
|
+
onChange: (w) => i(Number(w.target.value))
|
|
279
|
+
}
|
|
280
|
+
),
|
|
281
|
+
/* @__PURE__ */ o(
|
|
282
|
+
"button",
|
|
283
|
+
{
|
|
284
|
+
type: "button",
|
|
285
|
+
className: "peeek__btn",
|
|
286
|
+
"aria-label": e.zoomIn,
|
|
287
|
+
disabled: l >= f,
|
|
288
|
+
onClick: p,
|
|
289
|
+
children: "+"
|
|
290
|
+
}
|
|
291
|
+
),
|
|
292
|
+
b.thumbnails && /* @__PURE__ */ o(
|
|
293
|
+
"button",
|
|
294
|
+
{
|
|
295
|
+
type: "button",
|
|
296
|
+
className: `peeek__btn${h ? " peeek__btn--active" : ""}`,
|
|
297
|
+
"aria-label": e.thumbnails,
|
|
298
|
+
"aria-pressed": h,
|
|
299
|
+
onClick: _,
|
|
300
|
+
children: "▦"
|
|
301
|
+
}
|
|
302
|
+
),
|
|
303
|
+
s && /* @__PURE__ */ o(
|
|
304
|
+
"a",
|
|
305
|
+
{
|
|
306
|
+
className: "peeek__btn",
|
|
307
|
+
href: s,
|
|
308
|
+
"aria-label": e.download,
|
|
309
|
+
target: "_blank",
|
|
310
|
+
rel: "noopener noreferrer",
|
|
311
|
+
download: !0,
|
|
312
|
+
children: "↓"
|
|
313
|
+
}
|
|
314
|
+
),
|
|
315
|
+
b.fullscreen && /* @__PURE__ */ o(
|
|
316
|
+
"button",
|
|
317
|
+
{
|
|
318
|
+
type: "button",
|
|
319
|
+
className: `peeek__btn${g ? " peeek__btn--active" : ""}`,
|
|
320
|
+
"aria-label": e.fullscreen,
|
|
321
|
+
"aria-pressed": g,
|
|
322
|
+
onClick: L,
|
|
323
|
+
children: "⛶"
|
|
324
|
+
}
|
|
325
|
+
)
|
|
326
|
+
] });
|
|
327
|
+
}
|
|
328
|
+
function st({ pages: t, layout: e, rtl: n, activePages: r, onJump: l }) {
|
|
329
|
+
const c = t.length, f = new Set(r), h = re(c, e);
|
|
330
|
+
return /* @__PURE__ */ o("div", { className: "peeek__thumbs", role: "group", "aria-label": "Pages", children: Array.from({ length: h }, (g, s) => {
|
|
331
|
+
const b = he(s, c, e), p = b.length === 2;
|
|
332
|
+
return /* @__PURE__ */ v("div", { className: "peeek__thumb-group", children: [
|
|
333
|
+
b.map((u, i) => {
|
|
334
|
+
let _ = "";
|
|
335
|
+
return p && (_ = (n ? i === 1 : i === 0) ? " peeek__thumb--flat-right" : " peeek__thumb--flat-left"), /* @__PURE__ */ o(
|
|
336
|
+
"button",
|
|
337
|
+
{
|
|
338
|
+
type: "button",
|
|
339
|
+
"aria-label": `Go to page ${u + 1}`,
|
|
340
|
+
"aria-current": f.has(u),
|
|
341
|
+
className: `peeek__thumb${f.has(u) ? " peeek__thumb--active" : ""}${_}`,
|
|
342
|
+
onClick: () => l(u),
|
|
343
|
+
children: /* @__PURE__ */ o("img", { src: t[u], alt: "", loading: "lazy", referrerPolicy: "no-referrer" })
|
|
344
|
+
},
|
|
345
|
+
u
|
|
346
|
+
);
|
|
347
|
+
}),
|
|
348
|
+
/* @__PURE__ */ o("span", { className: "peeek__thumb-badge", "aria-hidden": !0, children: b.map((u) => u + 1).join("-") })
|
|
349
|
+
] }, s);
|
|
350
|
+
}) });
|
|
351
|
+
}
|
|
352
|
+
const ee = 1, te = 2, de = 0.25;
|
|
353
|
+
function it(t) {
|
|
354
|
+
const {
|
|
355
|
+
pages: e,
|
|
356
|
+
strings: n,
|
|
357
|
+
layout: r,
|
|
358
|
+
rtl: l,
|
|
359
|
+
pageShadows: c,
|
|
360
|
+
animateInteractions: f,
|
|
361
|
+
autoTransition: h,
|
|
362
|
+
autoTransitionInterval: g,
|
|
363
|
+
show: s,
|
|
364
|
+
downloadUrl: b,
|
|
365
|
+
isFullscreen: p,
|
|
366
|
+
onToggleFullscreen: u
|
|
367
|
+
} = t, i = e.length, _ = re(i, r), w = pe() || !f, [V, z] = T(0), [N, B] = T(1), [H, y] = T(!1), [m, x] = T({ x: 0, y: 0 }), [F, O] = T(!1), G = U(null), ae = U(null), [k, oe] = T(null), le = U(null), [be, _e] = T(0.707);
|
|
368
|
+
$(() => {
|
|
369
|
+
if (!e[0]) return;
|
|
370
|
+
const a = new globalThis.Image();
|
|
371
|
+
a.onload = () => {
|
|
372
|
+
a.naturalWidth && a.naturalHeight && _e(a.naturalWidth / a.naturalHeight);
|
|
373
|
+
}, a.src = e[0];
|
|
374
|
+
}, [e]);
|
|
375
|
+
const P = Q(V, i, r), ke = P <= 0, W = P >= _ - 1, A = S(
|
|
376
|
+
(a) => {
|
|
377
|
+
k || z((d) => {
|
|
378
|
+
const I = Q(d + a, i, r);
|
|
379
|
+
return I === d ? d : w ? I : (oe({ dir: a, to: I }), d);
|
|
380
|
+
});
|
|
381
|
+
},
|
|
382
|
+
[i, r, w, k]
|
|
383
|
+
), ye = S(() => {
|
|
384
|
+
oe((a) => (a && z(a.to), null));
|
|
385
|
+
}, []);
|
|
386
|
+
$(() => {
|
|
387
|
+
if (!k) return;
|
|
388
|
+
const a = le.current;
|
|
389
|
+
if (!a) return;
|
|
390
|
+
a.style.transform = "rotateY(0deg)";
|
|
391
|
+
let d = 0;
|
|
392
|
+
const I = requestAnimationFrame(() => {
|
|
393
|
+
d = requestAnimationFrame(() => {
|
|
394
|
+
a.style.transform = `rotateY(${k.dir === 1 ? -180 : 180}deg)`;
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
return () => {
|
|
398
|
+
cancelAnimationFrame(I), cancelAnimationFrame(d);
|
|
399
|
+
};
|
|
400
|
+
}, [k]);
|
|
401
|
+
const ve = S(
|
|
402
|
+
(a) => {
|
|
403
|
+
z(Q(ot(a, r), i, r));
|
|
404
|
+
},
|
|
405
|
+
[i, r]
|
|
406
|
+
), we = S(
|
|
407
|
+
(a) => {
|
|
408
|
+
a.key === "ArrowRight" ? A(l ? -1 : 1) : a.key === "ArrowLeft" && A(l ? 1 : -1);
|
|
409
|
+
},
|
|
410
|
+
[A, l]
|
|
411
|
+
);
|
|
412
|
+
$(() => {
|
|
413
|
+
if (!h || W) return;
|
|
414
|
+
const a = setTimeout(() => A(1), g);
|
|
415
|
+
return () => clearTimeout(a);
|
|
416
|
+
}, [h, g, W, P, A]);
|
|
417
|
+
const Te = () => B((a) => Math.min(te, a + de)), Ne = () => B((a) => Math.max(ee, a - de)), q = S((a, d, I) => {
|
|
418
|
+
const K = ae.current;
|
|
419
|
+
if (!K || I <= 1) return { x: 0, y: 0 };
|
|
420
|
+
const ce = (I - 1) * K.clientWidth / 2, ue = (I - 1) * K.clientHeight / 2;
|
|
421
|
+
return { x: Math.max(-ce, Math.min(ce, a)), y: Math.max(-ue, Math.min(ue, d)) };
|
|
422
|
+
}, []);
|
|
423
|
+
$(() => x((a) => q(a.x, a.y, N)), [N, q]), $(() => x({ x: 0, y: 0 }), [P]);
|
|
424
|
+
const Ie = (a) => {
|
|
425
|
+
N <= 1 || (G.current = { x: a.clientX, y: a.clientY, px: m.x, py: m.y }, O(!0), a.currentTarget.setPointerCapture(a.pointerId));
|
|
426
|
+
}, xe = (a) => {
|
|
427
|
+
const d = G.current;
|
|
428
|
+
d && x(q(d.px + (a.clientX - d.x), d.py + (a.clientY - d.y), N));
|
|
429
|
+
}, se = (a) => {
|
|
430
|
+
if (G.current) {
|
|
431
|
+
G.current = null, O(!1);
|
|
432
|
+
try {
|
|
433
|
+
a.currentTarget.releasePointerCapture(a.pointerId);
|
|
434
|
+
} catch {
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}, D = he(P, i, r), J = D[0] ?? 0, Ce = r === "double" && D.length === 2 ? `${D[0] + 1} - ${D[1] + 1} / ${i}` : `${J + 1} / ${i}`, $e = _ <= 1 ? 100 : P / (_ - 1) * 100, Fe = n.prev, Pe = n.next, Me = k ? k.to : P, E = Y(Me, i, r), Se = E.left < 0 && E.right >= 0, ze = E.left >= 0 && E.right < 0, Ae = E.left >= 0 && E.right >= 0, Ee = Se ? "-25%" : ze ? "25%" : "0%", M = Y(P, i, r), R = k ? Y(k.to, i, r) : M, Le = k ? k.dir === 1 ? M.right >= 0 ? M.right : M.left : M.left >= 0 ? M.left : M.right : J, Oe = k ? k.dir === 1 ? R.left >= 0 ? R.left : R.right : R.right >= 0 ? R.right : R.left : J, Re = k ? k.dir === 1 ? "left" : "right" : null, ie = (a) => a === Re ? M[a] : E[a], Ze = [
|
|
438
|
+
["left", ie("left")],
|
|
439
|
+
["right", ie("right")]
|
|
440
|
+
];
|
|
441
|
+
return /* @__PURE__ */ v(Ue, { children: [
|
|
442
|
+
/* @__PURE__ */ v(
|
|
443
|
+
"div",
|
|
444
|
+
{
|
|
445
|
+
ref: ae,
|
|
446
|
+
className: "peeek__stage",
|
|
447
|
+
tabIndex: 0,
|
|
448
|
+
onKeyDown: we,
|
|
449
|
+
style: { "--peeek-aspect": `${be}` },
|
|
450
|
+
children: [
|
|
451
|
+
s.arrows && /* @__PURE__ */ o(
|
|
452
|
+
"button",
|
|
453
|
+
{
|
|
454
|
+
type: "button",
|
|
455
|
+
className: "peeek__arrow peeek__arrow--prev",
|
|
456
|
+
"aria-label": Fe,
|
|
457
|
+
disabled: ke,
|
|
458
|
+
onClick: () => A(-1),
|
|
459
|
+
children: "‹"
|
|
460
|
+
}
|
|
461
|
+
),
|
|
462
|
+
/* @__PURE__ */ o(
|
|
463
|
+
"div",
|
|
464
|
+
{
|
|
465
|
+
className: `peeek__zoom${N > 1 ? " peeek__zoom--pannable" : ""}`,
|
|
466
|
+
style: {
|
|
467
|
+
transform: `translate(${m.x}px, ${m.y}px) scale(${N})`,
|
|
468
|
+
transition: w || F ? "none" : void 0
|
|
469
|
+
},
|
|
470
|
+
onPointerDown: Ie,
|
|
471
|
+
onPointerMove: xe,
|
|
472
|
+
onPointerUp: se,
|
|
473
|
+
onPointerCancel: se,
|
|
474
|
+
children: /* @__PURE__ */ v(
|
|
475
|
+
"div",
|
|
476
|
+
{
|
|
477
|
+
className: `peeek__spread${c ? " peeek--shadows" : ""}${Ae ? " peeek__spread--pair" : ""}`,
|
|
478
|
+
style: { transform: `translateX(${Ee})` },
|
|
479
|
+
children: [
|
|
480
|
+
Ze.map(([a, d]) => {
|
|
481
|
+
const I = d >= 0 && s.fullscreen && !p && !k && N === 1;
|
|
482
|
+
return /* @__PURE__ */ o(
|
|
483
|
+
"div",
|
|
484
|
+
{
|
|
485
|
+
className: `peeek__page peeek__page--${a}${d < 0 ? " peeek__page--empty" : ""}`,
|
|
486
|
+
children: d >= 0 && (I ? /* @__PURE__ */ o(
|
|
487
|
+
"button",
|
|
488
|
+
{
|
|
489
|
+
type: "button",
|
|
490
|
+
className: "peeek__page-btn",
|
|
491
|
+
"aria-label": n.openFullscreen,
|
|
492
|
+
onClick: u,
|
|
493
|
+
children: /* @__PURE__ */ o("img", { src: e[d], alt: `Page ${d + 1}`, loading: "lazy", referrerPolicy: "no-referrer" })
|
|
494
|
+
}
|
|
495
|
+
) : /* @__PURE__ */ o("img", { src: e[d], alt: `Page ${d + 1}`, loading: "lazy", referrerPolicy: "no-referrer" }))
|
|
496
|
+
},
|
|
497
|
+
a
|
|
498
|
+
);
|
|
499
|
+
}),
|
|
500
|
+
k && /* @__PURE__ */ v(
|
|
501
|
+
"div",
|
|
502
|
+
{
|
|
503
|
+
ref: le,
|
|
504
|
+
className: `peeek__leaf peeek__leaf--${k.dir === 1 ? "fwd" : "back"}`,
|
|
505
|
+
onTransitionEnd: ye,
|
|
506
|
+
children: [
|
|
507
|
+
/* @__PURE__ */ o("div", { className: "peeek__leaf-face peeek__leaf-face--front", children: /* @__PURE__ */ o("img", { src: e[Le], alt: "", referrerPolicy: "no-referrer" }) }),
|
|
508
|
+
/* @__PURE__ */ o("div", { className: "peeek__leaf-face peeek__leaf-face--back", children: /* @__PURE__ */ o("img", { src: e[Oe], alt: "", referrerPolicy: "no-referrer" }) })
|
|
509
|
+
]
|
|
510
|
+
}
|
|
511
|
+
)
|
|
512
|
+
]
|
|
513
|
+
}
|
|
514
|
+
)
|
|
515
|
+
}
|
|
516
|
+
),
|
|
517
|
+
s.arrows && /* @__PURE__ */ o(
|
|
518
|
+
"button",
|
|
519
|
+
{
|
|
520
|
+
type: "button",
|
|
521
|
+
className: "peeek__arrow peeek__arrow--next",
|
|
522
|
+
"aria-label": Pe,
|
|
523
|
+
disabled: W,
|
|
524
|
+
onClick: () => A(1),
|
|
525
|
+
children: "›"
|
|
526
|
+
}
|
|
527
|
+
)
|
|
528
|
+
]
|
|
529
|
+
}
|
|
530
|
+
),
|
|
531
|
+
s.toolbar && /* @__PURE__ */ o(
|
|
532
|
+
lt,
|
|
533
|
+
{
|
|
534
|
+
strings: n,
|
|
535
|
+
label: Ce,
|
|
536
|
+
progress: $e,
|
|
537
|
+
zoom: N,
|
|
538
|
+
minZoom: ee,
|
|
539
|
+
maxZoom: te,
|
|
540
|
+
thumbsOpen: H,
|
|
541
|
+
isFullscreen: p,
|
|
542
|
+
downloadUrl: b,
|
|
543
|
+
show: { bar: s.bar, fullscreen: s.fullscreen, thumbnails: s.thumbnails && s.overview },
|
|
544
|
+
onZoomIn: Te,
|
|
545
|
+
onZoomOut: Ne,
|
|
546
|
+
onZoomSet: (a) => B(Math.min(te, Math.max(ee, a))),
|
|
547
|
+
onToggleThumbs: () => y((a) => !a),
|
|
548
|
+
onToggleFullscreen: u
|
|
549
|
+
}
|
|
550
|
+
),
|
|
551
|
+
s.overview && H && /* @__PURE__ */ o(st, { pages: e, layout: r, rtl: l, activePages: D, onJump: ve })
|
|
552
|
+
] });
|
|
553
|
+
}
|
|
554
|
+
function ct(t, e) {
|
|
555
|
+
const n = e.toLowerCase();
|
|
556
|
+
if (n.includes("pdf")) return "PDF";
|
|
557
|
+
if (n.includes("wordprocessingml")) return "DOCX";
|
|
558
|
+
if (n.includes("msword")) return "DOC";
|
|
559
|
+
const r = t.toLowerCase().split(".").pop() ?? "";
|
|
560
|
+
return r ? r.toUpperCase().slice(0, 4) : "FILE";
|
|
561
|
+
}
|
|
562
|
+
function ut(t, e) {
|
|
563
|
+
if (t === 0) return { transform: "translateX(0) scale(1)", zIndex: 30, opacity: 1 };
|
|
564
|
+
const n = t < 0 ? -1 : 1, r = e ? -1 : 1;
|
|
565
|
+
return {
|
|
566
|
+
transform: `translateX(${r * n * 62}%) scale(0.82) rotateY(${-r * n * 28}deg)`,
|
|
567
|
+
zIndex: 20 - Math.abs(t),
|
|
568
|
+
opacity: 0.55
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
function ft(t) {
|
|
572
|
+
const {
|
|
573
|
+
pages: e,
|
|
574
|
+
strings: n,
|
|
575
|
+
filename: r,
|
|
576
|
+
mimeType: l,
|
|
577
|
+
rtl: c,
|
|
578
|
+
autoTransition: f,
|
|
579
|
+
autoTransitionInterval: h,
|
|
580
|
+
downloadUrl: g,
|
|
581
|
+
isFullscreen: s,
|
|
582
|
+
onToggleFullscreen: b,
|
|
583
|
+
show: p
|
|
584
|
+
} = t, u = e.length, [i, _] = T(0), L = pe(), w = S(
|
|
585
|
+
(y) => _((m) => Math.max(0, Math.min(u - 1, m + y))),
|
|
586
|
+
[u]
|
|
587
|
+
), V = i <= 0, z = i >= u - 1, N = U([]);
|
|
588
|
+
$(() => {
|
|
589
|
+
var y, m;
|
|
590
|
+
(m = (y = N.current[i]) == null ? void 0 : y.scrollIntoView) == null || m.call(y, { behavior: "smooth", inline: "center", block: "nearest" });
|
|
591
|
+
}, [i]), $(() => {
|
|
592
|
+
if (!f || L || z) return;
|
|
593
|
+
const y = setTimeout(() => w(1), h);
|
|
594
|
+
return () => clearTimeout(y);
|
|
595
|
+
}, [f, h, L, z, i, w]);
|
|
596
|
+
const B = S(
|
|
597
|
+
(y) => {
|
|
598
|
+
y.key === "ArrowRight" ? w(c ? -1 : 1) : y.key === "ArrowLeft" && w(c ? 1 : -1);
|
|
599
|
+
},
|
|
600
|
+
[w, c]
|
|
601
|
+
), H = ct(r, l);
|
|
602
|
+
return /* @__PURE__ */ v("div", { className: "peeek__cf", children: [
|
|
603
|
+
/* @__PURE__ */ v("div", { className: "peeek__cf-header", children: [
|
|
604
|
+
/* @__PURE__ */ o("span", { className: "peeek__cf-badge", children: H }),
|
|
605
|
+
/* @__PURE__ */ v("div", { className: "peeek__cf-meta", children: [
|
|
606
|
+
/* @__PURE__ */ o("span", { className: "peeek__cf-name", children: r }),
|
|
607
|
+
/* @__PURE__ */ v("span", { className: "peeek__cf-count", children: [
|
|
608
|
+
u,
|
|
609
|
+
" ",
|
|
610
|
+
u === 1 ? n.page : n.pages
|
|
611
|
+
] })
|
|
612
|
+
] }),
|
|
613
|
+
/* @__PURE__ */ v("span", { className: "peeek__cf-indicator", children: [
|
|
614
|
+
i + 1,
|
|
615
|
+
" / ",
|
|
616
|
+
u
|
|
617
|
+
] }),
|
|
618
|
+
g && /* @__PURE__ */ o(
|
|
619
|
+
"a",
|
|
620
|
+
{
|
|
621
|
+
className: "peeek__btn",
|
|
622
|
+
href: g,
|
|
623
|
+
"aria-label": n.download,
|
|
624
|
+
target: "_blank",
|
|
625
|
+
rel: "noopener noreferrer",
|
|
626
|
+
download: !0,
|
|
627
|
+
children: "↓"
|
|
628
|
+
}
|
|
629
|
+
),
|
|
630
|
+
p.fullscreen && /* @__PURE__ */ o(
|
|
631
|
+
"button",
|
|
632
|
+
{
|
|
633
|
+
type: "button",
|
|
634
|
+
className: `peeek__btn${s ? " peeek__btn--active" : ""}`,
|
|
635
|
+
"aria-label": n.fullscreen,
|
|
636
|
+
"aria-pressed": s,
|
|
637
|
+
onClick: b,
|
|
638
|
+
children: "⛶"
|
|
639
|
+
}
|
|
640
|
+
)
|
|
641
|
+
] }),
|
|
642
|
+
/* @__PURE__ */ v(
|
|
643
|
+
"div",
|
|
644
|
+
{
|
|
645
|
+
className: "peeek__cf-stage",
|
|
646
|
+
tabIndex: 0,
|
|
647
|
+
onKeyDown: B,
|
|
648
|
+
children: [
|
|
649
|
+
p.arrows && /* @__PURE__ */ o(
|
|
650
|
+
"button",
|
|
651
|
+
{
|
|
652
|
+
type: "button",
|
|
653
|
+
className: "peeek__arrow peeek__arrow--prev",
|
|
654
|
+
"aria-label": n.prev,
|
|
655
|
+
disabled: V,
|
|
656
|
+
onClick: () => w(-1),
|
|
657
|
+
children: "‹"
|
|
658
|
+
}
|
|
659
|
+
),
|
|
660
|
+
e.map((y, m) => {
|
|
661
|
+
const x = m - i;
|
|
662
|
+
if (Math.abs(x) > 1) return null;
|
|
663
|
+
const F = x === 0, O = F && p.fullscreen;
|
|
664
|
+
return /* @__PURE__ */ o(
|
|
665
|
+
"button",
|
|
666
|
+
{
|
|
667
|
+
type: "button",
|
|
668
|
+
className: `peeek__cf-card${F ? " peeek__cf-card--center" : ""}${O ? " peeek__cf-card--zoom" : ""}`,
|
|
669
|
+
style: ut(x, c),
|
|
670
|
+
tabIndex: F ? 0 : -1,
|
|
671
|
+
"aria-label": O ? n.openFullscreen : `Go to page ${m + 1}`,
|
|
672
|
+
onClick: () => O ? b() : _(m),
|
|
673
|
+
children: /* @__PURE__ */ o("img", { src: y, alt: F ? `Page ${m + 1}` : "", loading: "lazy", referrerPolicy: "no-referrer" })
|
|
674
|
+
},
|
|
675
|
+
m
|
|
676
|
+
);
|
|
677
|
+
}),
|
|
678
|
+
p.arrows && /* @__PURE__ */ o(
|
|
679
|
+
"button",
|
|
680
|
+
{
|
|
681
|
+
type: "button",
|
|
682
|
+
className: "peeek__arrow peeek__arrow--next",
|
|
683
|
+
"aria-label": n.next,
|
|
684
|
+
disabled: z,
|
|
685
|
+
onClick: () => w(1),
|
|
686
|
+
children: "›"
|
|
687
|
+
}
|
|
688
|
+
)
|
|
689
|
+
]
|
|
690
|
+
}
|
|
691
|
+
),
|
|
692
|
+
p.thumbnails && /* @__PURE__ */ o("div", { className: "peeek__cf-thumbs", role: "group", "aria-label": "Pages", children: e.map((y, m) => {
|
|
693
|
+
const x = m === i;
|
|
694
|
+
return /* @__PURE__ */ v(
|
|
695
|
+
"button",
|
|
696
|
+
{
|
|
697
|
+
ref: (F) => {
|
|
698
|
+
N.current[m] = F;
|
|
699
|
+
},
|
|
700
|
+
type: "button",
|
|
701
|
+
className: `peeek__cf-thumb${x ? " peeek__cf-thumb--active" : ""}`,
|
|
702
|
+
"aria-label": `Go to page ${m + 1}`,
|
|
703
|
+
"aria-current": x ? "page" : void 0,
|
|
704
|
+
onClick: () => _(m),
|
|
705
|
+
children: [
|
|
706
|
+
/* @__PURE__ */ o("img", { src: y, alt: "", loading: "lazy", referrerPolicy: "no-referrer" }),
|
|
707
|
+
/* @__PURE__ */ o("span", { className: "peeek__cf-thumb-num", children: String(m + 1).padStart(2, "0") })
|
|
708
|
+
]
|
|
709
|
+
},
|
|
710
|
+
m
|
|
711
|
+
);
|
|
712
|
+
}) })
|
|
713
|
+
] });
|
|
714
|
+
}
|
|
715
|
+
function dt({ logo: t, logoLink: e }) {
|
|
716
|
+
if (!t) return null;
|
|
717
|
+
const n = /* @__PURE__ */ o("img", { src: t, alt: "Logo", loading: "lazy", referrerPolicy: "no-referrer" });
|
|
718
|
+
return /* @__PURE__ */ o("div", { className: "peeek__branding", children: e ? /* @__PURE__ */ o("a", { href: e, target: "_blank", rel: "noopener noreferrer", children: n }) : n });
|
|
719
|
+
}
|
|
720
|
+
function pt(t) {
|
|
721
|
+
const e = et(t), n = Ke(e.language), r = U(null), { isFullscreen: l, toggle: c } = at(r), f = t.pages !== void 0, h = Be(
|
|
722
|
+
() => f ? nt(t.pages, { filename: t.filename, mimeType: t.mimeType }) : null,
|
|
723
|
+
[f, t.pages, t.filename, t.mimeType]
|
|
724
|
+
), g = rt(f ? null : e.src, e.pollInterval), s = f ? h : g.manifest, b = f ? h ? "ready" : "loading" : g.state, p = {
|
|
725
|
+
"--peeek-accent": e.accentColor
|
|
726
|
+
};
|
|
727
|
+
e.background === "transparent" ? p["--peeek-bg"] = "transparent" : e.background === "color" && e.backgroundColor ? p["--peeek-bg"] = e.backgroundColor : e.background === "image" && e.backgroundImage && (p["--peeek-bg"] = `center / cover no-repeat url("${e.backgroundImage}")`);
|
|
728
|
+
const u = {
|
|
729
|
+
toolbar: e.navigationControls,
|
|
730
|
+
bar: e.navigationBar,
|
|
731
|
+
fullscreen: e.fullscreen,
|
|
732
|
+
thumbnails: e.pagesOverview,
|
|
733
|
+
arrows: e.arrows,
|
|
734
|
+
overview: e.pagesOverview
|
|
735
|
+
};
|
|
736
|
+
return /* @__PURE__ */ v(
|
|
737
|
+
"div",
|
|
738
|
+
{
|
|
739
|
+
ref: r,
|
|
740
|
+
className: `peeek${e.fillHeight ? " peeek--fill-height" : ""}${e.className ? " " + e.className : ""}`,
|
|
741
|
+
"data-skin": e.skin,
|
|
742
|
+
"data-layout": e.layout,
|
|
743
|
+
dir: e.rtl ? "rtl" : void 0,
|
|
744
|
+
style: p,
|
|
745
|
+
children: [
|
|
746
|
+
/* @__PURE__ */ o(dt, { logo: e.logo, logoLink: e.logoLink }),
|
|
747
|
+
b === "loading" && /* @__PURE__ */ o("div", { className: "peeek__state", children: n.loading }),
|
|
748
|
+
b === "error" && /* @__PURE__ */ o("div", { className: "peeek__state", children: n.error }),
|
|
749
|
+
b === "ready" && s && e.mode === "coverflow" && /* @__PURE__ */ o(
|
|
750
|
+
ft,
|
|
751
|
+
{
|
|
752
|
+
pages: s.pages,
|
|
753
|
+
strings: n,
|
|
754
|
+
filename: s.metadata.filename,
|
|
755
|
+
mimeType: s.metadata.mimeType,
|
|
756
|
+
rtl: e.rtl,
|
|
757
|
+
autoTransition: e.autoTransition,
|
|
758
|
+
autoTransitionInterval: e.autoTransitionInterval,
|
|
759
|
+
downloadUrl: e.downloadUrl,
|
|
760
|
+
isFullscreen: l,
|
|
761
|
+
onToggleFullscreen: c,
|
|
762
|
+
show: { arrows: e.arrows, thumbnails: e.pagesOverview, fullscreen: e.fullscreen }
|
|
763
|
+
}
|
|
764
|
+
),
|
|
765
|
+
b === "ready" && s && e.mode === "flip" && /* @__PURE__ */ o(
|
|
766
|
+
it,
|
|
767
|
+
{
|
|
768
|
+
pages: s.pages,
|
|
769
|
+
strings: n,
|
|
770
|
+
layout: e.layout,
|
|
771
|
+
rtl: e.rtl,
|
|
772
|
+
pageShadows: e.pageShadows,
|
|
773
|
+
animateInteractions: e.animateInteractions,
|
|
774
|
+
autoTransition: e.autoTransition,
|
|
775
|
+
autoTransitionInterval: e.autoTransitionInterval,
|
|
776
|
+
show: u,
|
|
777
|
+
downloadUrl: e.downloadUrl,
|
|
778
|
+
isFullscreen: l,
|
|
779
|
+
onToggleFullscreen: c
|
|
780
|
+
}
|
|
781
|
+
)
|
|
782
|
+
]
|
|
783
|
+
}
|
|
784
|
+
);
|
|
785
|
+
}
|
|
786
|
+
export {
|
|
787
|
+
pt as PeeekViewer
|
|
788
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.peeek{--peeek-accent: #6E79D6;--peeek-bg: #0b0b10;--peeek-surface: rgba(255, 255, 255, .06);--peeek-text: #f5f5fa;--peeek-radius: 16px;position:relative;display:flex;flex-direction:column;width:100%;color:var(--peeek-text);background:var(--peeek-bg);border-radius:var(--peeek-radius);overflow:hidden;font-family:ui-sans-serif,system-ui,sans-serif}.peeek__stage{position:relative;display:flex;align-items:center;justify-content:center;flex:1;min-height:24rem;padding:1.75rem 3rem;overflow:hidden;perspective:2000px}.peeek__zoom{display:flex;align-items:center;justify-content:center;width:100%;height:100%;transform-origin:center center}.peeek__zoom--pannable{cursor:grab;touch-action:none}.peeek__zoom--pannable:active{cursor:grabbing}.peeek__zoom--pannable img{pointer-events:none;-webkit-user-select:none;user-select:none;-webkit-user-drag:none}.peeek__spread{position:relative;display:flex;width:100%;transition:transform .5s cubic-bezier(.6,.05,.3,.95);transform-style:preserve-3d}.peeek__page{position:relative;width:50%;aspect-ratio:var(--peeek-aspect, .707);background:#fff;overflow:hidden}.peeek__page--empty{background:transparent;box-shadow:none}.peeek__page--left{border-top-left-radius:8px;border-bottom-left-radius:8px}.peeek__page--right{border-top-right-radius:8px;border-bottom-right-radius:8px}.peeek__spread:not(.peeek__spread--pair) .peeek__page{border-radius:8px}.peeek__page img{display:block;width:100%;height:100%;object-fit:contain}.peeek__page-btn{all:unset;display:block;width:100%;height:100%;cursor:zoom-in}.peeek--shadows .peeek__spread{box-shadow:0 24px 60px -24px #000000b3}.peeek--shadows.peeek__spread--pair .peeek__page--left{box-shadow:inset -30px 0 36px -22px #0009}.peeek--shadows.peeek__spread--pair .peeek__page--right{box-shadow:inset 30px 0 36px -22px #0009}.peeek--shadows.peeek__spread--pair .peeek__page--left:after,.peeek--shadows.peeek__spread--pair .peeek__page--right:after{content:"";position:absolute;top:0;bottom:0;width:14px;pointer-events:none}.peeek--shadows.peeek__spread--pair .peeek__page--left:after{right:0;background:linear-gradient(to right,#0000,#00000047)}.peeek--shadows.peeek__spread--pair .peeek__page--right:after{left:0;background:linear-gradient(to left,#0000,#00000047)}.peeek__leaf{position:absolute;top:0;width:50%;height:100%;z-index:3;transform-style:preserve-3d;transition:transform .62s cubic-bezier(.55,.06,.3,.98);will-change:transform}.peeek__leaf--fwd{left:50%;transform-origin:left center}.peeek__leaf--back{right:50%;transform-origin:right center}.peeek__leaf-face{position:absolute;top:0;right:0;bottom:0;left:0;backface-visibility:hidden;background:#fff;overflow:hidden}.peeek__leaf-face img{display:block;width:100%;height:100%;object-fit:contain}.peeek__leaf-face--back{transform:rotateY(180deg)}.peeek__leaf-face:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;opacity:.15;animation:peeek-curl .62s cubic-bezier(.55,.06,.3,.98) forwards;background:linear-gradient(var(--peeek-curl-dir, to right),rgba(0,0,0,.34),rgba(0,0,0,0) 58%,rgba(255,255,255,.05))}.peeek__leaf--fwd .peeek__leaf-face:after{--peeek-curl-dir: to right}.peeek__leaf--back .peeek__leaf-face:after{--peeek-curl-dir: to left}.peeek__leaf-face--back:after{transform:scaleX(-1)}@keyframes peeek-curl{0%{opacity:.15}45%{opacity:1}to{opacity:.55}}.peeek__arrow{position:absolute;top:50%;transform:translateY(-50%);z-index:2;display:flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;border:none;border-radius:9999px;background:#00000059;color:#fff;cursor:pointer}.peeek__arrow:disabled{opacity:.3;cursor:default}.peeek__arrow--prev{left:.75rem}.peeek__arrow--next{right:.75rem}.peeek__toolbar{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;border-top:1px solid rgba(255,255,255,.08);font-size:14px}.peeek__scrubber{flex:1;height:2px;background:#ffffff26;border-radius:9999px;overflow:hidden}.peeek__scrubber-fill{height:100%;background:var(--peeek-accent)}.peeek__btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:none;border-radius:8px;background:transparent;color:var(--peeek-text);cursor:pointer}.peeek__btn:disabled{opacity:.3;cursor:default}.peeek__btn--active{color:var(--peeek-accent)}.peeek__thumbs{display:flex;gap:.4rem;overflow-x:auto;padding:.75rem 1rem;border-top:1px solid rgba(255,255,255,.08)}.peeek__thumb-group{flex:0 0 auto;display:flex;gap:2px;position:relative}.peeek__thumb{flex:0 0 auto;width:4rem;height:5rem;padding:0;border:2px solid transparent;border-radius:6px;background:#fff;cursor:pointer;overflow:hidden}.peeek__thumb img{width:100%;height:100%;object-fit:contain}.peeek__thumb--active{border-color:var(--peeek-accent)}.peeek__thumb--flat-right{border-top-right-radius:0;border-bottom-right-radius:0}.peeek__thumb--flat-left{border-top-left-radius:0;border-bottom-left-radius:0}.peeek__branding{display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem}.peeek__branding img{height:1.5rem;width:auto}.peeek__state{display:flex;align-items:center;justify-content:center;min-height:24rem;font-size:16px;color:var(--peeek-text)}.peeek[data-skin=minimal] .peeek__toolbar,.peeek[data-skin=minimal] .peeek__thumbs{border-top:none;background:#00000040}.peeek[data-skin=minimal] .peeek__arrow{background:#0003}.peeek[dir=rtl] .peeek__leaf{transform-origin:right center}.peeek__cf{display:flex;flex:1;flex-direction:column;min-height:0}.peeek__cf-header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;border-bottom:1px solid rgba(255,255,255,.08);font-size:14px}.peeek__cf-badge{display:flex;align-items:center;justify-content:center;width:2.5rem;height:2.75rem;flex:0 0 auto;border-radius:6px;background:var(--peeek-accent);color:#fff;font-size:13px;font-weight:700}.peeek__cf-meta{display:flex;min-width:0;flex:1;flex-direction:column}.peeek__cf-name{overflow:hidden;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.peeek__cf-count{font-size:14px;opacity:.6}.peeek__cf-indicator{padding:.25rem .75rem;border:1px solid rgba(255,255,255,.1);border-radius:8px;font-family:ui-monospace,monospace;font-size:14px}.peeek__cf-stage{position:relative;display:flex;flex:1;align-items:center;justify-content:center;min-height:20rem;overflow:hidden;perspective:1400px}.peeek__cf-card{position:absolute;display:flex;max-width:55%;align-items:center;justify-content:center;padding:0;border:none;background:transparent;cursor:pointer;transition:transform .3s ease-out,opacity .3s ease-out}.peeek__cf-card--center{max-width:70%}.peeek__cf-card--zoom{cursor:zoom-in}.peeek__cf-card img{max-width:100%;max-height:19rem;border-radius:8px;background:#fff;object-fit:contain;box-shadow:0 18px 40px -12px #0009}.peeek__cf-thumbs{display:flex;gap:.5rem;overflow-x:auto;padding:.75rem 1rem;border-top:1px solid rgba(255,255,255,.08);scrollbar-width:none}.peeek__cf-thumbs::-webkit-scrollbar{display:none}.peeek__cf-thumb{display:flex;flex:0 0 auto;flex-direction:column;align-items:center;gap:.25rem;padding:.25rem;border:2px solid transparent;border-radius:8px;background:transparent;cursor:pointer}.peeek__cf-thumb img{width:3rem;height:4rem;border-radius:4px;background:#fff;object-fit:cover;opacity:.8}.peeek__cf-thumb--active{border-color:var(--peeek-accent);background:#ffffff0f}.peeek__cf-thumb--active img{opacity:1}.peeek__cf-thumb-num{font-family:ui-monospace,monospace;font-size:14px;opacity:.6}.peeek__cf-thumb--active .peeek__cf-thumb-num{color:var(--peeek-accent);opacity:1}.peeek:fullscreen .peeek__cf-card img{max-height:78vh}.peeek:fullscreen .peeek__spread{width:auto;height:100%}.peeek:fullscreen .peeek__page{width:auto;height:100%}.peeek[data-skin=minimal] .peeek__cf-header,.peeek[data-skin=minimal] .peeek__cf-thumbs{border-color:transparent;background:#00000040}.peeek[data-skin=showcase] .peeek__label{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14px}.peeek[data-skin=showcase] .peeek__scrubber{height:2px}.peeek[data-skin=showcase] .peeek__scrubber-fill{background:var(--peeek-accent)}.peeek[data-skin=showcase] .peeek__arrow{width:2.5rem;height:2.5rem;border-radius:9999px;background:#0000004d;color:#fff;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}.peeek[data-skin=showcase] .peeek__arrow:hover{background:#00000080}.peeek__thumb-badge{position:absolute;right:2px;bottom:2px;padding:0 4px;border-radius:4px;background:#000000b3;color:#fff;font-size:14px;font-weight:500;pointer-events:none}.peeek--fill-height{height:100%}.peeek--fill-height .peeek__stage{min-height:0}.peeek--fill-height .peeek__spread,.peeek--fill-height .peeek__page{width:auto;height:100%}.peeek[data-layout=double] .peeek__spread:not(.peeek__spread--pair) .peeek__page--right{border-radius:0 8px 8px 0}.peeek[data-layout=double] .peeek__spread:not(.peeek__spread--pair) .peeek__page--left{border-radius:8px 0 0 8px}.peeek[data-layout=double] .peeek__leaf--fwd .peeek__leaf-face--front{border-top-right-radius:8px;border-bottom-right-radius:8px}.peeek[data-layout=double] .peeek__leaf--fwd .peeek__leaf-face--back,.peeek[data-layout=double] .peeek__leaf--back .peeek__leaf-face--front{border-top-left-radius:8px;border-bottom-left-radius:8px}.peeek[data-layout=double] .peeek__leaf--back .peeek__leaf-face--back{border-top-right-radius:8px;border-bottom-right-radius:8px}.peeek[data-layout=single] .peeek__leaf-face{border-radius:8px}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@peeekpage/viewer",
|
|
3
|
+
"version": "0.3.13",
|
|
4
|
+
"description": "PeeekViewer: embeddable document viewer (flip and coverflow) for peeek.page.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"private": false,
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://peeek.page",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"module": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./styles.css": "./dist/peeekviewer.css"
|
|
24
|
+
},
|
|
25
|
+
"sideEffects": [
|
|
26
|
+
"**/*.css"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc --noEmit && vite build",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:watch": "vitest",
|
|
32
|
+
"lint": "tsc --noEmit",
|
|
33
|
+
"prepublishOnly": "npm run build"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"react": ">=18",
|
|
37
|
+
"react-dom": ">=18"
|
|
38
|
+
}
|
|
39
|
+
}
|