agentsclimarketplace

React pdf kit toolbar customization

Skill react-pdf-kit/agent-skills/skills/react-pdf-kit-toolbar-customization

Skills to help developers using AI agents with React PDF Kit library

Install
npx -y skills add react-pdf-kit/agent-skills --skill react-pdf-kit-toolbar-customization

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Customize the @react-pdf-kit/viewer (>=2.0.0 <3.0.0) toolbar using the RPLayout toolbar prop with RPHorizontalBar / RPVerticalBar, or compose individual tool exports for a fully custom bar. Preserves Radix-based accessibility.

SKILL.md

9.2 KB, as published. Nobody here has run it

react-pdf-kit-toolbar-customization

Use this skill when: the developer asks to customize the viewer's toolbar. Examples: hide one or more built-in tools, add a custom button, replace an existing tool with a custom component, or split the layout into a custom top bar and left sidebar. For replacing the entire layout chrome (full headless), use react-pdf-kit-custom-layout instead.

The recommended path is RPLayout's toolbar prop with the RPHorizontalBar (top bar) and RPVerticalBar (left sidebar) components. Each bar accepts a slots prop that toggles individual tools on or off or replaces them with your own component. For projects that need a completely different visual shell, individual tool exports (ZoomInTool, PrintTool, etc.) can be composed in your own container.

Gotchas

  • RPDefaultLayout is deprecated in v2. Use RPLayout with the structured toolbar prop. Older examples that pass slots and icons directly to RPDefaultLayout should migrate.
  • The recommended customization API is RPHorizontalBar / RPVerticalBar, not bypassing RPLayout entirely. Bypassing RPLayout is reserved for fully custom shells (see step 4).
  • Each tool is independently exportable. Examples: ZoomInTool, ZoomOutTool, PrintTool, DownloadTool, RotateClockwiseTool, SwitchViewModeTool, ToggleSidebarTool. Use these only if you are building a fully custom bar (step 4). Do NOT replicate their behavior by hand, or you'll lose the accessibility wiring.
  • Preserve Radix primitives. Built-in tools wrap Radix tooltips and buttons. Custom tools should also use Radix or at minimum preserve aria-label, focusable buttons, and visible focus rings.
  • Keyboard navigation must keep working. Tools are reachable via Tab order. Don't insert non-focusable wrappers (div onClick) where a Radix Button belongs.
  • Use the documented hooks rather than reaching into context directly. The viewer exposes useZoomContext, useDocumentContext, usePaginationContext, usePrintContext, useFileDownload, etc. for custom tools to call.

Procedure

1. Default toolbar (no customization)

Drop in RPLayout. The default top bar (zoom, navigation, search, download, etc.) and left sidebar (thumbnails) render automatically.

import {
  RPConfig,
  RPProvider,
  RPLayout,
  RPPages,
} from '@react-pdf-kit/viewer'

export function PdfViewer({ src }: { src: string }) {
  return (
    <RPConfig>
      <RPProvider src={src}>
        <RPLayout toolbar>
          <RPPages />
        </RPLayout>
      </RPProvider>
    </RPConfig>
  )
}

<RPLayout toolbar> (the boolean form) renders the default top bar and left sidebar. The structured toolbar={{ ... }} form below customizes them.

2. Partial customization (hide / show individual tools)

Pass RPHorizontalBar (top bar) and RPVerticalBar (left sidebar) to RPLayout.toolbar. Each bar's slots prop toggles tools by name.

import {
  RPConfig,
  RPProvider,
  RPLayout,
  RPPages,
  RPHorizontalBar,
  RPVerticalBar,
} from '@react-pdf-kit/viewer'

export function PdfViewer({ src }: { src: string }) {
  return (
    <RPConfig>
      <RPProvider src={src}>
        <RPLayout
          toolbar={{
            topbar: {
              component: (
                <RPHorizontalBar
                  slots={{
                    // Hide these tools on the top bar:
                    searchTool: false,
                    openFileTool: false,
                    fullscreenTool: false,
                    // Everything else stays at its default.
                  }}
                />
              ),
            },
            leftSidebar: { component: <RPVerticalBar /> },
          }}
        >
          <RPPages />
        </RPLayout>
      </RPProvider>
    </RPConfig>
  )
}

Set a slot to false to hide it. Set it to a React component to replace it with your own implementation (see step 3).

To hide the left sidebar entirely, pass an empty fragment:

leftSidebar: { component: <></> }

To use only the top bar with no left sidebar, omit the leftSidebar key from toolbar.

3. Replace a built-in tool with a custom component

Pass a component to the slot instead of false. The skill below adds a confirmation prompt before download:

<RPLayout
  toolbar={{
    topbar: {
      component: (
        <RPHorizontalBar
          slots={{
            downloadTool: ({ download }) => (
              <button
                type="button"
                aria-label="Download with confirmation"
                onClick={() => {
                  if (confirm('Download this file?')) download()
                }}
              >
                Save
              </button>
            ),
          }}
        />
      ),
    },
  }}
>
  <RPPages />
</RPLayout>

The slot callback receives the same context the default tool would have used (here, download). Other slots expose similar props (see the RPHorizontalBar component docs for the full slot table).

4. Fully custom bar (compose individual tool exports)

When the visual shell needs to differ substantially from the default, skip RPLayout.toolbar and build your own bar from the individual *Tool exports. Render this bar yourself, with RPLayout configured to not render its own toolbar:

import {
  RPConfig,
  RPProvider,
  RPLayout,
  RPPages,
  ZoomInTool,
  ZoomOutTool,
  PrintTool,
  DownloadTool,
} from '@react-pdf-kit/viewer'

function CustomTopBar() {
  return (
    <div
      role="toolbar"
      aria-label="PDF viewer toolbar"
      style={{
        display: 'flex',
        gap: 8,
        padding: '8px 16px',
        borderBottom: '1px solid var(--rp-border, #e5e7eb)',
      }}
    >
      <ZoomOutTool />
      <ZoomInTool />
      <span style={{ flex: 1 }} />
      <PrintTool />
      <DownloadTool />
    </div>
  )
}

export function PdfViewer({ src }: { src: string }) {
  return (
    <RPConfig>
      <RPProvider src={src}>
        <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
          <CustomTopBar />
          <div style={{ flex: 1, minHeight: 0 }}>
            <RPLayout toolbar={false}>
              <RPPages />
            </RPLayout>
          </div>
        </div>
      </RPProvider>
    </RPConfig>
  )
}

The wrapper around RPLayout MUST set flex: 1; min-height: 0; so the virtualizer has a concrete viewport to measure. toolbar={false} tells RPLayout not to render its own bar (your custom one is already mounted above it).

If you also need to drop the sidebar, prefer react-pdf-kit-custom-layout instead, which gives you a clean headless surface for fully bespoke layouts.

5. Add a custom button using a documented hook

For a one-off custom tool (not replacing an existing slot), import the hook the tool needs and render a Radix-wrapped button:

import { useDocumentContext } from '@react-pdf-kit/viewer'
import * as Tooltip from '@radix-ui/react-tooltip'

export function CopyLinkTool() {
  const { src } = useDocumentContext()

  return (
    <Tooltip.Provider>
      <Tooltip.Root>
        <Tooltip.Trigger asChild>
          <button
            type="button"
            aria-label="Copy document link"
            onClick={() => navigator.clipboard.writeText(String(src))}
          >
            Copy link
          </button>
        </Tooltip.Trigger>
        <Tooltip.Portal>
          <Tooltip.Content sideOffset={6}>Copy link</Tooltip.Content>
        </Tooltip.Portal>
      </Tooltip.Root>
    </Tooltip.Provider>
  )
}

Drop <CopyLinkTool /> into either an RPHorizontalBar slot override or your fully custom bar from step 4.

Verify

pnpm install
pnpm build
pnpm dev

Open the page. Tab through the toolbar with the keyboard. Every button should receive focus, show a visible focus ring, and respond to Enter. Use a screen reader (VoiceOver, NVDA) to confirm each button has an accessible name. Open a PDF, scroll, select text. The viewer should still virtualize and the text layer should still be selectable.

References

Gives 0 of the 12 instructions most pdf office docs skills give

Counted across 635 of the 690 authors here whose files we hold, read 2026-08-06

  • extract text using pdfplumberin 92 of 635, across 25 files
  • create PDFs using reportlabin 83 of 635, across 16 files
  • read FORMS.md to fill out PDF formsin 80 of 635, across 13 files
  • OCR scanned PDFs using pytesseractin 77 of 635, across 10 files
  • merge or split PDFs using qpdfin 70 of 635, across 3 files
  • use Excel formulas instead of hardcoded calculated valuesin 68 of 635, across 12 files
  • unpack edit xml and repack existing documentsin 63 of 635, across 8 files
  • document sources for hardcoded valuesin 61 of 635, across 9 files
  • write minimal python code without unnecessary commentsin 59 of 635, across 7 files
  • run the recalculation script after adding or modifying formulasin 58 of 635, across 6 files
  • fix all identified formula errors and recalculatein 58 of 635, across 6 files
  • format years as text stringsin 57 of 635, across 5 files

Said here and by no other author read

  • use RPLayout toolbar prop with RPHorizontalBar or RPVerticalBar
  • migrate older RPDefaultLayout usages to RPLayout
  • set a slot to false to hide it
  • set a slot to a component to replace it
  • compose individual tool exports for a fully custom bar
  • set layout wrapper to flex 1 and min height 0

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.