Customize bookmark items

A bookmark item of a PDF document consists of different elements such as an icon to toggle its sub items, a title, a flag to indicate it is expanded or not, etc. We can customize bookmark items completely by using the `renderBookmarkItem` property:
const bookmarkPluginInstance = bookmarkPlugin();
const { Bookmarks } = bookmarkPluginInstance;
// Render bookmarks
<Bookmarks renderBookmarkItem={renderBookmarkItem} />;
`renderBookmarkItem` is a render prop accepting a `RenderBookmarkItemProps` parameter and returns a React element. The parameter contains the following properties:
PropertyTypeDescriptionFrom
`bookmark``PdfJs.Outline`The current bookmark model3.7.0
`defaultRenderItem``Function`The default renderer of a bookmark item3.7.0
`defaultRenderTitle``Function`The default renderer of a bookmark title3.7.0
`defaultRenderToggle``Function`The default renderer of a bookmark toggle3.7.0
`depth``number`The depth of the bookmark3.7.0
`hasSubItems``boolean`Indicate whether the bookmark has sub items3.7.0
`index``number`The zero-based index of the bookmark3.7.0
`isExpanded``boolean`Indicate whether the bookmark is expanded or collapsed3.7.0
`path``string`The path from the bookmark item to the root3.8.0
`onClickItem``Function`The default function triggers when the bookmark is clicked3.7.0
`onClickTitle``Function`The default function triggers when the bookmark title is clicked3.7.0
`onToggleSubItems``Function`The default function triggers when sub items of the bookmark is toggled3.7.0
By using these properties, you can create custom bookmark items completely. For the sake of simplicity, this example only customizes the toggle icons using the default renderers.
Let's take a closer look at the `defaultRenderItem`, `defaultRenderTitle` and `defaultRenderToggle` properties.

The default renderer of a bookmark item

defaultRenderItem: (onClickItem: () => void, children: React.ReactNode) => React.ReactElement;
PropertyTypeDescriptionFrom
`onClickItem``Function`The function triggers when users click a bookmark item3.7.0
`children``ReactNode`The renderer of a bookmark item3.7.0
We don't want to change the behavior when users click a bookmark, hence the `onClickItem` function is used as following:
const renderBookmarkItem = (renderProps: RenderBookmarkItemProps) =>
renderProps.defaultRenderItem(
renderProps.onClickItem
// We will custom bookmark renderer here
);

The default renderer of a bookmark toggle

defaultRenderToggle: (expandIcon: React.ReactElement, collapseIcon: React.ReactElement) => React.ReactElement;
PropertyTypeDescriptionFrom
`expandIcon``ReactElement`The icon when the bookmark is expanded3.7.0
`collapseIcon``ReactElement`The icon when the bookmark is collapsed3.7.0
The following snippet uses custom icons, `ExpandIcon` and `CollapseIcon`, to represent the toggle icons:
const renderBookmarkItem = (renderProps: RenderBookmarkItemProps) =>
renderProps.defaultRenderItem(
renderProps.onClickItem,
<>
{/* Render the toggle icon */}
{renderProps.defaultRenderToggle(<ExpandIcon />, <CollapseIcon />)}
</>
);
It's totally up to you to choose your own components. However, we can use the `Icon` component as the base one:
import { Icon } from '@react-pdf-viewer/core';
const ExpandIcon = () => (
<Icon size={16}>
<path d="M.541,5.627,11.666,18.2a.5.5,0,0,0,.749,0L23.541,5.627" />
</Icon>
);
const CollapseIcon = () => (
<Icon size={16}>
<path d="M5.651,23.5,18.227,12.374a.5.5,0,0,0,0-.748L5.651.5" />
</Icon>
);
It's possible to use the default icons:
import { DownArrowIcon, RightArrowIcon } from '@react-pdf-viewer/bookmark';
// Render the default toggle icons
renderProps.defaultRenderToggle(<DownArrowIcon />, <RightArrowIcon />);

The default renderer of a bookmark title

defaultRenderTitle: (onClickBookmark: () => void) => React.ReactElement;
PropertyTypeDescriptionFrom
`onClickBookmark``Function`The function triggers when users click the title3.7.0
We keep the default behavior when users the title by using the `onClickTitle` function:
const renderBookmarkItem = (renderProps: RenderBookmarkItemProps) =>
renderProps.defaultRenderItem(
renderProps.onClickItem,
<>
{/* Render the toggle icon */}
...
{/* Render the title */}
{renderProps.defaultRenderTitle(renderProps.onClickTitle)}
</>
);
Here is the live demonstration that uses the custom toggle icons:
Click a bookmark icon to see its expanded and collapsed variants (The sample code)
It's also possible to use the changes when using the default layout plugin:
Click the Bookmark tab in the sidebar (The sample code)

See also