entasis 0.13.5 → 0.13.6
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/dist/components/Address/Address.svelte +44 -0
- package/dist/components/Address/Address.svelte.d.ts +4 -0
- package/dist/components/Address/address.d.ts +99 -0
- package/dist/components/Address/address.google.d.ts +89 -0
- package/dist/components/Address/address.google.fixtures.json +808 -0
- package/dist/components/Address/address.google.js +184 -0
- package/dist/components/Address/address.js +109 -0
- package/dist/components/Address/address.mcp.d.ts +1 -0
- package/dist/components/Address/address.mcp.js +100 -0
- package/dist/components/Address/address.props.d.ts +26 -0
- package/dist/components/Address/address.props.js +1 -0
- package/dist/components/Address/address.provider.d.ts +19 -0
- package/dist/components/Address/address.provider.js +69 -0
- package/dist/components/Address/address.theme.d.ts +63 -0
- package/dist/components/Address/address.theme.js +42 -0
- package/dist/components/Address/index.d.ts +6 -0
- package/dist/components/Address/index.js +5 -0
- package/dist/components/Form/AddressInput/AddressInput.svelte +482 -0
- package/dist/components/Form/AddressInput/AddressInput.svelte.d.ts +4 -0
- package/dist/components/Form/AddressInput/addressInput.mcp.d.ts +1 -0
- package/dist/components/Form/AddressInput/addressInput.mcp.js +110 -0
- package/dist/components/Form/AddressInput/addressInput.props.d.ts +72 -0
- package/dist/components/Form/AddressInput/addressInput.props.js +1 -0
- package/dist/components/Form/AddressInput/addressInput.theme.d.ts +63 -0
- package/dist/components/Form/AddressInput/addressInput.theme.js +55 -0
- package/dist/components/Form/AddressInput/index.d.ts +3 -0
- package/dist/components/Form/AddressInput/index.js +2 -0
- package/dist/components/Form/Field/field.d.ts +5 -2
- package/dist/components/Form/Field/field.state.svelte.js +4 -0
- package/dist/components/Form/Field/index.d.ts +1 -1
- package/dist/components/Form/Field/schemas.js +8 -0
- package/dist/components/Form/Form/FormInputRenderer.svelte +6 -0
- package/dist/components/Form/Form/form.d.ts +6 -0
- package/dist/components/Form/Form/form.mcp.d.ts +1 -1
- package/dist/components/Form/Form/form.mcp.js +1 -1
- package/dist/components/Form/Form/form.state.svelte.d.ts +142 -11
- package/dist/components/Form/Form/form.state.svelte.js +2 -0
- package/dist/components/Form/Form/visibility.d.ts +186 -20
- package/dist/components/Form/MultiStepForm/multiStepForm.state.svelte.d.ts +136 -0
- package/dist/components/Form/SignatureInput/SignatureInput.svelte +327 -0
- package/dist/components/Form/SignatureInput/SignatureInput.svelte.d.ts +4 -0
- package/dist/components/Form/SignatureInput/index.d.ts +4 -0
- package/dist/components/Form/SignatureInput/index.js +2 -0
- package/dist/components/Form/SignatureInput/signatureInput.mcp.d.ts +1 -0
- package/dist/components/Form/SignatureInput/signatureInput.mcp.js +74 -0
- package/dist/components/Form/SignatureInput/signatureInput.props.d.ts +29 -0
- package/dist/components/Form/SignatureInput/signatureInput.props.js +1 -0
- package/dist/components/Form/SignatureInput/signatureInput.strokes.d.ts +77 -0
- package/dist/components/Form/SignatureInput/signatureInput.strokes.js +149 -0
- package/dist/components/Form/SignatureInput/signatureInput.theme.d.ts +99 -0
- package/dist/components/Form/SignatureInput/signatureInput.theme.js +70 -0
- package/dist/generated/componentAliases.d.ts +3 -0
- package/dist/generated/componentAliases.js +3 -0
- package/dist/generated/componentContract.d.ts +46 -1
- package/dist/generated/componentContract.js +113 -0
- package/dist/generated/componentMcpRegistry.js +6 -0
- package/dist/i18n/ar.js +18 -0
- package/dist/i18n/de.js +18 -0
- package/dist/i18n/en.d.ts +18 -0
- package/dist/i18n/en.js +18 -0
- package/dist/i18n/es.js +18 -0
- package/dist/i18n/fr.js +18 -0
- package/dist/i18n/ja.js +18 -0
- package/dist/i18n/pt.js +18 -0
- package/dist/i18n/zh.js +18 -0
- package/package.json +25 -1
|
@@ -437,6 +437,40 @@ export declare class MultiStepFormState<I extends MultiStepFormItems = FormStep[
|
|
|
437
437
|
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
438
438
|
}, "visible"> & {
|
|
439
439
|
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
440
|
+
}) | (Omit<{
|
|
441
|
+
type: "signature";
|
|
442
|
+
} & Omit<import("../Field/field.ts").InputProps<"signature">, "theme"> & {
|
|
443
|
+
format?: import("../SignatureInput/signatureInput.strokes.ts").SignatureFormat;
|
|
444
|
+
inkColor?: string;
|
|
445
|
+
strokeWidth?: number;
|
|
446
|
+
placeholder?: string;
|
|
447
|
+
clearLabel?: string;
|
|
448
|
+
undoLabel?: string;
|
|
449
|
+
i18n?: Partial<import("../../../i18n/en.ts").Messages>;
|
|
450
|
+
theme?: import("../SignatureInput/signatureInput.theme.ts").SignatureInputThemeProps & import("../Field/field.ts").InputProps<"signature">["theme"];
|
|
451
|
+
} & import("../../../types/props.ts").DataAttributes & {
|
|
452
|
+
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
453
|
+
}, "visible"> & {
|
|
454
|
+
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
455
|
+
}) | (Omit<{
|
|
456
|
+
type: "address";
|
|
457
|
+
} & Omit<import("../Field/field.ts").InputProps<"address">, "theme" | "placeholder"> & {
|
|
458
|
+
provider?: import("../../Address/address.ts").AddressProvider | null;
|
|
459
|
+
fields?: readonly import("../AddressInput/addressInput.props.ts").AddressFieldRow[];
|
|
460
|
+
editableFields?: readonly import("../../Address/address.ts").AddressField[];
|
|
461
|
+
requiredFields?: readonly import("../../Address/address.ts").AddressField[];
|
|
462
|
+
countries?: readonly string[];
|
|
463
|
+
defaultCountry?: string;
|
|
464
|
+
layout?: import("../AddressInput/addressInput.props.ts").AddressInputLayout;
|
|
465
|
+
minSearchLength?: number;
|
|
466
|
+
placeholder?: string;
|
|
467
|
+
onResolve?: (address: import("../../Address/address.ts").Address) => void;
|
|
468
|
+
i18n?: Partial<import("../../../i18n/en.ts").Messages>;
|
|
469
|
+
theme?: import("../AddressInput/addressInput.theme.ts").AddressInputThemeProps & import("../Field/field.ts").InputProps<"address">["theme"];
|
|
470
|
+
} & import("../../../types/props.ts").DataAttributes & {
|
|
471
|
+
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
472
|
+
}, "visible"> & {
|
|
473
|
+
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
440
474
|
}) | (Omit<{
|
|
441
475
|
type: "slider";
|
|
442
476
|
} & Omit<import("../Field/field.ts").InputProps<"slider">, "onValueChange" | "value" | "defaultValue" | "onValidate"> & {
|
|
@@ -1288,6 +1322,40 @@ export declare class MultiStepFormState<I extends MultiStepFormItems = FormStep[
|
|
|
1288
1322
|
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
1289
1323
|
}, "visible"> & {
|
|
1290
1324
|
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
1325
|
+
}) | (Omit<{
|
|
1326
|
+
type: "signature";
|
|
1327
|
+
} & Omit<import("../Field/field.ts").InputProps<"signature">, "theme"> & {
|
|
1328
|
+
format?: import("../SignatureInput/signatureInput.strokes.ts").SignatureFormat;
|
|
1329
|
+
inkColor?: string;
|
|
1330
|
+
strokeWidth?: number;
|
|
1331
|
+
placeholder?: string;
|
|
1332
|
+
clearLabel?: string;
|
|
1333
|
+
undoLabel?: string;
|
|
1334
|
+
i18n?: Partial<import("../../../i18n/en.ts").Messages>;
|
|
1335
|
+
theme?: import("../SignatureInput/signatureInput.theme.ts").SignatureInputThemeProps & import("../Field/field.ts").InputProps<"signature">["theme"];
|
|
1336
|
+
} & import("../../../types/props.ts").DataAttributes & {
|
|
1337
|
+
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
1338
|
+
}, "visible"> & {
|
|
1339
|
+
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
1340
|
+
}) | (Omit<{
|
|
1341
|
+
type: "address";
|
|
1342
|
+
} & Omit<import("../Field/field.ts").InputProps<"address">, "theme" | "placeholder"> & {
|
|
1343
|
+
provider?: import("../../Address/address.ts").AddressProvider | null;
|
|
1344
|
+
fields?: readonly import("../AddressInput/addressInput.props.ts").AddressFieldRow[];
|
|
1345
|
+
editableFields?: readonly import("../../Address/address.ts").AddressField[];
|
|
1346
|
+
requiredFields?: readonly import("../../Address/address.ts").AddressField[];
|
|
1347
|
+
countries?: readonly string[];
|
|
1348
|
+
defaultCountry?: string;
|
|
1349
|
+
layout?: import("../AddressInput/addressInput.props.ts").AddressInputLayout;
|
|
1350
|
+
minSearchLength?: number;
|
|
1351
|
+
placeholder?: string;
|
|
1352
|
+
onResolve?: (address: import("../../Address/address.ts").Address) => void;
|
|
1353
|
+
i18n?: Partial<import("../../../i18n/en.ts").Messages>;
|
|
1354
|
+
theme?: import("../AddressInput/addressInput.theme.ts").AddressInputThemeProps & import("../Field/field.ts").InputProps<"address">["theme"];
|
|
1355
|
+
} & import("../../../types/props.ts").DataAttributes & {
|
|
1356
|
+
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
1357
|
+
}, "visible"> & {
|
|
1358
|
+
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
1291
1359
|
}) | (Omit<{
|
|
1292
1360
|
type: "slider";
|
|
1293
1361
|
} & Omit<import("../Field/field.ts").InputProps<"slider">, "onValueChange" | "value" | "defaultValue" | "onValidate"> & {
|
|
@@ -2335,6 +2403,40 @@ export declare class MultiStepFormState<I extends MultiStepFormItems = FormStep[
|
|
|
2335
2403
|
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
2336
2404
|
}, "visible"> & {
|
|
2337
2405
|
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
2406
|
+
}) | (Omit<{
|
|
2407
|
+
type: "signature";
|
|
2408
|
+
} & Omit<import("../Field/field.ts").InputProps<"signature">, "theme"> & {
|
|
2409
|
+
format?: import("../SignatureInput/signatureInput.strokes.ts").SignatureFormat;
|
|
2410
|
+
inkColor?: string;
|
|
2411
|
+
strokeWidth?: number;
|
|
2412
|
+
placeholder?: string;
|
|
2413
|
+
clearLabel?: string;
|
|
2414
|
+
undoLabel?: string;
|
|
2415
|
+
i18n?: Partial<import("../../../i18n/en.ts").Messages>;
|
|
2416
|
+
theme?: import("../SignatureInput/signatureInput.theme.ts").SignatureInputThemeProps & import("../Field/field.ts").InputProps<"signature">["theme"];
|
|
2417
|
+
} & import("../../../types/props.ts").DataAttributes & {
|
|
2418
|
+
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
2419
|
+
}, "visible"> & {
|
|
2420
|
+
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
2421
|
+
}) | (Omit<{
|
|
2422
|
+
type: "address";
|
|
2423
|
+
} & Omit<import("../Field/field.ts").InputProps<"address">, "theme" | "placeholder"> & {
|
|
2424
|
+
provider?: import("../../Address/address.ts").AddressProvider | null;
|
|
2425
|
+
fields?: readonly import("../AddressInput/addressInput.props.ts").AddressFieldRow[];
|
|
2426
|
+
editableFields?: readonly import("../../Address/address.ts").AddressField[];
|
|
2427
|
+
requiredFields?: readonly import("../../Address/address.ts").AddressField[];
|
|
2428
|
+
countries?: readonly string[];
|
|
2429
|
+
defaultCountry?: string;
|
|
2430
|
+
layout?: import("../AddressInput/addressInput.props.ts").AddressInputLayout;
|
|
2431
|
+
minSearchLength?: number;
|
|
2432
|
+
placeholder?: string;
|
|
2433
|
+
onResolve?: (address: import("../../Address/address.ts").Address) => void;
|
|
2434
|
+
i18n?: Partial<import("../../../i18n/en.ts").Messages>;
|
|
2435
|
+
theme?: import("../AddressInput/addressInput.theme.ts").AddressInputThemeProps & import("../Field/field.ts").InputProps<"address">["theme"];
|
|
2436
|
+
} & import("../../../types/props.ts").DataAttributes & {
|
|
2437
|
+
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
2438
|
+
}, "visible"> & {
|
|
2439
|
+
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
2338
2440
|
}) | (Omit<{
|
|
2339
2441
|
type: "slider";
|
|
2340
2442
|
} & Omit<import("../Field/field.ts").InputProps<"slider">, "onValueChange" | "value" | "defaultValue" | "onValidate"> & {
|
|
@@ -3186,6 +3288,40 @@ export declare class MultiStepFormState<I extends MultiStepFormItems = FormStep[
|
|
|
3186
3288
|
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
3187
3289
|
}, "visible"> & {
|
|
3188
3290
|
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
3291
|
+
}) | (Omit<{
|
|
3292
|
+
type: "signature";
|
|
3293
|
+
} & Omit<import("../Field/field.ts").InputProps<"signature">, "theme"> & {
|
|
3294
|
+
format?: import("../SignatureInput/signatureInput.strokes.ts").SignatureFormat;
|
|
3295
|
+
inkColor?: string;
|
|
3296
|
+
strokeWidth?: number;
|
|
3297
|
+
placeholder?: string;
|
|
3298
|
+
clearLabel?: string;
|
|
3299
|
+
undoLabel?: string;
|
|
3300
|
+
i18n?: Partial<import("../../../i18n/en.ts").Messages>;
|
|
3301
|
+
theme?: import("../SignatureInput/signatureInput.theme.ts").SignatureInputThemeProps & import("../Field/field.ts").InputProps<"signature">["theme"];
|
|
3302
|
+
} & import("../../../types/props.ts").DataAttributes & {
|
|
3303
|
+
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
3304
|
+
}, "visible"> & {
|
|
3305
|
+
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
3306
|
+
}) | (Omit<{
|
|
3307
|
+
type: "address";
|
|
3308
|
+
} & Omit<import("../Field/field.ts").InputProps<"address">, "theme" | "placeholder"> & {
|
|
3309
|
+
provider?: import("../../Address/address.ts").AddressProvider | null;
|
|
3310
|
+
fields?: readonly import("../AddressInput/addressInput.props.ts").AddressFieldRow[];
|
|
3311
|
+
editableFields?: readonly import("../../Address/address.ts").AddressField[];
|
|
3312
|
+
requiredFields?: readonly import("../../Address/address.ts").AddressField[];
|
|
3313
|
+
countries?: readonly string[];
|
|
3314
|
+
defaultCountry?: string;
|
|
3315
|
+
layout?: import("../AddressInput/addressInput.props.ts").AddressInputLayout;
|
|
3316
|
+
minSearchLength?: number;
|
|
3317
|
+
placeholder?: string;
|
|
3318
|
+
onResolve?: (address: import("../../Address/address.ts").Address) => void;
|
|
3319
|
+
i18n?: Partial<import("../../../i18n/en.ts").Messages>;
|
|
3320
|
+
theme?: import("../AddressInput/addressInput.theme.ts").AddressInputThemeProps & import("../Field/field.ts").InputProps<"address">["theme"];
|
|
3321
|
+
} & import("../../../types/props.ts").DataAttributes & {
|
|
3322
|
+
[key: symbol]: import("svelte/attachments").Attachment<HTMLElement> | null | undefined;
|
|
3323
|
+
}, "visible"> & {
|
|
3324
|
+
visible?: boolean | ((value: FormValueRecord) => boolean);
|
|
3189
3325
|
}) | (Omit<{
|
|
3190
3326
|
type: "slider";
|
|
3191
3327
|
} & Omit<import("../Field/field.ts").InputProps<"slider">, "onValueChange" | "value" | "defaultValue" | "onValidate"> & {
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { untrack } from 'svelte';
|
|
3
|
+
import Button from '../../Button/Button.svelte';
|
|
4
|
+
import { arrowCounterClockwiseIcon } from '../../Icons/arrowCounterClockwise.js';
|
|
5
|
+
import { eraserIcon } from '../../Icons/eraser.js';
|
|
6
|
+
import { tooltip } from '../../Tooltip/tooltip.attachment.svelte.js';
|
|
7
|
+
import Field from '../Field/Field.svelte';
|
|
8
|
+
import FieldHiddenInputs from '../Field/FieldHiddenInputs.svelte';
|
|
9
|
+
import { createFieldState } from '../Field/field.state.svelte.js';
|
|
10
|
+
import { useI18n } from '../../../i18n/context.svelte.js';
|
|
11
|
+
import type { SignatureInputProps } from './signatureInput.props.js';
|
|
12
|
+
import {
|
|
13
|
+
exportStrokes,
|
|
14
|
+
strokeShapes,
|
|
15
|
+
type SignaturePoint,
|
|
16
|
+
type SignatureStroke
|
|
17
|
+
} from './signatureInput.strokes.js';
|
|
18
|
+
import { useSignatureInputTheme } from './signatureInput.theme.js';
|
|
19
|
+
|
|
20
|
+
let {
|
|
21
|
+
defaultValue = null,
|
|
22
|
+
value = $bindable(),
|
|
23
|
+
errors = $bindable([]),
|
|
24
|
+
focused = $bindable(false),
|
|
25
|
+
required = false,
|
|
26
|
+
disabled,
|
|
27
|
+
readOnly,
|
|
28
|
+
messages,
|
|
29
|
+
name,
|
|
30
|
+
onValidate,
|
|
31
|
+
onValueChange,
|
|
32
|
+
visible,
|
|
33
|
+
size = 'normal',
|
|
34
|
+
format = 'png',
|
|
35
|
+
inkColor = '#000000',
|
|
36
|
+
strokeWidth = 2.5,
|
|
37
|
+
placeholder,
|
|
38
|
+
clearLabel,
|
|
39
|
+
undoLabel,
|
|
40
|
+
i18n,
|
|
41
|
+
label,
|
|
42
|
+
theme,
|
|
43
|
+
...rest
|
|
44
|
+
}: SignatureInputProps = $props();
|
|
45
|
+
if (value === undefined) value = untrack(() => defaultValue);
|
|
46
|
+
|
|
47
|
+
const id = $props.id();
|
|
48
|
+
const statusId = `${id}-status`;
|
|
49
|
+
|
|
50
|
+
const field = createFieldState({
|
|
51
|
+
id,
|
|
52
|
+
get value() {
|
|
53
|
+
return value;
|
|
54
|
+
},
|
|
55
|
+
set value(nextValue) {
|
|
56
|
+
value = nextValue;
|
|
57
|
+
},
|
|
58
|
+
get errors() {
|
|
59
|
+
return errors;
|
|
60
|
+
},
|
|
61
|
+
set errors(nextErrors: string[] | boolean) {
|
|
62
|
+
errors = nextErrors;
|
|
63
|
+
},
|
|
64
|
+
get focused() {
|
|
65
|
+
return focused;
|
|
66
|
+
},
|
|
67
|
+
set focused(nextFocused: boolean) {
|
|
68
|
+
focused = nextFocused;
|
|
69
|
+
},
|
|
70
|
+
onValueChange: (nextValue) => onValueChange?.(nextValue),
|
|
71
|
+
get disabled() {
|
|
72
|
+
return disabled;
|
|
73
|
+
},
|
|
74
|
+
set disabled(nextDisabled: boolean | undefined) {
|
|
75
|
+
disabled = nextDisabled;
|
|
76
|
+
},
|
|
77
|
+
get readOnly() {
|
|
78
|
+
return readOnly;
|
|
79
|
+
},
|
|
80
|
+
get messages() {
|
|
81
|
+
return messages;
|
|
82
|
+
},
|
|
83
|
+
get required() {
|
|
84
|
+
return required;
|
|
85
|
+
},
|
|
86
|
+
get name() {
|
|
87
|
+
return name;
|
|
88
|
+
},
|
|
89
|
+
set name(nextName: string | undefined) {
|
|
90
|
+
name = nextName;
|
|
91
|
+
},
|
|
92
|
+
get onValidate() {
|
|
93
|
+
return onValidate;
|
|
94
|
+
},
|
|
95
|
+
get visible() {
|
|
96
|
+
return visible;
|
|
97
|
+
},
|
|
98
|
+
type: 'signature'
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const t = $derived(useI18n(i18n));
|
|
102
|
+
const classes = $derived(useSignatureInputTheme(theme));
|
|
103
|
+
const interactive = $derived(!field.disabled && !field.readOnly);
|
|
104
|
+
const resolvedClearLabel = $derived(clearLabel ?? t.signatureInputClear);
|
|
105
|
+
const resolvedUndoLabel = $derived(undoLabel ?? t.signatureInputUndo);
|
|
106
|
+
|
|
107
|
+
/** Finished strokes, drawn since the pad was last cleared. */
|
|
108
|
+
let strokes = $state<SignatureStroke[]>([]);
|
|
109
|
+
/** The stroke under the pointer, until the pointer is lifted. */
|
|
110
|
+
let current = $state<SignaturePoint[] | null>(null);
|
|
111
|
+
/** The value these strokes exported. Any other value came from outside. */
|
|
112
|
+
let exported = $state<string | null>(null);
|
|
113
|
+
|
|
114
|
+
// A value from outside (a saved signature, a reset) replaces the strokes: they no longer
|
|
115
|
+
// describe it, so it shows as an image until someone draws again.
|
|
116
|
+
$effect(() => {
|
|
117
|
+
const nextValue = field.value ?? null;
|
|
118
|
+
untrack(() => {
|
|
119
|
+
if (nextValue === exported) return;
|
|
120
|
+
strokes = [];
|
|
121
|
+
current = null;
|
|
122
|
+
exported = null;
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const hasInk = $derived(strokes.length > 0 || current !== null);
|
|
127
|
+
const image = $derived(hasInk ? null : (field.value ?? null));
|
|
128
|
+
const shapes = $derived(
|
|
129
|
+
[...strokes, ...(current ? [current] : [])].flatMap((stroke) =>
|
|
130
|
+
strokeShapes(stroke, strokeWidth)
|
|
131
|
+
)
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
let pad = $state<HTMLDivElement | null>(null);
|
|
135
|
+
let pointerId: number | null = null;
|
|
136
|
+
|
|
137
|
+
const pointFrom = (event: PointerEvent): SignaturePoint => {
|
|
138
|
+
const box = pad!.getBoundingClientRect();
|
|
139
|
+
return {
|
|
140
|
+
x: event.clientX - box.left,
|
|
141
|
+
y: event.clientY - box.top,
|
|
142
|
+
pressure: event.pointerType === 'pen' && event.pressure > 0 ? event.pressure : 0.5
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const commit = () => {
|
|
147
|
+
const next = exportStrokes(strokes, {
|
|
148
|
+
format,
|
|
149
|
+
color: inkColor,
|
|
150
|
+
width: strokeWidth,
|
|
151
|
+
padding: strokeWidth * 2,
|
|
152
|
+
scale: 2
|
|
153
|
+
});
|
|
154
|
+
exported = next;
|
|
155
|
+
field.setValue(next);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const finishStroke = () => {
|
|
159
|
+
if (!current) return;
|
|
160
|
+
strokes = [...strokes, current];
|
|
161
|
+
current = null;
|
|
162
|
+
pointerId = null;
|
|
163
|
+
commit();
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const undo = () => {
|
|
167
|
+
if (!interactive || strokes.length === 0) return;
|
|
168
|
+
strokes = strokes.slice(0, -1);
|
|
169
|
+
commit();
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const clear = () => {
|
|
173
|
+
if (!interactive || (!hasInk && !field.value)) return;
|
|
174
|
+
strokes = [];
|
|
175
|
+
current = null;
|
|
176
|
+
exported = null;
|
|
177
|
+
field.setValue(null);
|
|
178
|
+
pad?.focus();
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const onpointerdown = (event: PointerEvent) => {
|
|
182
|
+
if (!interactive || !pad || current) return;
|
|
183
|
+
if (event.pointerType === 'mouse' && event.button !== 0) return;
|
|
184
|
+
// The pad's `touch-action: none` and `user-select: none` keep the page from scrolling or
|
|
185
|
+
// selecting under the stroke. The default is not prevented, so the browser focuses the pad
|
|
186
|
+
// as for any click, without a keyboard focus ring.
|
|
187
|
+
pointerId = event.pointerId;
|
|
188
|
+
pad.setPointerCapture?.(event.pointerId);
|
|
189
|
+
current = [pointFrom(event)];
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const onpointermove = (event: PointerEvent) => {
|
|
193
|
+
if (!current || event.pointerId !== pointerId) return;
|
|
194
|
+
// Coalesced events carry the samples between frames, so a fast stroke stays round.
|
|
195
|
+
const samples = event.getCoalescedEvents?.() ?? [];
|
|
196
|
+
const next = [...current];
|
|
197
|
+
for (const sample of samples.length ? samples : [event]) {
|
|
198
|
+
const point = pointFrom(sample);
|
|
199
|
+
const last = next[next.length - 1]!;
|
|
200
|
+
if (Math.hypot(point.x - last.x, point.y - last.y) >= 1) next.push(point);
|
|
201
|
+
}
|
|
202
|
+
current = next;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const onpointerup = (event: PointerEvent) => {
|
|
206
|
+
if (event.pointerId === pointerId) finishStroke();
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// Delete or Backspace clears the pad, Ctrl/Cmd+Z undoes the last stroke.
|
|
210
|
+
const onkeydown = (event: KeyboardEvent) => {
|
|
211
|
+
if (!interactive) return;
|
|
212
|
+
if (event.key === 'Delete' || event.key === 'Backspace') {
|
|
213
|
+
if (!hasInk && !field.value) return;
|
|
214
|
+
event.preventDefault();
|
|
215
|
+
clear();
|
|
216
|
+
} else if ((event.ctrlKey || event.metaKey) && !event.shiftKey && event.key === 'z') {
|
|
217
|
+
if (strokes.length === 0) return;
|
|
218
|
+
event.preventDefault();
|
|
219
|
+
undo();
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
// A pad disabled or made read-only mid-stroke drops the stroke it was drawing.
|
|
224
|
+
$effect(() => {
|
|
225
|
+
if (interactive) return;
|
|
226
|
+
untrack(() => {
|
|
227
|
+
current = null;
|
|
228
|
+
pointerId = null;
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
</script>
|
|
232
|
+
|
|
233
|
+
<Field {field} {size} {theme} {label} labelFor={false} {...rest}>
|
|
234
|
+
<div data-slot="signature-frame" class={classes.frame()}>
|
|
235
|
+
<!-- The pad is the field's control: it takes focus and carries the label, the state and the
|
|
236
|
+
errors. Drawing is a pointer gesture; the buttons and the keys clear or undo it. -->
|
|
237
|
+
<div
|
|
238
|
+
bind:this={pad}
|
|
239
|
+
{@attach (node) => {
|
|
240
|
+
field.node = node;
|
|
241
|
+
return () => {
|
|
242
|
+
if (field.node === node) field.node = null;
|
|
243
|
+
};
|
|
244
|
+
}}
|
|
245
|
+
{id}
|
|
246
|
+
data-slot="signature-pad"
|
|
247
|
+
data-filled={field.value ? 'true' : undefined}
|
|
248
|
+
data-drawing={current ? 'true' : undefined}
|
|
249
|
+
role="img"
|
|
250
|
+
tabindex={field.disabled ? -1 : 0}
|
|
251
|
+
aria-label={label ? undefined : t.signatureInput}
|
|
252
|
+
aria-describedby={statusId}
|
|
253
|
+
aria-disabled={field.disabled || undefined}
|
|
254
|
+
class={classes.pad({
|
|
255
|
+
size,
|
|
256
|
+
interactive,
|
|
257
|
+
disabled: !!field.disabled,
|
|
258
|
+
hasError: field.hasError
|
|
259
|
+
})}
|
|
260
|
+
{onpointerdown}
|
|
261
|
+
{onpointermove}
|
|
262
|
+
{onpointerup}
|
|
263
|
+
onpointercancel={onpointerup}
|
|
264
|
+
onlostpointercapture={onpointerup}
|
|
265
|
+
{onkeydown}
|
|
266
|
+
onfocus={() => (field.focused = true)}
|
|
267
|
+
onblur={() => (field.focused = false)}
|
|
268
|
+
>
|
|
269
|
+
{#if !hasInk && !image}
|
|
270
|
+
<div
|
|
271
|
+
data-slot="signature-placeholder"
|
|
272
|
+
class={classes.placeholder({ size })}
|
|
273
|
+
aria-hidden="true"
|
|
274
|
+
>
|
|
275
|
+
<span>×</span>
|
|
276
|
+
<span>{placeholder ?? t.signatureInputPlaceholder}</span>
|
|
277
|
+
</div>
|
|
278
|
+
{/if}
|
|
279
|
+
{#if image}
|
|
280
|
+
<img data-slot="signature-image" src={image} alt="" class={classes.image()} />
|
|
281
|
+
{/if}
|
|
282
|
+
<svg data-slot="signature-ink" class={classes.ink()} aria-hidden="true" focusable="false">
|
|
283
|
+
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
|
|
284
|
+
{#each shapes as shape, index (index)}
|
|
285
|
+
{#if shape.kind === 'dot'}
|
|
286
|
+
<circle cx={shape.x} cy={shape.y} r={shape.r} fill="currentColor" stroke="none" />
|
|
287
|
+
{:else}
|
|
288
|
+
<path d={shape.d} stroke-width={shape.width} />
|
|
289
|
+
{/if}
|
|
290
|
+
{/each}
|
|
291
|
+
</g>
|
|
292
|
+
</svg>
|
|
293
|
+
<span id={statusId} class="sr-only">
|
|
294
|
+
{field.value ? t.signatureInputSigned : t.signatureInputEmpty}
|
|
295
|
+
</span>
|
|
296
|
+
</div>
|
|
297
|
+
{#if interactive && (hasInk || image)}
|
|
298
|
+
<div data-slot="signature-actions" class={classes.actions()}>
|
|
299
|
+
{#if strokes.length > 0}
|
|
300
|
+
<Button
|
|
301
|
+
variant="ghost"
|
|
302
|
+
color="neutral"
|
|
303
|
+
size="small"
|
|
304
|
+
squared
|
|
305
|
+
label={resolvedUndoLabel}
|
|
306
|
+
onclick={undo}
|
|
307
|
+
{@attach tooltip({ content: resolvedUndoLabel, position: 'top', size: 'small' })}
|
|
308
|
+
>
|
|
309
|
+
{@render arrowCounterClockwiseIcon({ size: 14 })}
|
|
310
|
+
</Button>
|
|
311
|
+
{/if}
|
|
312
|
+
<Button
|
|
313
|
+
variant="ghost"
|
|
314
|
+
color="neutral"
|
|
315
|
+
size="small"
|
|
316
|
+
squared
|
|
317
|
+
label={resolvedClearLabel}
|
|
318
|
+
onclick={clear}
|
|
319
|
+
{@attach tooltip({ content: resolvedClearLabel, position: 'top', size: 'small' })}
|
|
320
|
+
>
|
|
321
|
+
{@render eraserIcon({ size: 14 })}
|
|
322
|
+
</Button>
|
|
323
|
+
</div>
|
|
324
|
+
{/if}
|
|
325
|
+
</div>
|
|
326
|
+
<FieldHiddenInputs {field} value={field.value} />
|
|
327
|
+
</Field>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SignatureInputProps } from './signatureInput.props.js';
|
|
2
|
+
declare const SignatureInput: import("svelte").Component<SignatureInputProps, {}, "value" | "errors" | "focused">;
|
|
3
|
+
type SignatureInput = ReturnType<typeof SignatureInput>;
|
|
4
|
+
export default SignatureInput;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as SignatureInput } from './SignatureInput.svelte';
|
|
2
|
+
export type { SignatureInputProps } from './signatureInput.props.js';
|
|
3
|
+
export type { SignatureFormat, SignaturePoint, SignatureStroke } from './signatureInput.strokes.js';
|
|
4
|
+
export { signatureInputTheme, setSignatureInputTheme, useSignatureInputTheme, type SignatureInputTheme, type SignatureInputThemeProps } from './signatureInput.theme.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const signatureInputDescription = "\n# SignatureInput Component\n\nSignatureInput is a form field where a person signs with a mouse, a finger or a pen. Its value is the signature as an image: a data URL cropped to the ink (PNG by default, or SVG), ready to store, submit or place in a document.\n\n## Basic usage\n\n```svelte\n<script lang=\"ts\">\n import { SignatureInput } from './index.ts';\n\n let signature = $state<string | null>(null);\n</script>\n\n<SignatureInput label=\"Signature\" required bind:value={signature} />\n```\n\nIn a Form or `ask()`, use `type: 'signature'`:\n\n```ts\nimport { ask } from 'entasis/ask';\n\nconst result = await ask({\n title: 'Sign the mandate',\n inputs: { signature: { type: 'signature', label: 'Signature', required: true } },\n confirm: 'Sign',\n cancel: 'Cancel'\n});\n```\n\n## Props\n\nExtends the shared Field props (`label`, `description`, `helper`, `required`, `disabled`, `readOnly`, `name`, `size`, `density`, `labelPosition`, `messages`, `onValidate`, `errors`, `focused`, `visible`) plus:\n\n- **value**: `string | null` (bindable) \u2014 the signature as a data URL, or `null` while the pad is empty.\n- **defaultValue**: `string | null` \u2014 initial value when `value` is omitted. Any image data URL works: a saved signature shows in the pad, scaled to fit.\n- **onValueChange**: `(value: string | null) => void` \u2014 called once per finished stroke, undo and clear.\n- **format**: `'png' | 'svg'` (default `'png'`) \u2014 the image the value holds. A PNG is drawn at twice the pad's resolution; an SVG keeps every stroke as a vector path.\n- **inkColor**: `string` (default `'#000000'`) \u2014 CSS color of the ink in the exported image, so a signature reads on a white document whatever the app's theme. The pad itself draws in the theme's text color.\n- **strokeWidth**: `number` (default `2.5`) \u2014 line width in CSS pixels at a medium pen pressure. A pen's pressure makes the line thinner or thicker (half to one and a half times); a mouse or a finger draws at this width.\n- **placeholder**: `string` \u2014 hint on the signing line while the pad is empty. Defaults to the i18n `signatureInputPlaceholder` (\"Sign here\").\n- **clearLabel**, **undoLabel**: `string` \u2014 accessible labels and tooltips of the two buttons.\n- **i18n**: `Partial<Messages>` \u2014 per-instance translations.\n- **size**: `'small' | 'normal' | 'large'` \u2014 pad height (112, 144 or 176 px) and placeholder text size. Override the height with the `pad` theme part.\n- **theme**: `SignatureInputThemeProps` and Field theme parts.\n\n## Behaviour\n\n- Each stroke runs from pointer down to pointer up and is smoothed through its samples. The value updates when a stroke ends, not while it is drawn.\n- The undo button (or Ctrl/Cmd+Z on the pad) removes the last stroke; the clear button (or Delete/Backspace on the pad) empties the pad and sets the value to `null`. Both show only while the pad is editable and has a signature.\n- A value set from outside (a saved signature, a Form reset) replaces the strokes and shows as an image. Drawing over it starts a new signature: the image is replaced, not added to. Undo only steps back through strokes drawn since.\n- `disabled` and `readOnly` stop drawing and hide the buttons; a read-only pad still shows, focuses, validates and submits its value. A stroke in progress is dropped when the pad becomes disabled or read-only.\n- Required: an empty pad (`null` or `''`) fails `required`.\n- Native forms: a hidden input (`FieldHiddenInputs`) submits the data URL under `name`.\n\n## Accessibility\n\n- The pad is the field's control: it is focusable, labelled by the field label (or \"Signature\" without one), and has `role=\"img\"` with a description of its state (\"No signature yet\u2026\" or \"Signed.\"). Errors and descriptions are linked by Field.\n- Drawing is a path-based gesture with no keyboard equivalent: signing by hand is the purpose of the field. Keyboard users can clear and undo with the buttons and keys above. When a keyboard-only path to consent is needed, pair the pad with another field (a typed full name, a consent checkbox).\n- The ink, placeholder and image are decorative (`aria-hidden`, empty `alt`).\n\n## Styling hooks\n\n- `data-slot`: `signature-frame`, `signature-pad`, `signature-ink`, `signature-image`, `signature-placeholder`, `signature-actions`.\n- On the pad: `data-filled=\"true\"` while it holds a signature, `data-drawing=\"true\"` during a stroke.\n\n## Theme parts\n\n`frame` (the pad and its buttons), `pad` (variants `size`, `interactive`, `disabled`, `hasError`), `ink` (the SVG of strokes), `image` (a value set from outside), `placeholder` (the signing line and hint), `actions` (the undo and clear buttons).\n\n## Exports\n\n`SignatureInput`, `SignatureInputProps`, `SignatureFormat`, `SignaturePoint`, `SignatureStroke`, `signatureInputTheme`, `setSignatureInputTheme`, `useSignatureInputTheme`, `SignatureInputTheme`, `SignatureInputThemeProps`.\n";
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export const signatureInputDescription = `
|
|
2
|
+
# SignatureInput Component
|
|
3
|
+
|
|
4
|
+
SignatureInput is a form field where a person signs with a mouse, a finger or a pen. Its value is the signature as an image: a data URL cropped to the ink (PNG by default, or SVG), ready to store, submit or place in a document.
|
|
5
|
+
|
|
6
|
+
## Basic usage
|
|
7
|
+
|
|
8
|
+
\`\`\`svelte
|
|
9
|
+
<script lang="ts">
|
|
10
|
+
import { SignatureInput } from './index.ts';
|
|
11
|
+
|
|
12
|
+
let signature = $state<string | null>(null);
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<SignatureInput label="Signature" required bind:value={signature} />
|
|
16
|
+
\`\`\`
|
|
17
|
+
|
|
18
|
+
In a Form or \`ask()\`, use \`type: 'signature'\`:
|
|
19
|
+
|
|
20
|
+
\`\`\`ts
|
|
21
|
+
import { ask } from '../Ask/index.ts';
|
|
22
|
+
|
|
23
|
+
const result = await ask({
|
|
24
|
+
title: 'Sign the mandate',
|
|
25
|
+
inputs: { signature: { type: 'signature', label: 'Signature', required: true } },
|
|
26
|
+
confirm: 'Sign',
|
|
27
|
+
cancel: 'Cancel'
|
|
28
|
+
});
|
|
29
|
+
\`\`\`
|
|
30
|
+
|
|
31
|
+
## Props
|
|
32
|
+
|
|
33
|
+
Extends the shared Field props (\`label\`, \`description\`, \`helper\`, \`required\`, \`disabled\`, \`readOnly\`, \`name\`, \`size\`, \`density\`, \`labelPosition\`, \`messages\`, \`onValidate\`, \`errors\`, \`focused\`, \`visible\`) plus:
|
|
34
|
+
|
|
35
|
+
- **value**: \`string | null\` (bindable) — the signature as a data URL, or \`null\` while the pad is empty.
|
|
36
|
+
- **defaultValue**: \`string | null\` — initial value when \`value\` is omitted. Any image data URL works: a saved signature shows in the pad, scaled to fit.
|
|
37
|
+
- **onValueChange**: \`(value: string | null) => void\` — called once per finished stroke, undo and clear.
|
|
38
|
+
- **format**: \`'png' | 'svg'\` (default \`'png'\`) — the image the value holds. A PNG is drawn at twice the pad's resolution; an SVG keeps every stroke as a vector path.
|
|
39
|
+
- **inkColor**: \`string\` (default \`'#000000'\`) — CSS color of the ink in the exported image, so a signature reads on a white document whatever the app's theme. The pad itself draws in the theme's text color.
|
|
40
|
+
- **strokeWidth**: \`number\` (default \`2.5\`) — line width in CSS pixels at a medium pen pressure. A pen's pressure makes the line thinner or thicker (half to one and a half times); a mouse or a finger draws at this width.
|
|
41
|
+
- **placeholder**: \`string\` — hint on the signing line while the pad is empty. Defaults to the i18n \`signatureInputPlaceholder\` ("Sign here").
|
|
42
|
+
- **clearLabel**, **undoLabel**: \`string\` — accessible labels and tooltips of the two buttons.
|
|
43
|
+
- **i18n**: \`Partial<Messages>\` — per-instance translations.
|
|
44
|
+
- **size**: \`'small' | 'normal' | 'large'\` — pad height (112, 144 or 176 px) and placeholder text size. Override the height with the \`pad\` theme part.
|
|
45
|
+
- **theme**: \`SignatureInputThemeProps\` and Field theme parts.
|
|
46
|
+
|
|
47
|
+
## Behaviour
|
|
48
|
+
|
|
49
|
+
- Each stroke runs from pointer down to pointer up and is smoothed through its samples. The value updates when a stroke ends, not while it is drawn.
|
|
50
|
+
- The undo button (or Ctrl/Cmd+Z on the pad) removes the last stroke; the clear button (or Delete/Backspace on the pad) empties the pad and sets the value to \`null\`. Both show only while the pad is editable and has a signature.
|
|
51
|
+
- A value set from outside (a saved signature, a Form reset) replaces the strokes and shows as an image. Drawing over it starts a new signature: the image is replaced, not added to. Undo only steps back through strokes drawn since.
|
|
52
|
+
- \`disabled\` and \`readOnly\` stop drawing and hide the buttons; a read-only pad still shows, focuses, validates and submits its value. A stroke in progress is dropped when the pad becomes disabled or read-only.
|
|
53
|
+
- Required: an empty pad (\`null\` or \`''\`) fails \`required\`.
|
|
54
|
+
- Native forms: a hidden input (\`FieldHiddenInputs\`) submits the data URL under \`name\`.
|
|
55
|
+
|
|
56
|
+
## Accessibility
|
|
57
|
+
|
|
58
|
+
- The pad is the field's control: it is focusable, labelled by the field label (or "Signature" without one), and has \`role="img"\` with a description of its state ("No signature yet…" or "Signed."). Errors and descriptions are linked by Field.
|
|
59
|
+
- Drawing is a path-based gesture with no keyboard equivalent: signing by hand is the purpose of the field. Keyboard users can clear and undo with the buttons and keys above. When a keyboard-only path to consent is needed, pair the pad with another field (a typed full name, a consent checkbox).
|
|
60
|
+
- The ink, placeholder and image are decorative (\`aria-hidden\`, empty \`alt\`).
|
|
61
|
+
|
|
62
|
+
## Styling hooks
|
|
63
|
+
|
|
64
|
+
- \`data-slot\`: \`signature-frame\`, \`signature-pad\`, \`signature-ink\`, \`signature-image\`, \`signature-placeholder\`, \`signature-actions\`.
|
|
65
|
+
- On the pad: \`data-filled="true"\` while it holds a signature, \`data-drawing="true"\` during a stroke.
|
|
66
|
+
|
|
67
|
+
## Theme parts
|
|
68
|
+
|
|
69
|
+
\`frame\` (the pad and its buttons), \`pad\` (variants \`size\`, \`interactive\`, \`disabled\`, \`hasError\`), \`ink\` (the SVG of strokes), \`image\` (a value set from outside), \`placeholder\` (the signing line and hint), \`actions\` (the undo and clear buttons).
|
|
70
|
+
|
|
71
|
+
## Exports
|
|
72
|
+
|
|
73
|
+
\`SignatureInput\`, \`SignatureInputProps\`, \`SignatureFormat\`, \`SignaturePoint\`, \`SignatureStroke\`, \`signatureInputTheme\`, \`setSignatureInputTheme\`, \`useSignatureInputTheme\`, \`SignatureInputTheme\`, \`SignatureInputThemeProps\`.
|
|
74
|
+
`;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Messages } from '../../../i18n/en.js';
|
|
2
|
+
import type { WithAttachments } from '../../../types/props.js';
|
|
3
|
+
import type { InputProps } from '../Field/field.js';
|
|
4
|
+
import type { SignatureFormat } from './signatureInput.strokes.js';
|
|
5
|
+
import type { SignatureInputThemeProps } from './signatureInput.theme.js';
|
|
6
|
+
export type SignatureInputProps = WithAttachments<Omit<InputProps<'signature'>, 'theme'> & {
|
|
7
|
+
/**
|
|
8
|
+
* Image the value holds, as a data URL cropped to the ink: `'png'` (default, drawn at twice
|
|
9
|
+
* the pad's resolution) or `'svg'`.
|
|
10
|
+
*/
|
|
11
|
+
format?: SignatureFormat;
|
|
12
|
+
/**
|
|
13
|
+
* CSS color of the ink in the exported image. Defaults to black, so a signature reads on a
|
|
14
|
+
* white document whatever the app's theme; the pad itself draws in the theme's text color.
|
|
15
|
+
*/
|
|
16
|
+
inkColor?: string;
|
|
17
|
+
/** Line width in CSS pixels at a medium pen pressure. Defaults to 2.5. */
|
|
18
|
+
strokeWidth?: number;
|
|
19
|
+
/** Hint on the signing line while the pad is empty. Defaults to the i18n `signatureInputPlaceholder`. */
|
|
20
|
+
placeholder?: string;
|
|
21
|
+
/** Accessible label and tooltip of the clear button. */
|
|
22
|
+
clearLabel?: string;
|
|
23
|
+
/** Accessible label and tooltip of the undo button. */
|
|
24
|
+
undoLabel?: string;
|
|
25
|
+
/** Per-instance translations merged over the global i18n catalog. */
|
|
26
|
+
i18n?: Partial<Messages>;
|
|
27
|
+
/** Theme overrides for the pad parts and the surrounding field. */
|
|
28
|
+
theme?: SignatureInputThemeProps & InputProps<'signature'>['theme'];
|
|
29
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|