Skip to content
WANCRAFT

F.86Forms & Inputs

Signature Pad

Canvas signature capture with smooth, velocity-weighted strokes, pen pressure, undo, PNG / SVG export and a typed-name fallback.

NewReactCanvasTailwindadvanced

Overview

Signature Pad captures a handwritten signature that looks like ink, not a polyline. Points from pointer events (coalesced for full resolution) are joined with quadratic curves through their midpoints, and each segment's width follows the pen's speed — and its pressure on a stylus. Strokes are stored as points, so the pad redraws them crisply on resize, on high-DPI screens and when the theme flips the default ink. Undo and clear are buttons (plus Ctrl / Cmd + Z), and a ref exposes toDataURL, toSVG and toSVGPath, which onChange also reports. Drawing is not keyboard accessible, so the pad offers an honest alternative: a Type mode where people sign by typing their name.

01Installation

Method 01 · Registry

CLI verified

Uses the shadcn CLI in a project initialised with shadcn init. Installs the file to components/ui/signature-pad.tsx and adds its dependencies.

npx shadcn@latest add https://wancraft.my/r/signature-pad.json

Method 02 · Copy and paste

  1. 1. No extra dependencies — React and Tailwind CSS only.
  2. 2. Copy the source from the Code tab into components/ui/signature-pad.tsx.
  3. 3. Import it and adjust props.
Dependencies
None
Peer
react ≥ 18, tailwindcss ≥ 4
Added
13 Oct 2026
Updated
—

02Usage

The default configuration. Change properties above to generate a tailored example in the Usage tab.

example.tsx
import { SignaturePad, type SignaturePadHandle } from "@/components/ui/signature-pad";
import { useRef } from "react";

export function SignaturePadExample() {
  const pad = useRef<SignaturePadHandle>(null);

  return (
    <SignaturePad
      ref={pad}
      name="signature"
      onChange={(data) => console.log(data.isEmpty, data.svgPath)}
    />
  );
}

03Props

PropTypeDefaultDescription
refRef<SignaturePadHandle>—clear(), undo(), isEmpty(), toDataURL(type?), toSVG(), toSVGPath().
onChange(data: SignatureData) => void—After each stroke, undo, clear or typed change: { isEmpty, mode, dataUrl, svgPath, typedName }.
labelstring"Signature"Visible label and accessible name.
penColorstring—Ink colour. Defaults to the theme's text colour and follows theme switches.
strokeWidthnumber2.5Maximum stroke width in px (new strokes).
thinningnumber0.60–1: how much speed thins the line.
pressurebooleantrueScale width by stylus pressure when the pointer is a pen.
heightnumber200Pad height in px; width follows the container.
showGuidebooleantrueBaseline with a × mark, and the hint while empty.
hintstring"Sign here"Hint shown on the empty pad.
allowTypedFallbackbooleantrueOffer a Type mode (keyboard-accessible signature by name).
accentstring"#FF7448"Focus ring colour.
disabledbooleanfalseDisable input.
namestring—Submits the PNG data URL with a form via a hidden input.
...propsHTMLAttributes<HTMLDivElement>—Forwarded to the root role="group".

04Features

  • 01Quadratic smoothing through midpoints with velocity-based width
  • 02Stylus pressure and coalesced pointer events for full-resolution paths
  • 03Strokes stored as points: redrawn on resize, DPR (capped at 2) and theme changes
  • 04Undo, clear and Ctrl / Cmd + Z
  • 05PNG data URL (transparent, 2×) and SVG export via ref and onChange
  • 06Guide line with a “Sign here” hint
  • 07Typed-name fallback rendered in a script face and exported to PNG
input · draginput · pointerinput · keyboardinput · click

05Accessibility

  • The pad is a labelled role="group"; the canvas is role="img" with a label that states whether it is empty or how many strokes it holds.
  • Drawing needs a pointer and cannot be done with a keyboard. The Type mode (on by default) provides a labelled text field so keyboard and screen reader users can sign by name.
  • Draw / Type, Undo and Clear are real buttons with aria-pressed and disabled states and visible focus rings.
  • A polite status region announces captured, removed and cleared strokes.
  • There is no motion; the hint simply disappears once drawing starts.

06Limitations

  • Drawing itself is not keyboard accessible — keep allowTypedFallback on unless another accessible path exists.
  • The SVG export draws each stroke with its average width; the PNG keeps the variable width.
  • A drawn or typed signature on its own is not a legally verified e-signature.