Signature pad

Smooth ink that thins with speed, with undo, replay, and PNG or SVG export.

inputsnew
Preview
Signature pad preview
Save as

Press Control or Command Z to undo, add Shift to redo, and Delete to clear.

When to use

  • Contracts, delivery confirmations, and consent forms that need a drawn signature.
  • Initials or quick sketches where pen pressure and natural stroke width matter.
  • Flows that need a clean, cropped PNG or SVG of the signature.

When not to use

  • Use input for a typed name when a legal drawn signature is not required.
  • Use file-upload when the user already has a scanned signature image.
  • Use hold-to-confirm for a simple deliberate confirmation without a signature artifact.

shadcn CLI

Also installs (1)

  • manicat-foundation
Manual install(+)
registry.jsonjson
{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "signature-pad",
  "type": "registry:ui",
  "title": "Signature pad",
  "description": "Smooth ink that thins with speed, with undo, replay, and PNG or SVG export.",
  "categories": [
    "inputs"
  ],
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://manicat.viraza.net/r/manicat-foundation.json"
  ],
  "files": [
    {
      "path": "registry/components/signature-pad/signature-pad.tsx",
      "type": "registry:component",
      "target": "@components/manicat/signature-pad/signature-pad.tsx"
    },
    {
      "path": "registry/components/signature-pad/signature-pad.module.css",
      "type": "registry:component",
      "target": "@components/manicat/signature-pad/signature-pad.module.css"
    }
  ],
  "docs": "Docs and live preview: https://uiarc.dev/components/signature-pad",
  "meta": {
    "tier": "free",
    "kind": "component",
    "docs": "https://manicat.viraza.net/components/signature-pad",
    "markdown": "https://uiarc.dev/components/signature-pad/markdown",
    "tags": [
      "inputs",
      "new"
    ]
  }
}

Usage

Install the component, then copy this into your app. Change the content and the props to fit your screen.

example.tsxtsx
"use client";

import { SignaturePad } from "@/components/manicat/signature-pad/signature-pad";

export function SignaturePadExample() {
  return <SignaturePad signer="Ada Lovelace" hint="Sign above the line" />;
}

Examples

Real screens rather than isolated props. Switch to Code to copy a whole example into your project.

Sign a contract Draw a signature, with the signer's name under the line.

Sign a contract Draw a signature, with the signer's name under the line. preview
Save as

Press Control or Command Z to undo, add Shift to redo, and Delete to clear.

Keyboard interactions

KeysAction
Mod + ZUndoes the last change while the pad is focused.
Shift + Mod + Z / Mod + YRedoes.
Delete / BackspaceClears the signature with the wipe; undo brings it back.
EscapeStops a replay in progress.
Arrow keysMove between ink colors or nib widths inside each radio group.

Accessibility

  • The pad is focusable with role="img", aria-roledescription="signature pad", and a label that states the stroke count.
  • Keyboard shortcuts are described through aria-describedby on a visually hidden paragraph.
  • Ink color and width are radio groups with roving tabindex; toolbar icon buttons carry aria-label and title.
  • A polite status region announces strokes added, undo, redo, clear, replay, and export results.

Motion

  • Clear sweeps a squeegee edge across the pad while a clip-path wipe removes the ink over 0.56s.
  • Replay redraws each stroke in its original rhythm with a nib dot, capping gaps between strokes and fitting the whole replay into about 3.2s.
  • The hint fades up from a soft blur; the selected color and width highlight glides with a shared layout spring.
  • Reduced motion skips the wipe and blur and uses short opacity fades.

Responsive behavior

  • The pad keeps a 600 / 260 aspect ratio at every width, and strokes scale with it.
  • touch-action: none on the pad keeps finger strokes from scrolling the page; coalesced pointer events capture fast strokes on touch and pen.
  • The toolbar wraps on narrow widths; hover styles apply only on hover-capable fine pointers.

Performance

  • The live stroke writes its SVG path directly to the DOM on each pointer move, without a React render.
  • History keeps the last 60 states; replay runs a rAF loop that re-renders the visible strokes each frame, so very long signatures cost more to replay.
  • PNG export draws to an offscreen canvas at 3x by default.

Notes for AI

  • Use for capturing a handwritten signature or initials. Store the InkStroke[] from onChange, or convert it with signatureToSvg or signatureToPng on submit.
  • Strokes are stored in a 600 by 260 coordinate space (PAD_WIDTH, PAD_HEIGHT), so they scale with the pad and can be replayed later.
  • getStrokeOutline, outlineToPath, and strokePath are also exported if you need the raw outline math.
  • The pad is uncontrolled; to reset it, remount it with a new key.