A React component to view a PDF document

Overview

React PDF viewer

A React component to view a PDF document. It's written in TypeScript, and powered by React hooks completely.

// Core 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();

<Viewer
    fileUrl='/assets/pdf-open-parameters.pdf'
    plugins={[
        // Register plugins
        defaultLayoutPluginInstance,
        ...
    ]}
/>

React PDF viewer

Features

Basic features

  • Support password protected document
  • Zooming: Support custom levels such as actual size, page fit, and page width
  • Navigation between pages
  • Can go to the first and last pages quickly
  • Search for text
  • Preview page thumbnails
  • View and navigate the table of contents
  • List and download attachments
  • Rotating
  • Text selection and hand tool modes
  • Different scrolling modes
  • Full screen mode
  • Can open a file from local. Users can drag and drop a local file to view it
  • Download file
  • View the document properties
  • Support SSR
  • Print

Customization

  • The toolbar can be customized easily
  • All text items can be localized in another language

Coming soon

  • Theming
  • Darkmode

License

You have to purchase a Commercial License at the official website.

About

This project is developed by Nguyen Huu Phuoc. I love building products and sharing knowledge.

Be my friend on

Products

You might be interested in my products:

1 LOC (3.3k★)

Favorite JavaScript utilities in single line of code

Blur Page

A browser extension to hide sensitive information on a web page

Check Browsers Support

A browser extension to check browser compatibility without leaving your tab

CSS Layout (2.7k★)

A collection of popular layouts and patterns made with CSS

Fake Numbers

Generate fake and valid numbers

Form Validation

The best validation library for JavaScript

HTML DOM (3.1k★)

How to manage HTML DOM with vanilla JavaScript

React PDF Viewer

A React component to view a PDF document

this VS that

The differences between ___ and ___ in the front-end development
Comments
  • Loading a large pdf on Safari iOS and macOS causes a crash

    Loading a large pdf on Safari iOS and macOS causes a crash

    [Warning] Total canvas memory use exceeds the maximum limit (384 MB). (2.c9af885f.chunk.js, line 2)
    [Error] TypeError: null is not an object (evaluating 'r.canvasContext.canvas')
    
    bug core 
    opened by esetnik 21
  • Viewer does not render signature fields

    Viewer does not render signature fields

    Hello there,

    I'm using your wonderful lib on a new project I'm working on for my company and I ran into an issue today. If a try to render with your viewer a PDF which contains signature fields, they are just simply ignored 😱

    You can reproduce it by going to the home then use the action button "Open file" to open any PDF that has signature fields. For example, this the the PDF I'm using : test.pdf

    Any help on this issue would be very much appreciated because right now I can't display contracts with electronic signature to the users 😭

    Don't hesitate if you need more infos! Thank you ☺️

    bug core 
    opened by fmigot 20
  • SyntaxError: Unexpected token '||='

    SyntaxError: Unexpected token '||='

    I'm running into the following issue,

    image

    I suspect I should update the alias in webpack to point to the legacy version, but this is strange encountering such issues in a brand new project, eg nextjs.

    question 
    opened by paul-vd 19
  • Search isn't working with updated package

    Search isn't working with updated package

    I'm using the updated package and wanted to implement searching functionality and I'm gating an error like TypeError: Cannot read properties of undefined (reading 'map') at search.js:151:1 when submitting enter button for searching.

    Package:

    image

    Component:

    import { Viewer, Worker } from '@react-pdf-viewer/core';
    import { defaultLayoutPlugin } from '@react-pdf-viewer/default-layout';
    import { pageNavigationPlugin } from "@react-pdf-viewer/page-navigation";
    import { searchPlugin } from '@react-pdf-viewer/search';
    
    // import PDFList from './components/PDFList';
    
    
    function App() {
      // const data: IPDFList[] = Data
      const defaultLayoutPluginInstance = defaultLayoutPlugin();
      const searchPluginInstance = searchPlugin();
      const pageNavigationPluginInstance = pageNavigationPlugin();
      const { ShowSearchPopoverButton } = searchPluginInstance;
      const {
        CurrentPageInput,
        GoToFirstPageButton,
        GoToLastPageButton,
        GoToNextPageButton,
        GoToPreviousPage
      } = pageNavigationPluginInstance;
      const currentPage = localStorage.getItem("current-page");
      const initialPage = currentPage ? parseInt(currentPage, 10) : 0;
    
      const handlePageChange = (e: any) => {
        localStorage.setItem("current-page", `${e.currentPage}`);
      };
    
    
      return (
        <>
          <div className="p-4">
            <div className='max-w-4xl w-full mx-auto'>
              <h1 className='text-4xl text-center mt-4 mb-7 font-bold text-purple-600'>PDF Read and Search</h1>
              {/* <PDFList lists={data} /> */}
              <div className="">
                <Worker workerUrl="https://unpkg.com/[email protected]/build/pdf.worker.min.js">
    
                  <div
                    className="rpv-core__viewer flex flex-col h-full border border-solid border-black border-opacity-30"
    
                  >
                    <div className='flex items-center bg-[#eeeeee] border-b border-black border-opacity-10 p-1'>
                      <ShowSearchPopoverButton />
                      <div className='px-1'>
                        <GoToFirstPageButton />
                      </div>
                      <div className='px-1'>
                        <GoToPreviousPage />
                      </div>
                      <div className='px-1'>
                        <CurrentPageInput />
                      </div>
                      <div className='px-1'>
                        <GoToNextPageButton />
                      </div>
                      <div className='px-1'>
                        <GoToLastPageButton />
                      </div>
                    </div>
                    <div className='flex-1 overflow-hidden'></div>
                    <div className='h-[30rem]'>
                      <Viewer
                        fileUrl={`/recources/Angular_Router_Crash_Course.pdf`}
                        initialPage={initialPage}
                        onPageChange={handlePageChange}
                        plugins={[searchPluginInstance, pageNavigationPluginInstance]}
                        defaultScale={1}
                      />
                    </div>
                  </div>
    
                </Worker>
              </div>
    
            </div>
          </div>
    
        </>
      );
    }
    
    export default App;
    
    bug search plugin 
    opened by akib1997 16
  • Error: Invalid parameter object: need either .data, .range or .url

    Error: Invalid parameter object: need either .data, .range or .url

    Hi , i am trying to show a pdf file, and i got this error . Error: Invalid parameter object: need either .data, .range or .url

    my implementation :

    <Worker workerUrl="https://unpkg.com/[email protected]/build/pdf.worker.min.js"> <div style={{ height: "750px" }}> <Viewer fileUrl={documentURL} /> </div> </Worker>

    question 
    opened by David-moonsite 16
  • v3.1.0: document content is hidden

    v3.1.0: document content is hidden

    Hello,

    The issue occurred after react-pdf-viewer version update from 3.0.0 to 3.1.0. Document content is hidden on initial load however, the viewer displays the content as expected after actions such as mouse hover on one of the toolbar elements or navigation with a keyboard. For reference, I'm providing your own sample with updated react-pdf-viewer versions to 3.1.0.

    https://codesandbox.io/s/react-pdf-viewer-sample-forked-xhvqm

    bug core 
    opened by MPuida 13
  • pdfjs 2.7.570 breaks build for Create-React-Apps

    pdfjs 2.7.570 breaks build for Create-React-Apps

    I just want to leave that here: As with the latest versions of pdfjs-dist, my CRA app is broken as decribed here. I have no idea whether or not this might be a pdfjs problem, or if it might be related to react-pdf-viewer.

    Any insights are highly appreciated.

    documentation 
    opened by aspnetde 13
  • Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component.

    Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component.

    I installed

    "@react-pdf-viewer/core": "^2.0.1",
    "pdfjs-dist": "2.3.200",
    ...
    "react": "^16.12.0",
    "react-dom": "^16.12.0"
    

    Importing and rendering the worker in a high-level component:

    import { Worker } from '@react-pdf-viewer/core';
    <Worker workerUrl="https://unpkg.com/[email protected]/build/pdf.worker.min.js"}>
        {children}
    </Worker>
    

    Note: I'm using the downgraded version of pdfjs-dist as suggested here https://github.com/react-pdf-viewer/react-pdf-viewer/issues/263#issuecomment-672964145 and here https://github.com/react-pdf-viewer/react-pdf-viewer/issues/276#issuecomment-688312715

    And the Viewer:

    import { Viewer } from '@react-pdf-viewer/core';
    import '@react-pdf-viewer/core/lib/styles/index.css';
    
    <Viewer fileUrl="https://www.morganstanley.com/about-us-ir/shareholder/3q2020.pdf" />;
    

    And I'm getting this error when trying to load the page:

    Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component
    ...
    at Viewer (core.js:2944)
    
    question 
    opened by mmichael0413 13
  • Click to open link on pdf when link not hyperlink

    Click to open link on pdf when link not hyperlink

    Hello, I did a test by creating a simple example of pdf without hyperlink, I put https://google.fr and check it in the pdf reader, the link is not clickable, however, if the link is in hyperlink via libreoffice or other, the link is clickable :)

    I did the same test with the native pdf reader of google chrome and whether in hyperlink or not, it detects that it is a link and allows to be able to click on it

    Would it be possible to think of this scenario?

    Indeed, the standard is respected but I do not think that the agents (I work for a company recognized as a training organization / education) will have the idea of ​​creating hyperlinks while they make their pdf

    I could put a very quick example on a codesanbox or share the two pdf to dissociate the two cases, if necessary :)

    Thank you again for taking the time to read me.

    enhancement 
    opened by JSurquin 13
  • Highlight using x/y coordinates and page numbers

    Highlight using x/y coordinates and page numbers

    Hello @phuoc-ng and Team,

    I have a use case where I want to highlight certain words and sentences using their x/y coordinates and page numbers that will be sent from the backend api. As per my understanding, we do not currently have a feature/plugin for that.

    • I tried highlighting using keywords api in the search plugin but it highlights all instances of the word.
    • Highlight plugin can only be activated on text selection.

    Can you guide me on how to achieve this functionality using the current version and if not, can I make a feature request for the same? We at our organization are very much interested in buying the commercial license for our purpose and this highlight functionality is an integral part of our product.

    Thank You!

    enhancement highlight plugin 
    opened by dsac147 12
  • Password filled programmatically

    Password filled programmatically

    I have a question about protected pdf. I uploaded a pdf with password in viewer and it asked to me password. Can i fill this form and submit programmatically, for example automatically onPdfLoaded ?

    Thanks

    enhancement core 
    opened by lillogoal 12
  • Shortcut to move forward to next link/bookmark destinations

    Shortcut to move forward to next link/bookmark destinations

    With the shortcut key "Alt/Cmd + Right arrow", moving forward to next link/bookmark destinations. This is the same feature in Adobe Acrobat too. We'd like the feature moving forward with "Alt/Cmd + Right arrow".

    Related to #1382 #1383

    enhancement bookmark plugin 
    opened by phuocng 0
  • Shortcut key to move back to previous bookmark destinations

    Shortcut key to move back to previous bookmark destinations

    on Windows but we'd like "Alt + Left arrow" (On Mac, just "Cmd +Left arrow" though) We'd like the feature moving back to not only a previous link annotation but also a previous bookmark destination too with the same shortcut key. That is as Adobe Acrobat has as well.

    Similar to #1382

    enhancement bookmark plugin 
    opened by phuocng 0
  • Change the shortcut key on the feature moving back to previous link annotations

    Change the shortcut key on the feature moving back to previous link annotations

    Currently the key is "Ctrl + Up arrow" on Windows but we'd like "Alt + Left arrow" as it works on Adobe Acrobat. (On Mac, just "Cmd +Left arrow" though).

    enhancement core 
    opened by phuocng 0
  • Embedded JFIF image does not display

    Embedded JFIF image does not display

    Description

    When using the react-pdf-viewer to display and embedded image it does not work when the image is a JFIF type. ( https://fileinfo.com/extension/jfif )

    Screenshots

    image image

    bug core 
    opened by darin-critchlow 1
  • Search plugin: wholeWords not working as expected

    Search plugin: wholeWords not working as expected

    Steps to reproduce

    • Go to any example including search, like: https://react-pdf-viewer.dev/examples/use-the-default-button-to-show-the-search-popover/
    • Try searching for the word "Parameters" with the whole words option set to true.

    Expected behavior

    • it should highlight all occurrences including words that are alone on their line and words that are at the beginning or at the end of their line.

    Actual behavior

    • words that are alone on their line are not highlighted
    • words that are at the beginning or at the end of their line are not highlighted
    • same for a group of words (ex: try to match who should in "Who should read this guide?")
    • same for a whole line of text

    Screenshot 2022-12-08 at 15 04 40

    search plugin 
    opened by baptistefkt 0
Releases(v3.10.0)
  • v3.10.0(Dec 28, 2022)

    New features

    • New page scrolling mode:
    import { ScrollMode, Viewer } from '@react-pdf-viewer/core';
    
    <Viewer scrollMode={ScrollMode.Page} />;
    

    You can switch to the page scrolling mode from the toolbar.

    • New three page viewmodes:
    import { ViewMode, Viewer } from '@react-pdf-viewer/core';
    
    <Viewer viewMode={ViewMode.DualPage} />;
    

    | Mode | Description | | ---------------------------- | ---------------------------------------------------------------- | | ViewMode.SinglePage | The default mode. View single page continuously | | ViewMode.DualPage | View two pages each time | | ViewMode.DualPageWithCover | View two pages each time. The first page is displayed as a cover |

    • PluginFunctions provides new jumpToPreviousPage and jumpToNextPage to jump to the previous and next pages

    • The scroll-mode plugin provides new DualPageCoverViewModeIcon, DualPageViewModeIcon and PageScrollingIcon icons

    Bug fixes

    • Jumping to the previous and next pages in wrapped scrol mode don't work properly
    • Zooming doesn't keep current position properly
    Source code(tar.gz)
    Source code(zip)
  • v3.9.0(Nov 30, 2022)

    New feature

    • 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.
    Source code(tar.gz)
    Source code(zip)
  • v3.8.0(Nov 9, 2022)

    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 |

    • 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 ...
    }
    
    Source code(tar.gz)
    Source code(zip)
  • v3.7.0(Aug 21, 2022)

    New features

    • You can customize the bookmarks by using the renderBookmarkItem properly:
    <Bookmark renderBookmarkItem={renderBookmarkItem} />
    
    • 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
    • Targets of link annotations are sanitized 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
    Source code(tar.gz)
    Source code(zip)
  • v3.6.0(Jun 27, 2022)

    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),
    });
    

    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;
    

    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
    Source code(tar.gz)
    Source code(zip)
  • v3.5.0(Jun 14, 2022)

    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 |

    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
    • 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
    Source code(tar.gz)
    Source code(zip)
  • v3.4.0(Jun 6, 2022)

    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
    Source code(tar.gz)
    Source code(zip)
  • v3.3.3(May 31, 2022)

    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
    Source code(tar.gz)
    Source code(zip)
  • v3.3.2(May 8, 2022)

    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
    Source code(tar.gz)
    Source code(zip)
  • v3.3.1(May 2, 2022)

    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>
    
    Source code(tar.gz)
    Source code(zip)
  • v3.3.0(Apr 19, 2022)

    New features

    • 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
    • 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
    Source code(tar.gz)
    Source code(zip)
  • v3.2.0(Apr 3, 2022)

    New features

    • The Popover component has new prop lockScroll which indicates whether the body element is scrollable or not. By default, it takes the true value
    • The Viewer component adds new onRotate callback that is invoked when users rotate the document:
    <Viewer
        onRotate={({ direction, doc, rotation }) => {
            // `direction` is the rotate direction
            // `doc` is the current document
            // `rotation` is the latest rotation value
        }}
    />
    
    • Provide the ability of rotating a particular page. You can customize a thumbnail renderer to add the rotating functionality to each page:
    const renderThumbnailItem = (props: RenderThumbnailItemProps) => (
        <MinimalButton onClick={() => props.onRotatePage(RotateDirection.Forward)}>
            <RotateForwardIcon />
        </MinimalButton>
        <MinimalButton onClick={() => props.onRotatePage(RotateDirection.Backward)}>
            <RotateBackwardIcon />
        </MinimalButton>
    );
    
    const thumbnailPluginInstance = thumbnailPlugin();
    const { Thumbnails } = thumbnailPluginInstance;
    
    <Thumbnails renderThumbnailItem={renderThumbnailItem} />
    

    It's also possible to do it by using the renderPage:

    const renderPage: RenderPage = (props: RenderPageProps) => (
        <>
            {props.canvasLayer.children}
            <div>
                <MinimalButton onClick={() => props.onRotatePage(RotateDirection.Forward)}>
                    <RotateForwardIcon />
                </MinimalButton>
                <MinimalButton onClick={() => props.onRotatePage(RotateDirection.Backward)}>
                    <RotateBackwardIcon />
                </MinimalButton>
            </div>
            {props.annotationLayer.children}
            {props.textLayer.children}
        </>
    );
    
    <Viewer renderPage={renderPage} />;
    

    The rotate plugin adds new RotatePage component in case you want to rotate a particular page from outside:

    const rotatePluginInstance = rotatePlugin();
    const { RotatePage } = rotatePluginInstance;
    
    <RotatePage>
        {(props) => <PrimaryButton onClick={() => props.onRotatePage(0, RotateDirection.Forward)}>Rotate the first page forward</PrimaryButton>}
    </RotatePage>
    <RotatePage>
        {(props) => <PrimaryButton onClick={() => props.onRotatePage(0, RotateDirection.Backward)}>Rotate the first page backward</PrimaryButton>}
    </RotatePage>
    
    • The onRotatePage event is triggered when a page is rotated:
    <Viewer
        onRotatePage={({ direction, doc, pageIndex, rotation }) => {
            // `direction` is the rotate direction
            // `doc` is the current document
            // `pageIndex` is the zero-based page index
            // `rotation` is the latest rotation value
        }}
    />
    

    Improvements

    • The search popover is opened if users press the shortcuts (Ctrl + F, or Cmd + F on macOS) when the mouse is inside the viewer container
    • It's able to scroll the pages when opening the search popover
    • Support link annotations that have the unsafeUrl property

    Bug fixes

    • Typo in full screen change event
    • There is a visible page that isn't rendered when setting the zoom level as page width
    • The thumbnails aren't rotated after rotating the document

    Breaking changes

    • The RotateDirection provided by the @react-pdf-viewer/rotate package now belongs to the @react-pdf-viewer/core package:
    // v3.1.2 and previous versions
    import { RotateDirection } from '@react-pdf-viewer/rotate';
    
    // From v3.2.0
    import { RotateDirection } from '@react-pdf-viewer/core';
    
    • The rotate function used in the plugins changes the parameter type:
    // v3.1.2 and previous versions
    rotate(90);
    rotate(-90);
    
    // From v3.2.0
    rotate(RotateDirection.Forward);
    rotate(RotateDirection.Backward);
    
    Source code(tar.gz)
    Source code(zip)
  • v3.1.2(Mar 8, 2022)

    Bug fixes

    • Don't highlight spaces between words when searching for a keyword
    • The clearHighlights and clearKeyword() functions provided by the search plugin should remove all highlights when the keyword is empty
    • The current highlight is lost after zooming the document
    • The jumpToMatch() function provided by the search plugin does not properly highlight keyword when the page is not in the virtual list
    • The ScrollModePluginProps type isn't defined in the type definitions of the toolbar plugin
    Source code(tar.gz)
    Source code(zip)
  • v3.1.1(Mar 2, 2022)

    Improvement

    • The full screen button and menu item are disabled on browsers that don't support full screen APIs. It happens on iOS Safari and iOS Chrome, for example.

    Bug fixes

    • onPageChange() should fire after onDocumentLoad()
    • The pages aren't layouted properly when they have different dimensions
    • The pages are blank initially until users scroll or interact with the page
    Source code(tar.gz)
    Source code(zip)
  • v3.1.0(Jan 20, 2022)

    New features

    • Add new testId property to Spinner
    • The Viewer component provides new scrollMode option:
    import { ScrollMode, Viewer } from '@react-pdf-viewer/core';
    
    <Viewer scrollMode={ScrollMode.Horizontal} />;
    
    • Plugins can register and call the switchScrollMode method to switch the scroll mode programatically

    Improvements

    • The Viewer component now works on mobile.

    As we know, the mobile browsers such as iOS Safari have the limit value for canvas size and the maximum memory values (256 MB on iOS Safari, for example) for rendering canvases. It can cause the Viewer component to crash if we zoom the document to a big enough level. This version fixes these kinds of issues. There is no crash on mobile anymore!

    • Improve the performance when rendering a document.

    In the previous versions, each page is represented by a separated div element. The element isn't rendered by default, and will be rendered when the corresponding page is visible in the viewport. However, this optimization is not enough for a document that has a big number of pages.

    v3.1.0 brings the optimization to a new level. Instead of keeping the instance of all pages all the time, the Viewer component only renders a given range of pages including the visible pages and some pages that are before and after them. For example, if users see pages 5-8 in the screen, we will render the pages 3-10 ony. The range will be changed when users scroll up or down, and then the corresponding pages are rendered accordingly.

    Bug fixes

    • Keep the current page after switching the scroll mode
    • The Cover component has the same image source when loading different documents
    • The default Spinner is used when using the renderLoader option
    • The exit full screen button doesn't look good in dark theme
    • The onPageChange event fires more than once
    • The renderThumbnailItem option doesn't work with dynamic document
    • The sidebar doesn't fit in its container on Safari
    • There is a black area in the full screen mode if the zoom level is small enough

    Breaking changes

    • It is not possible to access the page element in a plugin with the getPageElement function. The method is removed because the pages are rendered dynamically
    • The ScrollMode provided by the @react-pdf-viewer/scroll-mode package now belongs to the @react-pdf-viewer/core package:
    // v3.0.0 and previous versions
    import { ScrollMode } from '@react-pdf-viewer/scroll-mode';
    
    // From v3.1.0
    import { ScrollMode } from '@react-pdf-viewer/core';
    
    • The inital scroll mode option provided by the scrollModePlugin plugin now belongs to the Viewer component:
    // v3.0.0 and previous versions
    import { scrollModePlugin, ScrollMode } from '@react-pdf-viewer/scroll-mode';
    
    const scrollModePluginInstance = scrollModePlugin({
        scrollMode: ScrollMode.Horizontal,
    });
    
    // From v3.1.0
    import { ScrollMode } from '@react-pdf-viewer/core';
    
    <Viewer scrollMode={ScrollMode.Horizontal} />;
    
    • There aren't CSS styles provided by the @react-pdf-viewer/scroll-mode package:
    // v3.0.0 and previous versions
    import '@react-pdf-viewer/scroll-mode/lib/styles/index.css';
    
    // From v3.1.0
    // Remove the import above
    
    • From v3.1.0, pages are rendered one by one. If you use a custom page renderer, then you have to call the markRendered method to mark the page rendered completely. Hence the next page in the queue will be rendered.
    // v3.0.0 and previous versions
    import type { RenderPageProps } from '@react-pdf-viewer/core';
    
    const CustomPageRender: React.FC<{
        renderPageProps: RenderPageProps,
    }> = ({ renderPageProps }) => {
        return (
            <>
                {/* Use the canvas and/or text layers */}
                {renderPageProps.canvasLayer.children}
                {renderPageProps.textLayer.children}
    
                {/* Your custom components on page ... */}
            </>
        );
    };
    
    <Viewer renderPage={(props) => <CustomPageRender renderPageProps={props} />} />;
    
    // From v3.1.0
    const CustomPageRender: React.FC<{
        renderPageProps: RenderPageProps,
    }> = ({ renderPageProps }) => {
        React.useEffect(() => {
            if (renderPageProps.canvasLayerRendered && renderPageProps.textLayerRendered) {
                renderPageProps.markRendered(renderPageProps.pageIndex);
            }
        }, [renderPageProps.canvasLayerRendered, renderPageProps.textLayerRendered]);
    
        return (
            <>
                {/* Use the canvas and/or text layers */}
                {renderPageProps.canvasLayer.children}
                {renderPageProps.textLayer.children}
    
                {/* Your custom components on page ... */}
            </>
        );
    };
    
    <Viewer renderPage={(props) => <CustomPageRender renderPageProps={props} />} />;
    
    Source code(tar.gz)
    Source code(zip)
  • v3.0.0(Dec 19, 2021)

    New features

    • Add new testId property to MenuItem, MinimalButton, PrimaryButton
    • Be able to customize the button to exit the full screen mode:
    const fullScreenPluginInstance = fullScreenPlugin({
        renderExitFullScreenButton: (props) => (
            <div
                style={{
                    bottom: '1rem',
                    position: 'fixed',
                    right: '1rem',
                }}
            >
                <button onClick={props.onClick}>Exit full screen</button>
            </div>
        ),
    });
    
    • The full screen plugin allows to set the full screen element. The following code will include the pages container and the toolbar in the full screen mode:
    const fullScreenPluginInstance = fullScreenPlugin({
        // `pagesContainer` is the pages container
        getFullScreenTarget: (pagesContainer) => pagesContainer.closest('[data-testid="default-layout__body"]'),
    }),
    
    • The thumbnail plugin adds new renderSpinner property that can be used to replace the default Spinner component. For example, it is displayed when loading the cover or thumbnail of a page:
    const thumbnailPluginInstance = thumbnailPlugin({
        renderSpinner: () => <div className="square-spinner" />,
    });
    
    • The Thumbnails component adds new renderThumbnailItem property that is used to customize the thumbnail renderer:
    const renderThumbnailItem = (props: RenderThumbnailItemProps) => (
        <div
            key={props.pageIndex}
            onClick={props.onJumpToPage}
            style={{
                backgroundColor: props.pageIndex === props.currentPage ? 'rgba(0, 0, 0, 0.3)' : '#fff',
                cursor: 'pointer',
                padding: '0.5rem',
            }}
        >
            {props.renderPageThumbnail}
        </div>
    );
    
    const thumbnailPluginInstance = thumbnailPlugin();
    const { Thumbnails } = thumbnailPluginInstance;
    
    <Thumbnails renderThumbnailItem={renderThumbnailItem} />;
    

    Improvements

    • Add data-testid attribute to buttons in the toolbar
    • The Cover component uses the image instead of canvas tag
    • The default layout shouldn't have a horizontal scrollbar when the default scale isn't set

    Bug fixes

    • Navigating between search results should be the same as their appearances on pages
    • The internal links don't work properly in some cases
    • The thumbnails are stuck at loading spinner
    • The Cover component position isn't correct
    • The number of pages slot <NumberOfPages /> isn't correct when using the renderToolbar
    • There is an exception of React has detected a change in the order of Hooks when switching documents
    Source code(tar.gz)
    Source code(zip)
  • v2.11.0(Nov 11, 2021)

    New features

    • The Button component has new testId property that is identical with the data-testid attribute
    • The Scroll Mode plugin provides new function to switch mode programmatically:
    const scrollModePluginInstance = scrollModePlugin();
    const { switchScrollMode } = scrollModePluginInstance;
    
    // Switch to Wrapped mode
    switchScrollMode(ScrollMode.Wrapped);
    

    You might find it useful when using with the full screen plugin. The following sample code switches the scroll mode after entering the full screen mode:

    const defaultLayoutPluginInstance = defaultLayoutPlugin({
        toolbarPlugin: {
            fullScreenPlugin: {
                onEnterFullScreen: (zoom) => {
                    zoom(SpecialZoomLevel.PageFit);
                    defaultLayoutPluginInstance.toolbarPluginInstance.scrollModePluginInstance.switchScrollMode(
                        ScrollMode.Wrapped
                    );
                },
                onExitFullScreen: (zoom) => {
                    zoom(SpecialZoomLevel.PageWidth);
                    defaultLayoutPluginInstance.toolbarPluginInstance.scrollModePluginInstance.switchScrollMode(
                        ScrollMode.Horizontal
                    );
                },
            },
        },
    });
    

    Improvements

    • Cache pages' labels. So we won't see blink in the current page label when navigating between pages
    • Keep the file name when downloading a file opened from local
    • It's possible to remove the sidebar created by the default layout plugin:
    const defaultLayoutPluginInstance = defaultLayoutPlugin({
        sidebarTabs: () => [],
    });
    

    Bug fixes

    • Can't use special characters such as (, ), [, ], * in the keyword
    • Downloading document doesn't work on iOS Safari and iOS Chrome
    • The Get File plugin doesn't work with a file which is opened with credentials
    • The highlight area aren't displayed
    • The selectedText prop of RenderHighlightContentProps isn't correct
    Source code(tar.gz)
    Source code(zip)
  • v2.10.1(Oct 18, 2021)

    New feature

    • The Zoom and ZoomPopover components provided by the zoom plugin adds a custom zoom levels
    <Zoom levels={[0.5, 1, 2, 3, 4]} />
    
    <ZoomPopover levels={[0.5, 1, 2, 3, 4]} />
    

    Bug fix

    • Clicking the Search button scrolls to the top of page
    Source code(tar.gz)
    Source code(zip)
  • v2.10.0(Oct 18, 2021)

    New features

    • Add new trigger option for the Highlight plugin
    import { Trigger } from '@react-pdf-viewer/highlight';
    
    const highlightPluginInstance = highlightPlugin({
        trigger: Trigger.None,
    });
    

    There are two possible values for the trigger option:

    | Value | Description | | --------------------------------- | ----------------------------------------------------------------------------- | | Trigger.TextSelection (default) | Show the target after users select text | | Trigger.None | Doesn't trigger the highlight. It is often used to render the highlight areas |

    • The render props of the CurrentPageLabel component provided by the Page Navigation plugin includes new pageLabel property. It is useful if the page has a label that isn't the same as its page number:
    const { CurrentPageLabel } = pageNavigationPluginInstance;
    
    <CurrentPageLabel>
        {(props) => (
            <>
                {props.numberOfPages}
                {props.pageLabel !== `${props.currentPage + 1}` && `(${props.pageLabel})`}
            </>
        )}
    </CurrentPageLabel>;
    
    • The Thumbnails component displays the page labels if there are. You also can customize the page labels:
    const thumbnailPluginInstance = thumbnailPlugin({
        renderCurrentPageLabel: (props) => (
            <>
                {props.pageIndex + 1}
                {props.pageLabel !== `${props.pageIndex + 1}` && `(${props.pageLabel})`}
            </>
        ),
    });
    const { Thumbnails } = thumbnailPluginInstance;
    
    <Thumbnails />;
    
    • The Toolbar plugin provides the renderDefaultToolbar function to create a custom toolbar from the default toolbar easily. The following sample code prepends of to the NumberOfPages component:
    import type { ToolbarSlot, TransformToolbarSlot } from '@react-pdf-viewer/toolbar';
    
    const { renderDefaultToolbar, Toolbar } = toolbarPluginInstance;
    
    const transform: TransformToolbarSlot = (slot: ToolbarSlot) => {
        const { NumberOfPages } = slot;
        return Object.assign({}, slot, {
            NumberOfPages: () => (
                <>
                    of <NumberOfPages />
                </>
            ),
        });
    };
    
    // Render the toolbar
    <Toolbar>{renderDefaultToolbar(transform)}</Toolbar>;
    

    Improvement

    • Disable the printing functionality if the document doesn't allow to print

    Bug fixes

    • Can't resize the sidebar when using with the Fluent UI library
    • Fix the TypeScript definition of the Cover component
    • Fix an edge case where there are extra empty pages when printing a document
    Source code(tar.gz)
    Source code(zip)
  • v2.9.1(Sep 19, 2021)

    Improvement

    As we know, the Viewer component only renders the pages which are visible in the screen. For an invisible page, users will see a spinner. However, the animation used in the Spinner component can slow down the app if the document has a big number of pages.

    This version improves the performance by animating the Spinner component when it's visible only.

    Source code(tar.gz)
    Source code(zip)
  • v2.9.0(Sep 13, 2021)

    New features

    • The core package provides new Splitter component
    • The thumbnail plugin provides new Cover component that shows the thumbnail of a particular page:
    const { thumbnailPluginInstance } = thumbnailPlugin();
    const { Cover } = thumbnailPluginInstance;
    
    // Thumbnail of the first page
    <Cover getPageIndex={_ => 0} />
    
    // Thumbnail of the last page
    <Cover getPageIndex={props => props.numPages - 1} />
    
    • Add new onDocumentAskPassword event that is triggered when a protected document requires a password to open:
    const handleAskPassword = (e: DocumentAskPasswordEvent) => {
        // ...
    };
    
    <Viewer onDocumentAskPassword={handleAskPassword} />;
    

    Improvements

    • Automatically focus on the keyword input in the search popover
    • Press Enter to submit the password when opening a protected document
    • Show the page numbers for thumbnails
    • The Default Layout plugin allows to resize the sidebar
    • The plugin instances which can be accessed from an instance of the Default Layout or Toolbar plugin should be readonly
    • Support more shortcuts

    | Shortcut | Supported plugin | Action | | ----------------------------------------------------------------- | ---------------------------------------------------------------- | -------------------------- | | ctrl + cmd + F or F11 | Full screen | Enter the full screen mode | | cmd + O | Open | Open a document | | cmd + F | Search | Open the search popover |

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

    // Use the standalone open plugin
    const openPluginInstance = openPlugin({
        enableShortcuts: false,
    });
    
    // Use the default layout plugin
    const defaultLayoutPluginInstance = defaultLayoutPlugin({
        toolbarPlugin: {
            openPlugin: {
                enableShortcuts: false,
            },
        },
    });
    
    Source code(tar.gz)
    Source code(zip)
  • v2.8.0(Aug 31, 2021)

    New features

    import { TextDirection, Viewer } from '@react-pdf-viewer/core';
    
    <Viewer
        theme={{
            direction: TextDirection.RightToLeft,
        }}
    />;
    
    • The RenderViewer type includes the theme context

    Bug fixes

    • The highlighting elements should be shown below the text, so users can still select the text
    • There is an exception when opening a password protected document
    Source code(tar.gz)
    Source code(zip)
  • v2.7.2(Aug 23, 2021)

    New feature

    The Search plugin provides new function named setTargetPages which sets the pages that you want to search in.

    import { searchPlugin } from '@react-pdf-viewer/search';
    
    const searchPluginInstance = searchPlugin();
    const { setTargetPages } = searchPluginInstance;
    
    // Only search in even pages
    setTargetPages((targetPage) => targetPage.pageIndex % 2 === 0);
    
    // Only search in the page 4
    setTargetPages((targetPage) => targetPage.pageIndex === 3);
    

    Improvements

    • Allow to change the theme from outside of the Viewer component
    • When the default scale is set to a special zoom level, we should keep it when resizing the window
    • The onDocumentLoad event and plugins' PluginOnDocumentLoad callback provide access to the current opened file which contains the data and name properties:
    const handleDocumentLoad = (e: DocumentLoadEvent) => {
        console.log(e.file.name, e.file.data);
    };
    
    <Viewer onDocumentLoad={handleDocumentLoad} />;
    

    Bug fixes

    • Can't close the menu when using with the Fluent UI
    • The activateTab() method provided by the default layout plugin shouldn't toggle the tab
    • The LocalePopover component doesn't update the localization
    • The pages' container overflows on initial render when setting the default scale to SpecialZoomLevel.PageWidth
    Source code(tar.gz)
    Source code(zip)
  • v2.7.1(Jul 26, 2021)

    Improvement

    Continue improving the accessibility:

    | Component | Press key | Action | | --------- | --------- | ---------------------------- | | Menu | End | Focus on the last menu item | | | Home | Focus on the first menu item |

    Bug fixes

    • Automatically scroll to the top of page when opening a menu
    • Fix the warning when pressing the Escape key to close a modal
    Source code(tar.gz)
    Source code(zip)
  • v2.7.0(Jul 25, 2021)

    New features

    • Add new onSwitchTheme option that allows to track if users switch theme. The following snippet demonstrates an example that the current theme is stored in the local storage, and is loaded back in the next user's visit:
    const handleSwitchTheme = (theme: string) => {
        localStorage.setItem('theme', theme);
    };
    const theme = localStorage.getItem('theme') || 'light';
    
    <Viewer theme={theme} onSwitchTheme={handleSwitchTheme} />;
    

    Improve the search plugin

    • Add new jumpToMatch function which jumps to the given match

    • The highlight function now returns a Promise that holds the results. Each result also contains the matching text

    • The core package provides isMac function

    Improvements

    Accessibility

    • Add ARIA attributes to Icon, Menu, MenuDivider, MenuItem, MinimalButton, Modal, Popover, TextBox, Tooltip components
    • Add ARIA attributes to pages and thumbnails
    • Add ARIA attributes to internal links of the document
    • When the shortcuts are enabled, the associal buttons will have the aria-keyshortcuts attributes
    • Use the keyboard to navigate between components:

    | Component | Press key | Action | | ------------- | ------------ | ------------------------------------------- | | Attachments | ArrowDown | Focus on the next attachment | | | ArrowUp | Focus on the previous attachment | | | End | Focus on the last attachment | | | Enter | Download the current focused attachment | | | Home | Focus on the first attachment | | Bookmark | ArrowDown | Focus on the next bookmark | | | ArrowLeft | Collapse the current bookmark | | | ArrowRight | Expand the current bookmark | | | ArrowUp | Focus on the previous bookmark | | | End | Focus on the last bookmark | | | Enter | Click the current focused bookmark | | | Home | Focus on the first bookmark | | | Space | Click the current focused bookmark | | Menu | ArrowDown | Focus on the next menu item | | | ArrowUp | Focus on the previous menu item | | | Enter | Click the current focused item | | Thumbnails | ArrowDown | Focus on the thumbnail of next page | | | ArrowUp | Focus on the thumbnail of the previous page | | | Enter | Jump to the associate page | | Tooltip | Escape | Close | | | Tab | Show when being focused | | | | Close when being blured |

    • Add a background color to the current search highlight
    • Show a loading indicator while searching for a keyword
    • The Spinner component adds new size property

    Bug fixes

    • Custom search control isn't rendered
    • Pressing shortcuts effects all viewer instances in the same page. The shortcuts should be enabled when the viewer gets focused.
    • Remove br elements generated by the recent versions of pdf.js before rendering the text layer
    • Remove keyCode usages because it's deprecated
    • The print progress container loses the border
    • The search popover isn't shown until the document is loaded
    Source code(tar.gz)
    Source code(zip)
  • v2.6.1(Jul 5, 2021)

    Improvements

    • Move the CSS variables of the default theme to :root, so we can use components (Button, Menu, Tooltip, etc.) outside of the Viewer
    • Update the DownloadIcon, ExitFullScreenIcon, FullScreenIcon and OpenFileIcon icons

    Bug fixes

    • Remove duplicate borders of keyword input
    • Search results are not highlighted
    • The Search plugin can cause a re-render
    Source code(tar.gz)
    Source code(zip)
  • v2.6.0(Jun 20, 2021)

    From this version, all the components use the BEM naming convention for CSS classes. So if you override the styles of given class, you need to change the class.

    The CSS classes are named as rpv-PACKAGE__COMPONENT, rpv-PACKAGE__COMPONENT--STATE. For example:

    /* Old version */
    .rpv-search-highlight {
        ...
    }
    .rpv-search-highlight-current {
        ...
    }
    
    /* From v2.6.0 */
    .rpv-search__highlight {
        ...
    }
    .rpv-search__highlight--current {
        ...
    }
    

    New features

    • The core package provides new TextBox component
    • Support themes. You can create a custom theme with new theme option:
    <Viewer theme='bootstrap' />
    

    The main viewer then will have the class rpv-core__viewer--bootstrap. You can set the value for CSS variables which are provided by plugins:

    .rpv-core__viewer--bootstrap {
        /* Custom the background color of toolbar in the default layout */
        --rpv-default-layout__toolbar-background-color: #eee;
    }
    

    The following built-in themes are provided:

    | Theme                     | Description | |-------------------------------|-------------------------------------------------------------------------------| | <Viewer theme='auto' /> | Switch to the dark or light mode automatically based on the system setting | | <Viewer theme='dark' /> | The dark theme | | <Viewer theme='light' /> | The light theme (default) | | <Viewer theme='' /> | The light theme (default) |

    • Add new theme plugin that provides components for switching between the dark and light themes
    • The toolbar Slot has new SwitchTheme and SwitchThemeMenuItem

    Improvements

    • Tweak toggle icons in bookmark items
    • The bookmark plugin provide new icons: DownArrowIcon and RightArrowIcon
    • Improve text selection in the highlight plugin
    • You can enable or disable shortcuts in the print and zoom plugins:
    const printPluginInstance = printPlugin({
        // The shortcuts are enabled by default
        enableShortcuts: false,
    });
    
    const zoomPluginInstance = zoomPlugin({
        // The shortcuts are enabled by default
        enableShortcuts: false,
    });
    

    Bug fixes

    • Can't close popovers after scrolling
    • Can't open any popover after printing
    • Icons in menu items aren't centered horizontally
    • There is an exception when jumping to the next or previous match if the keyword isn't found

    Breaking changes

    • The toolbar plugin doesn't include the drop plugin anymore. In order to use the drop plugin, you have to register it
    • Button is renamed to MinimalButton
    • The option prefixClass is removed
    Source code(tar.gz)
    Source code(zip)
  • v2.5.0(May 23, 2021)

    New features

    • The default layout is responsive in different screen sizes
    • You can add more options that will be passed to the pdf.js getDocument API:
    <Viewer
        fileUrl='...'
        transformGetDocumentParams={(options: PdfJs.GetDocumentParams) => (
            Object.assign({}, options, {
                disableRange: false,
                disableStream: false,
            })
        )}
    />
    
    • Provide more reusable components:

    | Component                     | Provided by plugin                                                        | Description                   | |-------------------------------|---------------------------------------------------------------------------|-------------------------------| | DownloadMenuItem            | Get File                 | Download the current file     | | EnterFullScreenMenuItem     | Full screen           | Enter the full screen mode    | | GoToNextPageMenuItem        | Page Navigation   | Go to the next page           | | GoToPreviousPageMenuItem    | Page Navigation   | Go to the previous page       | | OpenMenuItem                | Open                         | Open a new file               | | PrintMenuItem               | Print                       | Print the current file        | | ZoomInMenuItem              | Zoom                         | Zoom in the current file      | | ZoomOutMenuItem             | Zoom                         | Zoom out the current file     |

    These components are available as Toolbar slots, so it's possible to add them to a custom toolbar

    Improvements

    • Decrease the number of renders from twice to once when setting the default scale
    • The Button and MenuItem components have disabled state. For example, the button for going to the first page will be disabled if we're at the first page
    • The icons use the current color instead of hard coded one. It's easier for us to create themes

    Bug fixes

    • Doesn't work with NextJS because navigator isn't defined
    • Some bookmarks are hidden initially
    • The initialPage and defaultScale options don't work together
    • There are big spaces between thumbnails
    • Zoom the document best inside the container initially

    Breaking changes

    • If you are creating a custom toolbar or buttons to go to particular pages, then the following props are renamed:

    | Old name                      | New name              | |-------------------------------|-----------------------| | GoToFirstPageProps          | GoToPageProps       | | GoToLastPageProps           | GoToPageProps       | | GoToNextPageProps           | GoToPageProps       | | GoToPreviousPageProps       | GoToPageProps       | | RenderGoToFirstPageProps    | RenderGoToPageProps | | RenderGoToLastPageProps     | RenderGoToPageProps | | RenderGoToNextPageProps     | RenderGoToPageProps | | RenderGoToPreviousPageProps | RenderGoToPageProps |

    Source code(tar.gz)
    Source code(zip)
  • v2.4.3(May 10, 2021)

    Bug fix

    • Clicking on an internal link jumps to an incorrect page (one page after the destination one)

    Improvements

    • Automatically scroll to the thumbnail that represents the current page
    • Display the progress properly when printing a big document
    • Improve the performance of preparing pages for print such as using a shared canvas element for all pages
    • Keep showing a spinner until the canvas layer is rendered completely
    • The print plugin supports documents whose pages have different dimensions
    Source code(tar.gz)
    Source code(zip)
  • v2.4.2(Apr 25, 2021)

    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% |

    Source code(tar.gz)
    Source code(zip)
A web-based tool to view, edit, format, and validate JSON

JSON Editor JSON Editor is a web-based tool to view, edit, format, and validate JSON. It has various modes such as a tree editor, a code editor, and a

Jos de Jong 10.1k Jan 4, 2023
A VSCode extension that implements outline view and go to definition for Coq files.

Coq Outline A VSCode extension that provides outline view for Coq files. Features Provide outline views for Coq files. Provide go to definition functi

Wang Zhongye 5 Oct 29, 2022
🐉 Material Component Framework for Vue

Supporting Vuetify Vuetify is a MIT licensed project that is developed and maintained full-time by John Leider and Heather Leider; with support from t

vuetify 36.2k Jan 9, 2023
The world's #1 JavaScript library for rich text editing. Available for React, Vue and Angular

TinyMCE TinyMCE is the world's most advanced open source core rich text editor. Trusted by millions of developers, and used by some of the world's lar

Tiny 12.4k Jan 4, 2023
A React framework for building text editors.

Draft.js Draft.js is a JavaScript rich text editor framework, built for React and backed by an immutable model. Extensible and Customizable: We provid

Facebook 22.3k Jan 4, 2023
PDF.js Read Only is an additional readonly mode for PDF.js

PDF.js Read Only PDF.js Read Only is an additional readonly mode for PDF.js, a Portable Document Format (PDF) viewer that is built with HTML5 which is

Aprillio Latuminggi 19 Dec 22, 2022
I'm trying to create simple program for adding the digital signature to a pdf file with self-signed certificate. I use node-signpdf and pdf-lib library.

pdf-digital-signature-with-node-signpdf-ejs I'm trying to create simple program for adding the digital signature to a pdf file with self-signed certif

null 5 Dec 25, 2022
📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, Ember, Svelte & more!

Build bulletproof UI components faster Storybook is a development environment for UI components. It allows you to browse a component library, view the

Storybook 75.8k Jan 4, 2023
📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, Ember, Svelte & more!

Build bulletproof UI components faster Storybook is a development environment for UI components. It allows you to browse a component library, view the

Storybook 75.9k Jan 9, 2023
📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, Ember, Svelte & more!

Build bulletproof UI components faster Storybook is a development environment for UI components. It allows you to browse a component library, view the

Storybook 75.9k Jan 9, 2023
A plugin for Strapi CMS that adds a preview button and live view button to the content manager edit view.

Strapi Preview Button A plugin for Strapi CMS that adds a preview button and live view button to the content manager edit view. Get Started Features I

Matt Milburn 53 Dec 30, 2022
StarkNet support extension for VSCode. Visualize StarkNet contracts: view storage variables, external and view functions, and events.

StarkNet Explorer extension This VSCode extension quickly shows relevant aspects of StarkNet contracts: Storage variables of the current contract, and

Crytic 6 Nov 4, 2022
🔍 A view component for React Native with pinch to zoom and drag to pan functionality.

react-native-pan-pinch-view A view component for React Native with pinch to zoom and drag to pan functionality. ?? Introduction Even though the demo s

Ivanka Todorova 43 Oct 6, 2022
📄 Create PDF files using React

React renderer for creating PDF files on the browser and server Lost? This package is used to create PDFs using React. If you wish to display existing

Diego Muracciole 11.6k Jan 7, 2023
PDF-to-TEXT using Rest7 API REACT-NATIVE

PDF-to-TEXT-using-Rest7-API-REACT-NATIVE- I have made a Demo App to select PDF from documents and convert it into text than Display in ( component) us

Sahil saiyed 0 Nov 22, 2022
View component and controller of YouTube Player API, for fresh framework.

fresh-youtube View component and controller of YouTube Player API, for fresh framework. Try it now! git clone [email protected]:otiai10/fresh-youtube.git

Hiromu OCHIAI 10 Nov 2, 2022
A document head manager for React

React Helmet This reusable React component will manage all of your changes to the document head. Helmet takes plain HTML tags and outputs plain HTML t

National Football League 16.7k Dec 30, 2022
Document Typescript React components with TSDoc and export Storybook-friendly JSON 🤖

✨ Document React components with @prop ✨ react-tsdoc ?? react-tsdoc is an tool to extract information from React Typescript component files with TSDoc

Noah Buscher 13 Oct 15, 2022
Client-side JavaScript PDF generation for everyone.

A library to generate PDFs in JavaScript. You can catch me on twitter: @MrRio or head over to my company's website for consultancy. jsPDF is now co-ma

James Hall 25.7k Dec 28, 2022
PDF Reader in JavaScript

PDF.js PDF.js is a Portable Document Format (PDF) viewer that is built with HTML5. PDF.js is community-driven and supported by Mozilla. Our goal is to

Mozilla 41.1k Jan 8, 2023