SignaturePad
Freehand pad that captures a handwritten signature as SVG paths, with clear button, guide line and data URL export.
Component
Props
| Props | Default | Type |
|---|---|---|
ariaLabel | 'Signature pad' | string |
ariaLabelledby | — | string |
modelValue | [] | string[] |
name | — | string |
height | 200 | number |
minWidth | 240 | number |
strokeSize | 2 | number |
showGuide | true | boolean |
placeholder | 'Sign here' | string |
showClearButton | true | boolean |
clearIcon | 'mdi:eraser' | string |
clearAriaLabel | 'Clear signature' | string |
hasError | false | boolean |
disabled | false | boolean |
readOnly | false | boolean |
All props are optional. There is no required prop; bind v-model to keep the strokes in your own state.
Usage
ariaLabel
Accessible label of the drawing surface.
<template>
<SignaturePad ariaLabel="Customer signature" />
</template>
ariaLabelledby
Id of the element that labels the drawing surface. Takes precedence over ariaLabel.
<template>
<SignaturePad ariaLabelledby="signature-title" />
</template>
modelValue
Strokes drawn on the pad. Each item is an SVG path (d attribute) in pixels relative to the pad. Assign a previous value to restore a signature.
<template>
<SignaturePad v-model="paths" />
</template>
<script setup lang="ts">
const paths = ref<string[]>([])
</script>
name
Renders a hidden input with this name whose value is the JSON-serialized modelValue, so the pad takes part in native form submissions.
<template>
<SignaturePad name="signature" />
</template>
height
Sets the height of the pad in pixels. The pad always fills the width of its container.
<template>
<SignaturePad :height="280" />
</template>
minWidth
Sets the minimum width of the pad in pixels. Below this width the pad stops shrinking, so the container can scroll instead of squeezing the signature area.
<template>
<SignaturePad :minWidth="320" />
</template>
strokeSize
Sets the stroke width in pixels.
<template>
<SignaturePad :strokeSize="4" />
</template>
showGuide
Shows the dashed baseline to sign on.
<template>
<SignaturePad :showGuide="false" />
</template>
placeholder
Text shown over the guide while the pad is empty. It requires showGuide.
<template>
<SignaturePad placeholder="Sign inside the box" />
</template>
showClearButton
Shows the icon button that removes all strokes. It only appears once something has been drawn.
<template>
<SignaturePad :showClearButton="false" />
</template>
clearIcon
Sets the icon of the clear button.
<template>
<SignaturePad :clearIcon="'mdi:close'" />
</template>
clearAriaLabel
Sets the accessible label (aria-label) of the clear icon button.
<template>
<SignaturePad clearAriaLabel="Reset signature" />
</template>
hasError
Applies the error border. SignatureField sets it from its error prop.
<template>
<SignaturePad hasError />
</template>
disabled
Disables drawing and the clear button.
<template>
<SignaturePad disabled />
</template>
readOnly
Shows the strokes but prevents drawing or clearing.
<template>
<SignaturePad readOnly :modelValue="savedPaths" />
</template>
Accessibility
The drawing surface is exposed as role="img" with ariaLabel (or ariaLabelledby), and reflects aria-disabled and aria-readonly. Drawing needs a pointer (mouse, touch or pen), so provide an alternative way to confirm identity, such as a typed name, when keyboard-only users must sign.
Emits
| Value | Description |
|---|---|
@update:modelValue | Emitted with the full list of strokes when a stroke ends or the pad is cleared (v-model). |
@draw | Emitted while drawing with `{ paths, currentPath }`, where `currentPath` is the stroke in progress. |
@draw-end | Emitted with `{ paths }` when the user finishes a stroke. |
@clear | Emitted when the pad is cleared. |
Example
<template>
<SignaturePad v-model="paths" @draw-end="({ paths }) => console.log(paths.length)" />
</template>
<script setup lang="ts">
const paths = ref<string[]>([])
</script>
Methods
| Value | Description |
|---|---|
clear() | Removes all strokes. |
getDataUrl(type?, quality?) | Renders the strokes to a canvas and returns a data URL. `type` defaults to `'image/png'`. |
<template>
<SignaturePad ref="padRef" v-model="paths" />
<ActionButton text="Export" @click="exportImage" />
</template>
<script setup lang="ts">
const padRef = ref()
const paths = ref<string[]>([])
const exportImage = () => {
const dataUrl = padRef.value.getDataUrl('image/png')
console.log(dataUrl)
}
</script>