SignaturePad
Sign by drawing or by typing a name.
SourcePackage @weft-js/warp
Preview
tsx
import { state } from '@weft-js/core'import { SignaturePad, Stack, Text } from '@weft-js/warp'import type { SignatureValue } from '@weft-js/warp'export function Basic() { const signature = state<SignatureValue | null>(null) return ( <Stack gap="related"> <SignaturePad label="Signature" value={signature} /> <Text subtle>{signature.value ? `Signed: ${signature.value.method}` : 'Not signed yet'}</Text> </Stack> )}Installation
npm install @weft-js/warpUsage
tsx
import { SignaturePad } from '@weft-js/warp'Type to sign
Always on offer, for people who can't draw.
tsx
import { SignaturePad } from '@weft-js/warp'export function Typed() { return ( <SignaturePad label="Signature" defaultValue={{ method: 'typed', text: 'Mara Lindqvist', svg: '' }} /> )}States
A signature pad can be empty, show a hint, or show an error.
tsx
import { Grid, SignaturePad, Stack, Text } from '@weft-js/warp'export function States() { return ( <Grid cols={3} gap="group"> <Cell name="Empty"><SignaturePad label="Signature" /></Cell> <Cell name="Hint"><SignaturePad label="Signature" hint="Sign as Mara Lindqvist, Owner." /></Cell> <Cell name="Invalid"><SignaturePad label="Signature" error="Sign before you continue." /></Cell> </Grid> )}const Cell = (p: { name: string; children?: unknown }) => ( <Stack gap="tight"> <Text role="caption" subtle>{p.name}</Text> {p.children} </Stack>)Sign an agreement
Press the button without signing.
tsx
import { state } from '@weft-js/core'import { Button, SignaturePad, Stack, Text } from '@weft-js/warp'import type { SignatureValue } from '@weft-js/warp'export function FormDataAgreement() { const signature = state<SignatureValue | null>(null) const tried = state(false) const done = state(false) const submit = (e: Event) => { e.preventDefault() tried.value = true if (signature.value) done.value = true } return ( <Stack as="form" gap="group" onSubmit={submit}> <Stack gap="hair"> <Text role="heading">Data processing agreement</Text> <Text subtle>weft GmbH will process logs only to run your deploys.</Text> </Stack> <SignaturePad label="Signature" value={signature} error={tried.value && !signature.value ? 'Sign before you continue.' : undefined} /> <Button type="submit" full>{done.value ? 'Signed' : 'Sign agreement'}</Button> </Stack> )}Accessibility
- Typing a name is always available, so keyboard and switch users can sign.
- The status under the pad is announced.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | The visible name, and what screen readers announce. |
hint | unknown | — | A short line of help under the field. |
error | unknown | — | Replaces the hint and marks the field invalid. |
icon | IconRef | — | Leading icon: it sweeps with the border. |
prefix | unknown | — | Text or an element inside the field before the value, such as $. |
suffix | unknown | — | Text or an element inside the field after the value, such as kg. |
variant | "floating" | "classic" | — | floating (default, or the app's warp({ fields })) · classic: the label above. |
appearance | "line" | — | line: only a bottom line under the value, no box or fill. The boxed field otherwise. |
size | "sm" | "md" | "lg" | 'md' | Control size. md by default. |
clearable | boolean | false | A clear button (shown once there is a value). |
counter | number | — | Maximum length, shown as a counter. |
id | string | — | The element id. One is made for you if you leave it out. |
disabled | boolean | false | Can't be focused or changed. |
readonly | boolean | false | Shows the value and lets it be selected and copied, but not changed. |
value | SignatureValue | State<SignatureValue | null> | null | — | The signature with its strokes or text and an SVG, or a State to bind. |
defaultValue | SignatureValue | null | — | The starting value, when the component owns the state. |
| Event | Type | Default | Description |
|---|---|---|---|
onInput | ((e: InputEvent & { currentTarget: HTMLInputElement & HTMLTextAreaElemen… | — | Called on each keystroke. |
onValueChange | ((v: SignatureValue | null, reason: ChangeReason) => void) | — | Hears the new signature and why it changed. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="signature"] [data-part="pad"]
pademptybaselinetyped