build69
build69  /  Components  /  Text Inputs  /  SignaturePad

SignaturePad

v1.0.18NewUpdated 20 Oct 2026

Dependency-free canvas signature capture with smooth quadratic-curve strokes and velocity-based pen width. DPR-aware and responsive (ResizeObserver redraw), undo/clear toolbar, read-only display from a data URL, and PNG

Preview

Live · 12 stories
DefaultOpen ↗
▸Why this is recommendedformsignaturecanvasdraw+5

The default, out-of-the-box SignaturePad.

Recommended for+14
  • ✓Delivery / goods-received sign-off
  • ✓Quotation and contract acceptance
  • ✓Consent forms
  • ✓POS acknowledgements
Tags+6
formsignaturecanvasdrawe-signpointertouchpendefault
Features+4
  • Mouse / touch / pen via pointer events (coalesced events supported)
  • Smooth quadratic-curve strokes with velocity-based width
  • devicePixelRatio-aware sizing + ResizeObserver redraw
  • Undo stroke / clear with built-in toolbar (localisable labels)
  • Controlled (value/onChange) and uncontrolled (defaultValue) modes
  • Read-only display mode from an initial data URL
  • toDataURL(type, quality) + toSVG() via ref handle, onEnd(dataUrl) callback
  • Pen colour from currentColor token (dark-mode safe)
  • Keyboard: Backspace undoes last stroke, Escape cancels stroke in progress
  • Hidden form input via name, sizes sm / md / lg
  • Labelled by FormField: the canvas (role=img, not labelable) takes the id and is named by the field label through aria-labelledby; the built-in "Signature" name steps aside
Not recommended for−2
  • ✕Free-form sketching or image annotation (use a drawing tool)
  • ✕Typed name confirmation (use Input)

Install

Ask your agent, or call the MCP tool directly. The resolved bundle is written into your project.

get_registry_item({ name: "SignaturePad" })

Usage

import { SignaturePad, type SignaturePadHandle } from '@/components/inputs/signature-pad';

const padRef = useRef<SignaturePadHandle>(null);

<SignaturePad ref={padRef} aria-label="Customer signature" onEnd={(dataUrl) => save(dataUrl)} />

Tick variants in the left menu — each adds a tab with that variant’s real story source, the same code the preview above renders.

Props

PropTypeRequired
value

Controlled signature data URL

string | null—
defaultValue

Uncontrolled initial data URL

string | null—
onChange

Fires on stroke end / undo / clear (null when empty); after a clear or undo while the pointer is still down, lifting that pointer reports nothing more (no onChange or onEnd)

(dataUrl: string | null) => void—
onEnd

Fires when a stroke finishes

(dataUrl: string) => void—
size

Canvas height preset

'sm' | 'md' | 'lg'—
strokeWidth

Base pen width; actual width varies with velocity

number—
readOnly

Display-only render of the value

boolean—
disabled

Disable drawing and toolbar

boolean—
ref

clear / undo / isEmpty / toDataURL / toSVG / focus

Ref<SignaturePadHandle>—
aria-label

Accessible name of the surface; defaults to labels.signatureLabel ("Signature") except inside a labelled FormField

string—
aria-labelledby

Id(s) of the element(s) that label the drawing surface; wins over a FormField label

string—
id

DOM id set on the drawing surface; FormField clones its field id in, and its label then names the control

string—
aria-describedby

Id(s) of hint or error text describing the drawing surface (joined with the instructions) (FormField clones this in)

string—
aria-invalid

Mark the drawing surface invalid; FormField clones this in from its error prop

boolean—
aria-required

Accepted (FormField clones it in) but not rendered: ARIA does not allow it on role=img. The label text "required" is part of the name instead

boolean—

Related