react-native-signature-canvas 4.7.2 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/CLAUDE.md +88 -0
- package/QUICK_START.md +219 -0
- package/README.md +430 -362
- package/WEBVIEW_PROPS.md +166 -0
- package/h5/js/app.js +127 -39
- package/index.d.ts +44 -20
- package/index.js +255 -171
- package/package.json +11 -4
- package/tea.yaml +0 -6
package/WEBVIEW_PROPS.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# WebView Props Configuration
|
|
2
|
+
|
|
3
|
+
The `react-native-signature-canvas` component now supports a `webviewProps` parameter that allows you to customize the underlying WebView behavior while maintaining the core signature functionality.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```jsx
|
|
8
|
+
import SignatureCanvas from 'react-native-signature-canvas';
|
|
9
|
+
|
|
10
|
+
<SignatureCanvas
|
|
11
|
+
// ... other props
|
|
12
|
+
webviewProps={{
|
|
13
|
+
// Any WebView props can be passed here
|
|
14
|
+
cacheEnabled: false,
|
|
15
|
+
allowsFullscreenVideo: false,
|
|
16
|
+
decelerationRate: 'fast',
|
|
17
|
+
// ... more WebView props
|
|
18
|
+
}}
|
|
19
|
+
/>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Core vs Customizable Props
|
|
23
|
+
|
|
24
|
+
### Core Props (Cannot be overridden)
|
|
25
|
+
These props are essential for the signature functionality and cannot be overridden via `webviewProps`:
|
|
26
|
+
|
|
27
|
+
- `ref` - Internal WebView reference
|
|
28
|
+
- `source` - HTML content for signature pad
|
|
29
|
+
- `onMessage` - Message handler for signature events
|
|
30
|
+
- `onError` - Error handler (enhanced with retry logic)
|
|
31
|
+
- `onLoadEnd` - Load completion handler
|
|
32
|
+
- `onLoadStart` - Load start handler
|
|
33
|
+
- `onLoadProgress` - Load progress handler
|
|
34
|
+
- `javaScriptEnabled` - Must be true for signature pad to work
|
|
35
|
+
- `useWebKit` - Uses modern WebKit engine
|
|
36
|
+
|
|
37
|
+
### Default Props (Can be overridden)
|
|
38
|
+
These props have sensible defaults but can be customized via `webviewProps`:
|
|
39
|
+
|
|
40
|
+
#### Performance Optimizations
|
|
41
|
+
```jsx
|
|
42
|
+
webviewProps={{
|
|
43
|
+
cacheEnabled: true, // Enable/disable WebView cache
|
|
44
|
+
allowsInlineMediaPlayback: false, // Disable media playback
|
|
45
|
+
mediaPlaybackRequiresUserAction: true, // Require user action for media
|
|
46
|
+
allowsBackForwardNavigationGestures: false, // Disable navigation gestures
|
|
47
|
+
}}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### Security Enhancements
|
|
51
|
+
```jsx
|
|
52
|
+
webviewProps={{
|
|
53
|
+
allowsLinkPreview: false, // Disable link previews
|
|
54
|
+
allowFileAccess: false, // Disable file access
|
|
55
|
+
allowFileAccessFromFileURLs: false, // Disable file URL access
|
|
56
|
+
allowUniversalAccessFromFileURLs: false, // Disable universal access
|
|
57
|
+
mixedContentMode: "never", // Block mixed content
|
|
58
|
+
originWhitelist: ['*'], // Allow all origins
|
|
59
|
+
}}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### UI/UX Customization
|
|
63
|
+
```jsx
|
|
64
|
+
webviewProps={{
|
|
65
|
+
bounces: false, // Disable bounce effect
|
|
66
|
+
scrollEnabled: false, // Disable scrolling (use scrollable prop instead)
|
|
67
|
+
decelerationRate: 'fast', // Scroll deceleration rate
|
|
68
|
+
showsHorizontalScrollIndicator: false, // Hide horizontal scroll
|
|
69
|
+
showsVerticalScrollIndicator: false, // Hide vertical scroll
|
|
70
|
+
}}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Android-Specific
|
|
74
|
+
```jsx
|
|
75
|
+
webviewProps={{
|
|
76
|
+
androidLayerType: "hardware", // Use hardware acceleration
|
|
77
|
+
androidHardwareAccelerationDisabled: false, // Enable hardware acceleration
|
|
78
|
+
}}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Common Use Cases
|
|
82
|
+
|
|
83
|
+
### High Performance Mode
|
|
84
|
+
```jsx
|
|
85
|
+
<SignatureCanvas
|
|
86
|
+
webviewProps={{
|
|
87
|
+
cacheEnabled: true,
|
|
88
|
+
androidLayerType: "hardware",
|
|
89
|
+
androidHardwareAccelerationDisabled: false,
|
|
90
|
+
}}
|
|
91
|
+
/>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Low Memory Mode
|
|
95
|
+
```jsx
|
|
96
|
+
<SignatureCanvas
|
|
97
|
+
webviewProps={{
|
|
98
|
+
cacheEnabled: false,
|
|
99
|
+
androidLayerType: "software",
|
|
100
|
+
androidHardwareAccelerationDisabled: true,
|
|
101
|
+
}}
|
|
102
|
+
/>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Enhanced Security
|
|
106
|
+
```jsx
|
|
107
|
+
<SignatureCanvas
|
|
108
|
+
webviewProps={{
|
|
109
|
+
allowFileAccess: false,
|
|
110
|
+
allowFileAccessFromFileURLs: false,
|
|
111
|
+
allowUniversalAccessFromFileURLs: false,
|
|
112
|
+
mixedContentMode: "never",
|
|
113
|
+
originWhitelist: [], // Block all external origins
|
|
114
|
+
}}
|
|
115
|
+
/>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Custom Scrolling Behavior
|
|
119
|
+
```jsx
|
|
120
|
+
<SignatureCanvas
|
|
121
|
+
webviewProps={{
|
|
122
|
+
decelerationRate: 'normal',
|
|
123
|
+
alwaysBounceVertical: false,
|
|
124
|
+
alwaysBounceHorizontal: false,
|
|
125
|
+
directionalLockEnabled: true,
|
|
126
|
+
}}
|
|
127
|
+
/>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Important Notes
|
|
131
|
+
|
|
132
|
+
1. **Core Functionality**: The `webviewProps` cannot override core functionality props. These are protected to ensure the signature canvas works correctly.
|
|
133
|
+
|
|
134
|
+
2. **Prop Priority**: User-provided `webviewProps` take precedence over default props but not core props.
|
|
135
|
+
|
|
136
|
+
3. **TypeScript Support**: The `webviewProps` parameter is fully typed with `Partial<WebViewProps>` from `react-native-webview`.
|
|
137
|
+
|
|
138
|
+
4. **Performance Impact**: Some WebView props can significantly impact performance. Test thoroughly when customizing performance-related settings.
|
|
139
|
+
|
|
140
|
+
5. **Platform Differences**: Some props may behave differently on iOS vs Android. Refer to the `react-native-webview` documentation for platform-specific behavior.
|
|
141
|
+
|
|
142
|
+
## Migration from Previous Versions
|
|
143
|
+
|
|
144
|
+
If you were previously using individual WebView-related props, you can now consolidate them under `webviewProps`:
|
|
145
|
+
|
|
146
|
+
### Before
|
|
147
|
+
```jsx
|
|
148
|
+
<SignatureCanvas
|
|
149
|
+
androidLayerType="hardware"
|
|
150
|
+
androidHardwareAccelerationDisabled={false}
|
|
151
|
+
// other props...
|
|
152
|
+
/>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### After
|
|
156
|
+
```jsx
|
|
157
|
+
<SignatureCanvas
|
|
158
|
+
webviewProps={{
|
|
159
|
+
androidLayerType: "hardware",
|
|
160
|
+
androidHardwareAccelerationDisabled: false,
|
|
161
|
+
}}
|
|
162
|
+
// other props...
|
|
163
|
+
/>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Note: The old individual props are still supported for backward compatibility.
|
package/h5/js/app.js
CHANGED
|
@@ -1,28 +1,55 @@
|
|
|
1
1
|
export default `
|
|
2
|
+
// Enhanced error handling and validation
|
|
2
3
|
var wrapper = document.getElementById("signature-pad"),
|
|
3
|
-
clearButton = wrapper.querySelector("[data-action=clear]"),
|
|
4
|
-
saveButton = wrapper.querySelector("[data-action=save]"),
|
|
5
|
-
canvas = wrapper.querySelector("canvas"),
|
|
4
|
+
clearButton = wrapper && wrapper.querySelector("[data-action=clear]"),
|
|
5
|
+
saveButton = wrapper && wrapper.querySelector("[data-action=save]"),
|
|
6
|
+
canvas = wrapper && wrapper.querySelector("canvas"),
|
|
6
7
|
signaturePad;
|
|
8
|
+
|
|
9
|
+
if (!wrapper || !canvas) {
|
|
10
|
+
console.error('Required DOM elements not found');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Enhanced canvas resize with debouncing
|
|
15
|
+
function debounce(func, wait) {
|
|
16
|
+
var timeout;
|
|
17
|
+
return function executedFunction() {
|
|
18
|
+
var later = function() {
|
|
19
|
+
clearTimeout(timeout);
|
|
20
|
+
func.apply(this, arguments);
|
|
21
|
+
};
|
|
22
|
+
clearTimeout(timeout);
|
|
23
|
+
timeout = setTimeout(later, wait);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
7
26
|
|
|
8
|
-
// Adjust canvas coordinate space taking into account pixel ratio,
|
|
9
|
-
// to make it look crisp on mobile devices.
|
|
10
|
-
// This also causes canvas to be cleared.
|
|
11
27
|
function resizeCanvas() {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
if (!canvas || !canvas.getContext) {
|
|
29
|
+
console.warn('Canvas not available for resize');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
var context = canvas.getContext("2d");
|
|
35
|
+
var imgData = signaturePad ? signaturePad.toData() : null;
|
|
36
|
+
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
|
37
|
+
|
|
38
|
+
canvas.width = canvas.offsetWidth * ratio;
|
|
39
|
+
canvas.height = canvas.offsetHeight * ratio;
|
|
40
|
+
context.scale(ratio, ratio);
|
|
41
|
+
|
|
42
|
+
if (imgData && signaturePad) {
|
|
43
|
+
signaturePad.fromData(imgData);
|
|
44
|
+
}
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error('Error resizing canvas:', error);
|
|
47
|
+
}
|
|
23
48
|
}
|
|
24
49
|
|
|
25
|
-
|
|
50
|
+
// Use debounced resize handler
|
|
51
|
+
var debouncedResize = debounce(resizeCanvas, 100);
|
|
52
|
+
window.addEventListener('resize', debouncedResize);
|
|
26
53
|
resizeCanvas();
|
|
27
54
|
|
|
28
55
|
signaturePad = new SignaturePad(canvas, {
|
|
@@ -33,6 +60,7 @@ export default `
|
|
|
33
60
|
dotSize: <%dotSize%>,
|
|
34
61
|
minWidth: <%minWidth%>,
|
|
35
62
|
maxWidth: <%maxWidth%>,
|
|
63
|
+
minDistance: <%minDistance%>,
|
|
36
64
|
});
|
|
37
65
|
|
|
38
66
|
function clearSignature () {
|
|
@@ -51,14 +79,36 @@ export default `
|
|
|
51
79
|
}
|
|
52
80
|
|
|
53
81
|
function changePenColor(color) {
|
|
82
|
+
if (!signaturePad) {
|
|
83
|
+
console.warn('SignaturePad not initialized');
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Validate color format
|
|
88
|
+
if (typeof color !== 'string' || (!color.match(/^#[0-9A-F]{6}$/i) && !color.match(/^rgba?\(/))) {
|
|
89
|
+
console.warn('Invalid color format:', color);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
54
93
|
signaturePad.penColor = color;
|
|
55
|
-
window.ReactNativeWebView.postMessage("CHANGE_PEN");
|
|
94
|
+
window.ReactNativeWebView && window.ReactNativeWebView.postMessage("CHANGE_PEN");
|
|
56
95
|
}
|
|
57
96
|
|
|
58
97
|
function changePenSize(minW, maxW) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
98
|
+
if (!signaturePad) {
|
|
99
|
+
console.warn('SignaturePad not initialized');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Validate numeric values
|
|
104
|
+
if (typeof minW !== 'number' || typeof maxW !== 'number' || minW < 0 || maxW < minW) {
|
|
105
|
+
console.warn('Invalid pen size values:', minW, maxW);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
signaturePad.minWidth = minW;
|
|
110
|
+
signaturePad.maxWidth = maxW;
|
|
111
|
+
window.ReactNativeWebView && window.ReactNativeWebView.postMessage("CHANGE_PEN_SIZE");
|
|
62
112
|
}
|
|
63
113
|
|
|
64
114
|
function getData () {
|
|
@@ -66,6 +116,11 @@ export default `
|
|
|
66
116
|
window.ReactNativeWebView.postMessage(JSON.stringify(data));
|
|
67
117
|
}
|
|
68
118
|
|
|
119
|
+
function fromData (pointGroups) {
|
|
120
|
+
signaturePad.fromData(pointGroups);
|
|
121
|
+
window.ReactNativeWebView.postMessage(JSON.stringify(pointGroups));
|
|
122
|
+
}
|
|
123
|
+
|
|
69
124
|
function draw() {
|
|
70
125
|
signaturePad.draw();
|
|
71
126
|
window.ReactNativeWebView.postMessage("DRAW");
|
|
@@ -86,8 +141,8 @@ export default `
|
|
|
86
141
|
|
|
87
142
|
//-----------------------------------------//
|
|
88
143
|
function removeImageBlanks(imageObject) {
|
|
89
|
-
imgWidth = imageObject.width;
|
|
90
|
-
imgHeight = imageObject.height;
|
|
144
|
+
var imgWidth = imageObject.width;
|
|
145
|
+
var imgHeight = imageObject.height;
|
|
91
146
|
var canvas = document.createElement('canvas');
|
|
92
147
|
canvas.setAttribute("width", imgWidth);
|
|
93
148
|
canvas.setAttribute("height", imgHeight);
|
|
@@ -96,7 +151,10 @@ export default `
|
|
|
96
151
|
|
|
97
152
|
var imageData = context.getImageData(0, 0, imgWidth, imgHeight),
|
|
98
153
|
data = imageData.data,
|
|
99
|
-
|
|
154
|
+
getRGB = function(x, y) {
|
|
155
|
+
if (x < 0 || x >= imgWidth || y < 0 || y >= imgHeight) {
|
|
156
|
+
return { red: 255, green: 255, blue: 255, opacity: 255 };
|
|
157
|
+
}
|
|
100
158
|
var offset = imgWidth * y + x;
|
|
101
159
|
return {
|
|
102
160
|
red: data[offset * 4],
|
|
@@ -117,7 +175,7 @@ export default `
|
|
|
117
175
|
|
|
118
176
|
// loop through each column
|
|
119
177
|
for(var x = 0; x < imgWidth; x++) {
|
|
120
|
-
var rgb =
|
|
178
|
+
var rgb = getRGB(x, y);
|
|
121
179
|
if (!isWhite(rgb)) {
|
|
122
180
|
if (fromTop) {
|
|
123
181
|
return y;
|
|
@@ -137,7 +195,7 @@ export default `
|
|
|
137
195
|
|
|
138
196
|
// loop through each row
|
|
139
197
|
for(var y = 0; y < imgHeight; y++) {
|
|
140
|
-
var rgb =
|
|
198
|
+
var rgb = getRGB(x, y);
|
|
141
199
|
if (!isWhite(rgb)) {
|
|
142
200
|
if (fromLeft) {
|
|
143
201
|
return x;
|
|
@@ -168,13 +226,31 @@ export default `
|
|
|
168
226
|
}
|
|
169
227
|
}
|
|
170
228
|
|
|
171
|
-
function readSignature()
|
|
172
|
-
if (signaturePad
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
229
|
+
function readSignature() {
|
|
230
|
+
if (!signaturePad) {
|
|
231
|
+
console.warn('SignaturePad not initialized');
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
if (signaturePad.isEmpty()) {
|
|
237
|
+
window.ReactNativeWebView && window.ReactNativeWebView.postMessage("EMPTY");
|
|
238
|
+
} else {
|
|
239
|
+
var imageType = '<%imageType%>' || 'image/png';
|
|
240
|
+
var url = signaturePad.toDataURL(imageType);
|
|
241
|
+
|
|
242
|
+
if (trimWhitespace === true) {
|
|
243
|
+
cropWhitespace(url);
|
|
244
|
+
} else {
|
|
245
|
+
window.ReactNativeWebView && window.ReactNativeWebView.postMessage(url);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (autoClear === true && signaturePad) {
|
|
249
|
+
signaturePad.clear();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
} catch (error) {
|
|
253
|
+
console.error('Error reading signature:', error);
|
|
178
254
|
}
|
|
179
255
|
}
|
|
180
256
|
|
|
@@ -186,10 +262,22 @@ export default `
|
|
|
186
262
|
|
|
187
263
|
if (dataURL) signaturePad.fromDataURL(dataURL);
|
|
188
264
|
|
|
189
|
-
clearButton
|
|
265
|
+
if (clearButton) {
|
|
266
|
+
clearButton.addEventListener("click", clearSignature);
|
|
267
|
+
}
|
|
190
268
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
269
|
+
// Prevent race conditions by sequencing operations
|
|
270
|
+
if (saveButton) {
|
|
271
|
+
saveButton.addEventListener("click", function() {
|
|
272
|
+
try {
|
|
273
|
+
readSignature();
|
|
274
|
+
// Small delay to prevent race condition
|
|
275
|
+
setTimeout(function() {
|
|
276
|
+
getData();
|
|
277
|
+
}, 10);
|
|
278
|
+
} catch (error) {
|
|
279
|
+
console.error('Error in save button click:', error);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
195
283
|
`;
|
package/index.d.ts
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
declare module "react-native-signature-canvas" {
|
|
2
2
|
import React from "react";
|
|
3
|
-
import {StyleProp, ViewStyle} from "react-native";
|
|
3
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
4
|
+
import { WebViewProps } from "react-native-webview";
|
|
5
|
+
|
|
6
|
+
// Enhanced type definitions with better error handling
|
|
4
7
|
|
|
5
8
|
type ImageType = "image/png" | "image/jpeg" | "image/svg+xml";
|
|
6
9
|
|
|
7
|
-
type DataURL =
|
|
10
|
+
type DataURL = string; // Simplified - should be base64 data URL
|
|
11
|
+
|
|
12
|
+
type ForwardRef<T, P> = React.ForwardRefExoticComponent<
|
|
13
|
+
React.PropsWithoutRef<P> & React.RefAttributes<T>
|
|
14
|
+
>;
|
|
8
15
|
|
|
9
|
-
|
|
16
|
+
// Enhanced callback types
|
|
17
|
+
type SignatureCallback = (signature: string) => void;
|
|
18
|
+
type EmptyCallback = () => void;
|
|
19
|
+
type ErrorCallback = (error: Error) => void;
|
|
10
20
|
|
|
11
|
-
type SignatureViewProps = {
|
|
21
|
+
export type SignatureViewProps = {
|
|
12
22
|
androidHardwareAccelerationDisabled?: boolean;
|
|
13
23
|
autoClear?: boolean;
|
|
14
24
|
backgroundColor?: string;
|
|
@@ -24,21 +34,24 @@ declare module "react-native-signature-canvas" {
|
|
|
24
34
|
imageType?: ImageType;
|
|
25
35
|
minWidth?: number;
|
|
26
36
|
maxWidth?: number;
|
|
37
|
+
minDistance?: number;
|
|
38
|
+
onError?: ErrorCallback; // Added missing prop
|
|
27
39
|
nestedScrollEnabled?: boolean;
|
|
28
40
|
showsVerticalScrollIndicator?: boolean;
|
|
29
|
-
onOK?:
|
|
30
|
-
onEmpty?:
|
|
31
|
-
onClear?:
|
|
32
|
-
onUndo?:
|
|
33
|
-
onRedo?:
|
|
34
|
-
onDraw?:
|
|
35
|
-
onErase?:
|
|
36
|
-
onGetData?: (data:
|
|
37
|
-
onChangePenColor?:
|
|
38
|
-
onChangePenSize?:
|
|
39
|
-
onBegin?:
|
|
40
|
-
onEnd?:
|
|
41
|
-
onLoadEnd?:
|
|
41
|
+
onOK?: SignatureCallback;
|
|
42
|
+
onEmpty?: EmptyCallback;
|
|
43
|
+
onClear?: EmptyCallback;
|
|
44
|
+
onUndo?: EmptyCallback;
|
|
45
|
+
onRedo?: EmptyCallback;
|
|
46
|
+
onDraw?: EmptyCallback;
|
|
47
|
+
onErase?: EmptyCallback;
|
|
48
|
+
onGetData?: (data: string) => void; // Should be JSON string
|
|
49
|
+
onChangePenColor?: EmptyCallback;
|
|
50
|
+
onChangePenSize?: EmptyCallback;
|
|
51
|
+
onBegin?: EmptyCallback;
|
|
52
|
+
onEnd?: EmptyCallback;
|
|
53
|
+
onLoadEnd?: EmptyCallback;
|
|
54
|
+
onError?: ErrorCallback; // Added missing error callback
|
|
42
55
|
overlayHeight?: number;
|
|
43
56
|
overlayWidth?: number;
|
|
44
57
|
overlaySrc?: string;
|
|
@@ -50,21 +63,32 @@ declare module "react-native-signature-canvas" {
|
|
|
50
63
|
webStyle?: string;
|
|
51
64
|
webviewContainerStyle?: StyleProp<ViewStyle>;
|
|
52
65
|
androidLayerType?: "none" | "software" | "hardware";
|
|
53
|
-
|
|
66
|
+
webviewProps?: Partial<WebViewProps>;
|
|
67
|
+
};
|
|
54
68
|
|
|
55
69
|
export type SignatureViewRef = {
|
|
56
70
|
changePenColor: (color: string) => void;
|
|
57
71
|
changePenSize: (minW: number, maxW: number) => void;
|
|
58
72
|
clearSignature: () => void;
|
|
59
|
-
cropWhitespace: (url: string) => void;
|
|
60
73
|
draw: () => void;
|
|
61
74
|
erase: () => void;
|
|
62
75
|
getData: () => void;
|
|
63
76
|
readSignature: () => void;
|
|
64
77
|
undo: () => void;
|
|
65
78
|
redo: () => void;
|
|
79
|
+
fromData: (pointGroups, suppressClear = false) => void;
|
|
80
|
+
// Removed cropWhitespace as it's not exposed in the component
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Enhanced component interface with better type safety
|
|
84
|
+
interface SignatureCanvasComponent
|
|
85
|
+
extends ForwardRef<SignatureViewRef, SignatureViewProps> {
|
|
86
|
+
displayName?: string;
|
|
66
87
|
}
|
|
67
88
|
|
|
68
|
-
const SignatureView:
|
|
89
|
+
const SignatureView: SignatureCanvasComponent;
|
|
69
90
|
export default SignatureView;
|
|
91
|
+
|
|
92
|
+
// Export additional types for external use
|
|
93
|
+
export { SignatureViewProps, SignatureViewRef, ImageType, DataURL };
|
|
70
94
|
}
|