Skip to main content

A signature pad lets users draw handwritten signatures with pointer or touch input.

Loading...

Features

  • Draw signatures using touch or pointer input
  • Export signatures as data URLs
  • Clear signatures programmatically

Installation

Install the signature pad package:

npm install @zag-js/signature-pad @zag-js/react # or yarn add @zag-js/signature-pad @zag-js/react

Anatomy

To set up the signature pad correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

Usage

Import the signature pad package:

import * as signaturePad from "@zag-js/signature-pad"

The signature pad package exports two key functions:

  • machine - State machine logic.
  • connect - Maps machine state to JSX props and event handlers.

Then use the framework integration helpers:

import { normalizeProps, useMachine } from "@zag-js/react" import * as signaturePad from "@zag-js/signature-pad" import { useId, useState } from "react" export function SignaturePad() { const service = useMachine(signaturePad.machine, { id: useId(), }) const api = signaturePad.connect(service, normalizeProps) return ( <div {...api.getRootProps()}> <label {...api.getLabelProps()}>Signature Pad</label> <div {...api.getControlProps()}> <svg {...api.getSegmentProps()}> {api.paths.map((path, i) => ( <path key={i} {...api.getSegmentPathProps({ path })} /> ))} {api.currentPath && ( <path {...api.getSegmentPathProps({ path: api.currentPath })} /> )} </svg> <button {...api.getClearTriggerProps()}>X</button> <div {...api.getGuideProps()} /> </div> </div> ) }

Listening to drawing events

The signature pad component emits the following events:

  • onDraw: Emitted when the user is drawing the signature.
  • onDrawEnd: Emitted when the user stops drawing the signature.
const service = useMachine(signaturePad.machine, { onDraw(details) { // details => { paths: string[] } console.log("Drawing signature", details) }, onDrawEnd(details) { // details => { paths: string[], getDataUrl: (type, quality?) => Promise<string> } console.log("Signature drawn", details) }, })

Clearing the signature

To clear the signature, use the api.clear(), or render the clear trigger button.

<button onClick={() => api.clear()}>Clear</button>

Rendering an image preview

Use the api.getDataUrl() method to get the signature as a data URL and render it as an image.

You can also leverage the onDrawEnd event to get the signature data URL.

const service = useMachine(signaturePad.machine, { onDrawEnd(details) { details.getDataUrl("image/png").then((url) => { // set the image URL in local state setImageURL(url) }) }, })

Next, render the image preview using the URL.

<img src={imageURL} alt="Signature" />

Controlled signature paths

Use paths and onDraw for controlled usage.

const service = useMachine(signaturePad.machine, { paths, onDraw(details) { setPaths(details.paths) }, })

Changing the stroke color

To change the stroke color, set the drawing.fill option to a valid CSS color.

Note: You can't use a css variable as the stroke color.

const service = useMachine(signaturePad.machine, { drawing: { fill: "red", }, })

Changing the stroke width

To change the stroke width, set the drawing.size option to a number.

const service = useMachine(signaturePad.machine, { drawing: { size: 5, }, })

Controlling pressure simulation

Pressure simulation is enabled by default. Set drawing.simulatePressure to false to use raw pointer pressure values.

const service = useMachine(signaturePad.machine, { drawing: { simulatePressure: false, }, })

Usage in forms

To use the signature pad in a form, set the name context property.

const service = useMachine(signaturePad.machine, { name: "signature", })

Then, render the hidden input element using api.getHiddenInputProps().

<input {...api.getHiddenInputProps({ value: imageURL })} />

Customizing screen reader text

Use translations to customize accessible text for the drawing control and clear trigger.

const service = useMachine(signaturePad.machine, { translations: { control: "Signature drawing area", clearTrigger: "Clear signature", }, })

Methods and Properties

The signature pad api exposes the following methods and properties:

Machine Context

The signature pad machine exposes the following context properties:

  • idsPartial<{ root: string; control: string; hiddenInput: string; label: string; }>The ids of the signature pad elements. Useful for composition.
  • translationsIntlTranslationsThe translations of the signature pad. Useful for internationalization.
  • onDraw(details: DrawDetails) => voidCallback when the signature pad is drawing.
  • onDrawEnd(details: DrawEndDetails) => voidCallback when the signature pad is done drawing.
  • drawingDrawingOptionsThe drawing options.
  • disabledbooleanWhether the signature pad is disabled.
  • requiredbooleanWhether the signature pad is required.
  • readOnlybooleanWhether the signature pad is read-only.
  • namestringThe name of the signature pad. Useful for form submission.
  • defaultPathsstring[]The default paths of the signature pad. Use when you don't need to control the paths of the signature pad.
  • pathsstring[]The controlled paths of the signature pad.
  • dir"ltr" | "rtl"The document's text/writing direction.
  • idstringThe unique identifier of the machine.
  • getRootNode() => ShadowRoot | Node | DocumentA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

Machine API

The signature pad api exposes the following methods:

  • emptybooleanWhether the signature pad is empty.
  • drawingbooleanWhether the user is currently drawing.
  • currentPathstringThe current path being drawn.
  • pathsstring[]The paths of the signature pad.
  • getDataUrl(type: DataUrlType, quality?: number) => Promise<string>Returns the data URL of the signature pad.
  • clearVoidFunctionClears the signature pad.

Data Attributes

Label
data-scope
signature-pad
data-part
label
data-disabled
Present when disabled
data-required
Present when required
Root
data-scope
signature-pad
data-part
root
data-disabled
Present when disabled
Control
data-scope
signature-pad
data-part
control
data-disabled
Present when disabled
Guide
data-scope
signature-pad
data-part
guide
data-disabled
Present when disabled
Edit this page on GitHub