@epam/ai-dial-react-pdf-highlighter 0.1.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,35 @@
1
+ import { PDFSource, InputHighlightData } from '@epam/pdf-highlighter-kit';
2
+ import { FC } from 'react';
3
+ import { PdfViewerApi } from '../../models/pdf-viewer.models';
4
+ /**
5
+ * Props for the low-level PDF rendering component.
6
+ */
7
+ export interface PdfViewerProps {
8
+ /** PDF source: a URL string, `Blob`, or `ArrayBuffer`. */
9
+ pdf: PDFSource;
10
+ /** Highlight data rendered by pdf-highlighter-kit. */
11
+ highlights: InputHighlightData[];
12
+ /** Zoom mode: `auto`, `page-fit`, or stringified numeric value such as `1.25`. */
13
+ zoom?: string;
14
+ /** Highlight id to navigate to after highlights are loaded. */
15
+ selectedHighlightId?: string;
16
+ /** Auto-focus the first highlight when highlights are loaded. */
17
+ autoFocusFirstHighlight?: boolean;
18
+ /** Navigates to this page after viewer initialization. */
19
+ selectedPageNumber?: number;
20
+ /** Additional class name for the root viewer container. */
21
+ containerClassName?: string;
22
+ /** Callback invoked when total pages become available. */
23
+ onTotalPagesChange?: (totalPages: number) => void;
24
+ /** Callback invoked with an imperative API when viewer setup completes. */
25
+ onViewerReady?: (api: PdfViewerApi) => void;
26
+ /** Optional list of pages to load instead of the full document. */
27
+ selectedPages?: number[];
28
+ }
29
+ /**
30
+ * Low-level PDF viewer wrapper around `PDFHighlightViewer`.
31
+ *
32
+ * This component is intended for scenarios where only rendering/navigation logic is needed
33
+ * without the higher-level toolbar and overlays from `DocumentPreview`.
34
+ */
35
+ export declare const PDFViewer: FC<PdfViewerProps>;
@@ -0,0 +1,12 @@
1
+ import { ZoomOption } from '../models/pdf-viewer.models';
2
+ export declare const AUTO_ZOOM_ID = "auto";
3
+ export declare const FIT_ZOOM_ID = "page-fit";
4
+ export declare const ZOOM_OPTIONS: ZoomOption[];
5
+ export declare const THUMBNAIL_IMAGE_OPTIONS: {
6
+ maxWidth: number;
7
+ format: "image/jpeg";
8
+ quality: number;
9
+ };
10
+ export declare const THUMBNAIL_BATCH_SIZE = 15;
11
+ export declare const CONTENT_TYPE_PDF = "application/pdf";
12
+ export declare const FILE_EXTENSION_PDF = ".pdf";
@@ -0,0 +1,2 @@
1
+ import { InputHighlightData } from '@epam/pdf-highlighter-kit';
2
+ export declare const sampleHighlights: InputHighlightData[];
@@ -0,0 +1,2 @@
1
+ import { DocumentCacheContextValue } from '../models/document-cache.models';
2
+ export declare const DocumentPreviewCacheContext: import('react').Context<DocumentCacheContextValue | null>;
@@ -0,0 +1,15 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ interface DocumentCacheProviderProps extends PropsWithChildren {
3
+ /** TTL in milliseconds. Default: 1 200 000 ms (20 min) */
4
+ ttlMs?: number;
5
+ /** Maximum number of cached entries (LRU). Default: 20 */
6
+ maxEntries?: number;
7
+ }
8
+ /**
9
+ * Provides blob caching for document fetches with TTL expiration and LRU eviction.
10
+ *
11
+ * Wrap the subtree that renders `DocumentPreview` to avoid repeated network requests
12
+ * for frequently opened files.
13
+ */
14
+ export declare const DocumentCacheProvider: FC<DocumentCacheProviderProps>;
15
+ export {};
@@ -0,0 +1,7 @@
1
+ import { UseDocumentPreviewOptions, UseDocumentPreviewResult } from '../models/document-preview.models';
2
+ /**
3
+ * Encapsulates all logic for the document preview: file loading (with optional
4
+ * cache integration), highlight index navigation, zoom state, and thumbnail
5
+ * generation. Pair with a UI layer to build a custom document preview.
6
+ */
7
+ export declare const useDocumentPreview: ({ fileUrl, fileName, loadFileCb, highlights, selectedPageNumber: _selectedPageNumber, onTotalPagesChange: _onTotalPagesChange, thumbnailPageNumbers, onThumbnailsLoaded, onViewerReady, showLoaderOverlay, selectedPages: _selectedPages, }: UseDocumentPreviewOptions) => UseDocumentPreviewResult;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Returns the current document preview cache context.
3
+ *
4
+ * When used outside `DocumentPreviewCacheProvider`, returns `null`.
5
+ */
6
+ export declare const useDocumentPreviewCache: () => import('../models/document-cache.models').DocumentCacheContextValue | null;
@@ -0,0 +1,16 @@
1
+ export { PDFViewer } from './components/PdfViewer/PdfViewer';
2
+ export type { PdfViewerProps } from './components/PdfViewer/PdfViewer';
3
+ export { DocumentPreview } from './components/DocumentPreview/DocumentPreview';
4
+ export type { DocumentPreviewProps } from './components/DocumentPreview/DocumentPreview';
5
+ export { DocumentCacheProvider as DocumentPreviewCacheProvider } from './context/documentCacheProvider';
6
+ export { useDocumentPreviewCache } from './hooks/useDocumentPreviewCache';
7
+ export { useDocumentPreview } from './hooks/useDocumentPreview';
8
+ export type { UseDocumentPreviewResult } from './models/document-preview.models';
9
+ export { PdfPreviewLoader } from './components/PdfPreviewLoader/PdfPreviewLoader';
10
+ export type { PdfPreviewLoaderProps } from './components/PdfPreviewLoader/PdfPreviewLoader';
11
+ export { PageThumbnail } from './components/PageThumbnail/PageThumbnail';
12
+ export type { PageThumbnailProps } from './components/PageThumbnail/PageThumbnail';
13
+ export type { PdfViewerApi } from './models/pdf-viewer.models';
14
+ export type { ZoomOption } from './models/pdf-viewer.models';
15
+ export { AUTO_ZOOM_ID, FIT_ZOOM_ID, THUMBNAIL_BATCH_SIZE, THUMBNAIL_IMAGE_OPTIONS, ZOOM_OPTIONS, } from './constants/pdf-viewer.constants';
16
+ export { getStepZoomOptionValue, isPdfFile } from './utils/pdf-viewer.utils';
@@ -0,0 +1,17 @@
1
+ export interface DocumentCacheContextValue {
2
+ /**
3
+ * Returns a cached file when available, or invokes `loader` and caches the result.
4
+ */
5
+ getFile: (url: string, loader: () => Promise<Blob>) => Promise<Blob>;
6
+ /** Clears all cached entries immediately. */
7
+ clearCache: () => void;
8
+ }
9
+ /** Internal cache record for a loaded or in-flight document blob. */
10
+ export interface CacheEntry {
11
+ /** In-flight loader promise used for request coalescing. */
12
+ promise?: Promise<Blob>;
13
+ /** Resolved blob value when loading succeeded. */
14
+ file?: Blob;
15
+ /** Last touch timestamp used for TTL checks and LRU ordering. */
16
+ timestamp: number;
17
+ }
@@ -0,0 +1,33 @@
1
+ import { InputHighlightData } from '@epam/pdf-highlighter-kit';
2
+ import { PdfViewerApi } from './pdf-viewer.models';
3
+ export interface UseDocumentPreviewOptions {
4
+ fileUrl: string;
5
+ fileName?: string;
6
+ loadFileCb: (url: string) => Promise<Blob>;
7
+ highlights: InputHighlightData[];
8
+ selectedPageNumber?: number;
9
+ onTotalPagesChange?: (totalPages: number) => void;
10
+ thumbnailPageNumbers?: number[];
11
+ onThumbnailsLoaded?: (map: Map<number, string>) => void;
12
+ onViewerReady?: (api: PdfViewerApi) => void;
13
+ showLoaderOverlay?: boolean;
14
+ selectedPages?: number[];
15
+ }
16
+ export interface UseDocumentPreviewResult {
17
+ file: Blob | null;
18
+ isLoading: boolean | null;
19
+ isError: boolean;
20
+ isSupportedFile: boolean;
21
+ activeHighlightIndex: number;
22
+ zoom: string;
23
+ setZoom: (value: string) => void;
24
+ zoomSelectOptions: {
25
+ value: string;
26
+ label: string;
27
+ }[];
28
+ viewerApiRef: React.RefObject<PdfViewerApi | null>;
29
+ showLoader: boolean;
30
+ changeIndex: (dir: 1 | -1) => void;
31
+ handleZoomChange: (dir?: 1 | -1) => void;
32
+ handleViewerReady: (api: PdfViewerApi) => void;
33
+ }
@@ -0,0 +1,25 @@
1
+ import { ThumbnailOptions } from '@epam/pdf-highlighter-kit';
2
+ /**
3
+ * Imperative API exposed by {@link PDFViewer} through the `onViewerReady` callback.
4
+ */
5
+ export interface PdfViewerApi {
6
+ /**
7
+ * Generates data URLs for requested pages.
8
+ *
9
+ * @param pageNumbers 1-based page numbers to render thumbnails for.
10
+ * @param options Rendering options forwarded to pdf-highlighter-kit.
11
+ */
12
+ getThumbnailsDataUrl: (pageNumbers: number[], options?: ThumbnailOptions) => Promise<Map<number, string>>;
13
+ /** Increases current zoom level by one viewer step. */
14
+ zoomIn: () => void;
15
+ /** Decreases current zoom level by one viewer step. */
16
+ zoomOut: () => void;
17
+ /** Returns the current numeric zoom value. */
18
+ getZoom: () => number;
19
+ /** Navigates to a specific 1-based page number. */
20
+ navigateToPage: (page: number) => void;
21
+ }
22
+ export interface ZoomOption {
23
+ value: string;
24
+ label: string;
25
+ }
@@ -0,0 +1,2 @@
1
+ export declare const getStepZoomOptionValue: (currentZoom: string, direction: 1 | -1, actualZoom?: number) => string;
2
+ export declare function isPdfFile(name?: string | null | undefined, contentType?: string | null | undefined): boolean;
package/package.json ADDED
@@ -0,0 +1,111 @@
1
+ {
2
+ "name": "@epam/ai-dial-react-pdf-highlighter",
3
+ "version": "0.1.0-rc.0",
4
+ "type": "module",
5
+ "license": "Apache-2.0",
6
+ "description": "React components for PDF viewing and highlighting, built on @epam/pdf-highlighter-kit",
7
+ "types": "dist/src/index.d.ts",
8
+ "engines": {
9
+ "node": ">=22.2.0",
10
+ "npm": ">=10.7.0"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/src/index.d.ts",
15
+ "import": "./dist/ai-dial-react-pdf-highlighter.es.js",
16
+ "require": "./dist/ai-dial-react-pdf-highlighter.cjs.js"
17
+ },
18
+ "./styles.css": {
19
+ "require": "./dist/index.css",
20
+ "default": "./dist/index.css"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "sideEffects": [
27
+ "*.css",
28
+ "*.scss"
29
+ ],
30
+ "scripts": {
31
+ "dev": "vite",
32
+ "build": "vite build && npm run build:css",
33
+ "build:css": "tailwindcss -m -i ./src/styles/tailwind-entry.scss -o ./dist/index.css",
34
+ "lint": "eslint . --ext ts,tsx --fix --report-unused-disable-directives --max-warnings 0",
35
+ "lint:check": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
36
+ "typecheck": "tsc --noEmit",
37
+ "test:run": "vitest run",
38
+ "verify:agent-hook": "npm run typecheck && npm run lint:check && npm run test:run",
39
+ "format": "prettier --check .",
40
+ "format-fix": "prettier --write .",
41
+ "preview": "vite preview",
42
+ "storybook": "concurrently \"npm run storybook:css\" \"storybook dev -p 6007\"",
43
+ "storybook:css": "tailwindcss -w -i ./src/styles/tailwind-entry.scss -o ./src/index.css",
44
+ "build-storybook": "concurrently \"npm run build-storybook:css\" \"storybook build\"",
45
+ "build-storybook:css": "tailwindcss -m -i ./src/styles/tailwind-entry.scss -o ./src/index.css",
46
+ "prepare": "husky",
47
+ "publish": "node tools/publish-lib.mjs",
48
+ "publish:dry": "node tools/publish-lib.mjs --dry",
49
+ "test": "vitest --coverage"
50
+ },
51
+ "lint-staged": {
52
+ "*.{ts,tsx}": [
53
+ "npm run lint"
54
+ ]
55
+ },
56
+ "peerDependencies": {
57
+ "@epam/ai-dial-ui-kit": ">=0.8.0",
58
+ "@epam/pdf-highlighter-kit": ">=0.0.13",
59
+ "@tabler/icons-react": "^3.0.0",
60
+ "pdfjs-dist": ">=4.0.0",
61
+ "react": ">=18",
62
+ "react-dom": ">=18"
63
+ },
64
+ "devDependencies": {
65
+ "@chromatic-com/storybook": "^4.1.3",
66
+ "@epam/ai-dial-ui-kit": "0.9.0-rc.20",
67
+ "@epam/pdf-highlighter-kit": "^0.0.13",
68
+ "@eslint/compat": "^1.3.1",
69
+ "@eslint/eslintrc": "^3.3.1",
70
+ "@eslint/js": "^9.31.0",
71
+ "@modelcontextprotocol/sdk": "^1.29.0",
72
+ "@storybook/addon-a11y": "^10.2.17",
73
+ "@storybook/addon-docs": "^10.2.17",
74
+ "@storybook/addon-vitest": "^10.2.17",
75
+ "@storybook/react-vite": "^10.2.17",
76
+ "@tabler/icons-react": "^3.36.1",
77
+ "@testing-library/dom": "^10.4.0",
78
+ "@testing-library/react": "^16.3.0",
79
+ "@types/node": "^22.15.30",
80
+ "@types/react": "^19.1.8",
81
+ "@types/react-dom": "^19.1.6",
82
+ "@vitejs/plugin-react": "^4.6.0",
83
+ "@vitest/coverage-v8": "^3.2.4",
84
+ "autoprefixer": "^10.4.21",
85
+ "concurrently": "^9.2.0",
86
+ "esbuild": "^0.25.9",
87
+ "eslint": "^9.30.1",
88
+ "eslint-config-prettier": "^10.1.8",
89
+ "eslint-plugin-prettier": "^5.5.3",
90
+ "eslint-plugin-react": "7.37.5",
91
+ "eslint-plugin-react-hooks": "^5.2.0",
92
+ "eslint-plugin-react-refresh": "^0.4.20",
93
+ "eslint-plugin-storybook": "^10.2.17",
94
+ "globals": "^16.3.0",
95
+ "husky": "^9.1.7",
96
+ "jsdom": "^26.1.0",
97
+ "lint-staged": "^16.1.2",
98
+ "pdfjs-dist": "5.4.149",
99
+ "postcss": "^8.5.6",
100
+ "postcss-import": "^16.1.1",
101
+ "prettier": "3.6.2",
102
+ "sass": "^1.89.2",
103
+ "storybook": "^10.2.17",
104
+ "tailwindcss": "^3.4.17",
105
+ "typescript": "~5.9.3",
106
+ "typescript-eslint": "^8.48.0",
107
+ "vite": "^7.1.5",
108
+ "vite-plugin-dts": "^4.5.4",
109
+ "vitest": "^3.2.4"
110
+ }
111
+ }