@k2b/ui 0.18.0 → 0.19.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/README.md +3 -2
- package/dist/browser/actions/ContextMenu.js +3 -1
- package/dist/browser/actions/ContextMenu.js.map +1 -1
- package/dist/browser/actions/Dropdown.js +91 -46
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/FilterChip.js +4 -1
- package/dist/browser/actions/FilterChip.js.map +1 -1
- package/dist/browser/chat/ChatComposer.js +1293 -534
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/chat/chat-behavior.js +9 -0
- package/dist/browser/chat/chat-behavior.js.map +1 -1
- package/dist/browser/chat/index.js.map +1 -1
- package/dist/browser/chat/types.js.map +1 -1
- package/dist/browser/content/Calendar.js +579 -533
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/Lightbox.js +76 -40
- package/dist/browser/content/Lightbox.js.map +1 -1
- package/dist/browser/content/PdfPreview.js +146 -79
- package/dist/browser/content/PdfPreview.js.map +1 -1
- package/dist/browser/content/Timeline.js +1038 -0
- package/dist/browser/content/Timeline.js.map +1 -0
- package/dist/browser/content/VideoPlayer.js +29 -9
- package/dist/browser/content/VideoPlayer.js.map +1 -1
- package/dist/browser/content/chart-inspection.js +7 -2
- package/dist/browser/content/chart-inspection.js.map +1 -1
- package/dist/browser/content/index.js +1 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/timeline-model.js +579 -0
- package/dist/browser/content/timeline-model.js.map +1 -0
- package/dist/browser/feedback/dialog-core.js +26 -14
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/inputs/ChoiceChips.js +66 -0
- package/dist/browser/inputs/ChoiceChips.js.map +1 -0
- package/dist/browser/inputs/ChoiceGroups.js +53 -12
- package/dist/browser/inputs/ChoiceGroups.js.map +1 -1
- package/dist/browser/inputs/FileInputs.js +48 -33
- package/dist/browser/inputs/FileInputs.js.map +1 -1
- package/dist/browser/inputs/SignatureInput.js +558 -0
- package/dist/browser/inputs/SignatureInput.js.map +1 -0
- package/dist/browser/inputs/emoji/EmojiPicker.js +841 -0
- package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -0
- package/dist/browser/inputs/emoji/emoji-data.js +1903 -0
- package/dist/browser/inputs/emoji/emoji-data.js.map +1 -0
- package/dist/browser/inputs/emoji/emoji-index.js +209 -0
- package/dist/browser/inputs/emoji/emoji-index.js.map +1 -0
- package/dist/browser/inputs/emoji/emoji-messages.js +64 -0
- package/dist/browser/inputs/emoji/emoji-messages.js.map +1 -0
- package/dist/browser/inputs/index.js +5 -0
- package/dist/browser/inputs/index.js.map +1 -1
- package/dist/browser/inputs/markdown/actions.js +48 -2
- package/dist/browser/inputs/markdown/actions.js.map +1 -1
- package/dist/browser/inputs/markdown/code-zone.js +38 -2
- package/dist/browser/inputs/markdown/code-zone.js.map +1 -1
- package/dist/browser/inputs/signature-messages.js +39 -0
- package/dist/browser/inputs/signature-messages.js.map +1 -0
- package/dist/browser/inputs/signature.js +208 -0
- package/dist/browser/inputs/signature.js.map +1 -0
- package/dist/browser/internal/render-error.js +49 -0
- package/dist/browser/internal/render-error.js.map +1 -0
- package/dist/browser/intl/messages.js +108 -0
- package/dist/browser/intl/messages.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +321 -222
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/FloatingWindow.js +4 -1
- package/dist/browser/layout/FloatingWindow.js.map +1 -1
- package/dist/browser/layout/SidebarItemPreview.js +5 -1
- package/dist/browser/layout/SidebarItemPreview.js.map +1 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/surfaces/ResourceCard.js +212 -0
- package/dist/browser/surfaces/ResourceCard.js.map +1 -0
- package/dist/browser/surfaces/index.js +1 -0
- package/dist/browser/surfaces/index.js.map +1 -1
- package/dist/licenses/emojibase-data.txt +21 -0
- package/dist/ssr/actions/ContextMenu.js +3 -1
- package/dist/ssr/actions/ContextMenu.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +49 -12
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/FilterChip.js +4 -1
- package/dist/ssr/actions/FilterChip.js.map +1 -1
- package/dist/ssr/chat/ChatComposer.js +805 -214
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/chat/chat-behavior.js +9 -0
- package/dist/ssr/chat/chat-behavior.js.map +1 -1
- package/dist/ssr/chat/index.js.map +1 -1
- package/dist/ssr/chat/types.js.map +1 -1
- package/dist/ssr/content/Calendar.js +183 -142
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/Lightbox.js +19 -5
- package/dist/ssr/content/Lightbox.js.map +1 -1
- package/dist/ssr/content/PdfPreview.js +77 -36
- package/dist/ssr/content/PdfPreview.js.map +1 -1
- package/dist/ssr/content/Timeline.js +804 -0
- package/dist/ssr/content/Timeline.js.map +1 -0
- package/dist/ssr/content/VideoPlayer.js +29 -9
- package/dist/ssr/content/VideoPlayer.js.map +1 -1
- package/dist/ssr/content/chart-inspection.js +7 -2
- package/dist/ssr/content/chart-inspection.js.map +1 -1
- package/dist/ssr/content/index.js +1 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/timeline-model.js +579 -0
- package/dist/ssr/content/timeline-model.js.map +1 -0
- package/dist/ssr/feedback/dialog-core.js +26 -14
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/inputs/ChoiceChips.js +66 -0
- package/dist/ssr/inputs/ChoiceChips.js.map +1 -0
- package/dist/ssr/inputs/ChoiceGroups.js +12 -4
- package/dist/ssr/inputs/ChoiceGroups.js.map +1 -1
- package/dist/ssr/inputs/FileInputs.js +19 -4
- package/dist/ssr/inputs/FileInputs.js.map +1 -1
- package/dist/ssr/inputs/SignatureInput.js +404 -0
- package/dist/ssr/inputs/SignatureInput.js.map +1 -0
- package/dist/ssr/inputs/emoji/EmojiPicker.js +551 -0
- package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -0
- package/dist/ssr/inputs/emoji/emoji-data.js +1903 -0
- package/dist/ssr/inputs/emoji/emoji-data.js.map +1 -0
- package/dist/ssr/inputs/emoji/emoji-index.js +209 -0
- package/dist/ssr/inputs/emoji/emoji-index.js.map +1 -0
- package/dist/ssr/inputs/emoji/emoji-messages.js +64 -0
- package/dist/ssr/inputs/emoji/emoji-messages.js.map +1 -0
- package/dist/ssr/inputs/index.js +5 -0
- package/dist/ssr/inputs/index.js.map +1 -1
- package/dist/ssr/inputs/markdown/actions.js +48 -2
- package/dist/ssr/inputs/markdown/actions.js.map +1 -1
- package/dist/ssr/inputs/markdown/code-zone.js +38 -2
- package/dist/ssr/inputs/markdown/code-zone.js.map +1 -1
- package/dist/ssr/inputs/signature-messages.js +39 -0
- package/dist/ssr/inputs/signature-messages.js.map +1 -0
- package/dist/ssr/inputs/signature.js +208 -0
- package/dist/ssr/inputs/signature.js.map +1 -0
- package/dist/ssr/internal/render-error.js +49 -0
- package/dist/ssr/internal/render-error.js.map +1 -0
- package/dist/ssr/intl/messages.js +108 -0
- package/dist/ssr/intl/messages.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +112 -41
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/FloatingWindow.js +4 -1
- package/dist/ssr/layout/FloatingWindow.js.map +1 -1
- package/dist/ssr/layout/SidebarItemPreview.js +5 -1
- package/dist/ssr/layout/SidebarItemPreview.js.map +1 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/surfaces/ResourceCard.js +115 -0
- package/dist/ssr/surfaces/ResourceCard.js.map +1 -0
- package/dist/ssr/surfaces/index.js +1 -0
- package/dist/ssr/surfaces/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/Dropdown.d.ts +13 -1
- package/dist/types/actions/FilterChip.d.ts +5 -0
- package/dist/types/chat/ChatComposer.d.ts +24 -1
- package/dist/types/chat/chat-behavior.d.ts +15 -0
- package/dist/types/chat/index.d.ts +1 -1
- package/dist/types/chat/types.d.ts +34 -0
- package/dist/types/content/Calendar.d.ts +28 -8
- package/dist/types/content/Lightbox.d.ts +8 -0
- package/dist/types/content/Timeline.d.ts +49 -0
- package/dist/types/content/index.d.ts +4 -2
- package/dist/types/content/timeline-model.d.ts +148 -0
- package/dist/types/feedback/dialog-core.d.ts +1 -1
- package/dist/types/inputs/ChoiceChips.d.ts +20 -0
- package/dist/types/inputs/ChoiceGroups.d.ts +11 -2
- package/dist/types/inputs/FileInputs.d.ts +6 -0
- package/dist/types/inputs/SignatureInput.d.ts +22 -0
- package/dist/types/inputs/emoji/EmojiPicker.d.ts +42 -0
- package/dist/types/inputs/emoji/emoji-data.d.ts +2 -0
- package/dist/types/inputs/emoji/emoji-index.d.ts +109 -0
- package/dist/types/inputs/emoji/emoji-messages.d.ts +30 -0
- package/dist/types/inputs/index.d.ts +10 -0
- package/dist/types/inputs/markdown/actions.d.ts +4 -0
- package/dist/types/inputs/markdown/code-zone.d.ts +7 -0
- package/dist/types/inputs/signature-messages.d.ts +11 -0
- package/dist/types/inputs/signature.d.ts +72 -0
- package/dist/types/internal/render-error.d.ts +13 -0
- package/dist/types/intl/messages.d.ts +54 -0
- package/dist/types/layout/AppWorkspace.d.ts +17 -0
- package/dist/types/layout/SidebarItemPreview.d.ts +2 -0
- package/dist/types/layout/index.d.ts +1 -1
- package/dist/types/surfaces/ResourceCard.d.ts +31 -0
- package/dist/types/surfaces/index.d.ts +2 -0
- package/package.json +5 -4
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
import { template as _$template } from "solid-js/web";
|
|
2
|
+
import { delegateEvents as _$delegateEvents } from "solid-js/web";
|
|
3
|
+
import { setProperty as _$setProperty } from "solid-js/web";
|
|
4
|
+
import { runHydrationEvents as _$runHydrationEvents } from "solid-js/web";
|
|
5
|
+
import { effect as _$effect } from "solid-js/web";
|
|
6
|
+
import { use as _$use } from "solid-js/web";
|
|
7
|
+
import { getNextMarker as _$getNextMarker } from "solid-js/web";
|
|
8
|
+
import { memo as _$memo } from "solid-js/web";
|
|
9
|
+
import { createComponent as _$createComponent } from "solid-js/web";
|
|
10
|
+
import { getNextElement as _$getNextElement } from "solid-js/web";
|
|
11
|
+
import { insert as _$insert } from "solid-js/web";
|
|
12
|
+
import { setAttribute as _$setAttribute } from "solid-js/web";
|
|
13
|
+
var _tmpl$ = /*#__PURE__*/_$template(`<span hidden>`),
|
|
14
|
+
_tmpl$2 = /*#__PURE__*/_$template(`<i class="ti ti-arrow-back-up"aria-hidden=true>`),
|
|
15
|
+
_tmpl$3 = /*#__PURE__*/_$template(`<i class="ti ti-eraser"aria-hidden=true>`),
|
|
16
|
+
_tmpl$4 = /*#__PURE__*/_$template(`<span class=k2b-signature-input__placeholder aria-hidden=true><i class="ti ti-writing-sign"aria-hidden=true></i><!$><!/>`),
|
|
17
|
+
_tmpl$5 = /*#__PURE__*/_$template(`<svg><path></svg>`, false, true, false),
|
|
18
|
+
_tmpl$6 = /*#__PURE__*/_$template(`<svg class=k2b-signature-input__canvas role=img tabindex=-1 preserveAspectRatio="xMidYMid meet"><g fill=currentColor><!$><!/><!$><!/>`),
|
|
19
|
+
_tmpl$7 = /*#__PURE__*/_$template(`<div class=k2b-signature-input role=group><!$><!/><div class=k2b-signature-input__toolbar><!$><!/><div class=k2b-signature-input__actions><!$><!/><!$><!/></div></div><div class=k2b-signature-input__pad><span class=k2b-signature-input__line aria-hidden=true></span><!$><!/>`),
|
|
20
|
+
_tmpl$8 = /*#__PURE__*/_$template(`<input class=k2b-signature-input__name type=text autocomplete=name autocapitalize=words>`),
|
|
21
|
+
_tmpl$9 = /*#__PURE__*/_$template(`<input type=hidden>`);
|
|
22
|
+
import { createEffect, createSignal, For, on, Show, untrack } from "solid-js";
|
|
23
|
+
import { IconButton } from "../actions/Button";
|
|
24
|
+
import { SegmentedControl } from "../actions/SegmentedControl";
|
|
25
|
+
import { createFieldMeta, Field, fieldDescribedBy } from "../internal/field";
|
|
26
|
+
import { useUiMessages } from "../intl/messages";
|
|
27
|
+
import { commitFieldValue, resolveMaybeAccessor } from "./field-contract";
|
|
28
|
+
import { drawingToSvg, signatureName, strokeOutline, svgToDrawing, typedToSvg } from "./signature";
|
|
29
|
+
import { useSignatureMessages } from "./signature-messages";
|
|
30
|
+
/** Base stroke width in drawing units (CSS pixels at the time of drawing). */
|
|
31
|
+
const STROKE_SIZE = 3.2;
|
|
32
|
+
/** Points closer than this to the previous one add no shape, only path length. */
|
|
33
|
+
const MIN_POINT_DISTANCE = 1.2;
|
|
34
|
+
const EMPTY_SPACE = {
|
|
35
|
+
x: 0,
|
|
36
|
+
y: 0,
|
|
37
|
+
width: 600,
|
|
38
|
+
height: 200
|
|
39
|
+
};
|
|
40
|
+
const sameValue = (left, right) => left === right || left !== null && right !== null && left.kind === right.kind && left.svg === right.svg && (left.kind === "typed" && right.kind === "typed" ? left.name === right.name : true);
|
|
41
|
+
const drawingOf = value => (value?.kind === "drawn" ? svgToDrawing(value.svg) : null) ?? {
|
|
42
|
+
...EMPTY_SPACE,
|
|
43
|
+
strokes: []
|
|
44
|
+
};
|
|
45
|
+
let measureContext;
|
|
46
|
+
const measureText = (text, font) => {
|
|
47
|
+
measureContext ??= document.createElement("canvas").getContext("2d");
|
|
48
|
+
if (!measureContext) return undefined;
|
|
49
|
+
measureContext.font = font;
|
|
50
|
+
return measureContext.measureText(text).width;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A signature field: draw with a finger, pen, or mouse, or type the name. The
|
|
55
|
+
* value is an SVG document plus how it was given; `signatureToPng` turns it
|
|
56
|
+
* into a bitmap. Legal evidence such as timestamps or hashes stays with the app.
|
|
57
|
+
*/
|
|
58
|
+
export function SignatureInput(props) {
|
|
59
|
+
const messages = useUiMessages();
|
|
60
|
+
const text = useSignatureMessages();
|
|
61
|
+
const meta = createFieldMeta(props.id);
|
|
62
|
+
const requiredId = `${meta.controlId}-required`;
|
|
63
|
+
const value = () => resolveMaybeAccessor(props.value) ?? null;
|
|
64
|
+
const error = () => resolveMaybeAccessor(props.error);
|
|
65
|
+
const allowTyped = () => props.allowTyped !== false;
|
|
66
|
+
const editable = () => !props.disabled && !props.readOnly;
|
|
67
|
+
const initial = untrack(value);
|
|
68
|
+
const [mode, setMode] = createSignal(initial?.kind === "typed" ? "type" : "draw");
|
|
69
|
+
const [drawing, setDrawing] = createSignal(drawingOf(initial));
|
|
70
|
+
const [typedName, setTypedName] = createSignal(initial?.kind === "typed" ? initial.name : "");
|
|
71
|
+
const [live, setLive] = createSignal("");
|
|
72
|
+
let svg;
|
|
73
|
+
let nameInput;
|
|
74
|
+
let lastReported = initial;
|
|
75
|
+
const drawnValue = () => {
|
|
76
|
+
const markup = drawingToSvg(drawing());
|
|
77
|
+
return markup ? {
|
|
78
|
+
kind: "drawn",
|
|
79
|
+
svg: markup
|
|
80
|
+
} : null;
|
|
81
|
+
};
|
|
82
|
+
const typedValue = () => {
|
|
83
|
+
const name = signatureName(typedName());
|
|
84
|
+
if (!name) return null;
|
|
85
|
+
const family = nameInput ? getComputedStyle(nameInput).fontFamily : "cursive";
|
|
86
|
+
return {
|
|
87
|
+
kind: "typed",
|
|
88
|
+
name,
|
|
89
|
+
svg: typedToSvg(name, family, measureText)
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
const report = (next, commit) => {
|
|
93
|
+
if (sameValue(next, lastReported)) return;
|
|
94
|
+
lastReported = next;
|
|
95
|
+
if (commit) commitFieldValue(props, next);else props.onValueChange?.(next);
|
|
96
|
+
};
|
|
97
|
+
let stroke = null;
|
|
98
|
+
/** Drops the stroke in progress without keeping its ink. */
|
|
99
|
+
const abortStroke = () => {
|
|
100
|
+
if (!stroke) return;
|
|
101
|
+
const {
|
|
102
|
+
pointerId
|
|
103
|
+
} = stroke;
|
|
104
|
+
stroke = null;
|
|
105
|
+
setLive("");
|
|
106
|
+
if (svg?.hasPointerCapture(pointerId)) svg.releasePointerCapture(pointerId);
|
|
107
|
+
};
|
|
108
|
+
/** After Clear or the last Undo, keyboard focus moves from the now disabled button to the pad instead of the page. */
|
|
109
|
+
const keepFocus = button => {
|
|
110
|
+
if (button.matches(":focus-visible")) queueMicrotask(() => svg?.focus());
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// A value the parent sets (a stored signature, another record, a reset to null) replaces both inputs, so nothing of an
|
|
114
|
+
// earlier signer stays behind the mode switch. Our own reports echo back unchanged.
|
|
115
|
+
createEffect(on(value, next => {
|
|
116
|
+
if (next === lastReported || sameValue(next, lastReported)) return;
|
|
117
|
+
lastReported = next;
|
|
118
|
+
abortStroke();
|
|
119
|
+
setDrawing(drawingOf(next));
|
|
120
|
+
setTypedName(next?.kind === "typed" ? next.name : "");
|
|
121
|
+
if (next) setMode(next.kind === "typed" ? "type" : "draw");
|
|
122
|
+
}, {
|
|
123
|
+
defer: true
|
|
124
|
+
}));
|
|
125
|
+
// A field that turns disabled or read-only, or leaves drawing, ends the stroke in progress without a value.
|
|
126
|
+
createEffect(() => {
|
|
127
|
+
if (!editable() || mode() !== "draw") abortStroke();
|
|
128
|
+
});
|
|
129
|
+
const switchMode = next => {
|
|
130
|
+
if (!editable() || next === mode()) return;
|
|
131
|
+
setMode(next);
|
|
132
|
+
report(next === "draw" ? drawnValue() : typedValue(), true);
|
|
133
|
+
};
|
|
134
|
+
const undo = event => {
|
|
135
|
+
if (!editable()) return;
|
|
136
|
+
setDrawing(current => ({
|
|
137
|
+
...current,
|
|
138
|
+
strokes: current.strokes.slice(0, -1)
|
|
139
|
+
}));
|
|
140
|
+
if (drawing().strokes.length === 0) keepFocus(event.currentTarget);
|
|
141
|
+
report(drawnValue(), true);
|
|
142
|
+
};
|
|
143
|
+
const clear = event => {
|
|
144
|
+
if (!editable()) return;
|
|
145
|
+
abortStroke();
|
|
146
|
+
// Clear starts over in both modes. Without the Type option, a typed value it removes gives way to drawing.
|
|
147
|
+
setTypedName("");
|
|
148
|
+
setDrawing(current => ({
|
|
149
|
+
...current,
|
|
150
|
+
strokes: []
|
|
151
|
+
}));
|
|
152
|
+
if (mode() === "type" && allowTyped()) {
|
|
153
|
+
nameInput?.focus();
|
|
154
|
+
} else {
|
|
155
|
+
setMode("draw");
|
|
156
|
+
keepFocus(event.currentTarget);
|
|
157
|
+
}
|
|
158
|
+
report(null, true);
|
|
159
|
+
};
|
|
160
|
+
const toPoint = event => {
|
|
161
|
+
const matrix = svg?.getScreenCTM();
|
|
162
|
+
if (!matrix) return null;
|
|
163
|
+
const point = new DOMPoint(event.clientX, event.clientY).matrixTransform(matrix.inverse());
|
|
164
|
+
return {
|
|
165
|
+
x: point.x,
|
|
166
|
+
y: point.y
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
const addPoint = (event, force = false) => {
|
|
170
|
+
if (!stroke) return;
|
|
171
|
+
const position = toPoint(event);
|
|
172
|
+
if (!position) return;
|
|
173
|
+
const previous = stroke.points[stroke.points.length - 1];
|
|
174
|
+
const distance = previous ? Math.hypot(position.x - previous.x, position.y - previous.y) : 0;
|
|
175
|
+
if (previous && distance < MIN_POINT_DISTANCE && !force) return;
|
|
176
|
+
let pressure;
|
|
177
|
+
if (event.pointerType === "pen" && event.pressure > 0) {
|
|
178
|
+
pressure = event.pressure;
|
|
179
|
+
} else {
|
|
180
|
+
// Without real pressure, faster movement draws a thinner line, as ink does.
|
|
181
|
+
const elapsed = Math.max(1, event.timeStamp - stroke.time);
|
|
182
|
+
const target = Math.min(1, Math.max(0.3, 1.1 - distance / elapsed * 0.3));
|
|
183
|
+
pressure = previous ? previous.pressure * 0.6 + target * 0.4 : 0.6;
|
|
184
|
+
}
|
|
185
|
+
stroke.time = event.timeStamp;
|
|
186
|
+
stroke.points.push({
|
|
187
|
+
...position,
|
|
188
|
+
pressure
|
|
189
|
+
});
|
|
190
|
+
setLive(strokeOutline(stroke.points, STROKE_SIZE));
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* The drawing space after a stroke. It stays as it is while the ink lies inside it. Ink beyond it, drawn after the
|
|
194
|
+
* pad changed its shape (a rotated phone, a resized window, a drawing from another device), grows the space to the
|
|
195
|
+
* whole visible pad: the stored SVG then holds everything the signer saw, and the ink on the pad does not move.
|
|
196
|
+
*/
|
|
197
|
+
const spaceAfter = points => {
|
|
198
|
+
const {
|
|
199
|
+
strokes: _,
|
|
200
|
+
...space
|
|
201
|
+
} = drawing();
|
|
202
|
+
const matrix = svg?.getScreenCTM();
|
|
203
|
+
if (!svg || !matrix) return space;
|
|
204
|
+
const box = svg.getBoundingClientRect();
|
|
205
|
+
const inverse = matrix.inverse();
|
|
206
|
+
const start = new DOMPoint(box.left, box.top).matrixTransform(inverse);
|
|
207
|
+
const end = new DOMPoint(box.right, box.bottom).matrixTransform(inverse);
|
|
208
|
+
// Ink reaches half the widest stroke past its points; what lies outside the pad was never visible and does not count.
|
|
209
|
+
const reach = STROKE_SIZE / 2;
|
|
210
|
+
let left = end.x;
|
|
211
|
+
let top = end.y;
|
|
212
|
+
let right = start.x;
|
|
213
|
+
let bottom = start.y;
|
|
214
|
+
for (const point of points) {
|
|
215
|
+
left = Math.min(left, Math.max(start.x, point.x - reach));
|
|
216
|
+
top = Math.min(top, Math.max(start.y, point.y - reach));
|
|
217
|
+
right = Math.max(right, Math.min(end.x, point.x + reach));
|
|
218
|
+
bottom = Math.max(bottom, Math.min(end.y, point.y + reach));
|
|
219
|
+
}
|
|
220
|
+
if (left >= space.x && top >= space.y && right <= space.x + space.width && bottom <= space.y + space.height) return space;
|
|
221
|
+
const x = Math.min(space.x, start.x);
|
|
222
|
+
const y = Math.min(space.y, start.y);
|
|
223
|
+
return {
|
|
224
|
+
x,
|
|
225
|
+
y,
|
|
226
|
+
width: Math.max(space.x + space.width, end.x) - x,
|
|
227
|
+
height: Math.max(space.y + space.height, end.y) - y
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
const startStroke = event => {
|
|
231
|
+
// Only the primary contact draws: not a mouse's other buttons, a pen's barrel button, or its eraser.
|
|
232
|
+
if (!editable() || !svg || event.button !== 0) return;
|
|
233
|
+
// A pen takes over from a touch that is still down, such as a palm resting on a tablet.
|
|
234
|
+
if (stroke?.pointerType === "touch" && event.pointerType === "pen") abortStroke();
|
|
235
|
+
if (stroke) return;
|
|
236
|
+
event.preventDefault();
|
|
237
|
+
try {
|
|
238
|
+
// Capture keeps the stroke when the pointer leaves the pad; a pointer that already ended cannot be captured.
|
|
239
|
+
svg.setPointerCapture(event.pointerId);
|
|
240
|
+
} catch {}
|
|
241
|
+
if (drawing().strokes.length === 0) {
|
|
242
|
+
// An empty pad adopts its current size, so one drawing unit is one CSS pixel while drawing.
|
|
243
|
+
const box = svg.getBoundingClientRect();
|
|
244
|
+
setDrawing({
|
|
245
|
+
x: 0,
|
|
246
|
+
y: 0,
|
|
247
|
+
width: Math.max(1, box.width),
|
|
248
|
+
height: Math.max(1, box.height),
|
|
249
|
+
strokes: []
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
stroke = {
|
|
253
|
+
pointerId: event.pointerId,
|
|
254
|
+
pointerType: event.pointerType,
|
|
255
|
+
points: [],
|
|
256
|
+
time: event.timeStamp
|
|
257
|
+
};
|
|
258
|
+
addPoint(event, true);
|
|
259
|
+
};
|
|
260
|
+
const moveStroke = event => {
|
|
261
|
+
if (stroke?.pointerId !== event.pointerId) return;
|
|
262
|
+
event.preventDefault();
|
|
263
|
+
const events = event.getCoalescedEvents?.() ?? [];
|
|
264
|
+
for (const sample of events.length > 0 ? events : [event]) addPoint(sample);
|
|
265
|
+
};
|
|
266
|
+
const endStroke = event => {
|
|
267
|
+
if (!stroke || stroke.pointerId !== event.pointerId) return;
|
|
268
|
+
addPoint(event, false);
|
|
269
|
+
const {
|
|
270
|
+
points
|
|
271
|
+
} = stroke;
|
|
272
|
+
const outline = strokeOutline(points, STROKE_SIZE);
|
|
273
|
+
stroke = null;
|
|
274
|
+
setLive("");
|
|
275
|
+
if (!outline) return;
|
|
276
|
+
const space = spaceAfter(points);
|
|
277
|
+
setDrawing(current => ({
|
|
278
|
+
...space,
|
|
279
|
+
strokes: [...current.strokes, outline]
|
|
280
|
+
}));
|
|
281
|
+
report(drawnValue(), true);
|
|
282
|
+
};
|
|
283
|
+
// A cancelled pointer (an OS gesture, palm rejection) or lost capture is not a finished stroke.
|
|
284
|
+
const cancelStroke = event => {
|
|
285
|
+
if (stroke?.pointerId === event.pointerId) abortStroke();
|
|
286
|
+
};
|
|
287
|
+
const empty = () => mode() === "draw" ? drawing().strokes.length === 0 && !live() : !signatureName(typedName());
|
|
288
|
+
const serialized = () => {
|
|
289
|
+
const current = value();
|
|
290
|
+
return current ? JSON.stringify(current) : "";
|
|
291
|
+
};
|
|
292
|
+
return _$createComponent(Field, {
|
|
293
|
+
get ["class"]() {
|
|
294
|
+
return props.class;
|
|
295
|
+
},
|
|
296
|
+
get label() {
|
|
297
|
+
return props.label;
|
|
298
|
+
},
|
|
299
|
+
get description() {
|
|
300
|
+
return props.description;
|
|
301
|
+
},
|
|
302
|
+
get error() {
|
|
303
|
+
return error();
|
|
304
|
+
},
|
|
305
|
+
meta: meta,
|
|
306
|
+
labelFor: false,
|
|
307
|
+
get required() {
|
|
308
|
+
return props.required;
|
|
309
|
+
},
|
|
310
|
+
get disabled() {
|
|
311
|
+
return props.disabled;
|
|
312
|
+
},
|
|
313
|
+
get children() {
|
|
314
|
+
return [(() => {
|
|
315
|
+
var _el$ = _$getNextElement(_tmpl$7),
|
|
316
|
+
_el$26 = _el$.firstChild,
|
|
317
|
+
[_el$27, _co$8] = _$getNextMarker(_el$26.nextSibling),
|
|
318
|
+
_el$3 = _el$27.nextSibling,
|
|
319
|
+
_el$1 = _el$3.firstChild,
|
|
320
|
+
[_el$10, _co$3] = _$getNextMarker(_el$1.nextSibling),
|
|
321
|
+
_el$4 = _el$10.nextSibling,
|
|
322
|
+
_el$7 = _el$4.firstChild,
|
|
323
|
+
[_el$8, _co$] = _$getNextMarker(_el$7.nextSibling),
|
|
324
|
+
_el$9 = _el$8.nextSibling,
|
|
325
|
+
[_el$0, _co$2] = _$getNextMarker(_el$9.nextSibling),
|
|
326
|
+
_el$11 = _el$3.nextSibling,
|
|
327
|
+
_el$12 = _el$11.firstChild,
|
|
328
|
+
_el$24 = _el$12.nextSibling,
|
|
329
|
+
[_el$25, _co$7] = _$getNextMarker(_el$24.nextSibling);
|
|
330
|
+
_$insert(_el$, _$createComponent(Show, {
|
|
331
|
+
get when() {
|
|
332
|
+
return props.required;
|
|
333
|
+
},
|
|
334
|
+
get children() {
|
|
335
|
+
var _el$2 = _$getNextElement(_tmpl$);
|
|
336
|
+
_$setAttribute(_el$2, "id", requiredId);
|
|
337
|
+
_$insert(_el$2, () => messages().required);
|
|
338
|
+
return _el$2;
|
|
339
|
+
}
|
|
340
|
+
}), _el$27, _co$8);
|
|
341
|
+
_$insert(_el$3, _$createComponent(Show, {
|
|
342
|
+
get when() {
|
|
343
|
+
return allowTyped();
|
|
344
|
+
},
|
|
345
|
+
get children() {
|
|
346
|
+
return _$createComponent(SegmentedControl, {
|
|
347
|
+
"class": "k2b-signature-input__modes",
|
|
348
|
+
size: "sm",
|
|
349
|
+
get ariaLabel() {
|
|
350
|
+
return text().method;
|
|
351
|
+
},
|
|
352
|
+
get options() {
|
|
353
|
+
return [{
|
|
354
|
+
value: "draw",
|
|
355
|
+
label: text().draw,
|
|
356
|
+
icon: "ti ti-signature"
|
|
357
|
+
}, {
|
|
358
|
+
value: "type",
|
|
359
|
+
label: text().type,
|
|
360
|
+
icon: "ti ti-keyboard"
|
|
361
|
+
}];
|
|
362
|
+
},
|
|
363
|
+
value: mode,
|
|
364
|
+
onValueChange: switchMode,
|
|
365
|
+
get disabled() {
|
|
366
|
+
return !editable();
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}), _el$10, _co$3);
|
|
371
|
+
_$insert(_el$4, _$createComponent(IconButton, {
|
|
372
|
+
size: "sm",
|
|
373
|
+
variant: "ghost",
|
|
374
|
+
get label() {
|
|
375
|
+
return text().undo;
|
|
376
|
+
},
|
|
377
|
+
get ["data-hidden"]() {
|
|
378
|
+
return mode() === "type" ? "true" : undefined;
|
|
379
|
+
},
|
|
380
|
+
get disabled() {
|
|
381
|
+
return !editable() || mode() !== "draw" || drawing().strokes.length === 0;
|
|
382
|
+
},
|
|
383
|
+
onClick: undo,
|
|
384
|
+
get children() {
|
|
385
|
+
return _$getNextElement(_tmpl$2);
|
|
386
|
+
}
|
|
387
|
+
}), _el$8, _co$);
|
|
388
|
+
_$insert(_el$4, _$createComponent(IconButton, {
|
|
389
|
+
size: "sm",
|
|
390
|
+
variant: "ghost",
|
|
391
|
+
get label() {
|
|
392
|
+
return messages().clear;
|
|
393
|
+
},
|
|
394
|
+
get disabled() {
|
|
395
|
+
return !editable() || empty();
|
|
396
|
+
},
|
|
397
|
+
onClick: clear,
|
|
398
|
+
get children() {
|
|
399
|
+
return _$getNextElement(_tmpl$3);
|
|
400
|
+
}
|
|
401
|
+
}), _el$0, _co$2);
|
|
402
|
+
_$insert(_el$11, _$createComponent(Show, {
|
|
403
|
+
get when() {
|
|
404
|
+
return mode() === "draw";
|
|
405
|
+
},
|
|
406
|
+
get fallback() {
|
|
407
|
+
return (() => {
|
|
408
|
+
var _el$28 = _$getNextElement(_tmpl$8);
|
|
409
|
+
_el$28.addEventListener("change", () => props.onValueCommit?.(typedValue()));
|
|
410
|
+
_el$28.$$input = event => {
|
|
411
|
+
setTypedName(event.currentTarget.value);
|
|
412
|
+
report(typedValue(), false);
|
|
413
|
+
};
|
|
414
|
+
var _ref$2 = nameInput;
|
|
415
|
+
typeof _ref$2 === "function" ? _$use(_ref$2, _el$28) : nameInput = _el$28;
|
|
416
|
+
_$setAttribute(_el$28, "spellcheck", false);
|
|
417
|
+
_$effect(_p$ => {
|
|
418
|
+
var _v$11 = text().typeName,
|
|
419
|
+
_v$12 = text().typeName,
|
|
420
|
+
_v$13 = fieldDescribedBy(meta, props),
|
|
421
|
+
_v$14 = error() ? "true" : undefined,
|
|
422
|
+
_v$15 = props.required || undefined,
|
|
423
|
+
_v$16 = props.disabled,
|
|
424
|
+
_v$17 = props.readOnly || !allowTyped();
|
|
425
|
+
_v$11 !== _p$.e && _$setAttribute(_el$28, "placeholder", _p$.e = _v$11);
|
|
426
|
+
_v$12 !== _p$.t && _$setAttribute(_el$28, "aria-label", _p$.t = _v$12);
|
|
427
|
+
_v$13 !== _p$.a && _$setAttribute(_el$28, "aria-describedby", _p$.a = _v$13);
|
|
428
|
+
_v$14 !== _p$.o && _$setAttribute(_el$28, "aria-invalid", _p$.o = _v$14);
|
|
429
|
+
_v$15 !== _p$.i && _$setAttribute(_el$28, "aria-required", _p$.i = _v$15);
|
|
430
|
+
_v$16 !== _p$.n && _$setProperty(_el$28, "disabled", _p$.n = _v$16);
|
|
431
|
+
_v$17 !== _p$.s && _$setProperty(_el$28, "readOnly", _p$.s = _v$17);
|
|
432
|
+
return _p$;
|
|
433
|
+
}, {
|
|
434
|
+
e: undefined,
|
|
435
|
+
t: undefined,
|
|
436
|
+
a: undefined,
|
|
437
|
+
o: undefined,
|
|
438
|
+
i: undefined,
|
|
439
|
+
n: undefined,
|
|
440
|
+
s: undefined
|
|
441
|
+
});
|
|
442
|
+
_$effect(() => _$setProperty(_el$28, "value", typedName()));
|
|
443
|
+
_$runHydrationEvents();
|
|
444
|
+
return _el$28;
|
|
445
|
+
})();
|
|
446
|
+
},
|
|
447
|
+
get children() {
|
|
448
|
+
return [(() => {
|
|
449
|
+
var _el$13 = _$getNextElement(_tmpl$4),
|
|
450
|
+
_el$14 = _el$13.firstChild,
|
|
451
|
+
_el$15 = _el$14.nextSibling,
|
|
452
|
+
[_el$16, _co$4] = _$getNextMarker(_el$15.nextSibling);
|
|
453
|
+
_$insert(_el$13, () => text().signHere, _el$16, _co$4);
|
|
454
|
+
return _el$13;
|
|
455
|
+
})(), (() => {
|
|
456
|
+
var _el$17 = _$getNextElement(_tmpl$6),
|
|
457
|
+
_el$18 = _el$17.firstChild,
|
|
458
|
+
_el$20 = _el$18.firstChild,
|
|
459
|
+
[_el$21, _co$5] = _$getNextMarker(_el$20.nextSibling),
|
|
460
|
+
_el$22 = _el$21.nextSibling,
|
|
461
|
+
[_el$23, _co$6] = _$getNextMarker(_el$22.nextSibling);
|
|
462
|
+
_el$17.addEventListener("lostpointercapture", event => {
|
|
463
|
+
// A child path that held a touch's implicit capture hands it to the pad; only the pad's own loss counts.
|
|
464
|
+
if (event.target === event.currentTarget) cancelStroke(event);
|
|
465
|
+
});
|
|
466
|
+
_el$17.addEventListener("pointercancel", cancelStroke);
|
|
467
|
+
_el$17.$$pointerup = endStroke;
|
|
468
|
+
_el$17.$$pointermove = moveStroke;
|
|
469
|
+
_el$17.$$pointerdown = startStroke;
|
|
470
|
+
var _ref$ = svg;
|
|
471
|
+
typeof _ref$ === "function" ? _$use(_ref$, _el$17) : svg = _el$17;
|
|
472
|
+
_$insert(_el$18, _$createComponent(For, {
|
|
473
|
+
get each() {
|
|
474
|
+
return drawing().strokes;
|
|
475
|
+
},
|
|
476
|
+
children: outline => (() => {
|
|
477
|
+
var _el$29 = _$getNextElement(_tmpl$5);
|
|
478
|
+
_$setAttribute(_el$29, "d", outline);
|
|
479
|
+
return _el$29;
|
|
480
|
+
})()
|
|
481
|
+
}), _el$21, _co$5);
|
|
482
|
+
_$insert(_el$18, _$createComponent(Show, {
|
|
483
|
+
get when() {
|
|
484
|
+
return live();
|
|
485
|
+
},
|
|
486
|
+
get children() {
|
|
487
|
+
var _el$19 = _$getNextElement(_tmpl$5);
|
|
488
|
+
_$effect(() => _$setAttribute(_el$19, "d", live()));
|
|
489
|
+
return _el$19;
|
|
490
|
+
}
|
|
491
|
+
}), _el$23, _co$6);
|
|
492
|
+
_$effect(_p$ => {
|
|
493
|
+
var _v$ = drawing().strokes.length > 0 ? text().drawn : text().drawArea,
|
|
494
|
+
_v$2 = `${drawing().x} ${drawing().y} ${drawing().width} ${drawing().height}`;
|
|
495
|
+
_v$ !== _p$.e && _$setAttribute(_el$17, "aria-label", _p$.e = _v$);
|
|
496
|
+
_v$2 !== _p$.t && _$setAttribute(_el$17, "viewBox", _p$.t = _v$2);
|
|
497
|
+
return _p$;
|
|
498
|
+
}, {
|
|
499
|
+
e: undefined,
|
|
500
|
+
t: undefined
|
|
501
|
+
});
|
|
502
|
+
_$runHydrationEvents();
|
|
503
|
+
return _el$17;
|
|
504
|
+
})()];
|
|
505
|
+
}
|
|
506
|
+
}), _el$25, _co$7);
|
|
507
|
+
_$effect(_p$ => {
|
|
508
|
+
var _v$3 = meta.controlId,
|
|
509
|
+
_v$4 = props.label ? undefined : props["aria-label"],
|
|
510
|
+
_v$5 = props.label ? meta.labelId : undefined,
|
|
511
|
+
_v$6 = [props.required ? requiredId : undefined, fieldDescribedBy(meta, props)].filter(Boolean).join(" ") || undefined,
|
|
512
|
+
_v$7 = error() ? "true" : undefined,
|
|
513
|
+
_v$8 = mode(),
|
|
514
|
+
_v$9 = empty() ? "true" : undefined,
|
|
515
|
+
_v$0 = error() ? "true" : undefined,
|
|
516
|
+
_v$1 = props.disabled ? "true" : undefined,
|
|
517
|
+
_v$10 = props.readOnly ? "true" : undefined;
|
|
518
|
+
_v$3 !== _p$.e && _$setAttribute(_el$, "id", _p$.e = _v$3);
|
|
519
|
+
_v$4 !== _p$.t && _$setAttribute(_el$, "aria-label", _p$.t = _v$4);
|
|
520
|
+
_v$5 !== _p$.a && _$setAttribute(_el$, "aria-labelledby", _p$.a = _v$5);
|
|
521
|
+
_v$6 !== _p$.o && _$setAttribute(_el$, "aria-describedby", _p$.o = _v$6);
|
|
522
|
+
_v$7 !== _p$.i && _$setAttribute(_el$, "aria-invalid", _p$.i = _v$7);
|
|
523
|
+
_v$8 !== _p$.n && _$setAttribute(_el$, "data-mode", _p$.n = _v$8);
|
|
524
|
+
_v$9 !== _p$.s && _$setAttribute(_el$, "data-empty", _p$.s = _v$9);
|
|
525
|
+
_v$0 !== _p$.h && _$setAttribute(_el$, "data-invalid", _p$.h = _v$0);
|
|
526
|
+
_v$1 !== _p$.r && _$setAttribute(_el$, "data-disabled", _p$.r = _v$1);
|
|
527
|
+
_v$10 !== _p$.d && _$setAttribute(_el$, "data-readonly", _p$.d = _v$10);
|
|
528
|
+
return _p$;
|
|
529
|
+
}, {
|
|
530
|
+
e: undefined,
|
|
531
|
+
t: undefined,
|
|
532
|
+
a: undefined,
|
|
533
|
+
o: undefined,
|
|
534
|
+
i: undefined,
|
|
535
|
+
n: undefined,
|
|
536
|
+
s: undefined,
|
|
537
|
+
h: undefined,
|
|
538
|
+
r: undefined,
|
|
539
|
+
d: undefined
|
|
540
|
+
});
|
|
541
|
+
return _el$;
|
|
542
|
+
})(), _$createComponent(Show, {
|
|
543
|
+
get when() {
|
|
544
|
+
return props.name;
|
|
545
|
+
},
|
|
546
|
+
children: name => (() => {
|
|
547
|
+
var _el$30 = _$getNextElement(_tmpl$9);
|
|
548
|
+
_$effect(() => _$setAttribute(_el$30, "name", name()));
|
|
549
|
+
_$effect(() => _$setProperty(_el$30, "value", serialized()));
|
|
550
|
+
return _el$30;
|
|
551
|
+
})()
|
|
552
|
+
})];
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
export default SignatureInput;
|
|
557
|
+
_$delegateEvents(["pointerdown", "pointermove", "pointerup", "input"]);
|
|
558
|
+
//# sourceMappingURL=SignatureInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["inputs/SignatureInput.tsx"],"sourcesContent":["import { createEffect, createSignal, For, type JSX, on, Show, untrack } from \"solid-js\";\nimport { IconButton } from \"../actions/Button\";\nimport { SegmentedControl } from \"../actions/SegmentedControl\";\nimport { createFieldMeta, Field, fieldDescribedBy } from \"../internal/field\";\nimport { useUiMessages } from \"../intl/messages\";\nimport type { ValueFieldProps } from \"./field-contract\";\nimport { commitFieldValue, resolveMaybeAccessor } from \"./field-contract\";\nimport {\n drawingToSvg,\n type SignatureDrawing,\n type SignaturePoint,\n type SignatureValue,\n signatureName,\n strokeOutline,\n svgToDrawing,\n typedToSvg,\n} from \"./signature\";\nimport { useSignatureMessages } from \"./signature-messages\";\n\nexport type SignatureInputProps = ValueFieldProps<SignatureValue | null> & {\n /** Submits the value as JSON in a hidden input of this name. */\n name?: string;\n /** Shows the signature without allowing changes. */\n readOnly?: boolean;\n /**\n * Offers typing the name instead of drawing. Defaults to `true`: typing is the\n * keyboard and screen-reader path and helps people who cannot draw. Without\n * it, a typed value is still shown and can be cleared, but not edited.\n */\n allowTyped?: boolean;\n};\n\ntype SignatureMode = \"draw\" | \"type\";\n\n/** Base stroke width in drawing units (CSS pixels at the time of drawing). */\nconst STROKE_SIZE = 3.2;\n/** Points closer than this to the previous one add no shape, only path length. */\nconst MIN_POINT_DISTANCE = 1.2;\nconst EMPTY_SPACE = { x: 0, y: 0, width: 600, height: 200 };\n\nconst sameValue = (left: SignatureValue | null, right: SignatureValue | null) =>\n left === right ||\n (left !== null &&\n right !== null &&\n left.kind === right.kind &&\n left.svg === right.svg &&\n (left.kind === \"typed\" && right.kind === \"typed\" ? left.name === right.name : true));\n\nconst drawingOf = (value: SignatureValue | null): SignatureDrawing =>\n (value?.kind === \"drawn\" ? svgToDrawing(value.svg) : null) ?? { ...EMPTY_SPACE, strokes: [] };\n\nlet measureContext: CanvasRenderingContext2D | null | undefined;\nconst measureText = (text: string, font: string): number | undefined => {\n measureContext ??= document.createElement(\"canvas\").getContext(\"2d\");\n if (!measureContext) return undefined;\n measureContext.font = font;\n return measureContext.measureText(text).width;\n};\n\n/**\n * A signature field: draw with a finger, pen, or mouse, or type the name. The\n * value is an SVG document plus how it was given; `signatureToPng` turns it\n * into a bitmap. Legal evidence such as timestamps or hashes stays with the app.\n */\nexport function SignatureInput(props: SignatureInputProps): JSX.Element {\n const messages = useUiMessages();\n const text = useSignatureMessages();\n const meta = createFieldMeta(props.id);\n const requiredId = `${meta.controlId}-required`;\n const value = () => resolveMaybeAccessor(props.value) ?? null;\n const error = () => resolveMaybeAccessor(props.error);\n const allowTyped = () => props.allowTyped !== false;\n const editable = () => !props.disabled && !props.readOnly;\n\n const initial = untrack(value);\n const [mode, setMode] = createSignal<SignatureMode>(initial?.kind === \"typed\" ? \"type\" : \"draw\");\n const [drawing, setDrawing] = createSignal<SignatureDrawing>(drawingOf(initial));\n const [typedName, setTypedName] = createSignal(initial?.kind === \"typed\" ? initial.name : \"\");\n const [live, setLive] = createSignal(\"\");\n let svg: SVGSVGElement | undefined;\n let nameInput: HTMLInputElement | undefined;\n let lastReported: SignatureValue | null = initial;\n\n const drawnValue = (): SignatureValue | null => {\n const markup = drawingToSvg(drawing());\n return markup ? { kind: \"drawn\", svg: markup } : null;\n };\n const typedValue = (): SignatureValue | null => {\n const name = signatureName(typedName());\n if (!name) return null;\n const family = nameInput ? getComputedStyle(nameInput).fontFamily : \"cursive\";\n return { kind: \"typed\", name, svg: typedToSvg(name, family, measureText) };\n };\n const report = (next: SignatureValue | null, commit: boolean) => {\n if (sameValue(next, lastReported)) return;\n lastReported = next;\n if (commit) commitFieldValue(props, next);\n else props.onValueChange?.(next);\n };\n\n let stroke: { pointerId: number; pointerType: string; points: SignaturePoint[]; time: number } | null = null;\n /** Drops the stroke in progress without keeping its ink. */\n const abortStroke = () => {\n if (!stroke) return;\n const { pointerId } = stroke;\n stroke = null;\n setLive(\"\");\n if (svg?.hasPointerCapture(pointerId)) svg.releasePointerCapture(pointerId);\n };\n /** After Clear or the last Undo, keyboard focus moves from the now disabled button to the pad instead of the page. */\n const keepFocus = (button: HTMLElement) => {\n if (button.matches(\":focus-visible\")) queueMicrotask(() => svg?.focus());\n };\n\n // A value the parent sets (a stored signature, another record, a reset to null) replaces both inputs, so nothing of an\n // earlier signer stays behind the mode switch. Our own reports echo back unchanged.\n createEffect(\n on(\n value,\n (next) => {\n if (next === lastReported || sameValue(next, lastReported)) return;\n lastReported = next;\n abortStroke();\n setDrawing(drawingOf(next));\n setTypedName(next?.kind === \"typed\" ? next.name : \"\");\n if (next) setMode(next.kind === \"typed\" ? \"type\" : \"draw\");\n },\n { defer: true },\n ),\n );\n // A field that turns disabled or read-only, or leaves drawing, ends the stroke in progress without a value.\n createEffect(() => {\n if (!editable() || mode() !== \"draw\") abortStroke();\n });\n\n const switchMode = (next: SignatureMode) => {\n if (!editable() || next === mode()) return;\n setMode(next);\n report(next === \"draw\" ? drawnValue() : typedValue(), true);\n };\n const undo = (event: MouseEvent & { currentTarget: HTMLButtonElement }) => {\n if (!editable()) return;\n setDrawing((current) => ({ ...current, strokes: current.strokes.slice(0, -1) }));\n if (drawing().strokes.length === 0) keepFocus(event.currentTarget);\n report(drawnValue(), true);\n };\n const clear = (event: MouseEvent & { currentTarget: HTMLButtonElement }) => {\n if (!editable()) return;\n abortStroke();\n // Clear starts over in both modes. Without the Type option, a typed value it removes gives way to drawing.\n setTypedName(\"\");\n setDrawing((current) => ({ ...current, strokes: [] }));\n if (mode() === \"type\" && allowTyped()) {\n nameInput?.focus();\n } else {\n setMode(\"draw\");\n keepFocus(event.currentTarget);\n }\n report(null, true);\n };\n\n const toPoint = (event: PointerEvent): { x: number; y: number } | null => {\n const matrix = svg?.getScreenCTM();\n if (!matrix) return null;\n const point = new DOMPoint(event.clientX, event.clientY).matrixTransform(matrix.inverse());\n return { x: point.x, y: point.y };\n };\n const addPoint = (event: PointerEvent, force = false) => {\n if (!stroke) return;\n const position = toPoint(event);\n if (!position) return;\n const previous = stroke.points[stroke.points.length - 1];\n const distance = previous ? Math.hypot(position.x - previous.x, position.y - previous.y) : 0;\n if (previous && distance < MIN_POINT_DISTANCE && !force) return;\n let pressure: number;\n if (event.pointerType === \"pen\" && event.pressure > 0) {\n pressure = event.pressure;\n } else {\n // Without real pressure, faster movement draws a thinner line, as ink does.\n const elapsed = Math.max(1, event.timeStamp - stroke.time);\n const target = Math.min(1, Math.max(0.3, 1.1 - (distance / elapsed) * 0.3));\n pressure = previous ? previous.pressure * 0.6 + target * 0.4 : 0.6;\n }\n stroke.time = event.timeStamp;\n stroke.points.push({ ...position, pressure });\n setLive(strokeOutline(stroke.points, STROKE_SIZE));\n };\n /**\n * The drawing space after a stroke. It stays as it is while the ink lies inside it. Ink beyond it, drawn after the\n * pad changed its shape (a rotated phone, a resized window, a drawing from another device), grows the space to the\n * whole visible pad: the stored SVG then holds everything the signer saw, and the ink on the pad does not move.\n */\n const spaceAfter = (points: readonly SignaturePoint[]): Omit<SignatureDrawing, \"strokes\"> => {\n const { strokes: _, ...space } = drawing();\n const matrix = svg?.getScreenCTM();\n if (!svg || !matrix) return space;\n const box = svg.getBoundingClientRect();\n const inverse = matrix.inverse();\n const start = new DOMPoint(box.left, box.top).matrixTransform(inverse);\n const end = new DOMPoint(box.right, box.bottom).matrixTransform(inverse);\n // Ink reaches half the widest stroke past its points; what lies outside the pad was never visible and does not count.\n const reach = STROKE_SIZE / 2;\n let left = end.x;\n let top = end.y;\n let right = start.x;\n let bottom = start.y;\n for (const point of points) {\n left = Math.min(left, Math.max(start.x, point.x - reach));\n top = Math.min(top, Math.max(start.y, point.y - reach));\n right = Math.max(right, Math.min(end.x, point.x + reach));\n bottom = Math.max(bottom, Math.min(end.y, point.y + reach));\n }\n if (left >= space.x && top >= space.y && right <= space.x + space.width && bottom <= space.y + space.height) return space;\n const x = Math.min(space.x, start.x);\n const y = Math.min(space.y, start.y);\n return {\n x,\n y,\n width: Math.max(space.x + space.width, end.x) - x,\n height: Math.max(space.y + space.height, end.y) - y,\n };\n };\n const startStroke = (event: PointerEvent) => {\n // Only the primary contact draws: not a mouse's other buttons, a pen's barrel button, or its eraser.\n if (!editable() || !svg || event.button !== 0) return;\n // A pen takes over from a touch that is still down, such as a palm resting on a tablet.\n if (stroke?.pointerType === \"touch\" && event.pointerType === \"pen\") abortStroke();\n if (stroke) return;\n event.preventDefault();\n try {\n // Capture keeps the stroke when the pointer leaves the pad; a pointer that already ended cannot be captured.\n svg.setPointerCapture(event.pointerId);\n } catch {}\n if (drawing().strokes.length === 0) {\n // An empty pad adopts its current size, so one drawing unit is one CSS pixel while drawing.\n const box = svg.getBoundingClientRect();\n setDrawing({ x: 0, y: 0, width: Math.max(1, box.width), height: Math.max(1, box.height), strokes: [] });\n }\n stroke = { pointerId: event.pointerId, pointerType: event.pointerType, points: [], time: event.timeStamp };\n addPoint(event, true);\n };\n const moveStroke = (event: PointerEvent) => {\n if (stroke?.pointerId !== event.pointerId) return;\n event.preventDefault();\n const events = event.getCoalescedEvents?.() ?? [];\n for (const sample of events.length > 0 ? events : [event]) addPoint(sample);\n };\n const endStroke = (event: PointerEvent) => {\n if (!stroke || stroke.pointerId !== event.pointerId) return;\n addPoint(event, false);\n const { points } = stroke;\n const outline = strokeOutline(points, STROKE_SIZE);\n stroke = null;\n setLive(\"\");\n if (!outline) return;\n const space = spaceAfter(points);\n setDrawing((current) => ({ ...space, strokes: [...current.strokes, outline] }));\n report(drawnValue(), true);\n };\n // A cancelled pointer (an OS gesture, palm rejection) or lost capture is not a finished stroke.\n const cancelStroke = (event: PointerEvent) => {\n if (stroke?.pointerId === event.pointerId) abortStroke();\n };\n\n const empty = () => (mode() === \"draw\" ? drawing().strokes.length === 0 && !live() : !signatureName(typedName()));\n const serialized = () => {\n const current = value();\n return current ? JSON.stringify(current) : \"\";\n };\n\n return (\n <Field\n class={props.class}\n label={props.label}\n description={props.description}\n error={error()}\n meta={meta}\n labelFor={false}\n required={props.required}\n disabled={props.disabled}\n >\n <div\n id={meta.controlId}\n class=\"k2b-signature-input\"\n role=\"group\"\n aria-label={props.label ? undefined : props[\"aria-label\"]}\n aria-labelledby={props.label ? meta.labelId : undefined}\n aria-describedby={[props.required ? requiredId : undefined, fieldDescribedBy(meta, props)].filter(Boolean).join(\" \") || undefined}\n aria-invalid={error() ? \"true\" : undefined}\n data-mode={mode()}\n data-empty={empty() ? \"true\" : undefined}\n data-invalid={error() ? \"true\" : undefined}\n data-disabled={props.disabled ? \"true\" : undefined}\n data-readonly={props.readOnly ? \"true\" : undefined}\n >\n {/* A group cannot be marked required, so the required state is part of its description. */}\n <Show when={props.required}>\n <span id={requiredId} hidden>\n {messages().required}\n </span>\n </Show>\n <div class=\"k2b-signature-input__toolbar\">\n <Show when={allowTyped()}>\n <SegmentedControl\n class=\"k2b-signature-input__modes\"\n size=\"sm\"\n ariaLabel={text().method}\n options={[\n { value: \"draw\", label: text().draw, icon: \"ti ti-signature\" },\n { value: \"type\", label: text().type, icon: \"ti ti-keyboard\" },\n ]}\n value={mode}\n onValueChange={switchMode}\n disabled={!editable()}\n />\n </Show>\n <div class=\"k2b-signature-input__actions\">\n <IconButton\n size=\"sm\"\n variant=\"ghost\"\n label={text().undo}\n data-hidden={mode() === \"type\" ? \"true\" : undefined}\n disabled={!editable() || mode() !== \"draw\" || drawing().strokes.length === 0}\n onClick={undo}\n >\n <i class=\"ti ti-arrow-back-up\" aria-hidden=\"true\" />\n </IconButton>\n <IconButton size=\"sm\" variant=\"ghost\" label={messages().clear} disabled={!editable() || empty()} onClick={clear}>\n <i class=\"ti ti-eraser\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n </div>\n <div class=\"k2b-signature-input__pad\">\n <span class=\"k2b-signature-input__line\" aria-hidden=\"true\" />\n <Show\n when={mode() === \"draw\"}\n fallback={\n <input\n ref={nameInput}\n class=\"k2b-signature-input__name\"\n type=\"text\"\n value={typedName()}\n placeholder={text().typeName}\n aria-label={text().typeName}\n aria-describedby={fieldDescribedBy(meta, props)}\n aria-invalid={error() ? \"true\" : undefined}\n aria-required={props.required || undefined}\n autocomplete=\"name\"\n autocapitalize=\"words\"\n spellcheck={false}\n disabled={props.disabled}\n readOnly={props.readOnly || !allowTyped()}\n onInput={(event) => {\n setTypedName(event.currentTarget.value);\n report(typedValue(), false);\n }}\n onChange={() => props.onValueCommit?.(typedValue())}\n />\n }\n >\n <span class=\"k2b-signature-input__placeholder\" aria-hidden=\"true\">\n <i class=\"ti ti-writing-sign\" aria-hidden=\"true\" />\n {text().signHere}\n </span>\n <svg\n ref={svg}\n class=\"k2b-signature-input__canvas\"\n role=\"img\"\n tabindex=\"-1\"\n aria-label={drawing().strokes.length > 0 ? text().drawn : text().drawArea}\n viewBox={`${drawing().x} ${drawing().y} ${drawing().width} ${drawing().height}`}\n preserveAspectRatio=\"xMidYMid meet\"\n onPointerDown={startStroke}\n onPointerMove={moveStroke}\n onPointerUp={endStroke}\n onPointerCancel={cancelStroke}\n onLostPointerCapture={(event) => {\n // A child path that held a touch's implicit capture hands it to the pad; only the pad's own loss counts.\n if (event.target === event.currentTarget) cancelStroke(event);\n }}\n >\n <g fill=\"currentColor\">\n <For each={drawing().strokes}>{(outline) => <path d={outline} />}</For>\n <Show when={live()}>\n <path d={live()} />\n </Show>\n </g>\n </svg>\n </Show>\n </div>\n </div>\n <Show when={props.name}>{(name) => <input type=\"hidden\" name={name()} value={serialized()} />}</Show>\n </Field>\n );\n}\n\nexport default SignatureInput;\n"],"mappings":"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","ignoreList":[]}
|