UNPKG

@pdf-viewer/react

Version:

A react-pdf-viewer component for React and Next.js. Suitable for react-pdf document.

723 lines (722 loc) 23.6 kB
import { PDFPageProxy } from 'pdfjs-dist'; import { DocumentInitParameters, PDFDataRangeTransport, PDFDocumentProxy, TypedArray } from 'pdfjs-dist/types/src/display/api'; import { PageViewport } from 'pdfjs-dist/types/web/interfaces'; import { Dispatch, FC, PropsWithChildren, SetStateAction } from 'react'; export interface DocumentContextType { pdf?: PDFDocumentProxy; pages: Map<number, PdfPage>; pdfSrc?: PDFSrc; setPdfSrc: React.Dispatch<React.SetStateAction<RPSrc | undefined>>; pdfProperties?: PdfProperties; setFilename: React.Dispatch<React.SetStateAction<string | undefined>>; filename?: string | null; loading: boolean; loaderProgress: number; } export declare enum AnnotationSubType { Text = 1, Link = 2, FreeText = 3, Line = 4, Square = 5, Circle = 6, Polygon = 7, Polyline = 8, Highlight = 9, Underline = 10, Squiggly = 11, StrikeOut = 12, Stamp = 13, Caret = 14, Ink = 15, Popup = 16, FileAttachment = 17, Widget = 20 } export declare enum AnnotationType { INTERNAL_LINK = "internal-link", LINK = "link", FILE_ATTACHMENT = "file-attachment", FORM_TEXT = "form-text", FORM_SELECT = "form-select", FORM_CHECKBOX = "form-checkbox", FORM_RADIO = "form-radio", FORM_BUTTON = "form-button", BUTTON = "button" } export interface AnnotationEventPayload { type: AnnotationType; data: any; } interface AnnotationPoint { x: number; y: number; } export interface OutlineRef { gen: number; num: number; } export interface OutlineDestinationName { name: string; } export type OutlineDestination = [ OutlineRef | number, OutlineDestinationName, ...any[] ]; export type OutlineDestinationType = string | OutlineDestination; export declare enum ZoomLevel { ACTUAL = "Actual", PAGE_FIT = "Fit", PAGE_WIDTH = "Width" } export type Localization = { searchButtonTooltip?: string; searchInputPlaceholder?: string; searchInputTooltip?: string; searchPrevTooltip?: string; searchNextTooltip?: string; searchCloseButtonTooltip?: string; searchMatchCaseLabel?: string; searchMatchCaseTooltip?: string; searchWholeWordsLabel?: string; searchWholeWordsTooltip?: string; previousPageTooltip?: string; currentPageTooltip?: string; nextPageTooltip?: string; zoomOutTooltip?: string; zoomInTooltip?: string; zoomSelectTooltip?: string; zoomActualSize?: string; zoomPageFit?: string; zoomPageWidth?: string; themeEnableDarkTooltip?: string; themeEnableLightTooltip?: string; openLocalFileLabel?: string; openLocalFileTooltip?: string; downloadFileLabel?: string; downloadFileTooltip?: string; printLabel?: string; printTooltip?: string; printLoadingMessage?: string; printCancelLabel?: string; fullScreenLabel?: string; fullScreenTooltip?: string; moreOptionTooltip?: string; firstPageLabel?: string; firstPageTooltip?: string; lastPageLabel?: string; lastPageTooltip?: string; rotateClockwiseLabel?: string; rotateClockwiseTooltip?: string; rotateCounterclockwiseLabel?: string; rotateCounterclockwiseTooltip?: string; textSelectionLabel?: string; textSelectionTooltip?: string; handToolLabel?: string; handToolTooltip?: string; pageScrollingLabel?: string; pageScrollingTooltip?: string; verticalScrollingLabel?: string; verticalScrollingTooltip?: string; horizontalLabel?: string; horizontalTooltip?: string; singlePageLabel?: string; singlePageTooltip?: string; dualPageLabel?: string; dualPageTooltip?: string; documentPropertiesLabel?: string; documentPropertiesTooltip?: string; propertiesFilenameLabel?: string; propertiesFileSizeLabel?: string; propertiesTitleLabel?: string; propertiesAuthorLabel?: string; propertiesSubjectLabel?: string; propertiesKeywordLabel?: string; propertiesCreatorLabel?: string; propertiesCreateOnLabel?: string; propertiesModifiedOnLabel?: string; propertiesPDFProducerLabel?: string; propertiesPDFVersionLabel?: string; propertiesPageCountLabel?: string; thumbnailTooltip?: string; passwordModalTitle?: string; passwordModalMessage?: string; passwordPlaceholder?: string; passwordConfirmLabel?: string; passwordError?: string; dragDropFileMessage?: string; }; interface Attachment { content: Uint8Array; filename: string; } export interface Annotation { annotationType: number; color?: Uint8ClampedArray; dest: OutlineDestinationType; hasAppearance: boolean; id: string; rect: number[]; subtype: string; borderStyle: { dashArray: number[]; horizontalCornerRadius: number; style: number; verticalCornerRadius: number; width: number; }; hasPopup?: boolean; contents?: string; contentsObj?: { dir: string; str: string; }; modificationDate?: string; quadPoints?: AnnotationPoint[][]; title?: string; titleObj?: { dir: string; str: string; }; parentId?: string; parentType?: string; file?: Attachment; inkLists?: AnnotationPoint[][]; lineCoordinates: number[]; action?: string; unsafeUrl?: string; url?: string; newWindow?: boolean; vertices?: AnnotationPoint[]; name?: string; fieldType: string; pushButton: boolean; } export interface Destination { pageIndex: number; bottomOffset: number | DestinationOffsetFromViewport; leftOffset: number | DestinationOffsetFromViewport; label?: string; scaleTo?: number; } export type DestinationOffsetFromViewport = (viewportWidth: number, viewportHeight: number) => number; export interface OutlineRef { gen: number; num: number; } export interface RotateContextType { rotate: number; setRotate: React.Dispatch<React.SetStateAction<number>>; } export interface RPThemeContextType extends PropsWithChildren { customVariables?: Partial<Record<ThemeVariables, string>>; customDarkVariables?: Partial<Record<ThemeVariables, string>>; } export interface DarkModeProps { darkMode: boolean; setDarkMode: Dispatch<React.SetStateAction<boolean>>; } export interface DarkMode extends DarkModeProps { onDarkModeChange: (value: boolean) => void; } export interface License { validating?: boolean; isValid: boolean; invalidatedMessage?: string; type?: LicenseType; } export declare enum LicenseType { Organization = "organization", Developer = "developer" } export type DecryptedLicense = { exp: number; avu: number; t: LicenseType; dmt: 'specific' | 'wildcard'; dm: string; n: string; }; export interface PdfPage { page: PDFPageProxy; thumbnailViewport: PageViewport; thumbnailScale: number; defaultRotation: number; } export interface SetPageResult { success: boolean; currentPage: number; } export interface PageControl { focusedPage: number; setFocusedPage: (page: number | string) => void; goToPage: (page: number | string) => SetPageResult; totalPages: number; setTotalPages: (page: number) => void; nextPage: () => void; prevPage: () => void; } export interface PageControlContextType extends PageControl { } export interface ThumbnailContextType { thumbnailPages: Record<number, ThumbnailRenderedList>; addPage: (page: number) => void; addToPage: (page: number) => void; thumbnailLength: number; active: boolean; setActive: React.Dispatch<React.SetStateAction<boolean>>; } export interface FileDragDropControl { dragging: boolean; handleDragLeave: (event: React.DragEvent) => void; handleDragEnter: (event: React.DragEvent) => void; handleDrop: (event: React.DragEvent) => void; } export interface ThumbnailRenderedList { loading: boolean; page: PDFPageProxy; thumbnailSrc?: string; viewport: PageViewport; scale: number; defaultRotation: number; } export declare enum ViewMode { SINGLE_PAGE = "Single", DUAL_PAGE = "Dual" } export type PDFSrc = string | URL | TypedArray | PDFDataRangeTransport | DocumentInitParameters | undefined | null; export type RPSrc = Omit<PDFSrc, 'DocumentInitParameters' | 'PDFDataRangeTransport'>; export interface FullScreenToolProps { isFullScreen: boolean; toggleFullScreen: () => void; isSupported?: boolean; } export interface OpenFileToolProps { openFile: () => void; } export interface DownloadToolProps { download: () => void; } export interface PageNavigationToolProps { total: number; current: number; nextPage: () => void; prevPage: () => void; changePage: (page: number) => void; goToPage: (page: number) => SetPageResult; } export interface PreparePrintProgress { loadedPages: number; totalPages: number; percentage: number; } export interface PrintToolProps { print: () => void; cancel: () => void; setOnProgress: (callback: (progress: PreparePrintProgress) => void) => void; setOnComplete: (callback: () => void) => void; setOnError: (callback: (error: Error) => void) => void; progress: PreparePrintProgress; } export interface ThumbnailToolProps { onClick: () => void; active: boolean; } export interface RPSlots { themeSwitcher?: boolean | FC<Omit<DarkModeProps, 'onDarkModeChange'>>; documentProperties?: boolean; rotateTool?: boolean; fullscreenTool?: boolean | FC<FullScreenToolProps>; openFileTool?: boolean | FC<OpenFileToolProps>; dropFileZone?: boolean | React.ReactNode | React.ComponentType; downloadTool?: boolean | FC<DownloadToolProps>; zoomTool?: boolean | FC<ZoomProps>; viewModeTool?: boolean; scrollModeTool?: boolean; thumbnailTool?: boolean | FC<ThumbnailToolProps>; pageNavigationTool?: boolean | FC<PageNavigationToolProps>; printTool?: boolean | FC<PrintToolProps>; containerWidthSm?: number; showPrintProgress?: boolean; selectionModeTool?: boolean; searchTool?: boolean; jumpNavigationTool?: boolean; sidebarEnable?: boolean; } export interface RPIcons { goToFirstPageIcon?: React.ReactNode; goToLastPageIcon?: React.ReactNode; lightModeIcon?: React.ReactNode; darkModeIcon?: React.ReactNode; nextIcon?: React.ReactNode; prevIcon?: React.ReactNode; fullScreenIcon?: React.ReactNode; downloadIcon?: React.ReactNode; zoomInIcon?: React.ReactNode; zoomOutIcon?: React.ReactNode; openFileIcon?: React.ReactNode; rotateClockwiseIcon?: React.ReactNode; rotateCounterClockwiseIcon?: React.ReactNode; pageScrollIcon?: React.ReactNode; verticalScrollIcon?: React.ReactNode; horizontalScrollIcon?: React.ReactNode; documentPropertiesIcon?: React.ReactNode; printIcon?: React.ReactNode; thumbnailIcon?: React.ReactNode; searchIcon?: React.ReactNode; textSelectionIcon?: React.ReactNode; handModeIcon?: React.ReactNode; } export interface PdfProperties { filename: string; fileSize: string; title: string; author: string; subject: string; keywords: string; creator: string; createdOn: string; modifiedOn: string; pdfProducer: string; pdfVersion: string; pageCount?: number; } export interface ConfigContextType { workerUrlAdded: boolean; } export declare enum ThemeVariables { FONT_FAMILY = "--rp-font-family", PRIMARY_COLOR = "--rp-primary-color", BORDER_RADIUS = "--rp-border-radius", TEXT_COLOR = "--rp-text-color", OUTLINE_COLOR = "--rp-outline-color", FONT_SIZE = "--rp-font-size", DROP_MASK_BACKGROUND_COLOR = "--rp-drop-mask-background-color", LOADER_BACKDROP_COLOR = "--rp-loader-backdrop-color", ICON_DISABLED = "--rp-icon-disabled", ICON_FONT_SIZE = "--rp-icon-font-size", TOOLBAR_BACKGROUND = "--rp-toolbar-background", TOOLBAR_BORDER_COLOR = "--rp-toolbar-border-color", TOOLBAR_PADDING = "--rp-toolbar-padding", TOOLBAR_GAP = "--rp-toolbar-gap", TOOLBAR_SIZE = "--rp-toolbar-size", SIDEBAR_WIDTH = "--rp-sidebar-width", THUMBNAIL_BORDER_COLOR = "--rp-thumbnail-border-color", THUMBNAIL_BACKGROUND_COLOR = "--rp-thumbnail-background-color", THUMBNAIL_ACTIVE_COLOR = "--rp-thumbnail-active-color", THUMBNAIL_PADDING_Y = "--rp-thumbnail-padding-y", BUTTON_HOVER_BACKGROUND = "--rp-button-hover-background", BUTTON_PADDING = "--rp-button-padding", INPUT_PADDING = "--rp-input-padding", INPUT_BORDER_RADIUS = "--rp-input-border-radius", INPUT_BACKGROUND_COLOR = "--rp-input-background-color", INPUT_PLACEHOLDER_COLOR = "--rp-input-placeholder-color", PAGES_BACKGROUND_COLOR = "--rp-pages-background-color", ANNOTATION_LAYER_LINK_HOVER_BACKGROUND = "--rp-annotation-layer__link-hover-background", DROPDOWN_BACKGROUND_COLOR = "--rp-dropdown-background-color", DROPDOWN_PADDING = "--rp-dropdown-padding", DROPDOWN_HOVER_BACKGROUND_COLOR = "--rp-dropdown-hover-background-color", DROPDOWN_SEPARATOR_COLOR = "--rp-dropdown-separator-color", DROPDOWN_SEPARATOR_MARGIN = "--rp-dropdown-separator-margin", DROPDOWN_PADDING_MENU_ITEM = "--rp-dropdown-padding-menu-item", DROPDOWN_FONT_SIZE = "--rp-dropdown-font-size", DROPDOWN_BORDER_RADIUS = "--rp-dropdown-border-radius", SEARCH_TOOL_DROPDOWN_PADDING = "--rp-search-tool-dropdown-padding", POPOVER_FONT_SIZE = "--rp-popover-font-size", POPOVER_BACKGROUND_COLOR = "--rp-popover-background-color", POPOVER_COLOR = "--rp-popover-color", POPOVER_BORDER_COLOR = "--rp-popover-border-color", POPOVER_BORDER_RADIUS = "--rp-popover-border-radius", OVERLAY_BACKGROUND_COLOR = "--rp-overlay-background-color", DIALOG_BACKGROUND_COLOR = "--rp-dialog-background-color", PROPERTIES_DIVIDER_COLOR = "--rp-properties-divider-color", PROPERTIES_DIVIDER_MARGIN = "--rp-properties-divider-margin", PROPERTY_ITEM_GAP = "--rp-property-item-gap", DIALOG_TITLE_COLOR = "--rp-dialog-title-color", PROPERTY_ITEM_LABEL_COLOR = "--rp-property-item-label-color", PROPERTY_CLOSE_ICON_SIZE = "--rp-property-close-icon-size", PROPERTY_ITEM_FONT_SIZE = "--rp-property-item-font-size", PROPERTY_ITEM_FONT_WEIGHT = "--rp-property-item-font-weight", DIALOG_TITLE_FONT_SIZE = "--rp-dialog-title-font-size", DIALOG_TITLE_FONT_WEIGHT = "--rp-dialog-title-font-weight", MENU_ITEM_ICON_SIZE = "--rp-menu-item-icon-size", PRINT_PROGRESS_BACKGROUND = "--rp-print-progress-background", PRINT_PROGRESS_COLOR = "--rp-print-progress-color", DROP_ZONE_BORDER = "--rp-drop-zone-border", DROP_ZONE_FONT_COLOR = "--rp-drop-zone-font-color", DROP_ZONE_FONT_SIZE = "--rp-drop-zone-font-size", DROP_ZONE_BACKGROUND_COLOR = "--rp-drop-zone-background-color", CHECKBOX_BORDER_RADIUS = "--rp-checkbox-border-radius", CHECKBOX_BORDER_COLOR = "--rp-checkbox-border-color", CHECKBOX_INDICATOR_COLOR = "--rp-checkbox-indicator-color", HIGHLIGHT_BACKGROUND_COLOR = "--rp-highlight-background-color", TEXT_LAYER_HIGHLIGHT_BORDER_RADIUS = "--rp-text-layer-highlight-border-radius", CURRENT_HIGHLIGHT_BACKGROUND_COLOR = "--rp-current-highlight-background-color", TOOLTIP_BACKGROUND_COLOR = "--rp-tooltip-background-color", TOOLTIP_BORDER_RADIUS = "--rp-tooltip-border-radius", TOOLTIP_FONT_COLOR = "--rp-tooltip-font-color", TOOLTIP_FONT_SIZE = "--rp-tooltip-font-size", TOOLTIP_PADDING = "--rp-tooltip-padding", PASSWORD_MODAL_BACKGROUND_COLOR = "--rp-password-background-color", PASSWORD_MODAL_TITLE_FONT_COLOR = "--rp-password-title-font-color", PASSWORD_MODAL_CONTENT_FONT_COLOR = "--rp-password-content-font-color", PASSWORD_MODAL_INPUT_PLACEHOLDER_COLOR = "--rp-password-input-placeholder-color", PASSWORD_MODAL_INPUT_BORDER_COLOR = "--rp-password-input-border-color", PASSWORD_MODAL_INPUT_FONT_COLOR = "--rp-password-input-font-color", PASSWORD_MODAL_BUTTON_FONT_COLOR = "--rp-password-button-font-color", PASSWORD_MODAL_BUTTON_BACKGROUND_COLOR = "--rp-password-button-background-color", PASSWORD_MODAL_BUTTON_BORDER_COLOR = "--rp-password-button-border-color", PASSWORD_MODAL_BORDER_COLOR = "--rp-password-border-color", CONTAINER_FOCUS_OUTLINE_WIDTH = "--rp-container-focus-outline-width", CONTAINER_FOCUS_OUTLINE_COLOR = "--rp-container-focus-outline-color", CONTAINER_FOCUS_OUTLINE_OFFSET = "--rp-container-focus-outline-offset", BUTTON_BORDER_RADIUS = "--rp-button-border-radius" } export interface DarkModeProviderProps extends PropsWithChildren, Partial<Omit<DarkMode, 'setDarkMode'>> { } export interface RotateProviderProps extends PropsWithChildren { initialRotation?: number; } export interface LayerProviderProps extends PropsWithChildren { textLayer?: boolean; } export type RPThemeProps = RPThemeContextType; export interface CharacterMap { url: string; isCompressed: boolean; } export interface RPProviderProps extends PropsWithChildren, LoadPDFOptions, RPControllerProps { src: RPSrc; workerUrl?: string; characterMap?: CharacterMap; } export type LocalizationMap = Record<string, Localization>; export interface RPControllerProps extends PropsWithChildren, DarkModeProviderProps, RotateProviderProps, LayerProviderProps, ZoomProviderProps, PageProviderProps, ViewModeProps, ScrollModeProps { initialSearch?: string; initialThumbnailsVisible?: boolean; locale?: string; localization?: LocalizationMap; downloadFilename?: string; } export interface RPConfigProps extends Omit<ConfigContextType, 'workerUrlAdded'>, RPThemeContextType, PropsWithChildren { workerUrl?: string; licenseKey?: string; } export interface RPLayoutProps extends PropsWithChildren, ViewportProps { slots?: RPSlots; icons?: RPIcons; style?: React.CSSProperties; className?: string; onLoaded?: () => void; cleanupOnLoaded?: () => void; } export interface DimensionPagesContextType { widths: number[]; heights: number[]; setWidths: React.Dispatch<React.SetStateAction<number[]>>; setHeights: React.Dispatch<React.SetStateAction<number[]>>; } export interface ZoomContextType { zoomLevel: number; currentZoom: number; setZoomLevel: React.Dispatch<React.SetStateAction<number>>; } export type ZoomProps = Omit<ZoomContextType, 'currentZoom'>; export type InitialStateContextType = { instanceId: string; } & ZoomProviderProps & PageProviderProps & ViewModeProps & ScrollModeProps & RotateProviderProps; export interface ZoomProviderProps { initialScale?: number | ZoomLevel; } export interface PageProviderProps { initialPage?: number; } export interface ViewModeContextType { columnCount: number; setSinglePage: () => void; setDualPage: () => void; viewMode: ViewMode; } export interface ViewModeProps { initialViewMode?: ViewMode; } export interface ViewportProps { mobileWidth?: number; onLayoutWidthChange?: (isMobileScreen: boolean, currentWidth: number) => void; } export declare enum ScrollMode { PAGE_SCROLLING = "PAGE", VERTICAL_SCROLLING = "VERTICAL", HORIZONTAL_SCROLLING = "HORIZONTAL" } export interface ScrollModeContextType { scrollMode: ScrollMode; setScrollMode: (mode: ScrollMode) => void; } export interface ScrollModeProps { initialScrollMode?: ScrollMode; } export interface WordPositionRect { 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: WordPositionRect; } export interface MatchValue extends Match { page: number; pageMatchIdx: number; } export interface SearchOptions { matchCase?: boolean; wholeWords?: boolean; } export type TextItem = { /** * - Text content. */ str: string; /** * - Text direction: 'ttb', 'ltr' or 'rtl'. */ dir: string; /** * - Transformation matrix. */ transform: Array<any>; /** * - Width in device space. */ width: number; /** * - Height in device space. */ height: number; /** * - Font name used by PDF.js for converted font. */ fontName: string; /** * - Indicating if the text content is followed by a * line-break. */ hasEOL: boolean; }; export interface SearchContextType { search: string; setSearch: Dispatch<SetStateAction<string>>; loading: boolean; matches: MatchValue[]; totalMatches: number; currentMatchPosition: number; currentMatch: MatchValue | null; nextMatch: () => void; prevMatch: () => void; searchOptions: SearchOptions; setSearchOptions: Dispatch<SetStateAction<SearchOptions>>; currentMatchElement: HTMLElement | null; setCurrentMatchElement: Dispatch<SetStateAction<HTMLElement | null>>; } export declare enum SelectionMode { TEXT = "TEXT", HAND = "HAND" } export interface SelectionModeContextType { selectionMode: SelectionMode; setSelectionMode: (mode: SelectionMode) => void; } export interface SelectionModeProps { initialSelectionMode?: SelectionMode; } export type LoaderImage = JSX.Element | string; export interface LoadPDFOptions { onLoadError?: (error: any) => void; onLoaded?: (pdfDocument: PDFDocumentProxy) => void; loaderImage?: LoaderImage; } export interface ScrollPosition { left: number; top: number; } export declare const Locales: LocalizationMap; export interface LocalizationContextType { localeMessages?: Localization; } export interface LocalizationProps { locale?: string; localization?: LocalizationMap; } export interface LoaderContextType { LoaderImageComponent?: React.FC; } export interface TextHighlight { keyword: string | RegExp; highlightColor: string; options?: SearchOptions; } export interface UseHighlight { highlight: (value: TextHighlight[]) => Promise<void>; highlightMatches: MatchHighlight[]; highlightKeywords: TextHighlight[] | undefined; clear: () => void; } export interface useElementPage { updateElement: (pageNumber: number, element: (prevElements: Array<HTMLElement | JSX.Element>, dimension: { width: number; height: number; }, rotate: number, zoomLevel: number) => Array<HTMLElement | JSX.Element>) => void; removeElement: (pageNumber: number, index: number) => void; clearElements: (pageNumber: number) => void; elementList: Record<number, Array<HTMLElement | JSX.Element>>; } export interface MatchHighlight extends MatchValue { keyword: string | RegExp; color: string; } 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 MatchRangeIndex { keyword: RegExp; startIndex: number; endIndex: number; } export interface HighlightArea { keywordStr: string; left: number; top: number; height: number; width: number; pageHeight: number; pageWidth: number; highlightColor?: string; } export interface CharacterIndex { char: string; charIdxInSpan: number; spanIdx: number; } export {};