@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.
- package/dist/chunk-6HKN4SOY.mjs +344 -0
- package/dist/chunk-BJXKBZJG.mjs +9 -0
- package/dist/chunk-NT4W6JYX.mjs +7 -0
- package/dist/chunk-OI3DK2PT.mjs +100 -0
- package/dist/chunk-QX3A66VS.mjs +212 -0
- package/dist/index.d.ts +7 -1002
- package/dist/index.js +52 -36
- package/dist/index.mjs +11 -623
- package/dist/pin-input.anatomy.d.ts +6 -0
- package/dist/pin-input.anatomy.js +34 -0
- package/dist/pin-input.anatomy.mjs +8 -0
- package/dist/pin-input.connect.d.ts +22 -0
- package/dist/pin-input.connect.js +328 -0
- package/dist/pin-input.connect.mjs +9 -0
- package/dist/pin-input.dom.d.ts +38 -0
- package/dist/pin-input.dom.js +121 -0
- package/dist/pin-input.dom.mjs +6 -0
- package/dist/pin-input.machine.d.ts +7 -0
- package/dist/pin-input.machine.js +460 -0
- package/dist/pin-input.machine.mjs +8 -0
- package/dist/pin-input.types.d.ts +133 -0
- package/dist/pin-input.types.js +18 -0
- package/dist/pin-input.types.mjs +0 -0
- package/package.json +22 -12
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/pin-input.machine.ts
|
|
21
|
+
var pin_input_machine_exports = {};
|
|
22
|
+
__export(pin_input_machine_exports, {
|
|
23
|
+
machine: () => machine
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(pin_input_machine_exports);
|
|
26
|
+
var import_core = require("@zag-js/core");
|
|
27
|
+
|
|
28
|
+
// ../../utilities/core/src/guard.ts
|
|
29
|
+
var isArray = (v) => Array.isArray(v);
|
|
30
|
+
var isObject = (v) => !(v == null || typeof v !== "object" || isArray(v));
|
|
31
|
+
|
|
32
|
+
// ../../utilities/core/src/object.ts
|
|
33
|
+
function compact(obj) {
|
|
34
|
+
if (obj === void 0)
|
|
35
|
+
return obj;
|
|
36
|
+
return Object.fromEntries(
|
|
37
|
+
Object.entries(obj).filter(([, value]) => value !== void 0).map(([key, value]) => [key, isObject(value) ? compact(value) : value])
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ../../utilities/dom/src/query.ts
|
|
42
|
+
function isDocument(el) {
|
|
43
|
+
return el.nodeType === Node.DOCUMENT_NODE;
|
|
44
|
+
}
|
|
45
|
+
function isWindow(value) {
|
|
46
|
+
return (value == null ? void 0 : value.toString()) === "[object Window]";
|
|
47
|
+
}
|
|
48
|
+
function getDocument(el) {
|
|
49
|
+
var _a;
|
|
50
|
+
if (isWindow(el))
|
|
51
|
+
return el.document;
|
|
52
|
+
if (isDocument(el))
|
|
53
|
+
return el;
|
|
54
|
+
return (_a = el == null ? void 0 : el.ownerDocument) != null ? _a : document;
|
|
55
|
+
}
|
|
56
|
+
function getWindow(el) {
|
|
57
|
+
var _a;
|
|
58
|
+
return (_a = el == null ? void 0 : el.ownerDocument.defaultView) != null ? _a : window;
|
|
59
|
+
}
|
|
60
|
+
function defineDomHelpers(helpers) {
|
|
61
|
+
const dom2 = {
|
|
62
|
+
getRootNode: (ctx) => {
|
|
63
|
+
var _a, _b;
|
|
64
|
+
return (_b = (_a = ctx.getRootNode) == null ? void 0 : _a.call(ctx)) != null ? _b : document;
|
|
65
|
+
},
|
|
66
|
+
getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
|
|
67
|
+
getWin: (ctx) => {
|
|
68
|
+
var _a;
|
|
69
|
+
return (_a = dom2.getDoc(ctx).defaultView) != null ? _a : window;
|
|
70
|
+
},
|
|
71
|
+
getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
|
|
72
|
+
getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id),
|
|
73
|
+
createEmitter: (ctx, target) => {
|
|
74
|
+
const win = dom2.getWin(ctx);
|
|
75
|
+
return function emit(evt, detail, options) {
|
|
76
|
+
const { bubbles = true, cancelable, composed = true } = options != null ? options : {};
|
|
77
|
+
const eventName = `zag:${evt}`;
|
|
78
|
+
const init = { bubbles, cancelable, composed, detail };
|
|
79
|
+
const event = new win.CustomEvent(eventName, init);
|
|
80
|
+
target.dispatchEvent(event);
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
createListener: (target) => {
|
|
84
|
+
return function listen(evt, handler) {
|
|
85
|
+
const eventName = `zag:${evt}`;
|
|
86
|
+
const listener = (e) => handler(e);
|
|
87
|
+
target.addEventListener(eventName, listener);
|
|
88
|
+
return () => target.removeEventListener(eventName, listener);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
...dom2,
|
|
94
|
+
...helpers
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ../../utilities/dom/src/next-tick.ts
|
|
99
|
+
function raf(fn) {
|
|
100
|
+
const id = globalThis.requestAnimationFrame(fn);
|
|
101
|
+
return function cleanup() {
|
|
102
|
+
globalThis.cancelAnimationFrame(id);
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ../../utilities/dom/src/nodelist.ts
|
|
107
|
+
function queryAll(root, selector) {
|
|
108
|
+
var _a;
|
|
109
|
+
return Array.from((_a = root == null ? void 0 : root.querySelectorAll(selector)) != null ? _a : []);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ../../utilities/form-utils/src/input-event.ts
|
|
113
|
+
function getDescriptor(el, options) {
|
|
114
|
+
var _a;
|
|
115
|
+
const { type, property = "value" } = options;
|
|
116
|
+
const proto = getWindow(el)[type].prototype;
|
|
117
|
+
return (_a = Object.getOwnPropertyDescriptor(proto, property)) != null ? _a : {};
|
|
118
|
+
}
|
|
119
|
+
function dispatchInputValueEvent(el, value) {
|
|
120
|
+
var _a;
|
|
121
|
+
if (!el)
|
|
122
|
+
return;
|
|
123
|
+
const win = getWindow(el);
|
|
124
|
+
if (!(el instanceof win.HTMLInputElement))
|
|
125
|
+
return;
|
|
126
|
+
const desc = getDescriptor(el, { type: "HTMLInputElement", property: "value" });
|
|
127
|
+
(_a = desc.set) == null ? void 0 : _a.call(el, value);
|
|
128
|
+
const event = new win.Event("input", { bubbles: true });
|
|
129
|
+
el.dispatchEvent(event);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/pin-input.dom.ts
|
|
133
|
+
var dom = defineDomHelpers({
|
|
134
|
+
getRootId: (ctx) => {
|
|
135
|
+
var _a, _b;
|
|
136
|
+
return (_b = (_a = ctx.ids) == null ? void 0 : _a.root) != null ? _b : `pin-input:${ctx.id}`;
|
|
137
|
+
},
|
|
138
|
+
getInputId: (ctx, id) => {
|
|
139
|
+
var _a, _b, _c;
|
|
140
|
+
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}`;
|
|
141
|
+
},
|
|
142
|
+
getHiddenInputId: (ctx) => {
|
|
143
|
+
var _a, _b;
|
|
144
|
+
return (_b = (_a = ctx.ids) == null ? void 0 : _a.hiddenInput) != null ? _b : `pin-input:${ctx.id}:hidden`;
|
|
145
|
+
},
|
|
146
|
+
getLabelId: (ctx) => {
|
|
147
|
+
var _a, _b;
|
|
148
|
+
return (_b = (_a = ctx.ids) == null ? void 0 : _a.label) != null ? _b : `pin-input:${ctx.id}:label`;
|
|
149
|
+
},
|
|
150
|
+
getControlId: (ctx) => {
|
|
151
|
+
var _a, _b;
|
|
152
|
+
return (_b = (_a = ctx.ids) == null ? void 0 : _a.control) != null ? _b : `pin-input:${ctx.id}:control`;
|
|
153
|
+
},
|
|
154
|
+
getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
|
|
155
|
+
getElements: (ctx) => {
|
|
156
|
+
const ownerId = CSS.escape(dom.getRootId(ctx));
|
|
157
|
+
const selector = `input[data-ownedby=${ownerId}]`;
|
|
158
|
+
return queryAll(dom.getRootEl(ctx), selector);
|
|
159
|
+
},
|
|
160
|
+
getFocusedEl: (ctx) => dom.getElements(ctx)[ctx.focusedIndex],
|
|
161
|
+
getFirstInputEl: (ctx) => dom.getElements(ctx)[0],
|
|
162
|
+
getHiddenInputEl: (ctx) => dom.getById(ctx, dom.getHiddenInputId(ctx))
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// src/pin-input.machine.ts
|
|
166
|
+
var { and, not } = import_core.guards;
|
|
167
|
+
function machine(userContext) {
|
|
168
|
+
const ctx = compact(userContext);
|
|
169
|
+
return (0, import_core.createMachine)(
|
|
170
|
+
{
|
|
171
|
+
id: "pin-input",
|
|
172
|
+
initial: "unknown",
|
|
173
|
+
context: {
|
|
174
|
+
value: [],
|
|
175
|
+
focusedIndex: -1,
|
|
176
|
+
placeholder: "\u25CB",
|
|
177
|
+
otp: false,
|
|
178
|
+
type: "numeric",
|
|
179
|
+
...ctx,
|
|
180
|
+
translations: {
|
|
181
|
+
inputLabel: (index, length) => `pin code ${index + 1} of ${length}`,
|
|
182
|
+
...ctx.translations
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
computed: {
|
|
186
|
+
valueLength: (ctx2) => ctx2.value.length,
|
|
187
|
+
filledValueLength: (ctx2) => ctx2.value.filter((v) => (v == null ? void 0 : v.trim()) !== "").length,
|
|
188
|
+
isValueComplete: (ctx2) => ctx2.valueLength === ctx2.filledValueLength,
|
|
189
|
+
valueAsString: (ctx2) => ctx2.value.join(""),
|
|
190
|
+
focusedValue: (ctx2) => ctx2.value[ctx2.focusedIndex]
|
|
191
|
+
},
|
|
192
|
+
watch: {
|
|
193
|
+
focusedIndex: ["focusInput", "setInputSelection"],
|
|
194
|
+
value: ["dispatchInputEvent"],
|
|
195
|
+
isValueComplete: ["invokeOnComplete", "blurFocusedInputIfNeeded"]
|
|
196
|
+
},
|
|
197
|
+
on: {
|
|
198
|
+
SET_VALUE: [
|
|
199
|
+
{
|
|
200
|
+
guard: "hasIndex",
|
|
201
|
+
actions: ["setValueAtIndex", "invokeOnChange"]
|
|
202
|
+
},
|
|
203
|
+
{ actions: ["setValue", "invokeOnChange"] }
|
|
204
|
+
],
|
|
205
|
+
CLEAR_VALUE: [
|
|
206
|
+
{
|
|
207
|
+
guard: "isDisabled",
|
|
208
|
+
actions: ["clearValue", "invokeOnChange"]
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
actions: ["clearValue", "invokeOnChange", "setFocusIndexToFirst"]
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
},
|
|
215
|
+
states: {
|
|
216
|
+
unknown: {
|
|
217
|
+
on: {
|
|
218
|
+
SETUP: [
|
|
219
|
+
{
|
|
220
|
+
guard: "autoFocus",
|
|
221
|
+
target: "focused",
|
|
222
|
+
actions: ["setupValue", "setFocusIndexToFirst"]
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
target: "idle",
|
|
226
|
+
actions: "setupValue"
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
idle: {
|
|
232
|
+
on: {
|
|
233
|
+
FOCUS: {
|
|
234
|
+
target: "focused",
|
|
235
|
+
actions: "setFocusedIndex"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
focused: {
|
|
240
|
+
on: {
|
|
241
|
+
INPUT: [
|
|
242
|
+
{
|
|
243
|
+
guard: and("isFinalValue", "isValidValue"),
|
|
244
|
+
actions: ["setFocusedValue", "invokeOnChange", "dispatchInputEventIfNeeded"]
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
guard: "isValidValue",
|
|
248
|
+
actions: ["setFocusedValue", "invokeOnChange", "setNextFocusedIndex", "dispatchInputEventIfNeeded"]
|
|
249
|
+
}
|
|
250
|
+
],
|
|
251
|
+
PASTE: [
|
|
252
|
+
{
|
|
253
|
+
guard: "isValidValue",
|
|
254
|
+
actions: ["setPastedValue", "invokeOnChange", "setLastValueFocusIndex"]
|
|
255
|
+
},
|
|
256
|
+
{ actions: ["resetFocusedValue", "invokeOnChange"] }
|
|
257
|
+
],
|
|
258
|
+
BLUR: {
|
|
259
|
+
target: "idle",
|
|
260
|
+
actions: "clearFocusedIndex"
|
|
261
|
+
},
|
|
262
|
+
DELETE: {
|
|
263
|
+
guard: "hasValue",
|
|
264
|
+
actions: ["clearFocusedValue", "invokeOnChange"]
|
|
265
|
+
},
|
|
266
|
+
ARROW_LEFT: {
|
|
267
|
+
actions: "setPrevFocusedIndex"
|
|
268
|
+
},
|
|
269
|
+
ARROW_RIGHT: {
|
|
270
|
+
actions: "setNextFocusedIndex"
|
|
271
|
+
},
|
|
272
|
+
BACKSPACE: [
|
|
273
|
+
{
|
|
274
|
+
guard: "hasValue",
|
|
275
|
+
actions: ["clearFocusedValue", "invokeOnChange"]
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
actions: ["setPrevFocusedIndex", "clearFocusedValue", "invokeOnChange"]
|
|
279
|
+
}
|
|
280
|
+
],
|
|
281
|
+
ENTER: {
|
|
282
|
+
guard: "isValueComplete",
|
|
283
|
+
actions: "requestFormSubmit"
|
|
284
|
+
},
|
|
285
|
+
KEY_DOWN: {
|
|
286
|
+
guard: not("isValidValue"),
|
|
287
|
+
actions: ["preventDefault", "invokeOnInvalid"]
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
guards: {
|
|
295
|
+
autoFocus: (ctx2) => !!ctx2.autoFocus,
|
|
296
|
+
isValueEmpty: (_ctx, evt) => evt.value === "",
|
|
297
|
+
hasValue: (ctx2) => ctx2.value[ctx2.focusedIndex] !== "",
|
|
298
|
+
isValueComplete: (ctx2) => ctx2.isValueComplete,
|
|
299
|
+
isValidValue: (ctx2, evt) => {
|
|
300
|
+
if (!ctx2.pattern)
|
|
301
|
+
return isValidType(evt.value, ctx2.type);
|
|
302
|
+
const regex = new RegExp(ctx2.pattern, "g");
|
|
303
|
+
return regex.test(evt.value);
|
|
304
|
+
},
|
|
305
|
+
isFinalValue: (ctx2) => {
|
|
306
|
+
return ctx2.filledValueLength + 1 === ctx2.valueLength && ctx2.value.findIndex((v) => v.trim() === "") === ctx2.focusedIndex;
|
|
307
|
+
},
|
|
308
|
+
isLastInputFocused: (ctx2) => ctx2.focusedIndex === ctx2.valueLength - 1,
|
|
309
|
+
hasIndex: (_ctx, evt) => evt.index !== void 0,
|
|
310
|
+
isDisabled: (ctx2) => !!ctx2.disabled
|
|
311
|
+
},
|
|
312
|
+
actions: {
|
|
313
|
+
setupValue: (ctx2) => {
|
|
314
|
+
const inputs = dom.getElements(ctx2);
|
|
315
|
+
const empty = Array.from({ length: inputs.length }).map(() => "");
|
|
316
|
+
ctx2.value = Object.assign(empty, ctx2.value);
|
|
317
|
+
},
|
|
318
|
+
focusInput: (ctx2) => {
|
|
319
|
+
raf(() => {
|
|
320
|
+
var _a;
|
|
321
|
+
if (ctx2.focusedIndex === -1)
|
|
322
|
+
return;
|
|
323
|
+
(_a = dom.getFocusedEl(ctx2)) == null ? void 0 : _a.focus();
|
|
324
|
+
});
|
|
325
|
+
},
|
|
326
|
+
setInputSelection: (ctx2) => {
|
|
327
|
+
raf(() => {
|
|
328
|
+
if (ctx2.focusedIndex === -1)
|
|
329
|
+
return;
|
|
330
|
+
const input = dom.getFocusedEl(ctx2);
|
|
331
|
+
const length = input.value.length;
|
|
332
|
+
input.selectionStart = ctx2.selectOnFocus ? 0 : length;
|
|
333
|
+
input.selectionEnd = length;
|
|
334
|
+
});
|
|
335
|
+
},
|
|
336
|
+
invokeOnComplete: (ctx2) => {
|
|
337
|
+
var _a;
|
|
338
|
+
if (!ctx2.isValueComplete)
|
|
339
|
+
return;
|
|
340
|
+
(_a = ctx2.onComplete) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value), valueAsString: ctx2.valueAsString });
|
|
341
|
+
},
|
|
342
|
+
invokeOnChange: (ctx2, evt) => {
|
|
343
|
+
var _a;
|
|
344
|
+
if (evt.type === "SETUP")
|
|
345
|
+
return;
|
|
346
|
+
(_a = ctx2.onChange) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value) });
|
|
347
|
+
},
|
|
348
|
+
dispatchInputEvent: (ctx2, evt) => {
|
|
349
|
+
if (evt.type === "SETUP")
|
|
350
|
+
return;
|
|
351
|
+
dispatchInputValueEvent(dom.getHiddenInputEl(ctx2), ctx2.valueAsString);
|
|
352
|
+
const inputs = dom.getElements(ctx2);
|
|
353
|
+
ctx2.value.forEach((val, index) => {
|
|
354
|
+
const input = inputs[index];
|
|
355
|
+
input.value = val || "";
|
|
356
|
+
});
|
|
357
|
+
},
|
|
358
|
+
invokeOnInvalid: (ctx2, evt) => {
|
|
359
|
+
var _a;
|
|
360
|
+
(_a = ctx2.onInvalid) == null ? void 0 : _a.call(ctx2, { value: evt.value, index: ctx2.focusedIndex });
|
|
361
|
+
},
|
|
362
|
+
clearFocusedIndex: (ctx2) => {
|
|
363
|
+
ctx2.focusedIndex = -1;
|
|
364
|
+
},
|
|
365
|
+
setValue: (ctx2, evt) => {
|
|
366
|
+
assign(ctx2, evt.value);
|
|
367
|
+
},
|
|
368
|
+
setFocusedIndex: (ctx2, evt) => {
|
|
369
|
+
ctx2.focusedIndex = evt.index;
|
|
370
|
+
},
|
|
371
|
+
setFocusedValue: (ctx2, evt) => {
|
|
372
|
+
ctx2.value[ctx2.focusedIndex] = lastChar(evt.value);
|
|
373
|
+
},
|
|
374
|
+
dispatchInputEventIfNeeded: (ctx2, evt) => {
|
|
375
|
+
const valueIsChanged = lastChar(evt.value) !== ctx2.focusedValue;
|
|
376
|
+
if (evt.value.length <= 1 || valueIsChanged)
|
|
377
|
+
return;
|
|
378
|
+
const inputs = dom.getElements(ctx2);
|
|
379
|
+
const input = inputs[ctx2.focusedIndex];
|
|
380
|
+
input.value = lastChar(evt.value);
|
|
381
|
+
},
|
|
382
|
+
setPastedValue(ctx2, evt) {
|
|
383
|
+
raf(() => {
|
|
384
|
+
const startIndex = ctx2.focusedValue ? 1 : 0;
|
|
385
|
+
const value = evt.value.substring(startIndex, ctx2.valueLength);
|
|
386
|
+
assign(ctx2, value);
|
|
387
|
+
});
|
|
388
|
+
},
|
|
389
|
+
setValueAtIndex: (ctx2, evt) => {
|
|
390
|
+
ctx2.value[evt.index] = lastChar(evt.value);
|
|
391
|
+
},
|
|
392
|
+
clearValue: (ctx2) => {
|
|
393
|
+
ctx2.value = ctx2.value.map(() => "");
|
|
394
|
+
},
|
|
395
|
+
clearFocusedValue: (ctx2) => {
|
|
396
|
+
ctx2.value[ctx2.focusedIndex] = "";
|
|
397
|
+
},
|
|
398
|
+
resetFocusedValue: (ctx2) => {
|
|
399
|
+
const input = dom.getFocusedEl(ctx2);
|
|
400
|
+
input.value = ctx2.focusedValue;
|
|
401
|
+
},
|
|
402
|
+
setFocusIndexToFirst: (ctx2) => {
|
|
403
|
+
ctx2.focusedIndex = 0;
|
|
404
|
+
},
|
|
405
|
+
setNextFocusedIndex: (ctx2) => {
|
|
406
|
+
ctx2.focusedIndex = Math.min(ctx2.focusedIndex + 1, ctx2.valueLength - 1);
|
|
407
|
+
},
|
|
408
|
+
setPrevFocusedIndex: (ctx2) => {
|
|
409
|
+
ctx2.focusedIndex = Math.max(ctx2.focusedIndex - 1, 0);
|
|
410
|
+
},
|
|
411
|
+
setLastValueFocusIndex: (ctx2) => {
|
|
412
|
+
raf(() => {
|
|
413
|
+
ctx2.focusedIndex = Math.min(ctx2.filledValueLength, ctx2.valueLength - 1);
|
|
414
|
+
});
|
|
415
|
+
},
|
|
416
|
+
preventDefault(_, evt) {
|
|
417
|
+
evt.preventDefault();
|
|
418
|
+
},
|
|
419
|
+
blurFocusedInputIfNeeded(ctx2) {
|
|
420
|
+
if (!ctx2.blurOnComplete)
|
|
421
|
+
return;
|
|
422
|
+
raf(() => {
|
|
423
|
+
var _a;
|
|
424
|
+
(_a = dom.getFocusedEl(ctx2)) == null ? void 0 : _a.blur();
|
|
425
|
+
});
|
|
426
|
+
},
|
|
427
|
+
requestFormSubmit(ctx2) {
|
|
428
|
+
var _a;
|
|
429
|
+
if (!ctx2.name)
|
|
430
|
+
return;
|
|
431
|
+
const input = dom.getHiddenInputEl(ctx2);
|
|
432
|
+
(_a = input == null ? void 0 : input.form) == null ? void 0 : _a.requestSubmit();
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
var REGEX = {
|
|
439
|
+
numeric: /^[0-9]+$/,
|
|
440
|
+
alphabetic: /^[A-Za-z]+$/,
|
|
441
|
+
alphanumeric: /^[a-zA-Z0-9]+$/i
|
|
442
|
+
};
|
|
443
|
+
function isValidType(value, type) {
|
|
444
|
+
var _a;
|
|
445
|
+
if (!type)
|
|
446
|
+
return true;
|
|
447
|
+
return !!((_a = REGEX[type]) == null ? void 0 : _a.test(value));
|
|
448
|
+
}
|
|
449
|
+
function assign(ctx, value) {
|
|
450
|
+
const valueArr = Array.isArray(value) ? value : value.split("").filter(Boolean);
|
|
451
|
+
const valueObj = Object.assign({}, ctx.value, valueArr);
|
|
452
|
+
ctx.value = Object.values(valueObj);
|
|
453
|
+
}
|
|
454
|
+
function lastChar(value) {
|
|
455
|
+
return value.charAt(value.length - 1);
|
|
456
|
+
}
|
|
457
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
458
|
+
0 && (module.exports = {
|
|
459
|
+
machine
|
|
460
|
+
});
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { StateMachine } from '@zag-js/core';
|
|
2
|
+
import { RequiredBy, DirectionProperty, CommonProperties, Context } from '@zag-js/types';
|
|
3
|
+
|
|
4
|
+
type IntlTranslations = {
|
|
5
|
+
inputLabel: (index: number, length: number) => string;
|
|
6
|
+
};
|
|
7
|
+
type ElementIds = Partial<{
|
|
8
|
+
root: string;
|
|
9
|
+
hiddenInput: string;
|
|
10
|
+
label: string;
|
|
11
|
+
control: string;
|
|
12
|
+
input(id: string): string;
|
|
13
|
+
}>;
|
|
14
|
+
type PublicContext = DirectionProperty & CommonProperties & {
|
|
15
|
+
/**
|
|
16
|
+
* The name of the input element. Useful for form submission.
|
|
17
|
+
*/
|
|
18
|
+
name?: string;
|
|
19
|
+
/**
|
|
20
|
+
* The associate form of the underlying input element.
|
|
21
|
+
*/
|
|
22
|
+
form?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The regular expression that the user-entered input value is checked against.
|
|
25
|
+
*/
|
|
26
|
+
pattern?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The ids of the elements in the pin input. Useful for composition.
|
|
29
|
+
*/
|
|
30
|
+
ids?: ElementIds;
|
|
31
|
+
/**
|
|
32
|
+
* Whether the inputs are disabled
|
|
33
|
+
*/
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* The placeholder text for the input
|
|
37
|
+
*/
|
|
38
|
+
placeholder?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Whether to auto-focus the first input.
|
|
41
|
+
*/
|
|
42
|
+
autoFocus?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Whether the pin input is in the invalid state
|
|
45
|
+
*/
|
|
46
|
+
invalid?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* If `true`, the pin input component signals to its fields that they should
|
|
49
|
+
* use `autocomplete="one-time-code"`.
|
|
50
|
+
*/
|
|
51
|
+
otp?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* The value of the the pin input.
|
|
54
|
+
*/
|
|
55
|
+
value: string[];
|
|
56
|
+
/**
|
|
57
|
+
* The type of value the pin-input should allow
|
|
58
|
+
*/
|
|
59
|
+
type?: "alphanumeric" | "numeric" | "alphabetic";
|
|
60
|
+
/**
|
|
61
|
+
* Function called when all inputs have valid values
|
|
62
|
+
*/
|
|
63
|
+
onComplete?: (details: {
|
|
64
|
+
value: string[];
|
|
65
|
+
valueAsString: string;
|
|
66
|
+
}) => void;
|
|
67
|
+
/**
|
|
68
|
+
* Function called on input change
|
|
69
|
+
*/
|
|
70
|
+
onChange?: (details: {
|
|
71
|
+
value: string[];
|
|
72
|
+
}) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Function called when an invalid value is entered
|
|
75
|
+
*/
|
|
76
|
+
onInvalid?: (details: {
|
|
77
|
+
value: string;
|
|
78
|
+
index: number;
|
|
79
|
+
}) => void;
|
|
80
|
+
/**
|
|
81
|
+
* If `true`, the input's value will be masked just like `type=password`
|
|
82
|
+
*/
|
|
83
|
+
mask?: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Whether to blur the input when the value is complete
|
|
86
|
+
*/
|
|
87
|
+
blurOnComplete?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Whether to select input value when input is focused
|
|
90
|
+
*/
|
|
91
|
+
selectOnFocus?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Specifies the localized strings that identifies the accessibility elements and their states
|
|
94
|
+
*/
|
|
95
|
+
translations: IntlTranslations;
|
|
96
|
+
};
|
|
97
|
+
type UserDefinedContext = RequiredBy<PublicContext, "id">;
|
|
98
|
+
type ComputedContext = Readonly<{
|
|
99
|
+
/**
|
|
100
|
+
* @computed
|
|
101
|
+
* The number of inputs
|
|
102
|
+
*/
|
|
103
|
+
valueLength: number;
|
|
104
|
+
/**
|
|
105
|
+
* @computed
|
|
106
|
+
* The number of inputs that are not empty
|
|
107
|
+
*/
|
|
108
|
+
filledValueLength: number;
|
|
109
|
+
/**
|
|
110
|
+
* @computed
|
|
111
|
+
* Whether all input values are valid
|
|
112
|
+
*/
|
|
113
|
+
isValueComplete: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* @computed
|
|
116
|
+
* The string representation of the input values
|
|
117
|
+
*/
|
|
118
|
+
valueAsString: string;
|
|
119
|
+
/**
|
|
120
|
+
* @computed
|
|
121
|
+
* The value at focused index
|
|
122
|
+
*/
|
|
123
|
+
focusedValue: string;
|
|
124
|
+
}>;
|
|
125
|
+
type PrivateContext = Context<{}>;
|
|
126
|
+
type MachineContext = PublicContext & PrivateContext & ComputedContext;
|
|
127
|
+
type MachineState = {
|
|
128
|
+
value: "unknown" | "idle" | "focused";
|
|
129
|
+
};
|
|
130
|
+
type State = StateMachine.State<MachineContext, MachineState>;
|
|
131
|
+
type Send = StateMachine.Send<StateMachine.AnyEventObject>;
|
|
132
|
+
|
|
133
|
+
export { MachineContext, MachineState, Send, State, UserDefinedContext };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/pin-input.types.ts
|
|
17
|
+
var pin_input_types_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(pin_input_types_exports);
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/pin-input",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Core logic for the pin-input widget implemented as a state machine",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"module": "dist/index.mjs",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
5
|
"keywords": [
|
|
9
6
|
"js",
|
|
10
7
|
"machine",
|
|
@@ -29,19 +26,32 @@
|
|
|
29
26
|
"url": "https://github.com/chakra-ui/zag/issues"
|
|
30
27
|
},
|
|
31
28
|
"dependencies": {
|
|
32
|
-
"@zag-js/anatomy": "0.1.
|
|
33
|
-
"@zag-js/core": "0.2.
|
|
34
|
-
"@zag-js/types": "0.3.
|
|
29
|
+
"@zag-js/anatomy": "0.1.3",
|
|
30
|
+
"@zag-js/core": "0.2.4",
|
|
31
|
+
"@zag-js/types": "0.3.2"
|
|
35
32
|
},
|
|
36
33
|
"devDependencies": {
|
|
37
|
-
"
|
|
38
|
-
"@zag-js/
|
|
39
|
-
"@zag-js/utils": "0.3
|
|
34
|
+
"clean-package": "2.2.0",
|
|
35
|
+
"@zag-js/dom-utils": "0.2.2",
|
|
36
|
+
"@zag-js/form-utils": "0.2.3",
|
|
37
|
+
"@zag-js/utils": "0.3.2"
|
|
38
|
+
},
|
|
39
|
+
"clean-package": "../../../clean-package.config.json",
|
|
40
|
+
"main": "dist/index.js",
|
|
41
|
+
"module": "dist/index.mjs",
|
|
42
|
+
"types": "dist/index.d.ts",
|
|
43
|
+
"exports": {
|
|
44
|
+
".": {
|
|
45
|
+
"types": "./dist/index.d.ts",
|
|
46
|
+
"import": "./dist/index.mjs",
|
|
47
|
+
"require": "./dist/index.js"
|
|
48
|
+
},
|
|
49
|
+
"./package.json": "./package.json"
|
|
40
50
|
},
|
|
41
51
|
"scripts": {
|
|
42
|
-
"build-fast": "tsup src
|
|
52
|
+
"build-fast": "tsup src",
|
|
43
53
|
"start": "pnpm build --watch",
|
|
44
|
-
"build": "tsup src
|
|
54
|
+
"build": "tsup src --dts",
|
|
45
55
|
"test": "jest --config ../../../jest.config.js --rootDir . --passWithNoTests",
|
|
46
56
|
"lint": "eslint src --ext .ts,.tsx",
|
|
47
57
|
"test-ci": "pnpm test --ci --runInBand",
|