All Versions
52
Latest Version
Avg Release Cycle
20 days
Latest Release
-

Changelog History
Page 4

  • v2.4.2 Changes

    🐛 Bug fixes

    • Can't delete the last remaining digit in the page number input
    • Properly check whether or not the fileUrl changes
    • 👀 Fix the issue where we see the spinner if the document has a single page and the height is smaller than the viewer's height
    • Can't open the downloaded file if it was loaded with Uint8Array
    • Annotation popup can be displayed under the previous or next page
    • When users download a document loaded with Uint8Array, the download file is named as document.pdf instead of the document blob
    • Clicking a bookmark doesn't jump to the destination properly in the first time if the bookmark also requires to zoom the document to fit the width

    👌 Improvements

    • Display the current page number in the right
    • Make the content of annotation scrollable
    • 👍 Support shortcuts

    🔌 | Shortcut | Supported plugin | Action | | ----------------------------- | ---------------------------------------------------- | --------------------- | 🔌 | cmd + p | Print | Print the document | 🔌 | cmd + - | Zoom | Zoom out the document | 🔌 | cmd + + | Zoom | Zoom in the document | 🔌 | cmd + 0 | Zoom | Reset zoom to 100% |

  • v2.4.1 Changes

    🐛 Bug fixes

    • Clicking the Download button doesn't work. It only works the file when scrolling to the second page
    • 0️⃣ Using the Default Layout plugin, we can't scroll between pages on Safari 14
    • 🖨 The Open file button covers other elements, so we can't click on the Download or Print buttons. This issue only happens on Safari 14
  • v2.4.0 Changes

    🆕 New features

    • 🔌 The Search plugin provides methods to search for given keywords programatically:
    Method Description
    clearHighlights Clear the highlights
    highlight Highlight multiple keywords
    jumpToNextMatch Jump to the next match
    jumpToPreviousMatch Jump to the previous match
    🔌 import { searchPlugin } from '@react-pdf-viewer/search';
    🔌 const searchPluginInstance = searchPlugin();
    
    🔌 const { clearHighlights, highlight, jumpToNextMatch, jumpToPreviousMatch } = searchPluginInstance;
    
    <button onClick={() => highlight(['document', 'PDF']) }>
        Highlight: document, PDF
    </button>
    
    • 💅 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.
    0️⃣ const defaultLayoutPluginInstance = defaultLayoutPlugin();
    
    const {
        attachmentPluginInstance,
        bookmarkPluginInstance,
        thumbnailPluginInstance,
        toolbarPluginInstance,
    0️⃣ } = 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
    • 🔌 The SingleKeyword type in the Search plugin supports flags:
    interface FlagKeyword {
        keyword: string;
        matchCase?: boolean;    // `false` by default
        wholeWords?: boolean;   // `false` by default
    }
    
    type SingleKeyword = string | RegExp | FlagKeyword;
    

    You can use these flags when passing the keywords:

    🔌 const searchPluginInstance = searchPlugin({
        keyword: {
            keyword: 'document',
            matchCase: true,
        },
    });
    

    🐛 Bug fixes

    • 🔌 The Search plugin can find text that belongs to multiple span elements
    • 🛠 Fix the type definitions of the MoreActionsPopover component in the Toolbar plugin

    💥 Breaking changes

    • 📦 The Observer component is removed from the @react-pdf-viewer/core package
  • v2.3.2 Changes

    👌 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 Changes

    👌 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 Changes

    🆕 New features

    • 🔌 New highlight plugin provides the ability of selecting and adding notes for text in the document
    • 0️⃣ 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 Changes

    November 16, 2020

    👌 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 Changes

    November 10, 2020

    🆕 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

    • 0️⃣ 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 Changes

    October 27, 2020

    🆕 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 Changes

    October 20, 2020

    🔌 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

    • 0️⃣ 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 [email protected]
    npm install @react-pdf-viewer/[email protected]
    

    👷 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/[email protected]
    
    • 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,
            ...
        ]}
    />