Signature pad
Smooth ink that thins with speed, with undo, replay, and PNG or SVG export.
inputsnew
Preview
Signature pad preview
Live · keyboard ready
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
Live · keyboard ready
Save as
Press Control or Command Z to undo, add Shift to redo, and Delete to clear.
sign-a-contract-draw-a-signature-with-the-signer-s-name-under-the-line-.tsxtsx
"use client";
import { SignaturePad } from "@/components/manicat/signature-pad/signature-pad";
export function SignaturePadContractExample() {
return (
<div className="w-full max-w-md">
<SignaturePad signer="Ada Lovelace" hint="Sign above the line" />
</div>
);
}
Keyboard interactions
| Keys | Action |
|---|---|
| Mod + Z | Undoes the last change while the pad is focused. |
| Shift + Mod + Z / Mod + Y | Redoes. |
| Delete / Backspace | Clears the signature with the wipe; undo brings it back. |
| Escape | Stops a replay in progress. |
| Arrow keys | Move 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.