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-part
attribute 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>
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>
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 } 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')
}
</script>
<template>
<Field.Root>
<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>
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>
If you're using the
RootProvider
component, you don't need to use theRoot
component.
API Reference
Root
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
disabled | boolean Whether the signature pad is disabled. | |
drawing | '{ size: 2, simulatePressure: true }' | DrawingOptions The drawing options. |
ids | Partial<{
root: string
control: string
hiddenInput: string
label: string
}> The ids of the signature pad elements. Useful for composition. | |
name | string The name of the signature pad. Useful for form submission. | |
onDraw | (details: DrawDetails) => void Callback when the signature pad is drawing. | |
onDrawEnd | (details: DrawEndDetails) => void Callback when the signature pad is done drawing. | |
readOnly | boolean Whether the signature pad is read-only. | |
required | boolean Whether the signature pad is required. | |
translations | IntlTranslations The 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 | (props: ParentProps<'button'>) => Element Use 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 | (props: ParentProps<'div'>) => Element Use 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 | (props: ParentProps<'div'>) => Element Use 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 | (props: ParentProps<'input'>) => Element Use 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 | (props: ParentProps<'label'>) => Element Use 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 | (props: ParentProps<'div'>) => Element Use 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 | (props: ParentProps<'svg'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |