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

Changelog History
Page 1

  • v3.9.0 Changes

    🆕 New features

    • New pageLayout option to customize the layout of each page. The following code adds margin between pages, and center the page in its container:
    import { type PageLayout, Viewer } from '@react-pdf-viewer/core';
    
    const pageLayout: PageLayout = {
        buildPageStyles: () => ({
            alignItems: 'center',
            display: 'flex',
            justifyContent: 'center',
        }),
        tranformSize: ({ size }) => ({ height: size.height + 30, width: size.width + 30 }),
    };
    
    <Viewer pageLayout={pageLayout} />;
    

    🐛 Bug fixes

    • Keep the current page after rotating the document

    🛠 Fix bugs that might happen with a document whose pages have different dimensions

    • Clicking a link annotation doesn't go to the correct destination position
    • Don't scroll to the top of the target page corresponding to the initialPage option

    💥 Breaking change

    • The pageHeight and pageWidth properties in RenderViewer are replaced with the pageSizes property that are the sizes of pages. You don't have to do anything if you don't develope your own plugin using those properties.
  • v3.8.0 Changes

    🆕 New features

    • Set the initial rotation with the new initialRotation parameter:
    <Viewer initialRotation={90} />
    
    • 🔌 The highlight plugin provides new function to switch the trigger mode:
    const highlightPluginInstance = highlightPlugin();
    const { switchTrigger } = highlightPluginInstance;
    
    // Switch to None
    switchTrigger(Trigger.None);
    
    // Switch to Selection mode
    switchTrigger(Trigger.TextSelection);
    
    • Users can click and drag to highlight an area

    👌 Improvements

    • Adjust the pointer when hovering the mouse over checkboxes inside the search popover
    • Keep the expanded/collapsed state of each bookmark
    • 🔌 Set the title and aria-label attributes for link annotations without using the Bookmark plugin
    • 👍 Support pdf-js 3.0.279
    • RenderBookmarkItemProps includes new path property that indicates the path from each bookmark item to the root
    • SelectionData provides more information about the selected text including:
    Property Type Description
    selectedText string The selected text
    divTexts DivText[] List of text items contain the selected text

    A DivText item consists of

    Property Type Description
    divIndex number The zero-based text element rendered by the text layer
    pageIndex number The zero-based page index
    textContent string The text content of text element
    • 0️⃣ The open file dialog filters PDF files by default
    • The search popover should perform search based on the initial keyword passed to the keyword option:
    const searchPluginInstance = searchPlugin({
        keyword: '...',
    });
    
    • RenderSearchProps adds new isDocumentLoaded property that indicates if the document is loaded. You can use it to perform searching for a keyword in a sidebar:
    import type { Match, RenderSearchProps } from '@react-pdf-viewer/search';
    
    const SearchSidebarInner: React.FC<{
        renderSearchProps: RenderSearchProps
    }> = ({ renderSearchProps }) => {
        const [matches, setMatches] = React.useState<Match[]>([]);
        const { isDocumentLoaded, keyword, search } = renderSearchProps;
    
        React.useEffect(() => {
            if (isDocumentLoaded && keyword) {
                search().then((matches) => {
                    setMatches(matches);
                });
            }
        }, [isDocumentLoaded]);
    
        return (
            // Display matches ...
        );
    };
    

    🐛 Bug fixes

    • Can't render certain PDF documents that contain an annotation whose destination consists of non alphabetical characters
    • Popover doesn't work if the Viewer is rendered inside ShadowDOM
    • 🗄 Replace the deprecated contents and title properties of annotations with corresponding objects
    • The annotation link doesn't navigate to the correct page in some cases
    • The Cover component doesn't rotate the corresponding rotated page
    • The jumpToHighlightArea function does not work properly with some documents
    • The startPageIndex and endPageIndex properties of SelectionData aren't correct

    💥 Breaking change

    • In addition to selecting texts, users can click and drag to highlight a particular area. The second way doesn't provide the SelectionData data. The SelectionData property in RenderHighlightContentProps and RenderHighlightTargetProps turn to optional properties.
    interface RenderHighlightContentProps {
        selectionData?: SelectionData;
    }
    
    interface RenderHighlightTargetProps {
        selectionData?: SelectionData;
    }
    

    You have to check if it exists before using it:

    if (renderHighlightContentProps.selectionData) {
        // Do something ...
    }
    
    if (renderHighlightTargetProps.selectionData) {
        // Do something ...
    }
    
  • v3.7.0 Changes

    🆕 New feature

    • You can customize the bookmarks by using the renderBookmarkItem properly:
    <Bookmark renderBookmarkItem={renderBookmarkItem} />
    
    • 0️⃣ The default layout plugin provides new toggleTab function to toggle a given tab in the sidebar:
    const defaultLayoutPluginInstance = defaultLayoutPlugin();
    const { toggleTab } = defaultLayoutPluginInstance;
    
    // Toggle the second tab
    toggleTab(1);
    

    👌 Improvement

    • 🍎 Clicking Command + ArrowUp (on macOS) or Ctrl + ArrowUp (on Windows) will bring users to the previous clicked link annotation. You can disable that shortcuts via the enableShortcuts option:
    // Use the standalone page navigation plugin
    const pageNavigationPluginInstance = pageNavigationPlugin({
        enableShortcuts: false,
    });
    
    // Use the default layout plugin
    const defaultLayoutPluginInstance = defaultLayoutPlugin({
        toolbarPlugin: {
            pageNavigationPlugin: {
                enableShortcuts: false,
            },
        },
    });
    

    🐛 Bug fixes

    • Clicking a particular bookmark might not go to the destination
    • Link annotations with unsafe URLs won't be rendered to avoid secutiry issues
    • The CharacterMap type isn't available
    • The onPageChange callback does not trigger if the current page equals to the initial page
    • 🔌 The page navigation options are missing when creating a toolbar plugin
    • The search popover always shows up after pressing shortcuts
    • The viewer always navigates to previous, next pages after users press shortcuts even the document isn't focused
  • v3.6.0 Changes

    🆕 New features

    • 🖨 Allow to choose pages when printing a document via the setPages option. Is is a function that takes the current document and returns the list of zero-based index of pages you want to print.
    import type { PdfJs } from '@react-pdf-viewer/core';
    import { printPlugin } from '@react-pdf-viewer/print';
    
    const printPluginInstance = printPlugin({
        setPages: (doc: PdfJs.PdfDocument) => number[],
    });
    

    Here are some examples:

    // Only print the even pages
    const printPluginInstance = printPlugin({
        setPages: (doc) =>
            Array(doc.numPages)
                .fill(0)
                .map((_, i) => i)
                .filter((i) => (i + 1) % 2 === 0),
    });
    
    // Only print the odd pages
    const printPluginInstance = printPlugin({
        setPages: (doc) =>
            Array(doc.numPages)
                .fill(0)
                .map((_, i) => i)
                .filter((i) => (i + 1) % 2 === 1),
    });
    

    0️⃣ The option is also available when using the default layout plugin:

    const defaultLayoutPluginInstance = defaultLayoutPlugin({
        toolbarPlugin: {
            printPlugin: {
                setPages: ...,
            },
        },
    });
    

    🔌 You don't have to implement functions that return popular pages numbers. The print plugin provides useful functions for most popular cases:

    import {
        getAllPagesNumbers,
        getCustomPagesNumbers,
        getEvenPagesNumbers,
        getOddPagesNumbers,
    } from '@react-pdf-viewer/print';
    
    const printPluginInstance = printPlugin({
        setPages: getEvenPagesNumbers,
    });
    
    Function Description
    getAllPagesNumbers Returns all pages numbers of the document
    getCustomPagesNumbers Returns the custom pages numbers. The input is a string consists of given pages or ranges of pages. For example:
    1, 2, 3
    1-3
    1-3, 5, 8-11
    getEvenPagesNumbers Returns even pages numbers
    getOddPagesNumbers Returns odd pages numbers
    • 🖨 The target print pages can be determined from users' input:
    import { getEvenPagesNumbers } from '@react-pdf-viewer/print';
    const printPluginInstance = printPlugin();
    
    const { setPages } = printPluginInstance;
    
    // Show UI for users to choose pages
    const handleChooseEvenPages = () => setPages(getEvenPagesNumbers);
    
    <label>
        <input type="radio" onChange={handleChooseEvenPages} />
        Print even pages
    </label>;
    
    • 🔌 The print plugin exposes the print function:
    import { printPlugin } from '@react-pdf-viewer/print';
    
    const printPluginInstance = printPlugin();
    const { print } = printPluginInstance;
    

    0️⃣ The print function is also available if you use the default layout plugin:

    import { defaultLayoutPlugin } from '@react-pdf-viewer/default-layout';
    
    const defaultLayoutPluginInstance = defaultLayoutPlugin();
    const { print } = defaultLayoutPluginInstance.toolbarPluginInstance.printPluginInstance;
    
    • 🖨 You can customize the progress bar when preparing pages to print:
    const printPluginInstance = printPlugin({
        renderProgressBar: (numLoadedPages: number, numPages: number, onCancel: () => void) => (
            // Render the progress bar
        ),
    });
    

    👌 Improvement

    • Replace the icons used in buttons to download and open a document with less confusing one
    import { DownloadIcon } from '@react-pdf-viewer/get-file';
    import { OpenFileIcon } from '@react-pdf-viewer/open';
    

    🐛 Bug fix

    • Can't search or set the initial keyword for scanned documents
  • v3.5.0 Changes

    🆕 New feature

    • Be able to customize the highlight elements when searching for a keyword:
    const searchPluginInstance = searchPlugin({
        renderHighlights: (highlightPositions: HighlightPosition[]) => (
            // Your custom highlight elements
        ),
    });
    

    👌 Improvements

    • 🔌 The highlight plugin supports double click. Users can double click to select the entire text of a given element

    • 🔌 The page navigation plugin allows to jump to the previous and next pages with shortcuts.

    Shortcut Action
    PageUp or Alt + ArrowUp Go to the previous page
    PageDown or Alt + ArrowDown Go to the next page

    0️⃣ The shortcuts are enabled by default. It's possible to disable them, for example:

    // Use the standalone page navigation plugin
    const pageNavigationPluginInstance = pageNavigationPlugin({
        enableShortcuts: false,
    });
    
    // Use the default layout plugin
    const defaultLayoutPluginInstance = defaultLayoutPlugin({
        toolbarPlugin: {
            pageNavigationPlugin: {
                enableShortcuts: false,
            },
        },
    });
    

    🐛 Bug fixes

    • Don't highlight the entire page when selecting multiple lines
    • 0️⃣ The default layout plugin throws an exception if the setInitialTabFromPageMode function returns a Promise which resolves an invalid tab index
    • 🔌 The highlight plugin throws an exception when double click a page without selecting any text
    • 🔌 The search plugin can't set the initial keyword when using with the highlight plugins
  • v3.4.0 Changes

    🆕 New feature

    • It's possible to set the initial tab
    import { defaultLayoutPlugin } from '@react-pdf-viewer/default-layout';
    
    const defaultLayoutPluginInstance = defaultLayoutPlugin({
        // The `Bookmark` tab is active initially
        setInitialTab: () => Promise.resolve(1),
    });
    

    According to the PDF specifications, the initial tab can be determined based on the document's page mode. If you want to follow that behaviour, then you can use the setInitialTabFromPageMode function:

    import { defaultLayoutPlugin, setInitialTabFromPageMode } from '@react-pdf-viewer/default-layout';
    
    const defaultLayoutPluginInstance = defaultLayoutPlugin({
        setInitialTab: setInitialTabFromPageMode,
    });
    

    👌 Improvement

    • Smooth scroll when jumping to a given page or destination (clicking a bookmark, for example)

    🐛 Bug fixes

    • Can't add highlight to selected text
    • Keep current position after zooming
  • v3.3.3 Changes

    👌 Improvements

    • Clicking Enter automatically jumps to the next match when being focused on the keyword field
    • ⚡️ Support documents which are optimized for web. Users don't have to wait the full document loaded to see the first page.

    🐛 Bug fixes

    • Automatically scroll to the thumbnail of the initial page when it's set
    • 🔌 The text might not be selectable if a plugin registers the renderPageLayer method
    • There is a page that is not rendered even it is visible when users zoom the document
  • v3.3.2 Changes

    🐛 Bug fixes

    🛠 Fix more issues that only happen with React 18's Strict mode:

    • The initialPage option doesn't work
    • The pages are flickering when zooming the document
    • There is a page that is not rendered even it is visible when users zoom the document continuously
  • v3.3.1 Changes

    🆕 New feature

    • 🔌 The thumbnail plugin adds new option for customizing the width of thumbnails:
    const thumbnailPluginInstance = thumbnailPlugin({
        thumbnailWidth: 150,
    });
    
    // Use with the default layout plugin
    const defaultLayoutPluginInstance = defaultLayoutPlugin({
        thumbnailPlugin: {
            thumbnailWidth: 150,
        },
    });
    

    🐛 Bug fix

    • 👍 Support React 18 strict mode
    <React.StrictMode>
        <Worker workerUrl="...">
            <Viewer fileUrl="..." />
        </Worker>
    </React.StrictMode>
    
  • v3.3.0 Changes

    🆕 New feature

    • The Bookmarks component provides new property that can be used to set a bookmark expanded or collapsed initially. The following sample code expands bookmarks whose depth are smaller or equal to 2:
    const setBookmarkExpanded = ({ bookmark, depth, doc, index }) => {
        // `bookmark` is the bookmark data structure
        // `depth` is the current depth
        // `doc` is the current document
        // `index` is the zero-based index of bookmark relative to its parent
        return depth <= 2;
    };
    
    <Bookmarks isBookmarkExpanded={setBookmarkExpanded} />;
    

    Expanding or collapsing all bookmarks initially can be done easily:

    // Expand bookmarks initially
    const setBookmarkExpanded = ({ bookmark, depth, doc, index }) => true;
    
    // Collapse bookmarks initially
    const setBookmarkExpanded = ({ bookmark, depth, doc, index }) => false;
    
    • 🔌 The Page Navigation plugin provides new NumberOfPages component that displays the total number of pages

    👌 Improvements

    • Align bookmark titles
    • Compatible with React 18
    • 0️⃣ In previous versions, all bookmarks were expanded by default. From this version, a bookmark will be shown or hidden initially depending on its data structure. You can see this behaviour on popular viewers such as Acrobat Reader.
    • The toolbar slot NumberOfPages provides the ability of customizing the number of pages

    🐛 Bug fixes

    • The hightlights are lost when the whole words option is enabled
    • There is a visible page that isn't rendered when setting the zoom level as page width