Customize thumbnail items

You can preview pages of a PDF document by using the `Thumbnails` component provided by the Thumbnail plugin.
By default, the component displays the thumbnail and index of each page. This example demonstrates how you can customize thumbnail items.
Let's say that we want to select particular pages, and then you can manipulate them in the back-end. Removing the selected pages from the document, or merging them into a new document are two possible usages.
The component provides the `renderThumbnailItem` property for customizing thumbnail item renderer:
import type { RenderThumbnailItemProps } from '@react-pdf-viewer/thumbnail';
<Thumbnails renderThumbnailItem={renderThumbnailItem} />
const renderThumbnailItem = (props: RenderThumbnailItemProps) => (
// Your custom thumbnail item
);
The `RenderThumbnailItemProps` type contains the following properties:
PropertyTypeDescriptionFrom
`currentPage``number`The current page number3.0.0
`key``string`The unique key that should be used as the `key` property of the thumbnail item component3.0.0
`numPages``number`The total number of pages3.0.0
`pageIndex``number`The corresponding page index3.0.0
`renderPageLabel``React.ReactElement`The page label which can be the page index or custom page label if there is any3.0.0
`renderPageThumbnail``React.ReactElement`The thumbnail image3.0.0
`onJumpToPage``Function`Jump to the corresponding page3.0.0
`onRotatePage``Function`Rotate to the corresponding page3.2.0
The default thumbnail item can be constructed by
const renderThumbnailItem = (props: RenderThumbnailItemProps) => (
<div key={props.key}>
{/* Jump to the corresponding page when clicking the thumbnail */}
<div onClick={props.onJumpToPage}>
{/* Thumbnail image */}
{props.renderPageThumbnail}
</div>
{/* Page label */}
{props.renderPageLabel}
</div>
);
Now, come back to our example. In order to manage the selected state of pages, we can use an internal state which is an array of `boolean`:
const [selectedPages, setSelectedPages] = React.useState<boolean[]>([]);
The `selectedPages` variable is initialized right after the document is loaded completely:
<Viewer onDocumentLoad={handleDocumentLoad} />;
const handleDocumentLoad = (e: DocumentLoadEvent) => {
setSelectedPages(Array(e.doc.numPages).fill(false));
};
Since we want each thumbnail item to be selectable, it should include a `checkbox` whose the `checked` property is determined by the `selectedPages` state:
const renderThumbnailItem = (props: RenderThumbnailItemProps) => (
<div key={props.key}>
...
<input
type="checkbox"
checked={selectedPages[props.pageIndex] || false}
onChange={(e) => handleChoosePage(e, props.pageIndex)}
/>
</div>
);
The `handleChoosePage` function handles the `onChange` event of the checkbox:
const handleChoosePage = (e: React.ChangeEvent<HTMLInputElement>, pageIndex: number) => {
const isSelected = e.target.checked;
selectedPages[pageIndex] = isSelected;
setSelectedPages([...selectedPages]);
};
If you would like to have buttons which allow users to select or deselect all pages at the same time, then it is easy too. The following callbacks can be used to handle the `click` events of the buttons:
// Select all pages
const selectAllPages = () => {
setSelectedPages((selectedPages) => Array(selectedPages.length).fill(true));
};
// Deselect all pages
const deselectAllPages = () => {
setSelectedPages((selectedPages) => Array(selectedPages.length).fill(false));
};
Selected pages:

Customize the Thumbnails tab in the default layout

The default layout plugin uses the `Thumbnails` component as the first tab in the sidebar. Since we can manage the tabs via the `sidebarTabs` option, we can replace the default thumbnails tab with our custom thumbnails:
import { ThumbnailIcon } from '@react-pdf-viewer/default-layout';
const defaultLayoutPluginInstance = defaultLayoutPlugin({
sidebarTabs: (defaultTabs) =>
[
{
content: <Thumbnails renderThumbnailItem={renderThumbnailItem} />,
icon: <ThumbnailIcon />,
title: 'Thumbnails',
},
].concat(defaultTabs.slice(1)),
});
Instead of creating the `Thumbnails` component from the scratch, it can be taken from the instance of default layout plugin:
const thumbnailPluginInstance = defaultLayoutPluginInstance.thumbnailPluginInstance;
const { Thumbnails } = thumbnailPluginInstance;
Selected pages:

See also