suiss/uim · React Native Component

Signature Pad

A drawing area that captures a handwritten signature as strokes and can export it as an SVG string.

Signature Pad is an open-source mobile component from suiss/uim for React Native and Expo, with SwiftUI and Jetpack Compose versions built from the same design tokens. The @esuiss/uim CLI copies its source into your project, so you own the code.

iOS
Signature Pad on iOS in light mode

SignaturePad is a View with a single-finger pan gesture from react-native-gesture-handler. Each touch records a stroke of points, and the strokes are drawn as smoothed paths with react-native-svg. A signature line with an × mark and a placeholder sits near the bottom, and a ghost Clear button appears in the top corner once something is drawn.

Installation

$ pnpm dlx @esuiss/uim@latest add signature-pad

The CLI also adds what it builds on: Button, Icon, Text.

Manual

  1. Install the dependencies:
npx expo install cn phosphor-react-native react-native-gesture-handler react-native-svg
  1. Add the pieces it builds on: Button, Icon, Text.

  2. Copy the source into components/ui/signature-pad.tsx:

uniwind/components/ui/signature-pad.tsx
import { cn } from "cn"
import type { IconProps as PhosphorIconProps } from "phosphor-react-native"
import * as React from "react"
import { View } from "react-native"
import { Gesture, GestureDetector } from "react-native-gesture-handler"
import Svg, { Path } from "react-native-svg"
import { Button } from "@/components/ui/button"
import { Icon } from "@/components/ui/icon"
import { Text, TextClassContext } from "@/components/ui/text"

type SignaturePadPoint = { x: number; y: number }

type SignaturePadStroke = SignaturePadPoint[]

type SignaturePadHandle = {
  toSVG: (options?: { color?: string }) => string
  1. Update the import paths to match your project.

Usage

import { SignaturePad } from "@/components/ui/signature-pad"
<SignaturePad />

Use it uncontrolled with defaultValue, or controlled with value and onChange. The value is an array of strokes, where each stroke is an array of { x, y } points.

Pass a ref to get a SignaturePadHandle with toSVG(), clear() and isEmpty(). toSVG returns an SVG string sized to the pad and accepts an optional color (defaults to currentColor).

The SignaturePadHandle, SignaturePadPoint and SignaturePadStroke types are also exported.

Examples

Signed

A pad that starts with a saved signature.

iOS
Signature Pad (signed) on iOS in light mode

Thick stroke

A signature drawn with strokeWidth={5}.

iOS
Signature Pad (thick stroke) on iOS in light mode

Disabled

A disabled pad that ignores touches and hides the Clear button.

iOS
Signature Pad (disabled) on iOS in light mode

Controlled

A controlled pad that reads the signature through the ref and exports it with toSVG.

iOS
Signature Pad (controlled) on iOS in light mode

API Reference

SignaturePad

ExtendsReact.ComponentProps<typeof View>
PropType
About
Strokes for controlled use.
Type
SignaturePadStroke[]
Default
—
About
Initial strokes for uncontrolled use.
Type
SignaturePadStroke[]
Default
—
About
Called with the full list of strokes after each stroke ends or the pad is cleared.
Type
(value: SignaturePadStroke[]) => void
Default
—
About
Line width of the strokes. Defaults to 2.5.
Type
number
Default
2.5
About
Turns off drawing, hides the Clear button and dims the pad.
Type
boolean
Default
false
About
Content shown on the signature line while the pad is empty. Defaults to "Sign here".
Type
React.ReactNode
Default
"Sign here"
About
Label of the Clear button. Defaults to "Clear".
Type
React.ReactNode
Default
"Clear"
About
Receives a SignaturePadHandle with toSVG, clear and isEmpty.
Type
React.Ref<SignaturePadHandle>
Default
—

Accessibility

  • The pad is a single accessible element labeled by accessibilityLabel.
  • Its value is announced as "Empty" or "Signed", and disabled is reported in its state.
  • When it has a signature and is not disabled, it offers a clear accessibility action, so VoiceOver and TalkBack users can clear it without finding the button.

Notes

  • Uses bg-surface-raised in light mode and bg-surface-secondary in dark mode, with border-separator and text-label for the strokes.
  • Points closer than one point to the previous point are skipped while drawing.