@zag-js/pin-input 0.2.5 → 0.2.7

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.
@@ -0,0 +1,344 @@
1
+ import {
2
+ isObject
3
+ } from "./chunk-NT4W6JYX.mjs";
4
+ import {
5
+ dom,
6
+ getWindow
7
+ } from "./chunk-OI3DK2PT.mjs";
8
+
9
+ // src/pin-input.machine.ts
10
+ import { createMachine, guards } from "@zag-js/core";
11
+
12
+ // ../../utilities/core/src/object.ts
13
+ function compact(obj) {
14
+ if (obj === void 0)
15
+ return obj;
16
+ return Object.fromEntries(
17
+ Object.entries(obj).filter(([, value]) => value !== void 0).map(([key, value]) => [key, isObject(value) ? compact(value) : value])
18
+ );
19
+ }
20
+
21
+ // ../../utilities/dom/src/next-tick.ts
22
+ function raf(fn) {
23
+ const id = globalThis.requestAnimationFrame(fn);
24
+ return function cleanup() {
25
+ globalThis.cancelAnimationFrame(id);
26
+ };
27
+ }
28
+
29
+ // ../../utilities/form-utils/src/input-event.ts
30
+ function getDescriptor(el, options) {
31
+ var _a;
32
+ const { type, property = "value" } = options;
33
+ const proto = getWindow(el)[type].prototype;
34
+ return (_a = Object.getOwnPropertyDescriptor(proto, property)) != null ? _a : {};
35
+ }
36
+ function dispatchInputValueEvent(el, value) {
37
+ var _a;
38
+ if (!el)
39
+ return;
40
+ const win = getWindow(el);
41
+ if (!(el instanceof win.HTMLInputElement))
42
+ return;
43
+ const desc = getDescriptor(el, { type: "HTMLInputElement", property: "value" });
44
+ (_a = desc.set) == null ? void 0 : _a.call(el, value);
45
+ const event = new win.Event("input", { bubbles: true });
46
+ el.dispatchEvent(event);
47
+ }
48
+
49
+ // src/pin-input.machine.ts
50
+ var { and, not } = guards;
51
+ function machine(userContext) {
52
+ const ctx = compact(userContext);
53
+ return createMachine(
54
+ {
55
+ id: "pin-input",
56
+ initial: "unknown",
57
+ context: {
58
+ value: [],
59
+ focusedIndex: -1,
60
+ placeholder: "\u25CB",
61
+ otp: false,
62
+ type: "numeric",
63
+ ...ctx,
64
+ translations: {
65
+ inputLabel: (index, length) => `pin code ${index + 1} of ${length}`,
66
+ ...ctx.translations
67
+ }
68
+ },
69
+ computed: {
70
+ valueLength: (ctx2) => ctx2.value.length,
71
+ filledValueLength: (ctx2) => ctx2.value.filter((v) => (v == null ? void 0 : v.trim()) !== "").length,
72
+ isValueComplete: (ctx2) => ctx2.valueLength === ctx2.filledValueLength,
73
+ valueAsString: (ctx2) => ctx2.value.join(""),
74
+ focusedValue: (ctx2) => ctx2.value[ctx2.focusedIndex]
75
+ },
76
+ watch: {
77
+ focusedIndex: ["focusInput", "setInputSelection"],
78
+ value: ["dispatchInputEvent"],
79
+ isValueComplete: ["invokeOnComplete", "blurFocusedInputIfNeeded"]
80
+ },
81
+ on: {
82
+ SET_VALUE: [
83
+ {
84
+ guard: "hasIndex",
85
+ actions: ["setValueAtIndex", "invokeOnChange"]
86
+ },
87
+ { actions: ["setValue", "invokeOnChange"] }
88
+ ],
89
+ CLEAR_VALUE: [
90
+ {
91
+ guard: "isDisabled",
92
+ actions: ["clearValue", "invokeOnChange"]
93
+ },
94
+ {
95
+ actions: ["clearValue", "invokeOnChange", "setFocusIndexToFirst"]
96
+ }
97
+ ]
98
+ },
99
+ states: {
100
+ unknown: {
101
+ on: {
102
+ SETUP: [
103
+ {
104
+ guard: "autoFocus",
105
+ target: "focused",
106
+ actions: ["setupValue", "setFocusIndexToFirst"]
107
+ },
108
+ {
109
+ target: "idle",
110
+ actions: "setupValue"
111
+ }
112
+ ]
113
+ }
114
+ },
115
+ idle: {
116
+ on: {
117
+ FOCUS: {
118
+ target: "focused",
119
+ actions: "setFocusedIndex"
120
+ }
121
+ }
122
+ },
123
+ focused: {
124
+ on: {
125
+ INPUT: [
126
+ {
127
+ guard: and("isFinalValue", "isValidValue"),
128
+ actions: ["setFocusedValue", "invokeOnChange", "dispatchInputEventIfNeeded"]
129
+ },
130
+ {
131
+ guard: "isValidValue",
132
+ actions: ["setFocusedValue", "invokeOnChange", "setNextFocusedIndex", "dispatchInputEventIfNeeded"]
133
+ }
134
+ ],
135
+ PASTE: [
136
+ {
137
+ guard: "isValidValue",
138
+ actions: ["setPastedValue", "invokeOnChange", "setLastValueFocusIndex"]
139
+ },
140
+ { actions: ["resetFocusedValue", "invokeOnChange"] }
141
+ ],
142
+ BLUR: {
143
+ target: "idle",
144
+ actions: "clearFocusedIndex"
145
+ },
146
+ DELETE: {
147
+ guard: "hasValue",
148
+ actions: ["clearFocusedValue", "invokeOnChange"]
149
+ },
150
+ ARROW_LEFT: {
151
+ actions: "setPrevFocusedIndex"
152
+ },
153
+ ARROW_RIGHT: {
154
+ actions: "setNextFocusedIndex"
155
+ },
156
+ BACKSPACE: [
157
+ {
158
+ guard: "hasValue",
159
+ actions: ["clearFocusedValue", "invokeOnChange"]
160
+ },
161
+ {
162
+ actions: ["setPrevFocusedIndex", "clearFocusedValue", "invokeOnChange"]
163
+ }
164
+ ],
165
+ ENTER: {
166
+ guard: "isValueComplete",
167
+ actions: "requestFormSubmit"
168
+ },
169
+ KEY_DOWN: {
170
+ guard: not("isValidValue"),
171
+ actions: ["preventDefault", "invokeOnInvalid"]
172
+ }
173
+ }
174
+ }
175
+ }
176
+ },
177
+ {
178
+ guards: {
179
+ autoFocus: (ctx2) => !!ctx2.autoFocus,
180
+ isValueEmpty: (_ctx, evt) => evt.value === "",
181
+ hasValue: (ctx2) => ctx2.value[ctx2.focusedIndex] !== "",
182
+ isValueComplete: (ctx2) => ctx2.isValueComplete,
183
+ isValidValue: (ctx2, evt) => {
184
+ if (!ctx2.pattern)
185
+ return isValidType(evt.value, ctx2.type);
186
+ const regex = new RegExp(ctx2.pattern, "g");
187
+ return regex.test(evt.value);
188
+ },
189
+ isFinalValue: (ctx2) => {
190
+ return ctx2.filledValueLength + 1 === ctx2.valueLength && ctx2.value.findIndex((v) => v.trim() === "") === ctx2.focusedIndex;
191
+ },
192
+ isLastInputFocused: (ctx2) => ctx2.focusedIndex === ctx2.valueLength - 1,
193
+ hasIndex: (_ctx, evt) => evt.index !== void 0,
194
+ isDisabled: (ctx2) => !!ctx2.disabled
195
+ },
196
+ actions: {
197
+ setupValue: (ctx2) => {
198
+ const inputs = dom.getElements(ctx2);
199
+ const empty = Array.from({ length: inputs.length }).map(() => "");
200
+ ctx2.value = Object.assign(empty, ctx2.value);
201
+ },
202
+ focusInput: (ctx2) => {
203
+ raf(() => {
204
+ var _a;
205
+ if (ctx2.focusedIndex === -1)
206
+ return;
207
+ (_a = dom.getFocusedEl(ctx2)) == null ? void 0 : _a.focus();
208
+ });
209
+ },
210
+ setInputSelection: (ctx2) => {
211
+ raf(() => {
212
+ if (ctx2.focusedIndex === -1)
213
+ return;
214
+ const input = dom.getFocusedEl(ctx2);
215
+ const length = input.value.length;
216
+ input.selectionStart = ctx2.selectOnFocus ? 0 : length;
217
+ input.selectionEnd = length;
218
+ });
219
+ },
220
+ invokeOnComplete: (ctx2) => {
221
+ var _a;
222
+ if (!ctx2.isValueComplete)
223
+ return;
224
+ (_a = ctx2.onComplete) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value), valueAsString: ctx2.valueAsString });
225
+ },
226
+ invokeOnChange: (ctx2, evt) => {
227
+ var _a;
228
+ if (evt.type === "SETUP")
229
+ return;
230
+ (_a = ctx2.onChange) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value) });
231
+ },
232
+ dispatchInputEvent: (ctx2, evt) => {
233
+ if (evt.type === "SETUP")
234
+ return;
235
+ dispatchInputValueEvent(dom.getHiddenInputEl(ctx2), ctx2.valueAsString);
236
+ const inputs = dom.getElements(ctx2);
237
+ ctx2.value.forEach((val, index) => {
238
+ const input = inputs[index];
239
+ input.value = val || "";
240
+ });
241
+ },
242
+ invokeOnInvalid: (ctx2, evt) => {
243
+ var _a;
244
+ (_a = ctx2.onInvalid) == null ? void 0 : _a.call(ctx2, { value: evt.value, index: ctx2.focusedIndex });
245
+ },
246
+ clearFocusedIndex: (ctx2) => {
247
+ ctx2.focusedIndex = -1;
248
+ },
249
+ setValue: (ctx2, evt) => {
250
+ assign(ctx2, evt.value);
251
+ },
252
+ setFocusedIndex: (ctx2, evt) => {
253
+ ctx2.focusedIndex = evt.index;
254
+ },
255
+ setFocusedValue: (ctx2, evt) => {
256
+ ctx2.value[ctx2.focusedIndex] = lastChar(evt.value);
257
+ },
258
+ dispatchInputEventIfNeeded: (ctx2, evt) => {
259
+ const valueIsChanged = lastChar(evt.value) !== ctx2.focusedValue;
260
+ if (evt.value.length <= 1 || valueIsChanged)
261
+ return;
262
+ const inputs = dom.getElements(ctx2);
263
+ const input = inputs[ctx2.focusedIndex];
264
+ input.value = lastChar(evt.value);
265
+ },
266
+ setPastedValue(ctx2, evt) {
267
+ raf(() => {
268
+ const startIndex = ctx2.focusedValue ? 1 : 0;
269
+ const value = evt.value.substring(startIndex, ctx2.valueLength);
270
+ assign(ctx2, value);
271
+ });
272
+ },
273
+ setValueAtIndex: (ctx2, evt) => {
274
+ ctx2.value[evt.index] = lastChar(evt.value);
275
+ },
276
+ clearValue: (ctx2) => {
277
+ ctx2.value = ctx2.value.map(() => "");
278
+ },
279
+ clearFocusedValue: (ctx2) => {
280
+ ctx2.value[ctx2.focusedIndex] = "";
281
+ },
282
+ resetFocusedValue: (ctx2) => {
283
+ const input = dom.getFocusedEl(ctx2);
284
+ input.value = ctx2.focusedValue;
285
+ },
286
+ setFocusIndexToFirst: (ctx2) => {
287
+ ctx2.focusedIndex = 0;
288
+ },
289
+ setNextFocusedIndex: (ctx2) => {
290
+ ctx2.focusedIndex = Math.min(ctx2.focusedIndex + 1, ctx2.valueLength - 1);
291
+ },
292
+ setPrevFocusedIndex: (ctx2) => {
293
+ ctx2.focusedIndex = Math.max(ctx2.focusedIndex - 1, 0);
294
+ },
295
+ setLastValueFocusIndex: (ctx2) => {
296
+ raf(() => {
297
+ ctx2.focusedIndex = Math.min(ctx2.filledValueLength, ctx2.valueLength - 1);
298
+ });
299
+ },
300
+ preventDefault(_, evt) {
301
+ evt.preventDefault();
302
+ },
303
+ blurFocusedInputIfNeeded(ctx2) {
304
+ if (!ctx2.blurOnComplete)
305
+ return;
306
+ raf(() => {
307
+ var _a;
308
+ (_a = dom.getFocusedEl(ctx2)) == null ? void 0 : _a.blur();
309
+ });
310
+ },
311
+ requestFormSubmit(ctx2) {
312
+ var _a;
313
+ if (!ctx2.name)
314
+ return;
315
+ const input = dom.getHiddenInputEl(ctx2);
316
+ (_a = input == null ? void 0 : input.form) == null ? void 0 : _a.requestSubmit();
317
+ }
318
+ }
319
+ }
320
+ );
321
+ }
322
+ var REGEX = {
323
+ numeric: /^[0-9]+$/,
324
+ alphabetic: /^[A-Za-z]+$/,
325
+ alphanumeric: /^[a-zA-Z0-9]+$/i
326
+ };
327
+ function isValidType(value, type) {
328
+ var _a;
329
+ if (!type)
330
+ return true;
331
+ return !!((_a = REGEX[type]) == null ? void 0 : _a.test(value));
332
+ }
333
+ function assign(ctx, value) {
334
+ const valueArr = Array.isArray(value) ? value : value.split("").filter(Boolean);
335
+ const valueObj = Object.assign({}, ctx.value, valueArr);
336
+ ctx.value = Object.values(valueObj);
337
+ }
338
+ function lastChar(value) {
339
+ return value.charAt(value.length - 1);
340
+ }
341
+
342
+ export {
343
+ machine
344
+ };
@@ -0,0 +1,9 @@
1
+ // src/pin-input.anatomy.ts
2
+ import { createAnatomy } from "@zag-js/anatomy";
3
+ var anatomy = createAnatomy("pinInput").parts("root", "label", "hiddenInput", "input", "control");
4
+ var parts = anatomy.build();
5
+
6
+ export {
7
+ anatomy,
8
+ parts
9
+ };
@@ -0,0 +1,7 @@
1
+ // ../../utilities/core/src/guard.ts
2
+ var isArray = (v) => Array.isArray(v);
3
+ var isObject = (v) => !(v == null || typeof v !== "object" || isArray(v));
4
+
5
+ export {
6
+ isObject
7
+ };
@@ -0,0 +1,100 @@
1
+ // ../../utilities/dom/src/query.ts
2
+ function isDocument(el) {
3
+ return el.nodeType === Node.DOCUMENT_NODE;
4
+ }
5
+ function isWindow(value) {
6
+ return (value == null ? void 0 : value.toString()) === "[object Window]";
7
+ }
8
+ function getDocument(el) {
9
+ var _a;
10
+ if (isWindow(el))
11
+ return el.document;
12
+ if (isDocument(el))
13
+ return el;
14
+ return (_a = el == null ? void 0 : el.ownerDocument) != null ? _a : document;
15
+ }
16
+ function getWindow(el) {
17
+ var _a;
18
+ return (_a = el == null ? void 0 : el.ownerDocument.defaultView) != null ? _a : window;
19
+ }
20
+ function defineDomHelpers(helpers) {
21
+ const dom2 = {
22
+ getRootNode: (ctx) => {
23
+ var _a, _b;
24
+ return (_b = (_a = ctx.getRootNode) == null ? void 0 : _a.call(ctx)) != null ? _b : document;
25
+ },
26
+ getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
27
+ getWin: (ctx) => {
28
+ var _a;
29
+ return (_a = dom2.getDoc(ctx).defaultView) != null ? _a : window;
30
+ },
31
+ getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
32
+ getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id),
33
+ createEmitter: (ctx, target) => {
34
+ const win = dom2.getWin(ctx);
35
+ return function emit(evt, detail, options) {
36
+ const { bubbles = true, cancelable, composed = true } = options != null ? options : {};
37
+ const eventName = `zag:${evt}`;
38
+ const init = { bubbles, cancelable, composed, detail };
39
+ const event = new win.CustomEvent(eventName, init);
40
+ target.dispatchEvent(event);
41
+ };
42
+ },
43
+ createListener: (target) => {
44
+ return function listen(evt, handler) {
45
+ const eventName = `zag:${evt}`;
46
+ const listener = (e) => handler(e);
47
+ target.addEventListener(eventName, listener);
48
+ return () => target.removeEventListener(eventName, listener);
49
+ };
50
+ }
51
+ };
52
+ return {
53
+ ...dom2,
54
+ ...helpers
55
+ };
56
+ }
57
+
58
+ // ../../utilities/dom/src/nodelist.ts
59
+ function queryAll(root, selector) {
60
+ var _a;
61
+ return Array.from((_a = root == null ? void 0 : root.querySelectorAll(selector)) != null ? _a : []);
62
+ }
63
+
64
+ // src/pin-input.dom.ts
65
+ var dom = defineDomHelpers({
66
+ getRootId: (ctx) => {
67
+ var _a, _b;
68
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.root) != null ? _b : `pin-input:${ctx.id}`;
69
+ },
70
+ getInputId: (ctx, id) => {
71
+ var _a, _b, _c;
72
+ return (_c = (_b = (_a = ctx.ids) == null ? void 0 : _a.input) == null ? void 0 : _b.call(_a, id)) != null ? _c : `pin-input:${ctx.id}:${id}`;
73
+ },
74
+ getHiddenInputId: (ctx) => {
75
+ var _a, _b;
76
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.hiddenInput) != null ? _b : `pin-input:${ctx.id}:hidden`;
77
+ },
78
+ getLabelId: (ctx) => {
79
+ var _a, _b;
80
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.label) != null ? _b : `pin-input:${ctx.id}:label`;
81
+ },
82
+ getControlId: (ctx) => {
83
+ var _a, _b;
84
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.control) != null ? _b : `pin-input:${ctx.id}:control`;
85
+ },
86
+ getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
87
+ getElements: (ctx) => {
88
+ const ownerId = CSS.escape(dom.getRootId(ctx));
89
+ const selector = `input[data-ownedby=${ownerId}]`;
90
+ return queryAll(dom.getRootEl(ctx), selector);
91
+ },
92
+ getFocusedEl: (ctx) => dom.getElements(ctx)[ctx.focusedIndex],
93
+ getFirstInputEl: (ctx) => dom.getElements(ctx)[0],
94
+ getHiddenInputEl: (ctx) => dom.getById(ctx, dom.getHiddenInputId(ctx))
95
+ });
96
+
97
+ export {
98
+ getWindow,
99
+ dom
100
+ };
@@ -0,0 +1,212 @@
1
+ import {
2
+ parts
3
+ } from "./chunk-BJXKBZJG.mjs";
4
+ import {
5
+ dom
6
+ } from "./chunk-OI3DK2PT.mjs";
7
+
8
+ // ../../utilities/dom/src/attrs.ts
9
+ var dataAttr = (guard) => {
10
+ return guard ? "" : void 0;
11
+ };
12
+ var ariaAttr = (guard) => {
13
+ return guard ? "true" : void 0;
14
+ };
15
+
16
+ // ../../utilities/core/src/warning.ts
17
+ function invariant(...a) {
18
+ const m = a.length === 1 ? a[0] : a[1];
19
+ const c = a.length === 2 ? a[0] : true;
20
+ if (c && process.env.NODE_ENV !== "production") {
21
+ throw new Error(m);
22
+ }
23
+ }
24
+
25
+ // ../../utilities/dom/src/event.ts
26
+ function getNativeEvent(e) {
27
+ var _a;
28
+ return (_a = e.nativeEvent) != null ? _a : e;
29
+ }
30
+ var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
31
+
32
+ // ../../utilities/dom/src/keyboard-event.ts
33
+ var rtlKeyMap = {
34
+ ArrowLeft: "ArrowRight",
35
+ ArrowRight: "ArrowLeft"
36
+ };
37
+ var sameKeyMap = {
38
+ Up: "ArrowUp",
39
+ Down: "ArrowDown",
40
+ Esc: "Escape",
41
+ " ": "Space",
42
+ ",": "Comma",
43
+ Left: "ArrowLeft",
44
+ Right: "ArrowRight"
45
+ };
46
+ function getEventKey(event, options = {}) {
47
+ var _a;
48
+ const { dir = "ltr", orientation = "horizontal" } = options;
49
+ let { key } = event;
50
+ key = (_a = sameKeyMap[key]) != null ? _a : key;
51
+ const isRtl = dir === "rtl" && orientation === "horizontal";
52
+ if (isRtl && key in rtlKeyMap) {
53
+ key = rtlKeyMap[key];
54
+ }
55
+ return key;
56
+ }
57
+
58
+ // ../../utilities/dom/src/visually-hidden.ts
59
+ var visuallyHiddenStyle = {
60
+ border: "0",
61
+ clip: "rect(0 0 0 0)",
62
+ height: "1px",
63
+ margin: "-1px",
64
+ overflow: "hidden",
65
+ padding: "0",
66
+ position: "absolute",
67
+ width: "1px",
68
+ whiteSpace: "nowrap",
69
+ wordWrap: "normal"
70
+ };
71
+
72
+ // src/pin-input.connect.ts
73
+ function connect(state, send, normalize) {
74
+ const isValueComplete = state.context.isValueComplete;
75
+ const isInvalid = state.context.invalid;
76
+ const focusedIndex = state.context.focusedIndex;
77
+ const translations = state.context.translations;
78
+ function focus() {
79
+ var _a;
80
+ (_a = dom.getFirstInputEl(state.context)) == null ? void 0 : _a.focus();
81
+ }
82
+ return {
83
+ value: state.context.value,
84
+ valueAsString: state.context.valueAsString,
85
+ isValueComplete,
86
+ setValue(value) {
87
+ if (!Array.isArray(value)) {
88
+ invariant("[pin-input/setValue] value must be an array");
89
+ }
90
+ send({ type: "SET_VALUE", value });
91
+ },
92
+ clearValue() {
93
+ send({ type: "CLEAR_VALUE" });
94
+ },
95
+ setValueAtIndex(index, value) {
96
+ send({ type: "SET_VALUE", value, index });
97
+ },
98
+ focus,
99
+ rootProps: normalize.element({
100
+ dir: state.context.dir,
101
+ ...parts.root.attrs,
102
+ id: dom.getRootId(state.context),
103
+ "data-invalid": dataAttr(isInvalid),
104
+ "data-disabled": dataAttr(state.context.disabled),
105
+ "data-complete": dataAttr(isValueComplete)
106
+ }),
107
+ labelProps: normalize.label({
108
+ ...parts.label.attrs,
109
+ htmlFor: dom.getHiddenInputId(state.context),
110
+ id: dom.getLabelId(state.context),
111
+ "data-invalid": dataAttr(isInvalid),
112
+ "data-disabled": dataAttr(state.context.disabled),
113
+ "data-complete": dataAttr(isValueComplete),
114
+ onClick: (event) => {
115
+ event.preventDefault();
116
+ focus();
117
+ }
118
+ }),
119
+ hiddenInputProps: normalize.input({
120
+ ...parts.hiddenInput.attrs,
121
+ "aria-hidden": true,
122
+ type: "text",
123
+ tabIndex: -1,
124
+ id: dom.getHiddenInputId(state.context),
125
+ name: state.context.name,
126
+ form: state.context.form,
127
+ style: visuallyHiddenStyle,
128
+ maxLength: state.context.valueLength,
129
+ defaultValue: state.context.valueAsString
130
+ }),
131
+ controlProps: normalize.element({
132
+ ...parts.control.attrs,
133
+ id: dom.getControlId(state.context)
134
+ }),
135
+ getInputProps({ index }) {
136
+ const inputType = state.context.type === "numeric" ? "tel" : "text";
137
+ return normalize.input({
138
+ ...parts.input.attrs,
139
+ disabled: state.context.disabled,
140
+ "data-disabled": dataAttr(state.context.disabled),
141
+ "data-complete": dataAttr(isValueComplete),
142
+ id: dom.getInputId(state.context, index.toString()),
143
+ "data-ownedby": dom.getRootId(state.context),
144
+ "aria-label": translations.inputLabel(index, state.context.valueLength),
145
+ inputMode: state.context.otp || state.context.type === "numeric" ? "numeric" : "text",
146
+ "aria-invalid": ariaAttr(isInvalid),
147
+ "data-invalid": dataAttr(isInvalid),
148
+ type: state.context.mask ? "password" : inputType,
149
+ defaultValue: state.context.value[index] || "",
150
+ autoCapitalize: "none",
151
+ autoComplete: state.context.otp ? "one-time-code" : "off",
152
+ placeholder: focusedIndex === index ? "" : state.context.placeholder,
153
+ onChange(event) {
154
+ const evt = getNativeEvent(event);
155
+ const { value } = event.currentTarget;
156
+ if (evt.inputType === "insertFromPaste" || value.length > 2) {
157
+ send({ type: "PASTE", value });
158
+ event.preventDefault();
159
+ return;
160
+ }
161
+ if (evt.inputType === "deleteContentBackward") {
162
+ send("BACKSPACE");
163
+ return;
164
+ }
165
+ send({ type: "INPUT", value });
166
+ },
167
+ onKeyDown(event) {
168
+ const evt = getNativeEvent(event);
169
+ if (evt.isComposing || isModifiedEvent(evt))
170
+ return;
171
+ const keyMap = {
172
+ Backspace() {
173
+ send("BACKSPACE");
174
+ },
175
+ Delete() {
176
+ send("DELETE");
177
+ },
178
+ ArrowLeft() {
179
+ send("ARROW_LEFT");
180
+ },
181
+ ArrowRight() {
182
+ send("ARROW_RIGHT");
183
+ },
184
+ Enter() {
185
+ send("ENTER");
186
+ }
187
+ };
188
+ const key = getEventKey(event, { dir: state.context.dir });
189
+ const exec = keyMap[key];
190
+ if (exec) {
191
+ exec(event);
192
+ event.preventDefault();
193
+ } else {
194
+ if (key === "Tab")
195
+ return;
196
+ send({ type: "KEY_DOWN", value: key, preventDefault: () => event.preventDefault() });
197
+ }
198
+ },
199
+ onFocus() {
200
+ send({ type: "FOCUS", index });
201
+ },
202
+ onBlur() {
203
+ send({ type: "BLUR", index });
204
+ }
205
+ });
206
+ }
207
+ };
208
+ }
209
+
210
+ export {
211
+ connect
212
+ };