import { ComputedRef, MaybeRef, PropType, Reactive, Ref } from 'vue'; import type { PageViewport, RenderTask } from 'pdfjs-dist'; import type { DocumentInitParameters, OnProgressParameters, PDFDataRangeTransport, TextContent, TypedArray, PDFPageProxy, PDFDocumentProxy, RenderParameters } from 'pdfjs-dist/types/src/display/api'; import type { Metadata } from 'pdfjs-dist/types/src/display/metadata'; import type { Annotation, AnnotationToolOption, TextSelectionOption, AnnotationTextSelectionControl, AnnotationFreeTextControl } from '@vue-pdf-viewer/shared'; import { ZoomLevel, ViewMode, ScrollMode, SelectionMode, VPVAnnotationType, LicenseType, LicenseProduct } from './enumerators'; import { Localization, Plugin, AnnotationType } from '@vue-pdf-viewer/shared'; export interface VirtualRange { start: number; end: number; } export interface ElementRect { left: number; top: number; width: number; height: number; } export interface Match { start: { idx: number; offset: number; }; end: { idx: number; offset: number; }; str: string; oIndex: number; pageIndex: number; rect: ElementRect; } export type LoadedEventPayload = number; export type FocusedPageEventPayload = number; export interface PageShowRatioChangePayload { page: number; ratio: number; } export type AnnotationIconType = keyof typeof AnnotationType | 'Signature'; export type AnnotationTextSelectionType = 'highlight' | 'underline' | 'strikethrough'; export interface AnnotationEventPayload { type: VPVAnnotationType; data: any; } export interface RotateEvent { direction: 'clockwise' | 'counterclockwise'; rotate: number; } export interface CharacterIndex { char: string; charIdxInSpan: number; spanIdx: number; } export interface MatchRangeIndex { keyword: RegExp; startIndex: number; endIndex: number; } export interface FlagKeyword { keyword: string; matchCase?: boolean; wholeWords?: boolean; } export type SingleKeyword = string | RegExp | FlagKeyword; export interface NormalizedKeyword { keyword: string; regExp: RegExp; wholeWords: boolean; color?: string; } export interface HighlightArea { keywordStr: string; left: number; top: number; height: number; width: number; pageHeight: number; pageWidth: number; highlightColor?: string; } export interface HighlightEventPayload { matches: Match[]; page: number; textContent: TextContent; textDivs: HTMLElement[]; } export interface TextLayerLoadedEventPayload { textDivs: HTMLElement[]; textContent: TextContent | undefined; textLayerRef?: HTMLElement; } export interface CanvasRenderedEventPayload { pageIndex: number; canvas: HTMLCanvasElement; } export interface HighlightOptions { matchCase?: boolean; wholeWords?: boolean; } export interface TextLayerHighlightProps { keyword: string; options?: HighlightOptions; } export interface Base { type: T; spec: S; } export type XYZ = Base<'XYZ', [left: number, top: number, zoom: number]>; export type Fit = Base<'Fit', []>; export type FitH = Base<'FitH', [top: number]>; export type FitV = Base<'FitV', [left: number]>; export type FitR = Base<'FitR', [left: number, bottom: number, right: number, top: number]>; export type FitB = Base<'FitB', []>; export type FitBH = Base<'FitBH', [top: number]>; export type FitBV = Base<'FitBV', [left: number]>; export type PDFLocation = XYZ | Fit | FitH | FitV | FitR | FitB | FitBH | FitBV; export interface PDFDestination { pageIndex: number; location: PDFLocation; } export type OnProgressCallback = (progressData: OnProgressParameters) => void; export type UpdatePasswordFn = (newPassword: string) => void; export type OnPasswordCallback = (updatePassword: UpdatePasswordFn, reason: any) => void; export type OnErrorCallback = (error: any) => void; export declare enum ErrorType { NOT_SUPPORTED = "not-supported" } /** * Payload for the password-required event. */ export interface PasswordRequiredPayload { /** * The reason the password is required. * - 'initial': First time password is requested * - 'incorrect': Previous password attempt was incorrect */ reason: 'initial' | 'incorrect'; } /** * Control object for programmatic password submission. */ export interface PasswordControl { /** * Submit a password programmatically. * @param password - The password to submit * @returns Promise that resolves to true if password was accepted, false if incorrect */ submitPassword(password: string): Promise; } export type CharacterMap = { url: string; isCompressed?: boolean; }; /** * Document loading options for configuring how the PDF is fetched and loaded. */ export interface PDFDocumentOptions { /** * Specify maximum number of bytes fetched per range request. * The default value is 65536 (64KB). */ rangeChunkSize?: number; /** * Disable streaming of PDF file data. * By default PDF.js attempts to load PDF files in chunks. * The default value is `false`. */ disableStream?: boolean; /** * Disable pre-fetching of PDF file data. * When range requests are enabled PDF.js will automatically keep * fetching more data even if it isn't needed to display the current page. * The default value is `false`. * * NOTE: It is also necessary to disable streaming, see above, in order for * disabling of pre-fetching to work correctly. */ disableAutoFetch?: boolean; } export type PDFSrc = string | URL | TypedArray | PDFDataRangeTransport | DocumentInitParameters | undefined | null; export interface PDFOptions { onProgress?: OnProgressCallback; onPassword?: OnPasswordCallback; onError?: OnErrorCallback; password?: string; } export interface PDFInfoMetadata { info: Object; metadata: Metadata; } export interface PDFInfo { metadata: PDFInfoMetadata; attachments: Record; javascript: string[] | null; outline: any; } export interface AppPdfPage { page: PDFPageProxy; viewport: PageViewport; height: number; scale: number; } export type PageViewportRawDimensions = { pageWidth: number; pageHeight: number; pageX: number; pageY: number; }; export interface Rect { height: number; width: number; } export interface PdfPageSize { rotation: number; pageRect: Rect; } export interface VPVThumbnail { page: PDFPageProxy; } export interface Offset { left: number; top: number; } export interface ViewerPdfPage { page: PDFPageProxy; viewport: PageViewport; height: number; width: number; } export interface ItemMeasurement { index: number; start: Offset; size: Rect; end: Offset; visibility: number; } export interface VirtualItem extends ItemMeasurement { pdfPage: ViewerPdfPage; } export type DestinationOffsetFromViewport = (viewportWidth: number, viewportHeight: number) => number; export interface Destination { pageIndex: number; bottomOffset: number | DestinationOffsetFromViewport; leftOffset: number | DestinationOffsetFromViewport; label?: string; scaleTo?: number | ZoomLevel; } export interface PageDimensionsWithSummation { pageNumber: number; dimension: { width: number; height: number; }; summation: { totalWidth: number; totalHeight: number; }; } export interface ViewerState { pdfDocument: PDFDocumentProxy | undefined; pagesContainerRef: HTMLElement | undefined; pageIndex: number; viewMode: ViewMode; scrollMode: ScrollMode; scale: number; targetScale: number; isScaling: boolean; rotation: number; isEditing: boolean; } export interface ToolbarOptions { /** * Determines whether the toolbar includes a search functionality. * If set to `true`, users can search for specific text within the PDF document. */ searchable: boolean; /** * Indicates whether navigation controls (such as next page and previous page buttons) are available in the toolbar. * When set to `true`, users can navigate through the pages of the PDF document. */ navigatable: boolean; /** * Specifies whether zoom controls (zoom in, zoom out buttons, and zoom dropdown menu) are part of the toolbar. * If `zoomable` is `true`, users can adjust the zoom level for better readability. */ zoomable: boolean; /** * Determines whether users can switch between different themes (e.g., light mode and dark mode) using the toolbar. * If enabled, users can customize the appearance of the PDF viewer. */ themeSwitchable: boolean; /** * Indicates whether a full-screen button is available in the toolbar. * When set to `true`, users can expand the PDF viewer to fill the entire screen. */ fullscreen: boolean; /** * Specifies whether a download button is included in the toolbar. * If enabled, users can download the PDF document directly. */ downloadable: boolean; /** * Determines whether a print button is part of the toolbar. * When set to `true`, users can print the PDF document. */ printable: boolean; /** * Indicates whether the functionality to open a file from the local computer, * including both the open file icon and drag-and-drop, is enabled or disabled. */ newFileOpenable: boolean; /** * Determines whether a sidebar is part of the viewer. */ sidebarEnable: boolean; /** * Determines whether a thumbnail button is part of the toolbar. */ thumbnailViewable: boolean; /** * Determines whether rotation group menu is a part of the others dropdown menu. */ rotatable: boolean; /** * Determines whether document properties menu is a part of the others dropdown menu. */ docPropertiesEnabled: boolean; /** * Determines whether text selection & hand tool menu are a part of the others dropdown menu. */ pointerSwitchable: boolean; /** * Determines whether top page & last page menu are a part of the others dropdown menu. */ jumpNavigatable: boolean; /** * Indicates whether the viewer's scrolling modes (vertical, horizontal, wrapped) can be toggled via the more options dropdown menu. */ scrollingSwitchable: boolean; /** * Indicates whether the viewer's page view modes (single, dual) can be toggled via the more options dropdown menu. */ pageViewSwitchable: boolean; /** * Indicates whether the comment panel is enabled. */ commentPanelEnabled: boolean; } export interface License { isValidating: boolean; isValidated: boolean; isValidKey: boolean; licenseKey: string | null; type: LicenseType; product: LicenseProduct; } export interface AppLicense extends Omit { invalidatedMessage?: string; } export type VPVSrc = Omit; export interface TextHighlight { /** * The keyword or regular expression to match text for highlighting. */ keyword: string | RegExp; /** * The color used to highlight the matched text. */ highlightColor: string; /** * Optional match options for fine-tuning the search behavior. */ options?: HighlightOptions; } export interface VPdfViewerProps { src: MaybeRef; /** * The path of your prefer pdfjs worker * If unspecified, the viewer will use the worker from pdfjs-dist@3.11.174 */ workerUrl?: string; /** * The URL directory where the pdf.js WASM files are located. Include the trailing slash. * Required when hosting WASM assets at a custom path (e.g. for JPEG 2000 decoding). */ wasmUrl?: string; /** * The number of page that will be displayed initially */ initialPage?: number; /** * The initial zoom level default * If unspecified, the initial zoom level is determined by the page dimensions and the width of the container */ initialScale?: number | ZoomLevel; /** * The scroll mode */ scrollMode?: ScrollMode; /** * The viewer mode */ viewMode?: ViewMode; /** * The initial scroll mode */ initialScrollMode?: ScrollMode; /** * The initial viewer mode */ initialViewMode?: ViewMode; /** * The initial rotation must be divisible by 90 */ initialRotation?: number; /** * The initial thumbnails visible default * If unspecified, the thumbnails visible will be `false` */ initialThumbnailsVisible?: boolean; /** * The initial search value */ initialSearch?: string; /** * A layer on a PDF to allow text selection */ textLayer?: boolean; /** * The selection mode for the viewer (text selection or hand tool) * - 'text': Enable text selection with cursor * - 'hand': Enable grab-to-scroll with hand cursor */ selectionMode?: SelectionMode; /** * Specifies the character map (CMap) to be used for text rendering. * A CMap associates character codes with corresponding glyphs in CID fonts. * Use this property when displaying PDFs with complex character sets (e.g., East Asian languages). */ characterMap?: CharacterMap; /** * Determine whether the toolbar is visible in the VPV. * Remark: The toolbar consists of top bar and left sidebar. */ toolbarOptions?: Partial | false; /** * localization json data */ localization?: Record; /** * A callback function that will be executed after each canvas is loaded. * The key is the page number, and the value is the callback function. */ afterCanvasLoaded?: Record; /** * The initial text highlights */ textHighlights?: Array; /** * The plugins to be used in the VPV. */ plugins?: Plugin[]; /** * Document loading options for configuring how the PDF is fetched and loaded. * Controls chunk size, streaming, and auto-fetch behavior. */ documentOptions?: PDFDocumentOptions; } export interface HighlightMatchPosition { matchIdx: number; pageIdx: number; } export interface HighlightMatchPosition { matchIdx: number; pageIdx: number; } export interface ViewportDimensions { width: number; height: number; canvasWidth: number; canvasHeight: number; widthRatio: number; heightRatio: number; } export type CanvasLoadedCallback = (element: HTMLCanvasElement, viewport: ViewportDimensions) => void; export interface PdfProperties { filename: string; fileSize: string; title: string; author: string; subject: string; keywords: string; creator: string; createdOn: string; modifierOn: string; pdfProducer: string; pdfVersion: string; pageCount?: number; } export type TextSelectionMenuOption = Pick; export type TextSelectionMenuItemOption = AnnotationToolOption; export declare const VPVBaseProps: { readonly src: { readonly type: PropType; readonly required: true; }; readonly workerUrl: { readonly type: PropType; readonly default: undefined; }; readonly wasmUrl: { readonly type: PropType; readonly default: undefined; }; readonly initialPage: { readonly type: PropType; readonly default: () => number; }; readonly initialScale: { readonly type: PropType; readonly default: () => ZoomLevel; }; readonly scrollMode: { readonly type: PropType; readonly validator: (scrollMode: ScrollMode, args: unknown) => boolean; }; readonly viewMode: { readonly type: PropType; readonly validator: (viewMode: ViewMode, args: unknown) => boolean; }; readonly initialScrollMode: { readonly type: PropType; readonly validator: (initialScrollMode: ScrollMode, args: unknown) => boolean; }; readonly initialViewMode: { readonly type: PropType; readonly validator: (initialViewMode: ViewMode, args: unknown) => boolean; }; readonly initialRotation: { readonly type: PropType; readonly default: () => number; }; readonly initialThumbnailsVisible: { readonly type: PropType; readonly default: undefined; }; readonly textLayer: { readonly type: PropType; readonly default: () => boolean; }; readonly selectionMode: { readonly type: PropType; readonly default: undefined; }; readonly characterMap: { readonly type: PropType; readonly default: undefined; }; readonly toolbarOptions: { readonly type: PropType>; readonly default: () => ToolbarOptions; }; readonly localization: { readonly type: PropType>; readonly default: () => Record; }; readonly initialSearch: { readonly type: StringConstructor; readonly default: undefined; }; readonly afterCanvasLoaded: { readonly type: PropType>; readonly default: undefined; }; /** * Experiment property */ readonly textHighlights: { readonly type: PropType; readonly default: undefined; readonly validator: (value: Array) => boolean; }; readonly downloadFilename: { readonly type: StringConstructor; readonly default: undefined; }; readonly plugins: { readonly type: PropType[]>; readonly default: undefined; }; readonly documentOptions: { readonly type: PropType; readonly default: undefined; }; /** * Controls visibility of the default password modal. * Set to false to handle passwords programmatically via the passwordControl.submitPassword() method. * @default true */ readonly showPasswordModal: { readonly type: PropType; readonly default: true; }; }; export interface MatchValue extends Match { page: number; pageMatchIdx: number; } export interface MatchHighlight extends MatchValue { keyword: string | RegExp; color: string; } export interface FullMatchHighlightResult extends Match { pageIndex: number; pageMatchIdx: number; color: string; keyword: string | RegExp; lines?: any[]; } export interface MatchHighlightResult { /** * The index of the page that contains the match */ pageIndex: number; /** * The index of the match in the page */ pageMatchIdx: number; } export interface SearchControlValue { textContentPages: Ref>; searchValue: Ref; matches: Ref; matchCount: ComputedRef; currentSearchMatchIndex: Ref; currentSearchMatch: ComputedRef; searching: Ref; openSearch: Ref; onOpenSearch: () => void; onCloseSearch: () => void; handleSelectNext: () => void; handleSelectPrev: () => void; search: (value: string) => Promise; goToMatch: (index: number) => void; } export interface SearchControl { searchMatches?: { totalMatches: number; matches: { index: number; page: number; }[]; }; searching: Ref; search: (value: string) => void; goToMatch: (index: number) => void; nextSearchMatch: () => void; prevSearchMatch: () => void; } export interface PreparePrintProgress { loadedPages: number; totalPages: number; percentage: number; } export interface PrintControl { print(options?: { visibleDefaultProgress: boolean; }): Awaited; cancel(): void; onProgress?: (progress: PreparePrintProgress) => void; onError?: (error: Error) => void; onComplete?: () => void; } export interface RotateControl { rotateClockwise: () => void; rotateCounterclockwise: () => void; currentRotation: number; } export interface PageControl { goToPage: (page: number) => void; currentPage: number; totalPages: number; rotatePage: (pageNumber: number, degree: 90 | 180 | 270 | -90 | ((currentDegree: number) => 90 | 180 | 270 | -90)) => void; } export interface DownloadPdfProgress { bytesDownloaded: number; percentage: number; } export interface DownloadControl { download(): Awaited; getBlob: () => Promise<{ blob: Blob; filename: string; }>; onError?: (error: Error) => void; onComplete?: () => void; } export interface ZoomControl { scale: Ref; zoom(scale: number | ZoomLevel, options?: { immediate?: boolean; origin?: [number, number]; }): void; } export interface UseScaleCallback { status: 'success' | 'error'; scale: number; mode?: ZoomLevel; error?: string; } export interface VPVInstance { printControl: Reactive | undefined; searchControl: SearchControl | undefined; pageControl: Reactive | undefined; rotateControl: Reactive | undefined; downloadControl: Reactive | undefined; zoomControl: Reactive | undefined; passwordControl: Reactive | undefined; annotationTextSelectionControl: Reactive | undefined; annotationFreeTextControl: Reactive | undefined; } export interface NavigationAnnotation { action: 'FirstPage' | 'LastPage' | 'NextPage' | 'PrevPage'; } export interface Comment extends Pick { page: number; text: string; annotationIconType: AnnotationIconType; } export interface CommentWithReplies { original: Comment; replies: Comment[]; } export interface PdfCommentPage { page: number; comments: CommentWithReplies[]; } export interface UsePdfCommentsReturn { comments: Ref>; repliedCommentPages: Ref; } export interface RenderQueueItem { page: PDFPageProxy; canvasElem: HTMLCanvasElement; options: RenderParameters; onLoaded?: (renderTask: RenderTask) => void; onError?: (error: Error) => void; onComplete?: () => void; } export type RectBox = { x: number; y: number; width: number; height: number; }; export interface PageLayout { rotation: number; width: number; height: number; } export interface AnnotationHighlight extends Annotation { hexColor: string; drawLayerId: number; outlineId: number; pageIndex?: number; boxes?: Array<{ x: number; y: number; width: number; height: number; }>; } export type AnnotationUnderline = AnnotationHighlight; export type AnnotationStrikethrough = AnnotationHighlight; export interface AnnotationStamp extends Annotation { hasOwnCanvas: boolean; originalAnnotation?: any; pageIndex?: number; elementRect?: ElementRect; bitmapId?: string; bitmap?: ImageData; width?: number; height?: number; isSvg?: boolean; } export interface FreeTextAppearance { fontColor: Uint8ClampedArray; fontName: string; fontSize: number; } export interface AnnotationFreeText extends Annotation { defaultAppearanceData?: FreeTextAppearance; pageIndex?: number; fontSize?: number; value?: string; richText?: { html: { attributes: { style: Partial; class: string[]; }; name: string; }; str: string; }; isModified?: boolean; user?: string; } /** * Visible area of a page in viewport coordinates. * Following pdf.js pattern from pdf_page_detail_view.js */ export interface VisibleArea { minX: number; minY: number; maxX: number; maxY: number; } /** * Detail canvas rendering area (visible area + overflow padding). * Following pdf.js pattern from pdf_page_detail_view.js */ export interface DetailArea { minX: number; minY: number; width: number; height: number; scale: number; }