Skip to content
UI

Signature

A component that allows users to draw a signature using mouse or touch input.

<script setup lang="ts">
import { Signature } from '@destyler-ui/vue'
</script>

<template>
  <Signature.Root>
    <Signature.Label>Sign below</Signature.Label>
    <Signature.Control>
      <Signature.Segment />
      <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
      <Signature.Guide />
    </Signature.Control>
  </Signature.Root>
</template>
import { Signature } from '@destyler-ui/react'

export function Basic() {
  return (
    <Signature.Root>
      <Signature.Label>Sign below</Signature.Label>
      <Signature.Control>
        <Signature.Segment />
        <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
        <Signature.Guide />
      </Signature.Control>
    </Signature.Root>
  )
}
import { Signature } from '@destyler-ui/solid/signature'

export function Basic() {
  return (
    <Signature.Root>
      <Signature.Label>Sign below</Signature.Label>
      <Signature.Control>
        <Signature.Segment />
        <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
        <Signature.Guide />
      </Signature.Control>
    </Signature.Root>
  )
}
<script lang="ts">
  import { Signature } from '@destyler-ui/svelte'
</script>

<Signature.Root>
  <Signature.Label>Sign below</Signature.Label>
  <Signature.Control>
    <Signature.Segment />
    <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
    <Signature.Guide />
  </Signature.Control>
</Signature.Root>
<script setup lang="ts">
import { Signature } from '@destyler-ui/vue'
</script>
<template>
<Signature.Root>
<Signature.Label />
<Signature.Control>
<Signature.Segment />
<Signature.Guide />
</Signature.Control>
<Signature.ClearTrigger />
<Signature.HiddenInput />
</Signature.Root>
</template>
import { Signature } from '@destyler-ui/react'
export default function Basic() {
return (
<Signature.Root>
<Signature.Label />
<Signature.Control>
<Signature.Segment />
<Signature.Guide />
</Signature.Control>
<Signature.ClearTrigger />
<Signature.HiddenInput />
</Signature.Root>
)
}
import { Signature } from '@destyler-ui/solid'
import { createSignal } from 'solid-js'
export default function Basic() {
const [value, setValue] = createSignal('')
return (
<Signature.Root
onDrawEnd={(details) => {
if (details.paths.length === 0) {
setValue('')
return
}
void details.getDataUrl('image/png').then(setValue)
}}
>
<Signature.Label />
<Signature.Control>
<Signature.Segment />
<Signature.Guide />
</Signature.Control>
<Signature.ClearTrigger />
<Signature.HiddenInput value={value()} />
</Signature.Root>
)
}
<script lang="ts">
import { Signature } from '@destyler-ui/svelte'
</script>
<Signature.Root>
<Signature.Label>Sign below</Signature.Label>
<Signature.Control>
<Signature.Segment />
<Signature.ClearTrigger>Clear</Signature.ClearTrigger>
<Signature.Guide />
</Signature.Control>
</Signature.Root>
<script setup lang="ts">
import { Signature } from '@destyler-ui/vue'
</script>

<template>
  <Signature.Root>
    <Signature.Label>Sign below</Signature.Label>
    <Signature.Control>
      <Signature.Segment />
      <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
      <Signature.Guide />
    </Signature.Control>
  </Signature.Root>
</template>
import { Signature } from '@destyler-ui/react'

export function Basic() {
  return (
    <Signature.Root>
      <Signature.Label>Sign below</Signature.Label>
      <Signature.Control>
        <Signature.Segment />
        <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
        <Signature.Guide />
      </Signature.Control>
    </Signature.Root>
  )
}
import { Signature } from '@destyler-ui/solid/signature'

export function Basic() {
  return (
    <Signature.Root>
      <Signature.Label>Sign below</Signature.Label>
      <Signature.Control>
        <Signature.Segment />
        <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
        <Signature.Guide />
      </Signature.Control>
    </Signature.Root>
  )
}
<script lang="ts">
  import { Signature } from '@destyler-ui/svelte'
</script>

<Signature.Root>
  <Signature.Label>Sign below</Signature.Label>
  <Signature.Control>
    <Signature.Segment />
    <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
    <Signature.Guide />
  </Signature.Control>
</Signature.Root>

Preview the signature as an image.

<script setup lang="ts">
import { Signature } from '@destyler-ui/vue'
import { ref } from 'vue'

const imageUrl = ref<string | null>(null)

const handleDrawEnd = async (details: Signature.DrawEndDetails) => {
  imageUrl.value = await details.getDataUrl('image/png')
}
</script>

<template>
  <Signature.Root @draw-end="handleDrawEnd">
    <Signature.Label>Sign below</Signature.Label>
    <Signature.Control>
      <Signature.Segment fill="orange" />
      <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
      <Signature.Guide />
    </Signature.Control>
  </Signature.Root>
  <img v-if="imageUrl" :src="imageUrl" alt="Signature preview" />
</template>
'use client'

import type { DrawEndDetails } from '@destyler-ui/react'
import { useState } from 'react'
import { Signature } from '@destyler-ui/react'

export function ImagePreview() {
  const [imageUrl, setImageUrl] = useState<string | null>(null)

  const handleDrawEnd = async (details: DrawEndDetails) => {
    setImageUrl(await details.getDataUrl('image/png'))
  }

  return (
    <>
      <Signature.Root onDrawEnd={handleDrawEnd}>
        <Signature.Label>Sign below</Signature.Label>
        <Signature.Control>
          <Signature.Segment fill="orange" />
          <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
          <Signature.Guide />
        </Signature.Control>
      </Signature.Root>
      {imageUrl && <img src={imageUrl} alt="Signature preview" />}
    </>
  )
}
import { Signature } from '@destyler-ui/solid/signature'
import { createSignal, Show } from 'solid-js'

export function ImagePreview() {
  const [imageUrl, setImageUrl] = createSignal<string>()

  return (
    <>
      <Signature.Root
        onDrawEnd={details => details.getDataUrl('image/png').then(url => setImageUrl(url))}
      >
        <Signature.Label>Sign below</Signature.Label>
        <Signature.Control>
          <Signature.Segment fill="orange" />
          <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
          <Signature.Guide />
        </Signature.Control>
      </Signature.Root>
      <Show when={imageUrl()}>
        <img src={imageUrl()} alt="Signature" />
      </Show>
    </>
  )
}
<script lang="ts">
  import type { DrawEndDetails } from '@destyler-ui/svelte'
  import { Signature } from '@destyler-ui/svelte'

  let imageUrl = $state<string | null>(null)

  async function handleDrawEnd(details: DrawEndDetails) {
    imageUrl = await details.getDataUrl('image/png')
  }
</script>

<Signature.Root onDrawEnd={handleDrawEnd}>
  <Signature.Label>Sign below</Signature.Label>
  <Signature.Control>
    <Signature.Segment fill="orange" />
    <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
    <Signature.Guide />
  </Signature.Control>
</Signature.Root>

{#if imageUrl}
  <img src={imageUrl} alt="Signature preview" />
{/if}

Combine with a form field for validation and labeling.

<script setup lang="ts">
import { Field } from '@destyler-ui/vue'
import { Signature } from '@destyler-ui/vue'
import { ref } from 'vue'

interface Props {
  disabled?: boolean
  invalid?: boolean
  readOnly?: boolean
  required?: boolean
}

defineProps<Props>()

const imageUrl = ref('')

const handleDrawEnd = async (details: Signature.DrawEndDetails) => {
  imageUrl.value = await details.getDataUrl('image/png')
}
</script>

<template>
  <Field.Root :disabled="disabled" :invalid="invalid" :read-only="readOnly" :required="required">
    <Signature.Root @draw-end="handleDrawEnd">
      <Signature.Label>Label</Signature.Label>
      <Signature.Control>
        <Signature.Segment />
        <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
        <Signature.Guide />
      </Signature.Control>
      <Signature.HiddenInput :value="imageUrl" />
    </Signature.Root>
    <Field.HelperText>Additional Info</Field.HelperText>
    <Field.ErrorText>Error Info</Field.ErrorText>
  </Field.Root>
</template>
'use client'

import type { DrawEndDetails } from '@destyler-ui/react'
import { useState } from 'react'
import { Field } from '@destyler-ui/react'
import { Signature } from '@destyler-ui/react'

export function WithField(props: Field.RootProps) {
  const [imageUrl, setImageUrl] = useState('')

  const handleDrawEnd = async (details: DrawEndDetails) => {
    setImageUrl(await details.getDataUrl('image/png'))
  }

  return (
    <Field.Root {...props}>
      <Signature.Root onDrawEnd={handleDrawEnd}>
        <Signature.Label>Label</Signature.Label>
        <Signature.Control>
          <Signature.Segment />
          <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
          <Signature.Guide />
        </Signature.Control>
        <Signature.HiddenInput value={imageUrl} />
      </Signature.Root>
      <Field.HelperText>Additional Info</Field.HelperText>
      <Field.ErrorText>Error Info</Field.ErrorText>
    </Field.Root>
  )
}
import { Field } from '@destyler-ui/solid/field'
import { Signature } from '@destyler-ui/solid/signature'
import { createSignal } from 'solid-js'

export function WithField(props: Field.RootProps) {
  const [value, setValue] = createSignal('')

  return (
    <Field.Root {...props}>
      <Signature.Root
        onDrawEnd={details => details.getDataUrl('image/png').then(url => setValue(url))}
      >
        <Signature.Label>Label</Signature.Label>
        <Signature.Control>
          <Signature.Segment />
          <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
          <Signature.Guide />
        </Signature.Control>
        <Signature.HiddenInput value={value()} />
      </Signature.Root>
      <Field.HelperText>Additional Info</Field.HelperText>
      <Field.ErrorText>Error Info</Field.ErrorText>
    </Field.Root>
  )
}
<script module lang="ts">
  import type { FieldRootProps } from '@destyler-ui/svelte'

  export interface WithFieldProps extends FieldRootProps {}
</script>

<script lang="ts">
  import type { DrawEndDetails } from '@destyler-ui/svelte'
  import { Field } from '@destyler-ui/svelte'
  import { Signature } from '@destyler-ui/svelte'

  const props: WithFieldProps = $props()
  let imageUrl = $state('')

  async function handleDrawEnd(details: DrawEndDetails) {
    imageUrl = await details.getDataUrl('image/png')
  }
</script>

<Field.Root {...props}>
  <Signature.Root onDrawEnd={handleDrawEnd}>
    <Signature.Label>Label</Signature.Label>
    <Signature.Control>
      <Signature.Segment />
      <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
      <Signature.Guide />
    </Signature.Control>
    <Signature.HiddenInput value={imageUrl} />
  </Signature.Root>
  <Field.HelperText>Additional Info</Field.HelperText>
  <Field.ErrorText>Error Info</Field.ErrorText>
</Field.Root>
<script setup lang="ts">
import { Signature, useSignature } from '@destyler-ui/vue'

const signaturePad = useSignature()
</script>

<template>
  <button @click="signaturePad.clear()">Clear</button>

  <Signature.RootProvider :value="signaturePad">
    <Signature.Label>Sign below</Signature.Label>
    <Signature.Control>
      <Signature.Segment />
      <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
      <Signature.Guide />
    </Signature.Control>
  </Signature.RootProvider>
</template>
'use client'

import { Signature, useSignature } from '@destyler-ui/react'

export function RootProvider() {
  const signature = useSignature()

  return (
    <>
      <button onClick={() => signature.clear()}>Clear</button>
      <Signature.RootProvider value={signature}>
        <Signature.Label>Sign below</Signature.Label>
        <Signature.Control>
          <Signature.Segment />
          <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
          <Signature.Guide />
        </Signature.Control>
      </Signature.RootProvider>
    </>
  )
}
import { Signature, useSignature } from '@destyler-ui/solid/signature'

export function RootProvider() {
  const signature = useSignature()

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

      <Signature.RootProvider value={signature}>
        <Signature.Label>Sign below</Signature.Label>
        <Signature.Control>
          <Signature.Segment />
          <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
          <Signature.Guide />
        </Signature.Control>
      </Signature.RootProvider>
    </>
  )
}
<script lang="ts">
  import { Signature, useSignature } from '@destyler-ui/svelte'

  const id = $props.id()
  const signature = useSignature({ id })
</script>

<button type="button" onclick={() => signature().clear()}>Clear</button>

<Signature.RootProvider value={signature}>
  <Signature.Label>Sign below</Signature.Label>
  <Signature.Control>
    <Signature.Segment />
    <Signature.ClearTrigger>Clear</Signature.ClearTrigger>
    <Signature.Guide />
  </Signature.Control>
</Signature.RootProvider>

Root

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

disabledfalse | true

Whether the signature is disabled.

drawing'{ size: 2, simulatePressure: true }'signature.DrawingOptions

The drawing options.

idstring

The unique identifier of the machine.

idsPartial<{ root: string; control: string; hiddenInput: string; label: string; }>

The ids of the signature elements. Useful for composition.

namestring

The name of the signature. Useful for form submission.

readOnlyfalse | true

Whether the signature is read-only.

requiredfalse | true

Whether the signature is required.

translationssignature.IntlTranslations

The translations of the signature. Useful for internationalization.

ClearTrigger

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

Context

No serializable props or emits are declared for this part.

Control

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

Guide

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

HiddenInput

PropDefaultType
value*string
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

Label

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

RootProvider

PropDefaultType
value*MachineApi<PropTypes>
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

Segment

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

Root

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

disabledfalse | true

Whether the signature pad is disabled.

drawing'{ size: 2, simulatePressure: true }'signature.DrawingOptions

The drawing options.

idsPartial<{ root: string; control: string; hiddenInput: string; label: string; }>

The ids of the signature pad elements. Useful for composition.

namestring

The name of the signature pad. Useful for form submission.

onDraw(details: signature.DrawDetails) => void

Callback when the signature pad is drawing.

onDrawEnd(details: DrawEndDetails) => void

Callback when the signature pad is done drawing.

readOnlyfalse | true

Whether the signature pad is read-only.

requiredfalse | true

Whether the signature pad is required.

translationssignature.IntlTranslations

The translations of the signature pad. Useful for internationalization.

ClearTrigger

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

Context

PropDefaultType
children*(context: UseSignatureContext) => ReactNode

Control

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

Guide

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

HiddenInput

PropDefaultType
value*string
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

Label

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

RootProvider

PropDefaultType
value*UseSignatureReturn
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

Segment

PropDefaultType
asChildfalse | true

Use the provided child element as the default rendered element, combining their props and behavior.

Root

PropDefaultType
asChild(props: (userProps?: solid_js384.JSX.HTMLAttributes<HTMLDivElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

Use the provided child element as the default rendered element, combining their props and behavior.

disabledfalse | true

Whether the signature pad is disabled.

drawing'{ size: 2, simulatePressure: true }'signature.DrawingOptions

The drawing options.

idsPartial<{ root: string; control: string; hiddenInput: string; label: string; }>

The ids of the signature pad elements. Useful for composition.

namestring

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.

readOnlyfalse | true

Whether the signature pad is read-only.

requiredfalse | true

Whether the signature pad is required.

translationssignature.IntlTranslations

The translations of the signature pad. Useful for internationalization.

ClearTrigger

PropDefaultType
asChild(props: (userProps?: solid_js384.JSX.ButtonHTMLAttributes<HTMLButtonElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

Use the provided child element as the default rendered element, combining their props and behavior.

Context

PropDefaultType
children*(context: UseSignatureContext) => Element

Control

PropDefaultType
asChild(props: (userProps?: solid_js384.JSX.HTMLAttributes<HTMLDivElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

Use the provided child element as the default rendered element, combining their props and behavior.

Guide

PropDefaultType
asChild(props: (userProps?: solid_js384.JSX.HTMLAttributes<HTMLDivElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

Use the provided child element as the default rendered element, combining their props and behavior.

HiddenInput

PropDefaultType
value*string
asChild(props: (userProps?: solid_js384.JSX.InputHTMLAttributes<HTMLInputElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

Use the provided child element as the default rendered element, combining their props and behavior.

Label

PropDefaultType
asChild(props: (userProps?: solid_js384.JSX.LabelHTMLAttributes<HTMLLabelElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

Use the provided child element as the default rendered element, combining their props and behavior.

RootProvider

PropDefaultType
value*UseSignatureReturn
asChild(props: (userProps?: solid_js384.JSX.HTMLAttributes<HTMLDivElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

Use the provided child element as the default rendered element, combining their props and behavior.

Segment

PropDefaultType
asChild(props: (userProps?: solid_js384.JSX.SvgSVGAttributes<SVGSVGElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

Use the provided child element as the default rendered element, combining their props and behavior.

Root

PropDefaultType
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"div">]>
childrenSnippet<[]> | undefined
disabledfalse | true

Whether the signature pad is disabled.

drawing'{ size: 2, simulatePressure: true }'import("/home/runner/work/ui/ui/packages/svelte/dist/index").SignatureDrawingOptions

The drawing options.

idstring
idsPartial<{ root: string; control: string; hiddenInput: string; label: string; }>

The ids of the signature pad elements. Useful for composition.

namestring

The name of the signature pad. Useful for form submission.

onDraw(details: import("/home/runner/work/ui/ui/packages/svelte/dist/index").SignatureDrawDetails) => void

Callback when the signature pad is drawing.

onDrawEnd(details: import("/home/runner/work/ui/ui/packages/svelte/dist/index").DrawEndDetails) => void

Callback when the signature pad is done drawing.

readOnlyfalse | true

Whether the signature pad is read-only.

requiredfalse | true

Whether the signature pad is required.

translationsIntlTranslations | undefined

The translations of the signature pad. Useful for internationalization.

ClearTrigger

PropDefaultType
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"button">]>
childrenSnippet<[]> | undefined

Context

PropDefaultType
render*Snippet<[UseSignatureContext]>

Control

PropDefaultType
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"div">]>
childrenSnippet<[]> | undefined

Guide

PropDefaultType
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"div">]>
childrenSnippet<[]> | undefined

HiddenInput

PropDefaultType
value*string
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"input">]>
childrenSnippet<[]> | undefined

Label

PropDefaultType
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"label">]>
childrenSnippet<[]> | undefined

RootProvider

PropDefaultType
value*UseSignatureReturn
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"div">]>
childrenSnippet<[]> | undefined

Segment

PropDefaultType
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"svg">]>
childrenSnippet<[]> | undefined