Signature Pad

A page to sign on with a mouse, a finger or a stylus. It keeps each pen stroke as a smooth SVG path, in writing order, so a Signature can play the hand back and a form can submit it.

Sign with your mouse, a finger or a stylus.

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add signature-pad

Usage#

usage.tsxTSX
import {  SignaturePad,  SignaturePadActions,  SignaturePadUndo,  SignaturePadClear,} from "@/components/ui/signature-pad"export function Example() {  const [strokes, setStrokes] = React.useState<string[]>([])  return (    <SignaturePad value={strokes} onValueChange={setStrokes}>      <SignaturePadActions>        <SignaturePadUndo />        <SignaturePadClear />      </SignaturePadActions>    </SignaturePad>  )}

Play it back#

The value is one SVG path per stroke, in the order the hand wrote them, which is exactly what a Signature takes as its children. signatureViewBox(strokes) gives it the box around the ink, so it takes its width from the first paint. The Signature page has the full playground, with every speed and size.

Sign the pad and your hand is written back here.

States#

Inside a Field, the pad takes the field's label and hint as its name and description, and its hasError and disabled cascade in, the same as an Input. An error paints the frame; a disabled pad keeps its signature on show but no longer takes the pen or offers Undo and Clear. Both props can also be set on the pad itself. Focus works like any field's: the first stroke focuses the pad, and it stays lit through every lift of the pen and every Undo until you click away, so a signature of five strokes does not blink five times. While it has focus, Ctrl / ⌘ + Z takes back the last stroke.

Sign to accept the agreement.

Signed

Signed on 12 September 2026. The agreement is locked.

Without actions#

Undo and Clear are parts, not props: leave SignaturePadActions out and the pad is only a page, for an initial box or a flow that clears it some other way. With them in, they stay hidden until there is a stroke to take back. placeholder replaces the line under the empty page.

In a form#

With a name, the pad submits the drawing as a standalone SVG document, its ink in currentColor: store it, email it, or render it back. Sign, then submit, to see exactly what the form receives. signatureToSvg(strokes) builds the same document from a controlled value.

API reference#

SignaturePad

A <div role="group" tabIndex={-1}> framing the page, focused by the pen (the keyboard's tab stops are Undo and Clear). Props: value / defaultValue (string[], one SVG path per stroke), onValueChange (called when a stroke lands, and on undo and clear), name (submits the SVG), placeholder (default "Sign here"), hasError, disabled, plus every div prop. Its height is 160px; give it an h-* class for another. className is merged last.

SignaturePadActions · SignaturePadUndo · SignaturePadClear

The top-right corner and its two ghost Buttons. Undo takes back the last stroke, Clear wipes the page; both are disabled while the pad is empty and pass every Button prop through, so children relabels them.

signatureViewBox · signatureToSvg

signatureViewBox(strokes, padding?) returns the box around the ink as a viewBox string. signatureToSvg(strokes) returns the drawing as an SVG document, the value the pad submits.

FAQ#

An array of strings, one SVG path per pen stroke in the order it was written, each a smooth curve through the points the pen touched. It is small, it is plain text, and a Signature renders it as it is.