Changelog History
Page 1
-
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
orAlt
+ArrowUp
Go to the previous page PageDown
orAlt
+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 aPromise
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
- Clicking
-
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
- The
-
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
- The
-
v3.2.0 Changes
๐ New features
- 0๏ธโฃ The
Popover
component has new proplockScroll
which indicates whether thebody
element is scrollable or not. By default, it takes thetrue
value - The
Viewer
component adds newonRotate
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
, orCmd + 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);
- 0๏ธโฃ The
-
v3.1.2 Changes
๐ Bug fixes
- Don't highlight spaces between words when searching for a keyword
- ๐ The
clearHighlights
andclearKeyword()
functions provided by thesearch
plugin should remove all highlights when the keyword is empty - The current highlight is lost after zooming the document
- ๐ The
jumpToMatch()
function provided by thesearch
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 thetoolbar
plugin
-
v3.1.1 Changes
๐ 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 afteronDocumentLoad()
- The pages aren't layouted properly when they have different dimensions
- The pages are blank initially until users scroll or interact with the page
-
v3.1.0 Changes
๐ New features
- โ
Add new
testId
property toSpinner
- The
Viewer
component provides newscrollMode
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.
0๏ธโฃ 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 - 0๏ธโฃ The default
Spinner
is used when using therenderLoader
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 theViewer
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} />} />;
- โ
Add new