Skip to content

Latest commit

 

History

History
870 lines (677 loc) · 24.3 KB

CHANGELOG.md

File metadata and controls

870 lines (677 loc) · 24.3 KB

CHANGELOG

v2.4.0 [WIP]

New features

  • You can highlight multiple keywords programatically:
import { searchPlugin } from '@react-pdf-viewer/search';
const searchPluginInstance = searchPlugin();

const { highlight } = searchPluginInstance;

<button onClick={() => highlight(['document', 'PDF']) }>
    Highlight: document, PDF
</button>

It's also possible to clear the highlights:

const { clearHighlights } = searchPluginInstance;
  • It's possible to add custom styles for highlighted area based on the keyword:
const searchPluginInstance = searchPlugin({
    onHighlightKeyword: (props: OnHighlightKeyword) => {
        if (props.keyword.source === 'document') {
            props.highlightEle.style.outline = '2px dashed blue';
            props.highlightEle.style.backgroundColor = 'rgba(0, 0, 0, .1)';
        }
    },
});
  • The Zoom plugin exposes the zoomTo function:
const { zoomTo } = zoomPluginInstance;

// Zoom to a given level
zoomTo(1.5);
zoomTo(SpecialZoomLevel.PageFit);
  • The Page Navigation plugin provides the jumpToPage function:
const { jumpToPage } = pageNavigationPluginInstance;

// Jump to the third page
jumpToPage(2);
  • It's possible to retrieve the instances of Attachment, Bookmark, Thumbnail, Toolbar plugins from the Default Layout plugin instance.
const defaultLayoutPluginInstance = defaultLayoutPlugin();

const {
    attachmentPluginInstance,
    bookmarkPluginInstance,
    thumbnailPluginInstance,
    toolbarPluginInstance,
} = defaultLayoutPluginInstance;

Similarity, the Toolbar plugin instance provides the accesses to the instance of other plugins that build the toolbar:

const toolbarPluginInstance = toolbarPlugin();

const {
    dropPluginInstance,
    fullScreenPluginInstance,
    getFilePluginInstance,
    openPluginInstance,
    pageNavigationPluginInstance,
    printPluginInstance,
    propertiesPluginInstance,
    rotatePluginInstance,
    scrollModePluginInstance,
    searchPluginInstance,
    selectionModePluginInstance,
    zoomPluginInstance,
} = toolbarPluginInstance;

Improvements

  • Support Next.js integration
  • Fix a warning in the Console when using with Next.js

Bug fixes

  • The Search plugin can find text that belongs to multiple span elements

Breaking changes

  • The Observer component is removed from the @react-pdf-viewer/core package

v2.3.2

Improvements

  • Lazy load the document. The PDF document will be loaded if the viewer container is visible in the viewport.

Bug fixes Fix a bug that could happen when we load multiple documents by changing fileUrl. In that case, you may see the error message

  • Worker was destroyed
  • Cannot read property 'sendWithPromise' of null

This version also fixes a potential memory leaks reported by React DevTools when we try to load new document even if the current document isn't rendered completely.

v2.3.1

Improvements

  • full-screen plugin provides new callbacks that are triggered after entering and exiting the full screen mode
import { SpecialZoomLevel } from '@react-pdf-viewer/core';
import { fullScreenPlugin } from '@react-pdf-viewer/full-screen';

const fullScreenPluginInstance = fullScreenPlugin({
    // Zoom to fit the screen after entering and exiting the full screen mode
    onEnterFullScreen: (zoom) => {
        zoom(SpecialZoomLevel.PageFit);
    },
    onExitFullScreen: (zoom) => {
        zoom(SpecialZoomLevel.PageFit);
    },
});

Bug fixes

  • The style files are missing in the highlight plugin
  • Render highlight annotations formed by quadrilaterals
  • The popup annotations aren't shown if they are children of highlight annotations
  • Clicking a destination (bookmark, for example) with name of FitH or FitBH throws an exception

v2.3.0

New features

  • New highlight plugin provides the ability of selecting and adding notes for text in the document
  • The default-layout plugin allows to customize the tabs:
// `defaultTabs` is the list of default tabs which lists thumbnails, bookmarks and attachments respetively
const defaultLayoutPluginInstance = defaultLayoutPlugin({
    sidebarTabs: defaultTabs => { ... }
});

We also can activate a given tab:

const { activateTab } = defaultLayoutPluginInstance;

// Activate a tab
// activateTab(index);

Breaking changes

  • The getPagesRef method in plugins are changed to getPagesContainer:
// Before
interface PluginFunctions {
    getPagesRef(): React.RefObject<HTMLDivElement>;
}

// After
interface PluginFunctions {
    getPagesContainer(): HTMLElement;
}
  • The authorization option is removed. You can use new withCredentials option:
// Before v2.3.0
<Viewer
    fileUrl={...}
    authorization='Bearer ...'
/>

// From v2.3.0
<Viewer
    fileUrl={...}
    withCredentials={true}
    httpHeaders={{
        'Authorization': 'Bearer ...',
    }}
/>

v2.2.1

Improvements

  • Keep the current page and scroll position after zooming the document
  • Pre-render a few of previous and next pages of the current page, so users see the page instantly when scrolling

v2.2.0

New features

  • Support loading PDF from a protected resource with new authorization option.
import { Viewer } from '@react-pdf-viewer/core';

<Viewer
    fileUrl={...}
    authorization='Bearer ...'
/>

If you want to use another authorization servers or send more additional authentication headers, then use the new httpHeaders option, for example:

import { Viewer } from '@react-pdf-viewer/core';

<Viewer
    fileUrl={...}
    authorization='...'
    httpHeaders={{
        key: value,
    }}
/>
  • It's possible to customize the search control with the new Search component:
import { RenderSearchProps, Search } from '@react-pdf-viewer/search';

<Search>
{
    (renderSearchProps: RenderSearchProps) => (
        // Your custom search control
    )
}
</Search>

The parameter renderSearchProps provides the properties and methods to build up a custom search control:

Property Type Description
clearKeyword Function Clear the keyword
changeMatchCase Function The result has to match case with the keyword
changeWholeWords Function The result has to match the whole keyword
currentMatch number The index of current match
jumpToNextMatch Function Jump to the next match
jumpToPreviousMatch Function Jump to the previous match
keyword string The current keyword
matchCase boolean true if the result matches case with the keyword
wholeWords boolean true if the result matches the whole keyword
search Function Perform the search with current keyword and matchCase, wholeWords conditions
setKeyword Function Set the current keyword

Improvements

  • A current match search has a custom class rpv-search-text-highlight-current. So you can customize the current match by adding CSS properties for the class.
  • Avoid the black flickering when clicking a bookmark
  • Support both React v16 and v17

Bug fixes

  • The print plugin doesn't work with default-layout plugin
  • In some cases, there is an extra blank page when printing
  • Clicking bookmark doesn't jump to correct page in horizontal scroll mode
  • Jumping between search match doesn't work properly in horizontal scroll mode

Breaking changes

  • The onCanvasLayerRender option is removed. Instead, use the onCanvasLayerRender option in your plugin.
  • The TextLayerRenderStatus enum is renamed to LayerRenderStatus.

v2.1.0

New features

  • Add onAnnotationLayerRender hook for plugin. We can perform custom action after annotations are rendered. The following sample code creates a plugin that finds all annotation links, and add the target="_blank" attribute to the links:
import { AnnotationType, Plugin, PluginOnAnnotationLayerRender } from '@react-pdf-viewer/core';

const customPlugin = (): Plugin => {
    const onRenderAnnotations = (e: PluginOnAnnotationLayerRender) => {
        // Find all `Link` annotation
        e.annotations
            .filter(annotation => annotation.annotationType === AnnotationType.Link)
            .forEach(annotation => {
                if (annotation.url) {
                    // Find the `a` element represents the link
                    [...e.container.querySelectorAll('.rpv-core-annotation-link a')].forEach(linkEle => {
                        linkEle.setAttribute('target', '_blank');
                    });
                }
            });
    };

    return {
        onAnnotationLayerRender: onRenderAnnotations,
    };
};
  • The search plugin allows to set multiple keywords to be highlighted initially
// Use the search plugin
import { searchPlugin } from '@react-pdf-viewer/search';
const searchPluginInstance = searchPlugin({
    keyword: ['document', 'PDF'],
});

// Use with default-layout plugin
import { defaultLayoutPlugin } from '@react-pdf-viewer/default-layout';
const defaultLayoutPluginInstance = defaultLayoutPlugin({
    toolbarPlugin: {
        searchPlugin: {
            keyword: ['document', 'PDF'],
        },
    },
});

Improvements

  • Optimize the search plugin that doesn't perform unhighligting and highlighting many times after texts are rendered

Bug fixes

  • Clicking Previous match or Next match button throws an error if the keyword is empty
  • Fix the incorrect path of styles

Upgrade from 2.0.1 to 2.1.0

We have to update the path of styles which are placed in the lib directory. For example:

// Old version
import '@react-pdf-viewer/core/styles/index.css';

// New version
import '@react-pdf-viewer/core/lib/styles/index.css';

v2.0.1

This version rewrites the entire viewer with the plugin architecture. The main viewer component Viewer is very lightweight, and everything else is powered by plugins.

The basic setup looks like following:

// Import plugin
import { toolbarPlugin } from '@react-pdf-viewer/toolbar';

// Import styles
import '@react-pdf-viewer/toolbar/lib/styles/index.css';

// Create the plugin instance
const toolbarPluginInstance = toolbarPlugin(...);

// Register plugins
<Viewer
    plugins={[
        // Array of plugins
        toolbarPlugin,
        ...
    ]}
/>

New features

  • Viewer supports to use a custom loader instead of the default <Spinner>:
import { ProgressBar, Viewer } from '@react-pdf-viewer/core';

<Viewer
    renderLoader={(percentages: number) => (
        // You can use your own progress bar component
        <div style={{ width: '240px' }}>
            <ProgressBar progress={Math.round(percentages)} />
        </div>
    )}
/>
  • Customizable name of download file with the get-file plugin:
const getFilePluginInstance = getFilePlugin({
    fileNameGenerator: (file: OpenFile) => {
        // `file.name` is the URL of opened file
        const fileName = file.name.substring(file.name.lastIndexOf('/') + 1);
        return `a-copy-of-${fileName}`;
    },
});
  • New Locale Switcher plugin for switching between different locales
  • Provide the ability of setting the scroll mode via the Scroll Mode plugin.

Bug fixes

  • The onPageChange could be invoked several times when clicking an outline item

Breaking changes

  • The keyword option is removed. Use the keyword option provided by the search plugin.
  • The layout option is removed
  • The render option is removed
  • The selectionMode option is removed. Use the selectionMode option provided by the selection-mode plugin.
  • The onTextLayerRender option is removed. Instead, use the onTextLayerRender option in your plugin.

Upgrade from 1.7.0 to 2.0.0

Uninstall the old packages:

npm uninstall pdfjs-dist
npm uninstall @phuocng/react-pdf-viewer

Install the new packages:

npm install pdfjs-dist@2.5.207
npm install @react-pdf-viewer/core@2.0.1

Replace the old `Worker` with new one:

// Remove the old Worker
import { Worker } from '@phuocng/react-pdf-viewer';

// Use the new Worker
import { Worker } from '@react-pdf-viewer/core';

Use the new Viewer:

npm install @react-pdf-viewer/default-layout@2.0.0
  • Replace the old Viewer with new one:
// Old Viewer
import Viewer from '@phuocng/react-pdf-viewer';

// New Viewer
import { Viewer } from '@react-pdf-viewer/core';

// Plugins
import { defaultLayoutPlugin } from '@react-pdf-viewer/default-layout';

// Import styles
import '@react-pdf-viewer/core/lib/styles/index.css';
import '@react-pdf-viewer/default-layout/lib/styles/index.css';

// Create new plugin instance
const defaultLayoutPluginInstance = defaultLayoutPlugin();

// Your render function
<Viewer
    fileUrl='/path/to/document.pdf'
    plugins={[
        // Register plugins
        defaultLayoutPluginInstance,
        ...
    ]}
/>

v1.7.0

New features

  • Add onPageChange callback that is invoked when user changes page:
import Viewer, { PageChangeEvent } from '@phuocng/react-pdf-viewer';

const handlePageChange = (e: PageChangeEvent) => {
    console.log(`Changed to page: ${e.currentPage}`)
};

<Viewer
    fileUrl='/path/to/document.pdf'
    onPageChange={handlePageChange}
/>
  • Add onCanvasLayerRender event that is invoked when the canvas layer is rendered completely.
import Viewer, { CanvasLayerRenderEvent } from '@phuocng/react-pdf-viewer';

const onCanvasLayerRender = (e: CanvasLayerRenderEvent) => {
    // `e.ele` is the canvas element
    const canvas = e.ele;
    // Do something with the canvas element
};

<Viewer
    fileUrl='/path/to/document.pdf'
    onCanvasLayerRender={onCanvasLayerRender}
/>
  • Add onTextLayerRender event that is invoked when the text layer is ready.
import Viewer, { TextLayerRenderEvent } from '@phuocng/react-pdf-viewer';

const onTextLayerRender = (e: TextLayerRenderEvent) => {
    // For example, we can find all text elements that look like a link, 
    // and replace it with `a` elements
};

<Viewer
    fileUrl='/path/to/document.pdf'
    onTextLayerRender={onTextLayerRender}
/>
  • Support non-latin characters via the characterMap option
import Viewer, { CharacterMap } from '@phuocng/react-pdf-viewer';

const characterMap: CharacterMap = {
    isCompressed: true,
    url: 'https://unpkg.com/pdfjs-dist@2.4.456/cmaps/',
};

<Viewer
    characterMap={characterMap}
    fileUrl='/path/to/document.pdf'
/>

Bug fixes

  • The viewer doesn't jump to the destination or searching result exactly

Breaking changes

The parameters of onDocumentLoad and onZoom are changed as following:

v1.6.0 v1.7.0
onDocumentLoad(doc) onDocumentLoad({ doc })
onZoom(doc, scale) onZoom({ doc, scale })

v1.6.0

New features

  • The annotation layer is rewritten. Support the following type of annotations:

    • Caret
    • Circle
    • File attachment
    • Free text
    • Highlight
    • Ink
    • Line
    • Link
    • Polygon
    • Polyline
    • Popup
    • Square
    • Squiggly
    • Stamp
    • StrikeOut
    • Text
    • Underline
  • The link annotation supports named actions which allow to jump to the first, last, next or previous pages

  • Customize error renderer.

const renderError = (error: LoadError) => {
    let message = '';
    switch (error.name) {
        case 'InvalidPDFException':
            message = 'The document is invalid or corrupted';
            break;
        case 'MissingPDFException':
            message = 'The document is missing';
            break;
        case 'UnexpectedResponseException':
            message = 'Unexpected server response';
            break;
        default:
            message = 'Cannot load the document';
            break;
    }

    return (<div>{message}</div>);
};

<Viewer
    fileUrl={fileUrl}
    renderError={renderError}
/>

Improvements

  • Allow to control the fileUrl option
  • Bookmarks support external links
  • Support external links

Bug fixes

  • The canvas layer is blurry
  • The tooltip, popover positions are not correct in some cases
  • The drag zone isn't visible if the main area is scrolled
  • The document rotated initially isn't displayed properly

v1.5.0

New features

  • Highlight given keyword in the first render
<Viewer
    fileUrl='/path/to/document.pdf'
    // The `keyword` option can be a string or a regular expression
    // keyword='PDF Library'
    keyword={new RegExp('pdf document', 'i')}
/>
  • Add new SVG layer which can be used to replace the canvas layer
const renderPage = (props: RenderPageProps) => {
    return (
        <>
            {props.svgLayer.children}
            {props.textLayer.children}
            {props.annotationLayer.children}
        </>
    );
};

<Viewer
    fileUrl='/path/to/document.pdf'
    renderPage={renderPage}
/>
  • Customize page renderer. The following code adds a simple Draft watermark at the center of every page:
const renderPage: RenderPage = (props: RenderPageProps) => (
    <>
        {props.canvasLayer.children}
        <div
            style={{
                alignItems: 'center',
                display: 'flex',
                height: '100%',
                justifyContent: 'center',
                left: 0,
                position: 'absolute',
                top: 0,
                width: '100%',
            }
        }>
            <div
                style={{
                    color: 'rgba(0, 0, 0, 0.2)',
                    fontSize: `${8 * props.scale}rem`,
                    fontWeight: 'bold',
                    textTransform: 'uppercase',
                    transform: 'rotate(-45deg)',
                    userSelect: 'none',
                }}
            >
                Draft
            </div>
        </div>
        {props.annotationLayer.children}
        {props.textLayer.children}
    </>
);

<Viewer
    fileUrl='/path/to/document.pdf'
    renderPage={renderPage}
/>

Improvement

  • The default scale can be a special zoom level. For example, we can fit page in the container initially:
<Viewer
    fileUrl='/path/to/document.pdf'
    defaultScale={SpecialZoomLevel.PageFit}
/>
  • The fileUrl option can be Uint8Array:
<Viewer
    fileUrl={new Uint8Array([...])}
/>
  • Add styles for error message

v1.4.0

New features

  • Add new optional parameter indicating the page that will be displayed initially
<Viewer
    // The page is zero-based index
    // We will display the third page initially
    initialPage={2}
/>
  • Add new optional parameter to define the prefix of CSS classes
<Viewer
    prefixClass='viewer'
/>
  • Add new render parameter that includes many functions that could be called from outside of the component:
import Viewer, { RenderViewerProps, ScrollMode, SpecialZoomLevel, SelectionMode } from '@phuocng/react-pdf-viewer';

const render = (props: RenderViewerProps) => {
    return (
        <div>
            <div style={{ height: '500px' }}>
                {props.viewer}
            </div>
            <button onClick={() => props.jumpToPage(props.doc.numPages - 1)}>Jump to last page</button>
            <button onClick={() => props.rotate(90)}>Rotate +90 degrees</button>
            <button onClick={() => props.zoom(0.5)}>Zoom to 50%</button>
            <button onClick={() => props.zoom(SpecialZoomLevel.ActualSize)}>Zoom to actual size</button>
            <button onClick={() => props.changeScrollMode(ScrollMode.Wrapped)}>Switch to wrapped scrolling</button>
            <button onClick={() => props.changeSelectionMode(SelectionMode.Hand)}>Switch to hand tool</button>
            <button onClick={() => props.print()}>Print</button>
            <button onClick={() => props.download()}>Download</button>
        </div>
    );
};

<Viewer
    fileUrl='/path/to/document.pdf'
    render={render}
/>

Improvement

  • All styles are moved to external CSS files. It's possible for us to override components' styles.

Bug fixes

  • Can't scroll and print on IE 11
  • Printing doesn't look good if the page size isn't set
  • Blank page when print the current web page

v1.3.0

New features Expose all the buttons from the more actions popover to the toolbar. ToolbarSlot now includes

  • goToFirstPageButton: the button to go to the first page
  • goToLastPageButton: go to the last page
  • rotateClockwiseButton: rotate the document
  • rotateCounterclockwiseButton: rotate counterclockwise the document
  • textSelectionButton: switch to the text selection mode
  • handToolButton: switch to the hand tool mode
  • verticalScrollingButton: scroll the document vertically
  • horizontalScrollingButton: scroll the document horizontally
  • wrappedScrollingButton: display pages as a grid
  • documentPropertiesButton: show the document properties

v1.2.1

Improvement

  • Make the spinner thiner
  • Add minified CSS files

Bug fixes

  • Tooltip for the left/right buttons don't look good in full width mode
  • The view now takes full height by default. It fixes the issue that users can't navigate between pages from the toolbar in some cases

v1.2.0

New features

  • Provide the ability of printing document
  • Add new selectionMode option indicates the selection mode:
import Viewer, { SelectionMode } from '@phuocng/react-pdf-viewer';

<Viewer
    fileUrl='/path/to/document.pdf'
    // By default, it will be SelectionMode.Text
    selectionMode={SelectionMode.Hand}
/>
  • Add onDocumentLoad callback that uis invoked when the document is loaded completely
import Viewer, { PdfJs } from '@phuocng/react-pdf-viewer';

const documentLoad = (doc: PdfJs.PdfDocument) => {
    console.log(`Document is loaded: ${doc.numPages}`)
};

<Viewer
    fileUrl='/path/to/document.pdf'
    onDocumentLoad={documentLoad}
/>
  • Add onZoom callback that is invoked when zooming in/out the document
import Viewer, { PdfJs } from '@phuocng/react-pdf-viewer';

const zoom = (doc: PdfJs.PdfDocument, scale: number) => {
    console.log(`Zoom document to ${scale}`);
};

<Viewer
    fileUrl='/path/to/document.pdf'
    onZoom={zoom}
/>

v1.1.0

New features

  • Add new, optional defaultScale parameter that indicates the default zoom level:
<Viewer defaultScale={1.5} ... />

Improvement

  • The document should fit best in the container initially

v1.0.2

Improvement

  • Support SSR

Bug fixes

  • Cannot re-export a type when --isolatedModules is set to true
  • The CSS files are missing in es6 package

v1.0.0

First release