@kingtech/react-pdf-viewer 0.0.0-stage → 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/CHANGELOG.md +35 -0
- package/LICENSE +21 -0
- package/NOTICE +14 -0
- package/README.md +67 -2
- package/dist/PdfViewer.d.ts +23 -0
- package/dist/components/ContinuousPages.d.ts +23 -0
- package/dist/components/ErrorView.d.ts +10 -0
- package/dist/components/LoadingView.d.ts +6 -0
- package/dist/components/PageInput.d.ts +11 -0
- package/dist/components/PasswordPrompt.d.ts +10 -0
- package/dist/components/PdfPageCanvas.d.ts +53 -0
- package/dist/components/SearchBar.d.ts +18 -0
- package/dist/components/Thumbnails.d.ts +16 -0
- package/dist/components/Toolbar.d.ts +30 -0
- package/dist/components/ToolbarButton.d.ts +15 -0
- package/dist/components/ToolbarMenu.d.ts +25 -0
- package/dist/components/icons.d.ts +60 -0
- package/dist/core/download.d.ts +4 -0
- package/dist/core/env.d.ts +2 -0
- package/dist/core/errors.d.ts +19 -0
- package/dist/core/fileName.d.ts +10 -0
- package/dist/core/geometry.d.ts +25 -0
- package/dist/core/linkService.d.ts +29 -0
- package/dist/core/loadSource.d.ts +22 -0
- package/dist/core/pdfjs.d.ts +80 -0
- package/dist/core/print.d.ts +16 -0
- package/dist/core/scale.d.ts +26 -0
- package/dist/core/search.d.ts +36 -0
- package/dist/hooks/useControllableState.d.ts +19 -0
- package/dist/hooks/useDevicePixelRatio.d.ts +2 -0
- package/dist/hooks/useDocumentSearch.d.ts +13 -0
- package/dist/hooks/useElementSize.d.ts +13 -0
- package/dist/hooks/useFullscreen.d.ts +18 -0
- package/dist/hooks/useIsomorphicLayoutEffect.d.ts +3 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts +18 -0
- package/dist/hooks/useMediaQuery.d.ts +2 -0
- package/dist/hooks/usePageRenderer.d.ts +74 -0
- package/dist/hooks/usePdfDocument.d.ts +31 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +2290 -0
- package/dist/index.js.map +1 -0
- package/dist/labels.d.ts +64 -0
- package/dist/styles.css +2 -0
- package/dist/types.d.ts +324 -0
- package/package.json +95 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @kingtech/react-pdf-viewer
|
|
2
|
+
|
|
3
|
+
## 1.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Publish from GitHub Actions with provenance. The library's code and API are unchanged.
|
|
8
|
+
|
|
9
|
+
## 1.0.0
|
|
10
|
+
|
|
11
|
+
### Major Changes
|
|
12
|
+
|
|
13
|
+
- f39ecdb: First stable release of `PdfViewer`, an accessible, themeable React PDF viewer built on
|
|
14
|
+
`pdfjs-dist`. From this release on, the public API (components, hooks, props, `PdfViewerApi`,
|
|
15
|
+
labels, CSS classes and CSS variables) follows semantic versioning.
|
|
16
|
+
|
|
17
|
+
- Loads URLs, `URL` objects, `ArrayBuffer`, `Uint8Array`, `Blob` and `File` sources, with custom
|
|
18
|
+
`fetch` options, a replaceable fetcher, HTTP error hooks and typed `PdfViewerError`s with retry.
|
|
19
|
+
- Controlled or uncontrolled page, scale, rotation and fullscreen (`x` / `defaultX` / `onXChange`),
|
|
20
|
+
plus an imperative `PdfViewerApi` through `ref`.
|
|
21
|
+
- Cancellable, HiDPI, pixel-capped rendering that respects each page's intrinsic rotation. Memory
|
|
22
|
+
stays flat in long documents: pages and thumbnails far from view release their canvases and
|
|
23
|
+
cached page resources.
|
|
24
|
+
- A single-row responsive toolbar that collapses actions into a "More actions" menu, keyboard
|
|
25
|
+
shortcuts, WAI-ARIA toolbar and menu semantics, and native, overlay or controlled fullscreen.
|
|
26
|
+
- Download, and printing through a hidden frame with every page on a sheet of its own size, or
|
|
27
|
+
`printMode="open-url"` to hand the document to the browser's own viewer.
|
|
28
|
+
- Opt-in features: continuous layout, thumbnails, text layer, links, search, page-number input,
|
|
29
|
+
zoom presets and reset, fit modes, Ctrl/⌘ + wheel zoom and a password prompt.
|
|
30
|
+
- Label overrides with locale-aware number formatting, 50+ CSS variables and dark / auto presets.
|
|
31
|
+
- Headless building blocks: `usePdfDocument`, `PdfPageCanvas`, `PdfToolbar` and
|
|
32
|
+
`useControllableState`.
|
|
33
|
+
- Secure by default: `isEvalSupported: false`, a `pdfjs-dist` peer range that excludes
|
|
34
|
+
CVE-2024-4367, external links opened with `rel="noopener noreferrer"`, no script injection, and
|
|
35
|
+
SSR-safe rendering.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kiralygyula92
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
@kingtech/react-pdf-viewer
|
|
2
|
+
Copyright (c) 2026 kiralygyula92. Licensed under the MIT License (see LICENSE).
|
|
3
|
+
|
|
4
|
+
Third-party material
|
|
5
|
+
--------------------
|
|
6
|
+
|
|
7
|
+
This package includes SVG icon paths from Material Icons
|
|
8
|
+
(https://github.com/google/material-design-icons), Copyright Google LLC,
|
|
9
|
+
licensed under the Apache License, Version 2.0
|
|
10
|
+
(https://www.apache.org/licenses/LICENSE-2.0).
|
|
11
|
+
|
|
12
|
+
This package is designed to be used with PDF.js (https://github.com/mozilla/pdf.js),
|
|
13
|
+
Copyright Mozilla Foundation and contributors, licensed under the Apache License,
|
|
14
|
+
Version 2.0. PDF.js (`pdfjs-dist`) is a peer dependency and is not bundled.
|
package/README.md
CHANGED
|
@@ -1,3 +1,68 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @kingtech/react-pdf-viewer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@kingtech/react-pdf-viewer)
|
|
4
|
+
[](https://github.com/kiralygyula92/react-pdf-viewer/actions/workflows/ci.yml)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
|
|
7
|
+
Accessible, themeable PDF viewer for React, built on PDF.js.
|
|
8
|
+
|
|
9
|
+
A complete viewer with a toolbar for zoom, page navigation, fullscreen, rotation, download and
|
|
10
|
+
print, plus opt-in continuous scrolling, thumbnails, search, selectable text and links. No UI-kit
|
|
11
|
+
dependency, SSR-safe and fully typed.
|
|
12
|
+
|
|
13
|
+
- **Accessible:** WAI-ARIA toolbar and menu semantics, keyboard shortcuts, live page announcements, checked with axe.
|
|
14
|
+
- **Themeable:** plain CSS in a cascade layer, CSS variables, dark and automatic presets.
|
|
15
|
+
- **Controlled or uncontrolled:** page, zoom, rotation and fullscreen each follow `x` / `defaultX` / `onXChange`.
|
|
16
|
+
- **Production loading:** URLs with custom requests, `File`, `Blob` and bytes, typed errors with retry.
|
|
17
|
+
- **Composable:** replace the toolbar, or build your own viewer with `usePdfDocument` and `PdfPageCanvas`.
|
|
18
|
+
|
|
19
|
+
**[Documentation, live demos and API reference →](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/)**
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
npm install @kingtech/react-pdf-viewer pdfjs-dist
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Peer dependencies: `react` and `react-dom` 18 or 19, and `pdfjs-dist` 6. See
|
|
28
|
+
[Requirements](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/getting-started/requirements/)
|
|
29
|
+
for the tested versions and browsers.
|
|
30
|
+
|
|
31
|
+
## Quick start
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { PdfViewer } from '@kingtech/react-pdf-viewer';
|
|
35
|
+
import '@kingtech/react-pdf-viewer/styles.css';
|
|
36
|
+
|
|
37
|
+
export function Report() {
|
|
38
|
+
return <PdfViewer source="/files/report.pdf" />;
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Out of the box, PDF.js's worker and assets load from a CDN pinned to your installed version. For
|
|
43
|
+
production, self-host them once at startup (Vite shown):
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { configurePdfJs } from '@kingtech/react-pdf-viewer';
|
|
47
|
+
import workerSrc from 'pdfjs-dist/build/pdf.worker.min.mjs?url';
|
|
48
|
+
|
|
49
|
+
configurePdfJs({ workerSrc });
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Setup guides: [Vite](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/integrations/vite/),
|
|
53
|
+
[Next.js](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/integrations/nextjs/),
|
|
54
|
+
[webpack](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/integrations/webpack/).
|
|
55
|
+
|
|
56
|
+
## Documentation
|
|
57
|
+
|
|
58
|
+
- [Usage](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/getting-started/usage/): the common props and features.
|
|
59
|
+
- [All features](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/all-features/): one page per capability, each with live demos.
|
|
60
|
+
- [Customization](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/customization/): theming, labels, custom views.
|
|
61
|
+
- [API reference](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/api/): every prop, type, CSS variable and shortcut, generated from the source.
|
|
62
|
+
- [Security](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/guides/security/) and [Accessibility](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/guides/accessibility/) guides.
|
|
63
|
+
- [Changelog](https://react-pdf-viewer-chi.vercel.app/react-pdf-viewer/discover-more/changelog/).
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
[MIT](./LICENSE) © kiralygyula92. Third-party attributions (Material Icons paths, PDF.js) are listed in
|
|
68
|
+
[`NOTICE`](./NOTICE).
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PdfViewerApi, PdfViewerProps } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A PDF viewer: one page at a time with a toolbar for zoom, navigation, fullscreen, rotation,
|
|
4
|
+
* download and print. Default props give a classic single-page layout; every
|
|
5
|
+
* additional feature (text layer, links, continuous layout, thumbnails, search, …) is opt-in.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { PdfViewer } from '@kingtech/react-pdf-viewer';
|
|
10
|
+
* import '@kingtech/react-pdf-viewer/styles.css';
|
|
11
|
+
*
|
|
12
|
+
* <PdfViewer source="/files/document.pdf" fileName="document.pdf" />
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @cssClass rpv-root The root element. Add `rpv-theme-dark`, or `rpv-theme-auto` to follow the operating system, for the dark preset.
|
|
16
|
+
* @cssAttribute data-status Document status: `idle`, `loading`, `ready` or `error`.
|
|
17
|
+
* @cssAttribute data-layout The `layout` prop: `single` or `continuous`.
|
|
18
|
+
* @cssAttribute data-compact Present while the viewport is narrower than `compactBreakpoint`.
|
|
19
|
+
* @cssAttribute data-fullscreen Present in fullscreen, in any mode.
|
|
20
|
+
* @cssAttribute data-presentation How fullscreen is presented: `layout` (controlled mode), `native` or `overlay`.
|
|
21
|
+
* @cssAttribute data-zoomed Present while the scale is above `defaultScale`.
|
|
22
|
+
*/
|
|
23
|
+
export declare const PdfViewer: import('react').ForwardRefExoticComponent<PdfViewerProps & import('react').RefAttributes<PdfViewerApi>>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { PDFDocumentProxy } from 'pdfjs-dist';
|
|
3
|
+
import { FitOptions } from '../core/geometry.js';
|
|
4
|
+
import { Rotation } from '../types.js';
|
|
5
|
+
interface ContinuousPagesProps {
|
|
6
|
+
document: PDFDocumentProxy;
|
|
7
|
+
numPages: number;
|
|
8
|
+
/** Current page; the list scrolls to it unless the change came from scrolling. */
|
|
9
|
+
page: number;
|
|
10
|
+
/** Reports the most visible page while the user scrolls. */
|
|
11
|
+
onVisiblePageChange: (page: number) => void;
|
|
12
|
+
scale: number;
|
|
13
|
+
rotation: Rotation;
|
|
14
|
+
fit: FitOptions | undefined;
|
|
15
|
+
/** The scroll container. */
|
|
16
|
+
scroller: HTMLElement | null;
|
|
17
|
+
/** Renders one page at an explicit scale. */
|
|
18
|
+
renderPage: (page: number, scale: number) => ReactNode;
|
|
19
|
+
}
|
|
20
|
+
declare function ContinuousPagesImpl({ document, numPages, page, onVisiblePageChange, scale, rotation, fit, scroller, renderPage, }: ContinuousPagesProps): import('react').JSX.Element;
|
|
21
|
+
/** Vertically scrolling pages; only the visible pages ±1 are rendered. */
|
|
22
|
+
export declare const ContinuousPages: import('react').MemoExoticComponent<typeof ContinuousPagesImpl>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface ErrorViewProps {
|
|
2
|
+
message: string;
|
|
3
|
+
retryLabel: string;
|
|
4
|
+
onRetry?: (() => void) | undefined;
|
|
5
|
+
/** `document` fills a 400px area; `page` sits inside the page box. */
|
|
6
|
+
variant?: 'document' | 'page' | undefined;
|
|
7
|
+
}
|
|
8
|
+
/** Red error alert with an optional Retry button. */
|
|
9
|
+
export declare function ErrorView({ message, retryLabel, onRetry, variant }: ErrorViewProps): import('react').JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Indeterminate circular spinner. */
|
|
2
|
+
export declare function Spinner(): import('react').JSX.Element;
|
|
3
|
+
/** Centered spinner with a status text, shown while the document loads. */
|
|
4
|
+
export declare function LoadingView({ label }: {
|
|
5
|
+
label: string;
|
|
6
|
+
}): import('react').JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LabelContext } from '../labels.js';
|
|
2
|
+
interface PageInputProps {
|
|
3
|
+
page: number;
|
|
4
|
+
numPages: number;
|
|
5
|
+
label: string;
|
|
6
|
+
context: LabelContext;
|
|
7
|
+
onCommit: (page: number) => void;
|
|
8
|
+
}
|
|
9
|
+
/** Editable page number (`Enter` or blur commits, `Esc` reverts) followed by the page count. */
|
|
10
|
+
export declare function PageInput({ page, numPages, label, context, onCommit }: PageInputProps): import('react').JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PdfViewerLabels } from '../labels.js';
|
|
2
|
+
interface PasswordPromptProps {
|
|
3
|
+
labels: PdfViewerLabels;
|
|
4
|
+
/** The previous attempt was wrong. */
|
|
5
|
+
incorrect: boolean;
|
|
6
|
+
onSubmit: (password: string) => void;
|
|
7
|
+
}
|
|
8
|
+
/** Built-in password form for encrypted documents. */
|
|
9
|
+
export declare function PasswordPrompt({ labels, incorrect, onSubmit }: PasswordPromptProps): import('react').JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { PDFDocumentProxy } from 'pdfjs-dist';
|
|
3
|
+
import { FitOptions } from '../core/geometry.js';
|
|
4
|
+
import { PageHighlight, PageRenderInfo } from '../hooks/usePageRenderer.js';
|
|
5
|
+
import { PdfViewerError, Rotation } from '../types.js';
|
|
6
|
+
/** Props for {@link PdfPageCanvas}. */
|
|
7
|
+
export interface PdfPageCanvasProps {
|
|
8
|
+
/** A loaded document, e.g. from `usePdfDocument`. */
|
|
9
|
+
document: PDFDocumentProxy;
|
|
10
|
+
/** 1-based page number; clamped to the document. */
|
|
11
|
+
page: number;
|
|
12
|
+
/** Scale, 1 = 100%. Default `1`. */
|
|
13
|
+
scale?: number | undefined;
|
|
14
|
+
/** User rotation, added to the page's intrinsic rotation. Default `0`. */
|
|
15
|
+
rotation?: Rotation | undefined;
|
|
16
|
+
/** Box the page must fit into (see {@link FitOptions}). */
|
|
17
|
+
fit?: FitOptions | undefined;
|
|
18
|
+
/** Canvas pixel budget. Default `16_777_216`. */
|
|
19
|
+
maxCanvasPixels?: number | undefined;
|
|
20
|
+
/** Render a selectable text layer (copy, find, assistive technology). Default `false`. */
|
|
21
|
+
textLayer?: boolean | undefined;
|
|
22
|
+
/** Render clickable links. Default `false`. */
|
|
23
|
+
annotationLayer?: boolean | undefined;
|
|
24
|
+
/** Highlight search matches (requires `textLayer`). */
|
|
25
|
+
highlight?: PageHighlight | undefined;
|
|
26
|
+
/** Called when an internal link targets another page. */
|
|
27
|
+
onLinkNavigate?: ((page: number) => void) | undefined;
|
|
28
|
+
/** Called with the selected search match's element (e.g. to scroll it into view). */
|
|
29
|
+
onHighlight?: ((element: HTMLElement) => void) | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Accessible name, e.g. `Page 1 of 3`. With a name the page is exposed as an image (or, with
|
|
32
|
+
* a text or annotation layer, as a group containing the text and links); without one it is
|
|
33
|
+
* decorative.
|
|
34
|
+
*/
|
|
35
|
+
'aria-label'?: string | undefined;
|
|
36
|
+
className?: string | undefined;
|
|
37
|
+
style?: CSSProperties | undefined;
|
|
38
|
+
/** Replaces the default in-place error view. */
|
|
39
|
+
renderError?: ((error: PdfViewerError, actions: {
|
|
40
|
+
retry: () => void;
|
|
41
|
+
}) => ReactNode) | undefined;
|
|
42
|
+
/** Called after each completed render. */
|
|
43
|
+
onRender?: ((info: PageRenderInfo) => void) | undefined;
|
|
44
|
+
/** Called when rendering fails (cancellations are not failures). */
|
|
45
|
+
onError?: ((error: PdfViewerError) => void) | undefined;
|
|
46
|
+
}
|
|
47
|
+
declare function PdfPageCanvasImpl({ document, page, scale, rotation, fit, maxCanvasPixels, textLayer, annotationLayer, highlight, onLinkNavigate, onHighlight, 'aria-label': ariaLabel, className, style, renderError, onRender, onError, }: PdfPageCanvasProps): import('react').JSX.Element;
|
|
48
|
+
/**
|
|
49
|
+
* Renders a single PDF page: cancellable, double-buffered, HiDPI and pixel-capped, with optional
|
|
50
|
+
* text and annotation layers. The building block for custom viewers (see `usePdfDocument`).
|
|
51
|
+
*/
|
|
52
|
+
export declare const PdfPageCanvas: import('react').MemoExoticComponent<typeof PdfPageCanvasImpl>;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Ref } from 'react';
|
|
2
|
+
import { LabelContext, PdfViewerLabels } from '../labels.js';
|
|
3
|
+
interface SearchBarProps {
|
|
4
|
+
inputRef: Ref<HTMLInputElement>;
|
|
5
|
+
query: string;
|
|
6
|
+
onQueryChange: (query: string) => void;
|
|
7
|
+
total: number;
|
|
8
|
+
/** 0-based index of the current match. */
|
|
9
|
+
current: number;
|
|
10
|
+
searching: boolean;
|
|
11
|
+
onNext: () => void;
|
|
12
|
+
onPrevious: () => void;
|
|
13
|
+
labels: PdfViewerLabels;
|
|
14
|
+
context: LabelContext;
|
|
15
|
+
}
|
|
16
|
+
/** Find-in-document field: `Enter` / `Shift+Enter` step through matches, `Esc` clears. */
|
|
17
|
+
export declare function SearchBar({ inputRef, query, onQueryChange, total, current, searching, onNext, onPrevious, labels, context, }: SearchBarProps): import('react').JSX.Element;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { PDFDocumentProxy } from 'pdfjs-dist';
|
|
2
|
+
import { LabelContext, PdfViewerLabels } from '../labels.js';
|
|
3
|
+
import { Rotation } from '../types.js';
|
|
4
|
+
interface ThumbnailsProps {
|
|
5
|
+
document: PDFDocumentProxy;
|
|
6
|
+
numPages: number;
|
|
7
|
+
page: number;
|
|
8
|
+
rotation: Rotation;
|
|
9
|
+
onSelect: (page: number) => void;
|
|
10
|
+
labels: PdfViewerLabels;
|
|
11
|
+
context: LabelContext;
|
|
12
|
+
}
|
|
13
|
+
declare function ThumbnailsImpl({ document, numPages, page, rotation, onSelect, labels, context, }: ThumbnailsProps): import('react').JSX.Element;
|
|
14
|
+
/** Page thumbnails sidebar; thumbnails render only while they are near the visible area. */
|
|
15
|
+
export declare const Thumbnails: import('react').MemoExoticComponent<typeof ThumbnailsImpl>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { PdfViewerLabels } from '../labels.js';
|
|
3
|
+
import { PdfViewerApi, ToolbarConfig } from '../types.js';
|
|
4
|
+
/** Props for {@link PdfToolbar}. */
|
|
5
|
+
export interface PdfToolbarProps {
|
|
6
|
+
/** The viewer API (from a `ref` or `renderToolbar`). */
|
|
7
|
+
api: PdfViewerApi;
|
|
8
|
+
/** Label overrides. */
|
|
9
|
+
labels?: Partial<PdfViewerLabels> | undefined;
|
|
10
|
+
/** Which actions to show and where. */
|
|
11
|
+
config?: ToolbarConfig | undefined;
|
|
12
|
+
/** Compact layout (narrow viewport): hides `hiddenWhenCompact` actions outside fullscreen. */
|
|
13
|
+
compact?: boolean | undefined;
|
|
14
|
+
/** Locale for number formatting. */
|
|
15
|
+
locale?: string | undefined;
|
|
16
|
+
/** The zoom label becomes a button that resets zoom. Default `false`. */
|
|
17
|
+
zoomReset?: boolean | undefined;
|
|
18
|
+
/** Replaces the page indicator text (e.g. with a page-number input). */
|
|
19
|
+
pageIndicator?: ReactNode;
|
|
20
|
+
/** Where the "More actions" menu opens: `'top'` (above; default) or `'bottom'`. */
|
|
21
|
+
menuPlacement?: 'top' | 'bottom' | undefined;
|
|
22
|
+
}
|
|
23
|
+
declare function PdfToolbarImpl({ api, labels: labelOverrides, config, compact, locale, zoomReset, pageIndicator, menuPlacement, }: PdfToolbarProps): import('react').JSX.Element;
|
|
24
|
+
/**
|
|
25
|
+
* The default toolbar: zoom, page navigation, fullscreen, rotate, download and print, on one
|
|
26
|
+
* row. When the row does not fit, secondary actions collapse into a "More actions" menu. Usable
|
|
27
|
+
* on its own, e.g. inside `renderToolbar`.
|
|
28
|
+
*/
|
|
29
|
+
export declare const PdfToolbar: import('react').MemoExoticComponent<typeof PdfToolbarImpl>;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ToolbarAction } from '../types.js';
|
|
3
|
+
interface ToolbarButtonProps {
|
|
4
|
+
action: ToolbarAction;
|
|
5
|
+
label: string;
|
|
6
|
+
icon: ReactNode;
|
|
7
|
+
onClick: () => void;
|
|
8
|
+
disabled?: boolean | undefined;
|
|
9
|
+
tabIndex: number;
|
|
10
|
+
onFocus: (action: ToolbarAction) => void;
|
|
11
|
+
}
|
|
12
|
+
declare function ToolbarButtonImpl({ action, label, icon, onClick, disabled, tabIndex, onFocus, }: ToolbarButtonProps): import('react').JSX.Element;
|
|
13
|
+
/** Round icon button used by the toolbar. */
|
|
14
|
+
export declare const ToolbarButton: import('react').MemoExoticComponent<typeof ToolbarButtonImpl>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/** An entry of the toolbar's overflow menu. */
|
|
3
|
+
export interface ToolbarMenuItem {
|
|
4
|
+
key: string;
|
|
5
|
+
label: string;
|
|
6
|
+
icon: ReactNode;
|
|
7
|
+
onSelect: () => void;
|
|
8
|
+
disabled?: boolean | undefined;
|
|
9
|
+
}
|
|
10
|
+
interface ToolbarMenuProps {
|
|
11
|
+
/** Accessible name of the button and the menu. */
|
|
12
|
+
label: string;
|
|
13
|
+
items: readonly ToolbarMenuItem[];
|
|
14
|
+
/** Opens above the toolbar (`'top'`, toolbar at the bottom) or below it. */
|
|
15
|
+
placement: 'top' | 'bottom';
|
|
16
|
+
tabIndex: number;
|
|
17
|
+
onFocus: () => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The "More actions" button and its menu (WAI-ARIA menu button pattern): arrow keys, Home and
|
|
21
|
+
* End move between items, `Esc` closes and returns focus to the button, `Tab` or a click outside
|
|
22
|
+
* closes it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function ToolbarMenu({ label, items, placement, tabIndex, onFocus }: ToolbarMenuProps): import('react').JSX.Element;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export declare const ZoomOutIcon: {
|
|
2
|
+
(): import('react').JSX.Element;
|
|
3
|
+
displayName: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const ZoomInIcon: {
|
|
6
|
+
(): import('react').JSX.Element;
|
|
7
|
+
displayName: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const NavigateBeforeIcon: {
|
|
10
|
+
(): import('react').JSX.Element;
|
|
11
|
+
displayName: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const NavigateNextIcon: {
|
|
14
|
+
(): import('react').JSX.Element;
|
|
15
|
+
displayName: string;
|
|
16
|
+
};
|
|
17
|
+
export declare const FullscreenIcon: {
|
|
18
|
+
(): import('react').JSX.Element;
|
|
19
|
+
displayName: string;
|
|
20
|
+
};
|
|
21
|
+
export declare const FullscreenExitIcon: {
|
|
22
|
+
(): import('react').JSX.Element;
|
|
23
|
+
displayName: string;
|
|
24
|
+
};
|
|
25
|
+
export declare const RotateRightIcon: {
|
|
26
|
+
(): import('react').JSX.Element;
|
|
27
|
+
displayName: string;
|
|
28
|
+
};
|
|
29
|
+
export declare const DownloadIcon: {
|
|
30
|
+
(): import('react').JSX.Element;
|
|
31
|
+
displayName: string;
|
|
32
|
+
};
|
|
33
|
+
export declare const PrintIcon: {
|
|
34
|
+
(): import('react').JSX.Element;
|
|
35
|
+
displayName: string;
|
|
36
|
+
};
|
|
37
|
+
export declare const ErrorOutlineIcon: {
|
|
38
|
+
(): import('react').JSX.Element;
|
|
39
|
+
displayName: string;
|
|
40
|
+
};
|
|
41
|
+
export declare const SearchIcon: {
|
|
42
|
+
(): import('react').JSX.Element;
|
|
43
|
+
displayName: string;
|
|
44
|
+
};
|
|
45
|
+
export declare const ExpandLessIcon: {
|
|
46
|
+
(): import('react').JSX.Element;
|
|
47
|
+
displayName: string;
|
|
48
|
+
};
|
|
49
|
+
export declare const ExpandMoreIcon: {
|
|
50
|
+
(): import('react').JSX.Element;
|
|
51
|
+
displayName: string;
|
|
52
|
+
};
|
|
53
|
+
export declare const MoreVertIcon: {
|
|
54
|
+
(): import('react').JSX.Element;
|
|
55
|
+
displayName: string;
|
|
56
|
+
};
|
|
57
|
+
export declare const RestartIcon: {
|
|
58
|
+
(): import('react').JSX.Element;
|
|
59
|
+
displayName: string;
|
|
60
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Wraps PDF bytes in a Blob (copying, so a shared or transferred buffer is never exposed). */
|
|
2
|
+
export declare function toPdfBlob(data: Uint8Array): Blob;
|
|
3
|
+
/** Saves bytes as a file through a temporary object URL and a hidden `<a download>`. */
|
|
4
|
+
export declare function saveBytes(data: Uint8Array, fileName: string): void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PdfViewerError, PdfViewerErrorCode } from '../types.js';
|
|
2
|
+
interface ErrorDetails {
|
|
3
|
+
status?: number | undefined;
|
|
4
|
+
cause?: unknown;
|
|
5
|
+
}
|
|
6
|
+
/** Creates a {@link PdfViewerError}. `message` defaults to a generic text for the code. */
|
|
7
|
+
export declare function createPdfViewerError(code: PdfViewerErrorCode, message?: string, details?: ErrorDetails): PdfViewerError;
|
|
8
|
+
/** Type guard for errors created by the viewer. */
|
|
9
|
+
export declare function isPdfViewerError(value: unknown): value is PdfViewerError;
|
|
10
|
+
/** True for fetch aborts and PDF.js loading-task aborts. */
|
|
11
|
+
export declare function isAbortError(error: unknown): boolean;
|
|
12
|
+
/** True for PDF.js render cancellations, which are a normal outcome. */
|
|
13
|
+
export declare function isRenderCancelled(error: unknown): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Maps anything thrown by the loading or rendering pipeline to a {@link PdfViewerError}.
|
|
16
|
+
* PDF.js exceptions are recognized by `name`, so this works with any `pdfjs-dist` build.
|
|
17
|
+
*/
|
|
18
|
+
export declare function toPdfViewerError(error: unknown, fallback: PdfViewerErrorCode): PdfViewerError;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PdfSource } from '../types.js';
|
|
2
|
+
/** Name used when nothing better is known. */
|
|
3
|
+
export declare const DEFAULT_FILE_NAME = "document.pdf";
|
|
4
|
+
/** Last path segment of `url` when it ends in `.pdf`, otherwise `null`. */
|
|
5
|
+
export declare function fileNameFromUrl(url: string): string | null;
|
|
6
|
+
/**
|
|
7
|
+
* Download file name: the explicit `fileName`, then a `File`'s name, then the URL's last
|
|
8
|
+
* `.pdf` segment, then {@link DEFAULT_FILE_NAME}.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveFileName(fileName: string | undefined, source: PdfSource | null | undefined): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Rotation } from '../types.js';
|
|
2
|
+
/** Default canvas pixel budget: 4096², the iOS Safari limit. */
|
|
3
|
+
export declare const DEFAULT_MAX_CANVAS_PIXELS = 16777216;
|
|
4
|
+
/** Clamps a 1-based page number to `[1, numPages]`. */
|
|
5
|
+
export declare function clampPage(page: number, numPages: number): number;
|
|
6
|
+
/** Snaps any angle to the nearest quarter turn in `[0, 360)`. */
|
|
7
|
+
export declare function normalizeRotation(degrees: number): Rotation;
|
|
8
|
+
/** Page rotation actually rendered: the page's intrinsic `/Rotate` plus the user rotation. */
|
|
9
|
+
export declare function effectiveRotation(intrinsic: number, user: number): Rotation;
|
|
10
|
+
/**
|
|
11
|
+
* Canvas backing-store multiplier: the device pixel ratio, reduced when the canvas would exceed
|
|
12
|
+
* `maxCanvasPixels` or the largest side browsers accept. Resolution degrades; CSS size does not.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getOutputScale(cssWidth: number, cssHeight: number, devicePixelRatio: number, maxCanvasPixels: number): number;
|
|
15
|
+
/** Constrains the rendered page to a box. */
|
|
16
|
+
export interface FitOptions {
|
|
17
|
+
/** Available width in CSS pixels, including the page's border and padding. */
|
|
18
|
+
width?: number | undefined;
|
|
19
|
+
/** Available height in CSS pixels, including the page's border and padding. */
|
|
20
|
+
height?: number | undefined;
|
|
21
|
+
/** When `true` the page is scaled to fill the box; otherwise it only ever shrinks. */
|
|
22
|
+
upscale?: boolean | undefined;
|
|
23
|
+
}
|
|
24
|
+
/** Scale that satisfies `fit` for a page whose size at scale 1 is `baseWidth × baseHeight`. */
|
|
25
|
+
export declare function fitScale(requested: number, baseWidth: number, baseHeight: number, fit: FitOptions | undefined): number;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { PDFDocumentProxy } from 'pdfjs-dist';
|
|
2
|
+
/** Navigation callbacks the link service needs from the viewer. */
|
|
3
|
+
export interface LinkNavigation {
|
|
4
|
+
/** Go to a 1-based page. */
|
|
5
|
+
goToPage: (page: number) => void;
|
|
6
|
+
/** Current 1-based page (for named actions such as NextPage). */
|
|
7
|
+
getPage: () => number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The subset of PDF.js's `PDFLinkService` that `AnnotationLayer` uses for links. External links
|
|
11
|
+
* open in a new tab with `rel="noopener noreferrer"`; internal links navigate the viewer.
|
|
12
|
+
* (PDF.js only passes URLs with safe protocols through to `addLinkAttributes`.)
|
|
13
|
+
*/
|
|
14
|
+
export declare function createLinkService(pdf: PDFDocumentProxy, navigation: LinkNavigation): {
|
|
15
|
+
externalLinkEnabled: boolean;
|
|
16
|
+
isInPresentationMode: boolean;
|
|
17
|
+
eventBus: {
|
|
18
|
+
on: () => undefined;
|
|
19
|
+
off: () => undefined;
|
|
20
|
+
dispatch: () => undefined;
|
|
21
|
+
};
|
|
22
|
+
addLinkAttributes(link: HTMLAnchorElement, url: string): void;
|
|
23
|
+
getDestinationHash: () => string;
|
|
24
|
+
getAnchorUrl: () => string;
|
|
25
|
+
goToDestination(destination: unknown): void;
|
|
26
|
+
goToPage(page: number): void;
|
|
27
|
+
executeNamedAction(action: string): void;
|
|
28
|
+
executeSetOCGState: () => undefined;
|
|
29
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PdfRequestOptions, PdfSource } from '../types.js';
|
|
2
|
+
/** Result of reading a source: PDF bytes, or an HTTP error the host handled itself. */
|
|
3
|
+
export type LoadedSource = {
|
|
4
|
+
readonly kind: 'bytes';
|
|
5
|
+
readonly data: Uint8Array;
|
|
6
|
+
} | {
|
|
7
|
+
readonly kind: 'handled';
|
|
8
|
+
};
|
|
9
|
+
/** `null`, `undefined` and `''` mean "no document". */
|
|
10
|
+
export declare function isEmptySource(source: PdfSource | null | undefined): source is null | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* The default message logic: RFC 7807 `detail`, then `title`, then a JSON string body,
|
|
13
|
+
* then `Failed to fetch PDF: {status} {statusText}`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function defaultHttpErrorMessage(response: Response): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Turns any {@link PdfSource} into bytes for PDF.js.
|
|
18
|
+
*
|
|
19
|
+
* Binary sources are copied because PDF.js transfers (detaches) the buffer it receives; without
|
|
20
|
+
* the copy a consumer's `ArrayBuffer` would become unusable after the first load.
|
|
21
|
+
*/
|
|
22
|
+
export declare function loadSource(source: PdfSource, signal: AbortSignal, options?: PdfRequestOptions): Promise<LoadedSource>;
|