Signature pad
Smooth ink that thins with speed, with undo, replay, and PNG or SVG export.
pnpm dlx shadcn@latest add @uiarc/signature-padLease agreement
Press Control or Command Z to undo, add Shift to redo, and Delete to clear.
- 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.
- 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.
Installation
Add Signature pad with the shadcn CLI, or copy the source by hand.
pnpm dlx shadcn@latest add @uiarc/signature-padAdds the component and its local dependencies, and installs motion, lucide-react. First time? Add the @uiarc registry to components.json, or use the full URL:
import { useState } from "react";import { SignaturePad, signatureToSvg } from "@/registry/components/signature-pad/signature-pad";import type { InkStroke } from "@/registry/components/signature-pad/signature-pad"; export function SignContract() { const [strokes, setStrokes] = useState<InkStroke[]>([]); return ( <form onSubmit={event => { event.preventDefault(); submit(signatureToSvg(strokes)); }}> <SignaturePad signer="Ada Lovelace" fileName="ada-signature" onChange={setStrokes} /> <button type="submit" disabled={!strokes.length}>Sign</button> </form> );}API reference
3 parts. The first is the root.
SignaturePad
A signature field with pressure-sensitive ink, undo and redo, a wipe to clear, replay, and PNG or SVG export.
signerstring–Printed under the baseline, such as the signer's name.hintstring"Sign here"Resting hint on the baseline before the first stroke.defaultColor"black" | "blue" | "violet""black"Starting ink color.defaultWidth"fine" | "medium" | "bold""medium"Starting nib width.onChange(strokes: InkStroke[]) => void–Receives the strokes after every change, including undo, redo, and clear.fileNamestring"signature"File name for exports, without extension.labelstring"Signature pad"Accessible name of the drawing surface.classNamestring–Extra class on the root.signatureToSvg
Returns a standalone SVG string of the strokes, cropped to the ink with print ink colors. Empty string for no strokes.
strokesRequiredInkStroke[]–Strokes as received from onChange.signatureToPng
Resolves to a transparent PNG Blob cropped to the ink. Rejects when there are no strokes.
strokesRequiredInkStroke[]–Strokes as received from onChange.scalenumber3Multiple of the 600 by 260 pad resolution.- Mod+Z
- Undoes the last change while the pad is focused.
- Shift+Mod+ZorMod+Y
- Redoes.
- DeleteorBackspace
- 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.
- 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.
- 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.
- 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.
- 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
Give your coding assistant the Markdown reference instead of screenshots.
- 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.
The full library index for assistants is at /llms.txt.