SignaturePad
A standalone signature capture component that supports drawing signatures with touch and mouse input.
Import
import { SignaturePad, type SignatureData } from '@mims/sdk-react';Basic Usage
<SignaturePad
onComplete={(data) => {
console.log('Signature captured:', data);
}}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
width | number | 400 | Width of the signature canvas in pixels. |
height | number | 200 | Height of the signature canvas in pixels. |
strokeColor | string | "#000000" | Color of the signature stroke. |
strokeWidth | number | 2 | Width of the signature stroke in pixels. |
onSignatureChange | (data: SignatureData | null) => void | — | Called whenever the signature changes (including clear). |
onComplete | (data: SignatureData) => void | — | Called when user clicks "Accept Signature" button. |
SignatureData Type
The signature data returned by the component:
interface SignatureData {
/** Base64 encoded PNG image of the signature */
imageData: string;
/** SVG path data for vector representation */
pathData: string;
/** Raw points for custom rendering (normalized 0-1) */
points: Array<{ x: number; y: number }[]>;
}Examples
Basic Signature Capture
function SignatureCapture() {
const [signature, setSignature] = useState<SignatureData | null>(null);
return (
<div>
<SignaturePad
width={500}
height={250}
strokeColor="#1a1a1a"
strokeWidth={3}
onComplete={(data) => {
setSignature(data);
console.log('Signature accepted');
}}
/>
{signature && (
<div className="mt-4">
<h4>Captured Signature:</h4>
<img src={signature.imageData} alt="Signature" />
</div>
)}
</div>
);
}Signature in Form
1function ContractForm() {2 const [formData, setFormData] = useState({3 name: '',4 email: '',5 signature: null as SignatureData | null,6 });78 const handleSubmit = async (e: React.FormEvent) => {9 e.preventDefault();10 11 if (!formData.signature) {12 alert('Please sign the document');13 return;14 }15 16 // Submit form with signature17 await fetch('/api/contracts', {18 method: 'POST',19 headers: { 'Content-Type': 'application/json' },20 body: JSON.stringify({21 ...formData,22 signatureImage: formData.signature.imageData,23 }),24 });25 };2627 return (28 <form onSubmit={handleSubmit}>29 <div className="space-y-4">30 <input31 type="text"32 placeholder="Full Name"33 value={formData.name}34 onChange={(e) => setFormData({ ...formData, name: e.target.value })}35 required36 />37 38 <input39 type="email"40 placeholder="Email"41 value={formData.email}42 onChange={(e) => setFormData({ ...formData, email: e.target.value })}43 required44 />45 46 <div>47 <label>Signature</label>48 <SignaturePad49 onComplete={(data) => {50 setFormData({ ...formData, signature: data });51 }}52 />53 </div>54 55 <button type="submit">Submit Contract</button>56 </div>57 </form>58 );59}Real-time Preview
function SignatureWithPreview() {
const [preview, setPreview] = useState<string | null>(null);
return (
<div className="grid grid-cols-2 gap-8">
<div>
<h4>Draw Signature</h4>
<SignaturePad
onSignatureChange={(data) => {
setPreview(data?.imageData ?? null);
}}
onComplete={(data) => {
// Handle completion
saveSignature(data);
}}
/>
</div>
<div>
<h4>Preview</h4>
<div className="border rounded-lg p-4 bg-gray-50 h-[200px] flex items-center justify-center">
{preview ? (
<img
src={preview}
alt="Signature preview"
className="max-w-full max-h-full"
/>
) : (
<span className="text-gray-400">
Start drawing to see preview
</span>
)}
</div>
</div>
</div>
);
}Custom Styling
<div className="signature-container">
<SignaturePad
width={450}
height={180}
strokeColor="#0066cc"
strokeWidth={2.5}
onComplete={handleComplete}
/>
</div>
/* CSS */
.signature-container {
padding: 20px;
background: linear-gradient(to bottom, #f8f9fa, #e9ecef);
border-radius: 12px;
}
.signature-container .mims-signature-pad {
border: 2px solid #dee2e6;
border-radius: 8px;
background: white;
}Touch Support
The SignaturePad automatically supports touch devices. Users can sign using their finger on tablets and mobile phones.
Mobile Optimization
For best mobile experience, ensure the signature pad has enough size for comfortable signing. We recommend at least 300x150 pixels on mobile devices.
Clear and Reset
The component includes a built-in "Clear" button. When clicked:
- The canvas is cleared
onSignatureChangeis called withnull- The "Accept Signature" button becomes disabled
Working with Image Data
Display Captured Signature
// The imageData is a data URL that can be used directly
<img src={signature.imageData} alt="Signature" />
// Or convert to Blob for upload
const blob = await fetch(signature.imageData).then(r => r.blob());
const file = new File([blob], 'signature.png', { type: 'image/png' });
// Upload to server
const formData = new FormData();
formData.append('signature', file);
await fetch('/api/upload', { method: 'POST', body: formData });Server-side Processing
// On the server (Node.js example)
app.post('/api/signature', async (req, res) => {
const { imageData } = req.body;
// Remove data URL prefix
const base64Data = imageData.replace(/^data:image\/png;base64,/, '');
// Convert to buffer
const buffer = Buffer.from(base64Data, 'base64');
// Save to file or storage
await fs.writeFile('signature.png', buffer);
// Or process with image library
const image = await sharp(buffer)
.resize(200, 100)
.toBuffer();
});Accessibility
Accessibility Note
The signature pad is primarily designed for visual input. For users who cannot draw, consider providing alternative options like:
- Typed signature option
- Upload signature image
- Checkbox agreement instead of signature
TypeScript Types
import type { SignatureData } from '@mims/sdk-react';
// Use in your components
const handleSignature = (data: SignatureData) => {
// TypeScript knows the shape of data
console.log(data.imageData); // string
console.log(data.pathData); // string
console.log(data.points); // Array<{x: number, y: number}[]>
};