Signature Pad
Headless signature pad: pointer-captured, pressure-aware strokes rendered as SVG.
|
|
| Package |
@vizejs/ui/signature-pad |
| Maturity |
stable |
| Own the source |
vize lib pull signature-pad |
| Requires |
context, controllable-state, id |
| Aliases |
signature pad, signature, e-signature, drawing pad, sign here |
| Covers |
signature_pad, perfect-freehand, Pointer Events getCoalescedEvents, Mantine Signature examples |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/ui
Add the public import below to <script setup lang="ts">. Components provide behavior without styles; the preview uses optional Paper styles.
import { SignaturePadCanvas, SignaturePadClear, SignaturePadGuide, SignaturePadRedo, SignaturePad, SignaturePadRoot, SignaturePadUndo } from "@vizejs/ui/signature-pad";
Or copy the source into your project with vize lib pull signature-pad (see Source Distribution).
Try it
This is the basic example maintained with the component source, using the public package imports. The preview adds the optional Paper styles.
Open the interactive example · Styling these components
Copy the example
<!-- Signature pad bound with v-model, with a sign-here guide and undo, redo, and clear buttons. -->
<script setup lang="ts">
import { ref } from "vue";
import {
SignaturePad,
SignaturePadCanvas,
SignaturePadClear,
SignaturePadGuide,
SignaturePadRedo,
SignaturePadUndo,
type SignatureValue,
} from "@vizejs/ui/signature-pad";
const signature = ref<SignatureValue>([]);
</script>
<template>
<SignaturePad v-slot="{ empty }" v-model="signature" name="signature" :width="400" :height="160">
<SignaturePadCanvas aria-label="Your signature" />
<SignaturePadGuide>Sign above the line</SignaturePadGuide>
<SignaturePadUndo>Undo</SignaturePadUndo>
<SignaturePadRedo>Redo</SignaturePadRedo>
<SignaturePadClear>Clear</SignaturePadClear>
<p>{{ empty ? "Not signed yet" : "Signed" }}</p>
</SignaturePad>
</template>
API
SignaturePadCanvas
Source: src/families/media/signature-pad/signature-pad-canvas.vue
Props
| Prop |
Type |
Default |
Description |
ariaLabel |
string |
"Signature" |
Accessible name of the drawing surface. Localize by passing your own text. |
ariaDescribedby |
string |
undefined |
Ids of instructions, e.g. a note offering a typed-name alternative. |
Slots
| Slot |
Slot props |
Description |
default |
SignaturePadSlotState |
Extra SVG content drawn above the strokes, e.g. a baseline. Receives the pad state. |
Exposed
| Member |
Type |
Description |
element |
SVGSVGElement | null |
Rendered drawing surface. |
drawing |
boolean |
Whether a stroke is in progress. |
SignaturePadClear
Source: src/families/media/signature-pad/signature-pad-clear.vue
Events
| Event |
Payload |
Description |
click |
[nativeEvent: MouseEvent] |
Fired before clearing. Call preventDefault() to keep the strokes. |
Slots
| Slot |
Slot props |
Description |
default |
SignaturePadSlotState |
Button label. Receives the pad state. |
Exposed
| Member |
Type |
Description |
disabled |
— |
|
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
SignaturePadGuide
Source: src/families/media/signature-pad/signature-pad-guide.vue
Slots
| Slot |
Slot props |
Description |
default |
SignaturePadSlotState |
Decorative guide content such as a baseline or "Sign here" hint. |
Exposed
| Member |
Type |
Description |
element |
HTMLDivElement | null |
Rendered guide element. |
SignaturePadRedo
Source: src/families/media/signature-pad/signature-pad-redo.vue
Events
| Event |
Payload |
Description |
click |
[nativeEvent: MouseEvent] |
Fired before redoing. Call preventDefault() to keep the strokes. |
Slots
| Slot |
Slot props |
Description |
default |
SignaturePadSlotState |
Button label. Receives the pad state. |
Exposed
| Member |
Type |
Description |
disabled |
— |
|
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
SignaturePad
Source: src/families/media/signature-pad/signature-pad-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id. null and undefined select a deterministic fallback. |
modelValue |
SignatureValue |
undefined |
Controlled strokes. undefined selects uncontrolled behavior. |
defaultValue |
SignatureValue |
[] |
Initial strokes for uncontrolled use. |
disabled |
boolean |
false |
Suppress drawing and every editing control. |
readOnly |
boolean |
false |
Show the signature while suppressing drawing and editing. |
name |
string |
undefined |
Form field name. When set, a hidden input submits the serialized signature. |
form |
string |
undefined |
Id of the form that owns the hidden input. |
valueFormat |
SignaturePadValueFormat |
"json" |
Serialization written to the hidden input. |
width |
number |
400 |
Drawing-surface width in viewBox units; stroke coordinates use this space. |
height |
number |
200 |
Drawing-surface height in viewBox units. |
size |
number |
3 |
Stroke diameter at full pressure, in viewBox units. |
thinning |
number |
0.6 |
How strongly pressure thins the stroke, from 0 to 1. |
smoothing |
number |
0.5 |
Curve smoothing between samples, from 0 (polyline) to 1. |
pressure |
SignaturePadPressureMode |
"auto" |
Pressure source: pen pressure with simulated pressure for mouse and touch (auto), raw pointer pressure, or always simulated from velocity. |
historyLimit |
number |
100 |
Maximum undo steps kept. |
Events
| Event |
Payload |
Description |
update:modelValue |
[value: SignatureValue] |
Fired when the strokes request a new controlled value. |
change |
[value: SignatureValue, previous: SignatureValue, reason: SignaturePadChangeReason] |
Fired after every distinct value request, with its cause. |
strokeStart |
[point: SignaturePoint] |
Fired when a pointer starts a stroke. |
strokeEnd |
[stroke: SignatureStroke] |
Fired when a stroke is committed. |
Slots
| Slot |
Slot props |
Description |
default |
SignaturePadSlotState |
Canvas, guide, and controls. Receives the signature state. |
Exposed
| Member |
Type |
Description |
canRedo |
— |
|
canUndo |
— |
|
clear |
— |
|
disabled |
— |
|
drawing |
— |
|
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
empty |
— |
|
readOnly |
— |
|
redo |
— |
|
setValue |
— |
|
state |
— |
|
toDataUrl |
— |
|
toSvg |
— |
|
undo |
— |
|
value |
— |
|
SignaturePadRoot
Source: src/families/media/signature-pad/signature-pad-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id. null and undefined select a deterministic fallback. |
modelValue |
SignatureValue |
undefined |
Controlled strokes. undefined selects uncontrolled behavior. |
defaultValue |
SignatureValue |
[] |
Initial strokes for uncontrolled use. |
disabled |
boolean |
false |
Suppress drawing and every editing control. |
readOnly |
boolean |
false |
Show the signature while suppressing drawing and editing. |
name |
string |
undefined |
Form field name. When set, a hidden input submits the serialized signature. |
form |
string |
undefined |
Id of the form that owns the hidden input. |
valueFormat |
SignaturePadValueFormat |
"json" |
Serialization written to the hidden input. |
width |
number |
400 |
Drawing-surface width in viewBox units; stroke coordinates use this space. |
height |
number |
200 |
Drawing-surface height in viewBox units. |
size |
number |
3 |
Stroke diameter at full pressure, in viewBox units. |
thinning |
number |
0.6 |
How strongly pressure thins the stroke, from 0 to 1. |
smoothing |
number |
0.5 |
Curve smoothing between samples, from 0 (polyline) to 1. |
pressure |
SignaturePadPressureMode |
"auto" |
Pressure source: pen pressure with simulated pressure for mouse and touch (auto), raw pointer pressure, or always simulated from velocity. |
historyLimit |
number |
100 |
Maximum undo steps kept. |
Events
| Event |
Payload |
Description |
update:modelValue |
[value: SignatureValue] |
Fired when the strokes request a new controlled value. |
change |
[value: SignatureValue, previous: SignatureValue, reason: SignaturePadChangeReason] |
Fired after every distinct value request, with its cause. |
strokeStart |
[point: SignaturePoint] |
Fired when a pointer starts a stroke. |
strokeEnd |
[stroke: SignatureStroke] |
Fired when a stroke is committed. |
Slots
| Slot |
Slot props |
Description |
default |
SignaturePadSlotState |
Canvas, guide, and controls. Receives the signature state. |
Exposed
| Member |
Type |
Description |
value |
SignatureValue |
Current strokes. |
empty |
boolean |
Whether no stroke has been drawn. |
drawing |
boolean |
Whether a stroke is in progress. |
disabled |
boolean |
Whether drawing and editing are suppressed. |
readOnly |
boolean |
Whether the value is shown but cannot change. |
canUndo |
boolean |
Whether an undo step is available. |
canRedo |
boolean |
Whether a redo step is available. |
state |
SignaturePadState |
Stable state token for styling and tests. |
element |
HTMLDivElement | null |
Rendered root element. |
clear |
() => boolean |
Remove every stroke. Reports whether the value changed. |
undo |
() => boolean |
Restore the previous value. Reports whether a step was undone. |
redo |
() => boolean |
Re-apply the last undone value. Reports whether a step was redone. |
setValue |
(value: SignatureValue) => boolean |
Replace the value. Reports whether it changed. |
toSvg |
(options?: Partial<SignatureSvgOptions>) => string |
Serialize the current value as standalone SVG markup. |
toDataUrl |
(options?: Partial<SignatureDataUrlOptions>) => Promise<string> |
Export the current value as a data URL (client-only for raster types). |
SignaturePadUndo
Source: src/families/media/signature-pad/signature-pad-undo.vue
Events
| Event |
Payload |
Description |
click |
[nativeEvent: MouseEvent] |
Fired before undoing. Call preventDefault() to keep the strokes. |
Slots
| Slot |
Slot props |
Description |
default |
SignaturePadSlotState |
Button label. Receives the pad state. |
Exposed
| Member |
Type |
Description |
disabled |
— |
|
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
Behavior
Normative state x input -> outcome table for signature-pad-root.vue,
signature-pad-canvas.vue, signature-pad-guide.vue, signature-pad-undo.vue,
signature-pad-redo.vue, and signature-pad-clear.vue (@vizejs/ui/signature-pad).
Every row is proven by the named test.
Strokes are typed data ({ points: { x, y, pressure, time }[] }[]) in the
drawing surface's viewBox coordinates, rendered as filled SVG outlines whose
width follows pressure. The surface is not keyboard drawable; name it with
ariaLabel, describe it with ariaDescribedby, and offer a typed-name field as
the accessible alternative when a signature is required.
| ID |
State |
Input |
Outcome |
Evidence |
| SP1 |
empty |
render |
root carries data-state="empty"; the <svg role="img"> has a label, description, viewBox, and client-side touch-action: none; controls are disabled |
renders an accessible SVG surface with empty state hooks |
| SP2 |
idle |
pointerdown / move / up |
client coordinates map to viewBox units, a live stroke renders while drawing, and pointerup commits with strokeStart, strokeEnd, change |
pointer strokes map to viewBox coordinates and commit on pointerup |
| SP3 |
drawing |
pen / coalesced events / pressure modes |
auto keeps pen pressure and simulates mouse/touch pressure; coalesced samples are appended; pointer and simulate force a source |
pen pressure, coalesced samples, and pressure modes shape the points |
| SP4 |
drawing |
secondary button / other pointer / cancel |
secondary buttons and foreign pointers are ignored; pointercancel discards the live stroke without a change |
ignores secondary buttons, foreign pointers, and cancelled strokes |
| SP5 |
filled |
Undo / Redo / Clear |
history restores and re-applies values, clear is undoable, new strokes drop the redo branch, and preventDefault() keeps state |
undo, redo, and clear walk history and honor preventDefault |
| SP6 |
history |
historyLimit |
only the configured number of undo steps is kept; 0 disables history |
history honors the configured limit |
| SP7 |
disabled/read-only |
draw / edit |
no stroke starts and every edit action reports false; state hooks reflect the mode |
disabled and read-only pads never draw or edit |
| SP8 |
controlled |
draw |
the request is emitted while the controlled value renders until the parent accepts it |
controlled strokes win until the parent accepts the request |
| SP9 |
name |
change / format / disabled |
a hidden input submits compact JSON or SVG (valueFormat), "" when empty, and is disabled with the pad |
submits the serialized value through a hidden input |
| SP10 |
exposed instance |
read / setValue / export |
exposes state, history, setValue, toSvg, and toDataUrl |
exposes typed state, history controls, and exports |
| SP11 |
missing provider |
setup |
compound parts fail closed with the shared context diagnostic |
compound parts require a matching root provider |
| SP12 |
pure helpers |
empty check |
isSignatureEmpty ignores strokes without points |
detects empty signatures |
| SP13 |
pure helpers |
velocity |
simulated pressure thickens slow and thins fast movement with easing |
simulates pressure from velocity with easing |
| SP14 |
pure helpers |
one sample / none |
single samples render dots; empty strokes and zero size render nothing; near-duplicates collapse |
renders single samples as dots and empty strokes as nothing |
| SP15 |
pure helpers |
outline |
half-width follows size, thinning, and pressure; edges smooth with smoothing; ends use round caps |
outlines strokes with pressure-dependent width, smoothing, and round caps |
| SP16 |
pure helpers |
SVG export |
standalone markup escapes attributes and adds an optional background |
serializes standalone SVG with escaped attributes and optional background |
| SP17 |
pure helpers |
data URL without canvas |
SVG data URLs need no canvas; raster export rejects with VIZE_UI_SIGNATURE_PAD_CANVAS_UNAVAILABLE |
exports SVG data URLs without a canvas and rejects raster export without one |
| SP18 |
pure helpers |
raster export |
raster output scales the canvas, fills the background, and fills each stroke through Path2D |
draws raster exports through Path2D on a scaled canvas |
| SP19 |
pure helpers |
JSON |
serialization rounds samples; parsing round-trips, clamps pressure, freezes, and rejects malformed input with a typed error |
round-trips compact JSON and serializes SVG for forms |
| SP20 |
SSR |
isolated requests |
markup, including stroke paths and the hidden input, is byte-identical and carries no inline style |
renders byte-identical signature markup across isolated SSR requests |
| SP21 |
SSR / hydration |
hydrate |
server markup hydrates without warnings or node replacement, then enables touch drawing |
hydrates signature markup without warnings or node replacement |
| SP22 |
types |
compile |
points, values, states, formats, reasons, and exposes are closed and read-only |
signature-pad.types.test-d.ts |
Undo and redo history record requests; in controlled mode the parent decides
whether each request is applied.