0

PDF Stamp Button

Pick a rubber stamp from a library and click a page to place it.

"use client";

import { createPluginRegistration } from "@embedpdf/core";

About

<PdfStampButton /> is the front end for embedpdf's stamp plugin. The plugin owns the workflow — loading a library of rubber stamps, arming placement of one, and rendering the placed stamp through the annotation layer. This button wraps that in styled chrome:

  • Palette — a dialog listing every stamp across the loaded libraries, each previewed with the plugin's own <StampImg />. Registered with no config, the plugin loads a standard set (Approved, Draft, Confidential, and more) from its CDN manifest, so the palette is populated out of the box.
  • Place — picking a stamp arms placement (forDocument(documentId).activateStampPlacement(libraryId, stamp)); the next click on a page drops it in. While a placement is armed the button stays pressed and clicking it cancels.

Placed stamps render through the annotation plugin's <PdfAnnotationLayer> — the stamp plugin registers a rubber-stamp tool there — so both plugins have to be registered and a layer rendered.

Installation

pnpm dlx shadcn@latest add pdfcn/stamp-button

Usage

Register the annotation and stamp plugins.

import { createPluginRegistration } from "@embedpdf/core";
import { AnnotationPluginPackage } from "@embedpdf/plugin-annotation/react";
import { StampPluginPackage } from "@embedpdf/plugin-stamp/react";
 
// Outside the component — a new array identity on every render tears the
// engine down and rebuilds it, losing scroll and zoom state.
const plugins = [
  createPluginRegistration(AnnotationPluginPackage),
  createPluginRegistration(StampPluginPackage),
];

Render the annotation layer — placed stamps render through it — and drop the button in the toolbar.

<PdfViewer
  documents={[{ url: "/sample.pdf" }]}
  plugins={plugins}
  className="h-[720px]"
>
  <PdfToolbar>
    <PdfStampButton />
  </PdfToolbar>
  <PdfViewerContent
    pageLayers={({ documentId, pageIndex }) => (
      <PdfAnnotationLayer documentId={documentId} pageIndex={pageIndex} />
    )}
  />
</PdfViewer>

Examples

Default

Open the button to see the stamp palette, pick a stamp to arm placement, then click a page to drop it in. Click the button again while it's pressed to cancel placement.

"use client";

import { createPluginRegistration } from "@embedpdf/core";

Accessibility

The trigger is a single toggle button labelled "Stamp", with a tooltip to match. Its pressed state reflects whether a placement is armed, and the tooltip switches to explain that clicking a page places the stamp — or clicking the button cancels.

Placing a stamp requires a pointer, since the drop point is chosen by clicking a page; there's no keyboard equivalent for picking a spot. The palette itself is keyboard reachable — each stamp is a button focusable in order, named by its subject. A stamp's preview is a bitmap of its page and carries no text of its own, so that name is the card's only one: it goes on aria-label and in a tooltip, rather than in a title a keyboard would never surface.

API Reference

PdfStampButton

A <Toggle /> carrying data-slot="pdf-stamp-button". Accepts every prop the underlying toggle takes; pressed, onPressedChange, aria-label, and the default icon are managed internally but can be overridden.

The button reads the stamp capability through useStampCapability() and the armed placement through useActiveStamp(documentId). It renders disabled whenever there's no active document or the stamp plugin isn't registered.