Signature Pad
A component that allows users to draw a signature using a signature pad.
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-partattribute to help identify them in the DOM.
Examples
Learn how to use the Signature Pad component in your project. Let's take a look at the most basic example:
import { SignaturePad } from '@ark-ui/react/signature-pad'
export const Basic = () => (
  <SignaturePad.Root>
    <SignaturePad.Label>Sign below</SignaturePad.Label>
    <SignaturePad.Control>
      <SignaturePad.Segment />
      <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
      <SignaturePad.Guide />
    </SignaturePad.Control>
  </SignaturePad.Root>
)
import { SignaturePad } from '@ark-ui/solid/signature-pad'
export const Basic = () => (
  <SignaturePad.Root>
    <SignaturePad.Label>Sign below</SignaturePad.Label>
    <SignaturePad.Control>
      <SignaturePad.Segment />
      <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
      <SignaturePad.Guide />
    </SignaturePad.Control>
  </SignaturePad.Root>
)
<script setup lang="ts">
import { SignaturePad } from '@ark-ui/vue/signature-pad'
</script>
<template>
  <SignaturePad.Root>
    <SignaturePad.Label>Sign below</SignaturePad.Label>
    <SignaturePad.Control>
      <SignaturePad.Segment />
      <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
      <SignaturePad.Guide />
    </SignaturePad.Control>
  </SignaturePad.Root>
</template>
<script>
  import { SignaturePad } from '@ark-ui/svelte/signature-pad'
</script>
<SignaturePad.Root>
  <SignaturePad.Label>Sign below</SignaturePad.Label>
  <SignaturePad.Control>
    <SignaturePad.Segment />
    <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
    <SignaturePad.Guide />
  </SignaturePad.Control>
</SignaturePad.Root>
Image Preview
After the user draws a signature, you can display a preview of the signature as an image. This is useful when you want to show the user a preview of the signature before saving it.
import { SignaturePad } from '@ark-ui/react/signature-pad'
import { useState } from 'react'
export const ImagePreview = () => {
  const [imageUrl, setImageUrl] = useState('')
  return (
    <>
      <SignaturePad.Root onDrawEnd={(details) => details.getDataUrl('image/png').then((url) => setImageUrl(url))}>
        <SignaturePad.Label>Sign below</SignaturePad.Label>
        <SignaturePad.Control>
          <SignaturePad.Segment fill="orange" />
          <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
          <SignaturePad.Guide />
        </SignaturePad.Control>
      </SignaturePad.Root>
      {imageUrl && <img src={imageUrl} alt="Signature" />}
    </>
  )
}
import { SignaturePad } from '@ark-ui/solid/signature-pad'
import { Show, createSignal } from 'solid-js'
export const ImagePreview = () => {
  const [imageUrl, setImageUrl] = createSignal<string>()
  return (
    <>
      <SignaturePad.Root onDrawEnd={(details) => details.getDataUrl('image/png').then((url) => setImageUrl(url))}>
        <SignaturePad.Label>Sign below</SignaturePad.Label>
        <SignaturePad.Control>
          <SignaturePad.Segment fill="orange" />
          <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
          <SignaturePad.Guide />
        </SignaturePad.Control>
      </SignaturePad.Root>
      <Show when={imageUrl()}>
        <img src={imageUrl()} alt="Signature" />
      </Show>
    </>
  )
}
<script setup lang="ts">
import { SignaturePad, type SignaturePadDrawEndDetails } from '@ark-ui/vue/signature-pad'
import { ref } from 'vue'
const imageUrl = ref<string | null>(null)
const handleDrawEnd = async (details: SignaturePadDrawEndDetails) => {
  imageUrl.value = await details.getDataUrl('image/png')
}
</script>
<template>
  <SignaturePad.Root @draw-end="handleDrawEnd">
    <SignaturePad.Label>Sign below</SignaturePad.Label>
    <SignaturePad.Control>
      <SignaturePad.Segment fill="orange" />
      <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
      <SignaturePad.Guide />
    </SignaturePad.Control>
  </SignaturePad.Root>
  <img v-if="imageUrl" :src="imageUrl" alt="Signature preview" />
</template>
<script>
  import { SignaturePad } from '@ark-ui/svelte/signature-pad'
  let imageUrl = $state('')
</script>
<SignaturePad.Root onDrawEnd={(details) => details.getDataUrl('image/png').then((url) => (imageUrl = url))}>
  <SignaturePad.Label>Sign below</SignaturePad.Label>
  <SignaturePad.Control>
    <SignaturePad.Segment fill="orange" />
    <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
    <SignaturePad.Guide />
  </SignaturePad.Control>
</SignaturePad.Root>
{#if imageUrl}
  <img src={imageUrl} alt="Signature" />
{/if}
Using the Field Component
The Field component helps manage form-related state and accessibility attributes of a signature pad. It includes
handling ARIA labels, helper text, and error text to ensure proper accessibility.
import { Field } from '@ark-ui/react/field'
import { SignaturePad } from '@ark-ui/react/signature-pad'
import { useState } from 'react'
export const WithField = (props: Field.RootProps) => {
  const [value, setValue] = useState('')
  return (
    <Field.Root {...props}>
      <SignaturePad.Root onDrawEnd={(details) => details.getDataUrl('image/png').then((url) => setValue(url))}>
        <SignaturePad.Label>Label</SignaturePad.Label>
        <SignaturePad.Control>
          <SignaturePad.Segment />
          <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
          <SignaturePad.Guide />
        </SignaturePad.Control>
        <SignaturePad.HiddenInput value={value} />
      </SignaturePad.Root>
      <Field.HelperText>Additional Info</Field.HelperText>
      <Field.ErrorText>Error Info</Field.ErrorText>
    </Field.Root>
  )
}
import { Field } from '@ark-ui/solid/field'
import { SignaturePad } from '@ark-ui/solid/signature-pad'
import { createSignal } from 'solid-js'
export const WithField = (props: Field.RootProps) => {
  const [value, setValue] = createSignal('')
  return (
    <Field.Root {...props}>
      <SignaturePad.Root onDrawEnd={(details) => details.getDataUrl('image/png').then((url) => setValue(url))}>
        <SignaturePad.Label>Label</SignaturePad.Label>
        <SignaturePad.Control>
          <SignaturePad.Segment />
          <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
          <SignaturePad.Guide />
        </SignaturePad.Control>
        <SignaturePad.HiddenInput value={value()} />
      </SignaturePad.Root>
      <Field.HelperText>Additional Info</Field.HelperText>
      <Field.ErrorText>Error Info</Field.ErrorText>
    </Field.Root>
  )
}
<script setup lang="ts">
import { Field, type FieldRootProps } from '@ark-ui/vue/field'
import { SignaturePad, type SignaturePadDrawEndDetails } from '@ark-ui/vue/signature-pad'
import { ref } from 'vue'
const imageUrl = ref('')
const handleDrawEnd = async (details: SignaturePadDrawEndDetails) => {
  imageUrl.value = await details.getDataUrl('image/png')
}
const props = defineProps<FieldRootProps>()
</script>
<template>
  <Field.Root v-bind="props">
    <SignaturePad.Root @draw-end="handleDrawEnd">
      <SignaturePad.Label>Label</SignaturePad.Label>
      <SignaturePad.Control>
        <SignaturePad.Segment />
        <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
        <SignaturePad.Guide />
      </SignaturePad.Control>
      <SignaturePad.HiddenInput :value="imageUrl" />
    </SignaturePad.Root>
    <Field.HelperText>Additional Info</Field.HelperText>
    <Field.ErrorText>Error Info</Field.ErrorText>
  </Field.Root>
</template>
<script>
  import { Field } from '@ark-ui/svelte/field'
  import { SignaturePad } from '@ark-ui/svelte/signature-pad'
  let value = $state('')
</script>
<Field.Root>
  <SignaturePad.Root onDrawEnd={(details) => details.getDataUrl('image/png').then((url) => (value = url))}>
    <SignaturePad.Label>Label</SignaturePad.Label>
    <SignaturePad.Control>
      <SignaturePad.Segment />
      <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
      <SignaturePad.Guide />
    </SignaturePad.Control>
    <SignaturePad.HiddenInput {value} />
  </SignaturePad.Root>
  <Field.HelperText>Additional Info</Field.HelperText>
  <Field.ErrorText>Error Info</Field.ErrorText>
</Field.Root>
Using the Root Provider
The RootProvider component provides a context for the signature-pad. It accepts the value of the useSignature-pad
hook. You can leverage it to access the component state and methods from outside the signature-pad.
import { SignaturePad, useSignaturePad } from '@ark-ui/react/signature-pad'
export const RootProvider = () => {
  const signaturePad = useSignaturePad()
  return (
    <>
      <button onClick={() => signaturePad.clear()}>Clear</button>
      <SignaturePad.RootProvider value={signaturePad}>
        <SignaturePad.Label>Sign below</SignaturePad.Label>
        <SignaturePad.Control>
          <SignaturePad.Segment />
          <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
          <SignaturePad.Guide />
        </SignaturePad.Control>
      </SignaturePad.RootProvider>
    </>
  )
}
import { SignaturePad, useSignaturePad } from '@ark-ui/solid/signature-pad'
export const RootProvider = () => {
  const signaturePad = useSignaturePad()
  return (
    <>
      <button onClick={() => signaturePad().clear()}>Clear</button>
      <SignaturePad.RootProvider value={signaturePad}>
        <SignaturePad.Label>Sign below</SignaturePad.Label>
        <SignaturePad.Control>
          <SignaturePad.Segment />
          <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
          <SignaturePad.Guide />
        </SignaturePad.Control>
      </SignaturePad.RootProvider>
    </>
  )
}
<script setup lang="ts">
import { SignaturePad, useSignaturePad } from '@ark-ui/vue/signature-pad'
const signaturePad = useSignaturePad()
</script>
<template>
  <button @click="signaturePad.clear()">Clear</button>
  <SignaturePad.RootProvider :value="signaturePad">
    <SignaturePad.Label>Sign below</SignaturePad.Label>
    <SignaturePad.Control>
      <SignaturePad.Segment />
      <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
      <SignaturePad.Guide />
    </SignaturePad.Control>
  </SignaturePad.RootProvider>
</template>
<script>
  import { SignaturePad, useSignaturePad } from '@ark-ui/svelte/signature-pad'
  const id = $props.id()
  const signaturePad = useSignaturePad({ id })
</script>
<SignaturePad.RootProvider value={signaturePad}>
  <SignaturePad.Label>Sign below</SignaturePad.Label>
  <SignaturePad.Control>
    <SignaturePad.Segment />
    <SignaturePad.ClearTrigger>Clear</SignaturePad.ClearTrigger>
    <SignaturePad.Guide />
  </SignaturePad.Control>
</SignaturePad.RootProvider>
If you're using the
RootProvidercomponent, you don't need to use theRootcomponent.
API Reference
Root
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | |
| defaultPaths | string[]The default paths of the signature pad. Use when you don't need to control the paths of the signature pad. | |
| disabled | booleanWhether the signature pad is disabled. | |
| drawing | '{ size: 2, simulatePressure: true }' | DrawingOptionsThe drawing options. | 
| ids | Partial<{ root: string; control: string; hiddenInput: string; label: string }>The ids of the signature pad elements. Useful for composition. | |
| name | stringThe name of the signature pad. Useful for form submission. | |
| onDraw | (details: DrawDetails) => voidCallback when the signature pad is drawing. | |
| onDrawEnd | (details: DrawEndDetails) => voidCallback when the signature pad is done drawing. | |
| paths | string[]The controlled paths of the signature pad. | |
| readOnly | booleanWhether the signature pad is read-only. | |
| required | booleanWhether the signature pad is required. | |
| translations | IntlTranslationsThe translations of the signature pad. Useful for internationalization. | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | signature-pad | 
| [data-part] | root | 
| [data-disabled] | Present when disabled | 
ClearTrigger
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
Control
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | signature-pad | 
| [data-part] | control | 
| [data-disabled] | Present when disabled | 
Guide
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | signature-pad | 
| [data-part] | guide | 
| [data-disabled] | Present when disabled | 
HiddenInput
| Prop | Default | Type | 
|---|---|---|
| value | string | |
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
Label
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | signature-pad | 
| [data-part] | label | 
| [data-disabled] | Present when disabled | 
RootProvider
| Prop | Default | Type | 
|---|---|---|
| value | UseSignaturePadReturn | |
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
Segment
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. |