React PDF viewer
v1.4.0

Example: Always show the sidebar

First, we will remove the toogle sidebar button from the toolbar. We will clone the default toolbar by copying the code from layouts/defaultToolbar.tsx, and remove the toogle sidebar button:

const renderToolbar = (toolbarSlot: ToolbarSlot): React.ReactElement => {
    return (
        <div
            style={{
                alignItems: 'center',
                display: 'flex',
                width: '100%',
            }}
        >
            <div
                style={{
                    alignItems: 'center',
                    display: 'flex',
                }}
            >
                <div style={{ padding: '0 2px' }}>
                    {toolbarSlot.searchPopover}
                </div>
                <div style={{ padding: '0 2px' }}>
                    {toolbarSlot.previousPageButton}
                </div>
                <div style={{ padding: '0 2px' }}>
                    {toolbarSlot.currentPageInput} / {toolbarSlot.numPages}
                </div>
                <div style={{ padding: '0 2px' }}>
                    {toolbarSlot.nextPageButton}
                </div>
            </div>
            <div
                style={{
                    alignItems: 'center',
                    display: 'flex',
                    flexGrow: 1,
                    flexShrink: 1,
                    justifyContent: 'center',
                }}
            >
                <div style={{ padding: '0 2px' }}>
                    {toolbarSlot.zoomOutButton}
                </div>
                <div style={{ padding: '0 2px' }}>
                    {toolbarSlot.zoomPopover}
                </div>
                <div style={{ padding: '0 2px' }}>
                    {toolbarSlot.zoomInButton}
                </div>
            </div>
            <div
                style={{
                    alignItems: 'center',
                    display: 'flex',
                    marginLeft: 'auto',
                }}
            >
                <div style={{ padding: '0 2px' }}>
                    {toolbarSlot.fullScreenButton}
                </div>
                <div style={{ padding: '0 2px' }}>
                    {toolbarSlot.openFileButton}
                </div>
                <div style={{ padding: '0 2px' }}>
                    {toolbarSlot.downloadButton}
                </div>
                <div style={{ padding: '0 2px' }}>
                    {toolbarSlot.moreActionsPopover}
                </div>
            </div>
        </div>
    );
};

The default layout is defined in layouts/defaultLayout.tsx. It uses the CSS grid to locate the toolbar, sidebar and main parts. Imagine that the container is a grid of 2 columns and 2 rows:

┌───────────┬───────────┐
│ toolbar   │ toolbar   │
├───────────┼───────────┤
│ sidebar   │ main      │
└───────────┴───────────┘

Their container has style of grid-template-areas: 'toolbar toolbar' 'sidebar main'. Meanwhile, each part needs to indicate the area in grid via the grid-area style:

AreaStyle
ToolbargridArea: 'toolbar'
SidebargridArea: 'sidebar'
MaingridArea: 'main'

Depending on the layout is opened or not, we have to update the style for the container.

// Container style
gridTemplateAreas: isSidebarOpened
                ? "'toolbar toolbar' 'sidebar main'"
                : "'toolbar' 'main'"

// Sidebar
display: isSidebarOpened ? 'flex' : 'none',

Here is the sample code taken from the layouts/defaultLayout.tsx file which demonstrates the idea of building the layout:

const defaultLayout = (
    isSidebarOpened: boolean,
    container: Slot,
    main: Slot,
    toolbar: React.ReactElement,
    sidebar: Slot,
): React.ReactElement => {
    return (
        <div
            {...container.attrs}
            style={Object.assign({}, {
                display: 'grid',
                gridTemplateAreas: isSidebarOpened
                    ? "'toolbar toolbar' 'sidebar main'"
                    : "'toolbar' 'main'",
            }, container.attrs.style)}
        >
            {container.children}
            <div
                style={{
                    gridArea: 'toolbar',
                }}
            >
                {toolbar}
            </div>
            <div
                style={{
                    display: isSidebarOpened ? 'flex' : 'none',
                    gridArea: 'sidebar',
                }}
            >
                {sidebar.children}
            </div>
            <div
                style={{
                    gridArea: 'main',
                }}
            >
                {main.children}
            </div>
        </div>
    );
};

Hopefully you get an idea how the layout is constructed on top of its part. By ignoring the isSidebarOpened parameter, you can show up the sidebar all the time:

const layout = (
    isSidebarOpened: boolean,
    container: Slot,
    main: Slot,
    toolbar: RenderToolbar,
    sidebar: Slot,
): React.ReactElement => {
    return (
        <div
            style={{
                display: 'grid',
                gridTemplateAreas: "'toolbar toolbar' 'sidebar main'",
                gridTemplateColumns: '30% 1fr',
            }}
        >
            ...
        </div>
    );
};

This file consists of the full code which creates the following viewer:

/ 8
90%