0

PDF Signature Button

Draw, type, or upload a signature, keep a reusable library, and click a page to place one.

"use client";

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

About

<PdfSignatureButton /> is the front end for embedpdf's signature plugin. The plugin owns the whole workflow — capturing a signature, keeping a reusable library of them, and rendering a placed signature through the annotation layer. This button wraps that in styled chrome:

  • Create — a dialog with three tabs built on embedpdf's own headless pads: <SignatureDrawPad /> (draw), <SignatureTypePad /> (type), and the useSignatureUpload hook (upload an image). Saving adds the result to the library via the signature capability's addEntry.
  • Place — picking a saved signature arms placement (forDocument(documentId).activateSignaturePlacement(entryId)); the next click on a page drops it in. While a placement is armed the button stays pressed and clicking it cancels.

Placed signatures render through the annotation plugin's <PdfAnnotationLayer> — the signature plugin registers its renderers there — so both plugins have to be registered and a layer rendered.

Installation

pnpm dlx shadcn@latest add pdfcn/signature-button

Usage

Register the annotation and signature plugins.

import { createPluginRegistration } from "@embedpdf/core";
import { AnnotationPluginPackage } from "@embedpdf/plugin-annotation/react";
import { SignaturePluginPackage } from "@embedpdf/plugin-signature/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(SignaturePluginPackage),
];

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

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

Examples

Default

Open the button, create a signature by drawing, typing, or uploading an image, and save it. Pick a saved signature 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 "Signature", 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 signature — or clicking the button cancels.

Placing a signature requires a pointer, since the drop point is chosen by clicking a page; there's no keyboard equivalent for picking a spot. Creation is keyboard reachable: the upload dropzone is a real button, so it takes focus and opens the file picker on Enter or Space, and each saved signature is a button named by its label.

API Reference

PdfSignatureButton

A <Toggle /> carrying data-slot="pdf-signature-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 signature capability through useSignatureCapability() and the armed placement through useActivePlacement(documentId). It renders disabled whenever there's no active document or the signature plugin isn't registered.