@zag-js/pin-input 1.0.2 → 1.2.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/dist/index.d.mts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +55 -63
- package/dist/index.mjs +57 -65
- package/package.json +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -112,6 +112,11 @@ interface PinInputProps extends DirectionProperty, CommonProperties {
|
|
|
112
112
|
* Specifies the localized strings that identifies the accessibility elements and their states
|
|
113
113
|
*/
|
|
114
114
|
translations?: IntlTranslations | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* The number of inputs to render to improve SSR aria attributes.
|
|
117
|
+
* This will be required in next major version.
|
|
118
|
+
*/
|
|
119
|
+
count?: number | undefined;
|
|
115
120
|
}
|
|
116
121
|
type PropsWithDefault = "placeholder" | "otp" | "type" | "defaultValue";
|
|
117
122
|
interface PinInputSchema {
|
|
@@ -120,8 +125,10 @@ interface PinInputSchema {
|
|
|
120
125
|
context: {
|
|
121
126
|
value: string[];
|
|
122
127
|
focusedIndex: number;
|
|
128
|
+
count: number;
|
|
123
129
|
};
|
|
124
130
|
computed: {
|
|
131
|
+
_value: string[];
|
|
125
132
|
valueLength: number;
|
|
126
133
|
filledValueLength: number;
|
|
127
134
|
isValueComplete: boolean;
|
|
@@ -151,6 +158,14 @@ interface PinInputApi<T extends PropTypes = PropTypes> {
|
|
|
151
158
|
* Whether all inputs are filled.
|
|
152
159
|
*/
|
|
153
160
|
complete: boolean;
|
|
161
|
+
/**
|
|
162
|
+
* The number of inputs to render
|
|
163
|
+
*/
|
|
164
|
+
count: number;
|
|
165
|
+
/**
|
|
166
|
+
* The array of input values.
|
|
167
|
+
*/
|
|
168
|
+
items: number[];
|
|
154
169
|
/**
|
|
155
170
|
* Function to set the value of the inputs.
|
|
156
171
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -112,6 +112,11 @@ interface PinInputProps extends DirectionProperty, CommonProperties {
|
|
|
112
112
|
* Specifies the localized strings that identifies the accessibility elements and their states
|
|
113
113
|
*/
|
|
114
114
|
translations?: IntlTranslations | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* The number of inputs to render to improve SSR aria attributes.
|
|
117
|
+
* This will be required in next major version.
|
|
118
|
+
*/
|
|
119
|
+
count?: number | undefined;
|
|
115
120
|
}
|
|
116
121
|
type PropsWithDefault = "placeholder" | "otp" | "type" | "defaultValue";
|
|
117
122
|
interface PinInputSchema {
|
|
@@ -120,8 +125,10 @@ interface PinInputSchema {
|
|
|
120
125
|
context: {
|
|
121
126
|
value: string[];
|
|
122
127
|
focusedIndex: number;
|
|
128
|
+
count: number;
|
|
123
129
|
};
|
|
124
130
|
computed: {
|
|
131
|
+
_value: string[];
|
|
125
132
|
valueLength: number;
|
|
126
133
|
filledValueLength: number;
|
|
127
134
|
isValueComplete: boolean;
|
|
@@ -151,6 +158,14 @@ interface PinInputApi<T extends PropTypes = PropTypes> {
|
|
|
151
158
|
* Whether all inputs are filled.
|
|
152
159
|
*/
|
|
153
160
|
complete: boolean;
|
|
161
|
+
/**
|
|
162
|
+
* The number of inputs to render
|
|
163
|
+
*/
|
|
164
|
+
count: number;
|
|
165
|
+
/**
|
|
166
|
+
* The array of input values.
|
|
167
|
+
*/
|
|
168
|
+
items: number[];
|
|
154
169
|
/**
|
|
155
170
|
* Function to set the value of the inputs.
|
|
156
171
|
*/
|
package/dist/index.js
CHANGED
|
@@ -52,6 +52,8 @@ function connect(service, normalize) {
|
|
|
52
52
|
}
|
|
53
53
|
return {
|
|
54
54
|
focus,
|
|
55
|
+
count: context.get("count"),
|
|
56
|
+
items: Array.from({ length: context.get("count") }).map((_, i) => i),
|
|
55
57
|
value: context.get("value"),
|
|
56
58
|
valueAsString: computed("valueAsString"),
|
|
57
59
|
complete,
|
|
@@ -216,7 +218,7 @@ var machine = createMachine({
|
|
|
216
218
|
placeholder: "\u25CB",
|
|
217
219
|
otp: false,
|
|
218
220
|
type: "numeric",
|
|
219
|
-
defaultValue: [],
|
|
221
|
+
defaultValue: props2.count ? fill([], props2.count) : [],
|
|
220
222
|
...props2,
|
|
221
223
|
translations: {
|
|
222
224
|
inputLabel: (index, length) => `pin code ${index + 1} of ${length}`,
|
|
@@ -230,10 +232,8 @@ var machine = createMachine({
|
|
|
230
232
|
context({ prop, bindable }) {
|
|
231
233
|
return {
|
|
232
234
|
value: bindable(() => ({
|
|
233
|
-
sync: true,
|
|
234
235
|
value: prop("value"),
|
|
235
236
|
defaultValue: prop("defaultValue"),
|
|
236
|
-
isEqual: utils.isEqual,
|
|
237
237
|
onChange(value) {
|
|
238
238
|
prop("onValueChange")?.({ value, valueAsString: value.join("") });
|
|
239
239
|
}
|
|
@@ -241,26 +241,27 @@ var machine = createMachine({
|
|
|
241
241
|
focusedIndex: bindable(() => ({
|
|
242
242
|
sync: true,
|
|
243
243
|
defaultValue: -1
|
|
244
|
+
})),
|
|
245
|
+
// TODO: Move this to `props` in next major version
|
|
246
|
+
count: bindable(() => ({
|
|
247
|
+
defaultValue: prop("count")
|
|
244
248
|
}))
|
|
245
249
|
};
|
|
246
250
|
},
|
|
247
251
|
computed: {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
},
|
|
255
|
-
valueAsString: ({ context }) => context.get("value").join(""),
|
|
256
|
-
focusedValue: ({ context }) => context.get("value")[context.get("focusedIndex")] || ""
|
|
252
|
+
_value: ({ context }) => fill(context.get("value"), context.get("count")),
|
|
253
|
+
valueLength: ({ computed }) => computed("_value").length,
|
|
254
|
+
filledValueLength: ({ computed }) => computed("_value").filter((v) => v?.trim() !== "").length,
|
|
255
|
+
isValueComplete: ({ computed }) => computed("valueLength") === computed("filledValueLength"),
|
|
256
|
+
valueAsString: ({ computed }) => computed("_value").join(""),
|
|
257
|
+
focusedValue: ({ computed, context }) => computed("_value")[context.get("focusedIndex")] || ""
|
|
257
258
|
},
|
|
258
259
|
entry: choose([
|
|
259
260
|
{
|
|
260
261
|
guard: "autoFocus",
|
|
261
|
-
actions: ["
|
|
262
|
+
actions: ["setInputCount", "setFocusIndexToFirst"]
|
|
262
263
|
},
|
|
263
|
-
{ actions: ["
|
|
264
|
+
{ actions: ["setInputCount"] }
|
|
264
265
|
]),
|
|
265
266
|
watch({ action, track, context, computed }) {
|
|
266
267
|
track([() => context.get("focusedIndex")], () => {
|
|
@@ -296,18 +297,15 @@ var machine = createMachine({
|
|
|
296
297
|
},
|
|
297
298
|
focused: {
|
|
298
299
|
on: {
|
|
299
|
-
"INPUT.CHANGE":
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
actions: ["setFocusedValue", "syncInputValue"]
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
actions: ["setFocusedValue", "setNextFocusedIndex", "syncInputValue"]
|
|
306
|
-
}
|
|
307
|
-
],
|
|
300
|
+
"INPUT.CHANGE": {
|
|
301
|
+
actions: ["setFocusedValue", "syncInputValue", "setNextFocusedIndex"]
|
|
302
|
+
},
|
|
308
303
|
"INPUT.PASTE": {
|
|
309
304
|
actions: ["setPastedValue", "setLastValueFocusIndex"]
|
|
310
305
|
},
|
|
306
|
+
"INPUT.FOCUS": {
|
|
307
|
+
actions: ["setFocusedIndex"]
|
|
308
|
+
},
|
|
311
309
|
"INPUT.BLUR": {
|
|
312
310
|
target: "idle",
|
|
313
311
|
actions: ["clearFocusedIndex"]
|
|
@@ -346,7 +344,6 @@ var machine = createMachine({
|
|
|
346
344
|
autoFocus: ({ prop }) => !!prop("autoFocus"),
|
|
347
345
|
hasValue: ({ context }) => context.get("value")[context.get("focusedIndex")] !== "",
|
|
348
346
|
isValueComplete: ({ computed }) => computed("isValueComplete"),
|
|
349
|
-
isFinalValue: ({ context, computed }) => computed("filledValueLength") + 1 === computed("valueLength") && context.get("value").findIndex((v) => v.trim() === "") === context.get("focusedIndex"),
|
|
350
347
|
hasIndex: ({ event }) => event.index !== void 0
|
|
351
348
|
},
|
|
352
349
|
actions: {
|
|
@@ -354,13 +351,10 @@ var machine = createMachine({
|
|
|
354
351
|
const inputEl = getHiddenInputEl(scope);
|
|
355
352
|
domQuery.dispatchInputValueEvent(inputEl, { value: computed("valueAsString") });
|
|
356
353
|
},
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
const emptyValues = Array.from({ length: inputEls.length }).fill("");
|
|
362
|
-
context.set("value", emptyValues);
|
|
363
|
-
});
|
|
354
|
+
setInputCount({ scope, context, prop }) {
|
|
355
|
+
if (prop("count")) return;
|
|
356
|
+
const inputEls = getInputEls(scope);
|
|
357
|
+
context.set("count", inputEls.length);
|
|
364
358
|
},
|
|
365
359
|
focusInput({ context, scope }) {
|
|
366
360
|
const focusedIndex = context.get("focusedIndex");
|
|
@@ -374,10 +368,10 @@ var machine = createMachine({
|
|
|
374
368
|
getInputElAtIndex(scope, focusedIndex)?.select();
|
|
375
369
|
});
|
|
376
370
|
},
|
|
377
|
-
invokeOnComplete({
|
|
371
|
+
invokeOnComplete({ computed, prop }) {
|
|
378
372
|
if (!computed("isValueComplete")) return;
|
|
379
373
|
prop("onValueComplete")?.({
|
|
380
|
-
value:
|
|
374
|
+
value: computed("_value"),
|
|
381
375
|
valueAsString: computed("valueAsString")
|
|
382
376
|
});
|
|
383
377
|
},
|
|
@@ -394,64 +388,58 @@ var machine = createMachine({
|
|
|
394
388
|
context.set("focusedIndex", event.index);
|
|
395
389
|
},
|
|
396
390
|
setValue({ context, event }) {
|
|
397
|
-
context.
|
|
391
|
+
const value = fill(event.value, context.get("count"));
|
|
392
|
+
context.set("value", value);
|
|
398
393
|
},
|
|
399
394
|
setFocusedValue({ context, event, computed }) {
|
|
400
395
|
const focusedValue = computed("focusedValue");
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
next[context.get("focusedIndex")] = nextValue;
|
|
405
|
-
return next;
|
|
406
|
-
});
|
|
396
|
+
const focusedIndex = context.get("focusedIndex");
|
|
397
|
+
const value = getNextValue(focusedValue, event.value);
|
|
398
|
+
context.set("value", utils.setValueAtIndex(computed("_value"), focusedIndex, value));
|
|
407
399
|
},
|
|
408
400
|
revertInputValue({ context, computed, scope }) {
|
|
409
401
|
const inputEl = getInputElAtIndex(scope, context.get("focusedIndex"));
|
|
410
|
-
|
|
402
|
+
inputEl.value = computed("focusedValue");
|
|
411
403
|
},
|
|
412
404
|
syncInputValue({ context, event, scope }) {
|
|
413
405
|
const value = context.get("value");
|
|
414
406
|
const inputEl = getInputElAtIndex(scope, event.index);
|
|
415
|
-
|
|
407
|
+
inputEl.value = value[event.index];
|
|
416
408
|
},
|
|
417
409
|
syncInputElements({ context, scope }) {
|
|
418
410
|
const inputEls = getInputEls(scope);
|
|
411
|
+
const value = context.get("value");
|
|
419
412
|
inputEls.forEach((inputEl, index) => {
|
|
420
|
-
|
|
413
|
+
inputEl.value = value[index];
|
|
421
414
|
});
|
|
422
415
|
},
|
|
423
|
-
setPastedValue({ context, event, computed }) {
|
|
416
|
+
setPastedValue({ context, event, computed, flush }) {
|
|
424
417
|
domQuery.raf(() => {
|
|
425
418
|
const valueAsString = computed("valueAsString");
|
|
426
419
|
const focusedIndex = context.get("focusedIndex");
|
|
420
|
+
const valueLength = computed("valueLength");
|
|
427
421
|
const filledValueLength = computed("filledValueLength");
|
|
428
422
|
const startIndex = Math.min(focusedIndex, filledValueLength);
|
|
429
423
|
const left = startIndex > 0 ? valueAsString.substring(0, focusedIndex) : "";
|
|
430
|
-
const right = event.value.substring(0,
|
|
431
|
-
const value = left
|
|
432
|
-
|
|
424
|
+
const right = event.value.substring(0, valueLength - startIndex);
|
|
425
|
+
const value = fill(`${left}${right}`.split(""), valueLength);
|
|
426
|
+
flush(() => {
|
|
427
|
+
context.set("value", value);
|
|
428
|
+
});
|
|
433
429
|
});
|
|
434
430
|
},
|
|
435
431
|
setValueAtIndex({ context, event, computed }) {
|
|
436
432
|
const nextValue = getNextValue(computed("focusedValue"), event.value);
|
|
437
|
-
context.set("value", (
|
|
438
|
-
const next = [...prev];
|
|
439
|
-
next[event.index] = nextValue;
|
|
440
|
-
return next;
|
|
441
|
-
});
|
|
433
|
+
context.set("value", utils.setValueAtIndex(computed("_value"), event.index, nextValue));
|
|
442
434
|
},
|
|
443
|
-
clearValue({ context
|
|
444
|
-
const nextValue = Array.from({ length:
|
|
435
|
+
clearValue({ context }) {
|
|
436
|
+
const nextValue = Array.from({ length: context.get("count") }).fill("");
|
|
445
437
|
context.set("value", nextValue);
|
|
446
438
|
},
|
|
447
|
-
clearFocusedValue({ context }) {
|
|
439
|
+
clearFocusedValue({ context, computed }) {
|
|
448
440
|
const focusedIndex = context.get("focusedIndex");
|
|
449
441
|
if (focusedIndex === -1) return;
|
|
450
|
-
context.set("value", (
|
|
451
|
-
const next = [...prev];
|
|
452
|
-
next[focusedIndex] = "";
|
|
453
|
-
return next;
|
|
454
|
-
});
|
|
442
|
+
context.set("value", utils.setValueAtIndex(computed("_value"), focusedIndex, ""));
|
|
455
443
|
},
|
|
456
444
|
setFocusIndexToFirst({ context }) {
|
|
457
445
|
context.set("focusedIndex", 0);
|
|
@@ -487,9 +475,14 @@ function getNextValue(current, next) {
|
|
|
487
475
|
else if (current[0] === next[1]) nextValue = next[0];
|
|
488
476
|
return nextValue.split("")[nextValue.length - 1];
|
|
489
477
|
}
|
|
478
|
+
function fill(value, count) {
|
|
479
|
+
return Array.from({ length: count }).fill("").map((v, i) => value[i] || v);
|
|
480
|
+
}
|
|
490
481
|
var props = types.createProps()([
|
|
491
482
|
"autoFocus",
|
|
492
483
|
"blurOnComplete",
|
|
484
|
+
"count",
|
|
485
|
+
"defaultValue",
|
|
493
486
|
"dir",
|
|
494
487
|
"disabled",
|
|
495
488
|
"form",
|
|
@@ -503,15 +496,14 @@ var props = types.createProps()([
|
|
|
503
496
|
"onValueComplete",
|
|
504
497
|
"onValueInvalid",
|
|
505
498
|
"otp",
|
|
506
|
-
"readOnly",
|
|
507
499
|
"pattern",
|
|
508
500
|
"placeholder",
|
|
501
|
+
"readOnly",
|
|
509
502
|
"required",
|
|
510
503
|
"selectOnFocus",
|
|
511
504
|
"translations",
|
|
512
505
|
"type",
|
|
513
|
-
"value"
|
|
514
|
-
"defaultValue"
|
|
506
|
+
"value"
|
|
515
507
|
]);
|
|
516
508
|
var splitProps = utils.createSplitProps(props);
|
|
517
509
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createAnatomy } from '@zag-js/anatomy';
|
|
2
|
-
import { dispatchInputValueEvent, raf,
|
|
3
|
-
import {
|
|
2
|
+
import { dispatchInputValueEvent, raf, queryAll, dataAttr, visuallyHiddenStyle, ariaAttr, getBeforeInputValue, getNativeEvent, isComposingEvent, isModifierKey, getEventKey } from '@zag-js/dom-query';
|
|
3
|
+
import { setValueAtIndex, createSplitProps, invariant } from '@zag-js/utils';
|
|
4
4
|
import { setup } from '@zag-js/core';
|
|
5
5
|
import { createProps } from '@zag-js/types';
|
|
6
6
|
|
|
@@ -50,6 +50,8 @@ function connect(service, normalize) {
|
|
|
50
50
|
}
|
|
51
51
|
return {
|
|
52
52
|
focus,
|
|
53
|
+
count: context.get("count"),
|
|
54
|
+
items: Array.from({ length: context.get("count") }).map((_, i) => i),
|
|
53
55
|
value: context.get("value"),
|
|
54
56
|
valueAsString: computed("valueAsString"),
|
|
55
57
|
complete,
|
|
@@ -214,7 +216,7 @@ var machine = createMachine({
|
|
|
214
216
|
placeholder: "\u25CB",
|
|
215
217
|
otp: false,
|
|
216
218
|
type: "numeric",
|
|
217
|
-
defaultValue: [],
|
|
219
|
+
defaultValue: props2.count ? fill([], props2.count) : [],
|
|
218
220
|
...props2,
|
|
219
221
|
translations: {
|
|
220
222
|
inputLabel: (index, length) => `pin code ${index + 1} of ${length}`,
|
|
@@ -228,10 +230,8 @@ var machine = createMachine({
|
|
|
228
230
|
context({ prop, bindable }) {
|
|
229
231
|
return {
|
|
230
232
|
value: bindable(() => ({
|
|
231
|
-
sync: true,
|
|
232
233
|
value: prop("value"),
|
|
233
234
|
defaultValue: prop("defaultValue"),
|
|
234
|
-
isEqual,
|
|
235
235
|
onChange(value) {
|
|
236
236
|
prop("onValueChange")?.({ value, valueAsString: value.join("") });
|
|
237
237
|
}
|
|
@@ -239,26 +239,27 @@ var machine = createMachine({
|
|
|
239
239
|
focusedIndex: bindable(() => ({
|
|
240
240
|
sync: true,
|
|
241
241
|
defaultValue: -1
|
|
242
|
+
})),
|
|
243
|
+
// TODO: Move this to `props` in next major version
|
|
244
|
+
count: bindable(() => ({
|
|
245
|
+
defaultValue: prop("count")
|
|
242
246
|
}))
|
|
243
247
|
};
|
|
244
248
|
},
|
|
245
249
|
computed: {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
},
|
|
253
|
-
valueAsString: ({ context }) => context.get("value").join(""),
|
|
254
|
-
focusedValue: ({ context }) => context.get("value")[context.get("focusedIndex")] || ""
|
|
250
|
+
_value: ({ context }) => fill(context.get("value"), context.get("count")),
|
|
251
|
+
valueLength: ({ computed }) => computed("_value").length,
|
|
252
|
+
filledValueLength: ({ computed }) => computed("_value").filter((v) => v?.trim() !== "").length,
|
|
253
|
+
isValueComplete: ({ computed }) => computed("valueLength") === computed("filledValueLength"),
|
|
254
|
+
valueAsString: ({ computed }) => computed("_value").join(""),
|
|
255
|
+
focusedValue: ({ computed, context }) => computed("_value")[context.get("focusedIndex")] || ""
|
|
255
256
|
},
|
|
256
257
|
entry: choose([
|
|
257
258
|
{
|
|
258
259
|
guard: "autoFocus",
|
|
259
|
-
actions: ["
|
|
260
|
+
actions: ["setInputCount", "setFocusIndexToFirst"]
|
|
260
261
|
},
|
|
261
|
-
{ actions: ["
|
|
262
|
+
{ actions: ["setInputCount"] }
|
|
262
263
|
]),
|
|
263
264
|
watch({ action, track, context, computed }) {
|
|
264
265
|
track([() => context.get("focusedIndex")], () => {
|
|
@@ -294,18 +295,15 @@ var machine = createMachine({
|
|
|
294
295
|
},
|
|
295
296
|
focused: {
|
|
296
297
|
on: {
|
|
297
|
-
"INPUT.CHANGE":
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
actions: ["setFocusedValue", "syncInputValue"]
|
|
301
|
-
},
|
|
302
|
-
{
|
|
303
|
-
actions: ["setFocusedValue", "setNextFocusedIndex", "syncInputValue"]
|
|
304
|
-
}
|
|
305
|
-
],
|
|
298
|
+
"INPUT.CHANGE": {
|
|
299
|
+
actions: ["setFocusedValue", "syncInputValue", "setNextFocusedIndex"]
|
|
300
|
+
},
|
|
306
301
|
"INPUT.PASTE": {
|
|
307
302
|
actions: ["setPastedValue", "setLastValueFocusIndex"]
|
|
308
303
|
},
|
|
304
|
+
"INPUT.FOCUS": {
|
|
305
|
+
actions: ["setFocusedIndex"]
|
|
306
|
+
},
|
|
309
307
|
"INPUT.BLUR": {
|
|
310
308
|
target: "idle",
|
|
311
309
|
actions: ["clearFocusedIndex"]
|
|
@@ -344,7 +342,6 @@ var machine = createMachine({
|
|
|
344
342
|
autoFocus: ({ prop }) => !!prop("autoFocus"),
|
|
345
343
|
hasValue: ({ context }) => context.get("value")[context.get("focusedIndex")] !== "",
|
|
346
344
|
isValueComplete: ({ computed }) => computed("isValueComplete"),
|
|
347
|
-
isFinalValue: ({ context, computed }) => computed("filledValueLength") + 1 === computed("valueLength") && context.get("value").findIndex((v) => v.trim() === "") === context.get("focusedIndex"),
|
|
348
345
|
hasIndex: ({ event }) => event.index !== void 0
|
|
349
346
|
},
|
|
350
347
|
actions: {
|
|
@@ -352,13 +349,10 @@ var machine = createMachine({
|
|
|
352
349
|
const inputEl = getHiddenInputEl(scope);
|
|
353
350
|
dispatchInputValueEvent(inputEl, { value: computed("valueAsString") });
|
|
354
351
|
},
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
const emptyValues = Array.from({ length: inputEls.length }).fill("");
|
|
360
|
-
context.set("value", emptyValues);
|
|
361
|
-
});
|
|
352
|
+
setInputCount({ scope, context, prop }) {
|
|
353
|
+
if (prop("count")) return;
|
|
354
|
+
const inputEls = getInputEls(scope);
|
|
355
|
+
context.set("count", inputEls.length);
|
|
362
356
|
},
|
|
363
357
|
focusInput({ context, scope }) {
|
|
364
358
|
const focusedIndex = context.get("focusedIndex");
|
|
@@ -372,10 +366,10 @@ var machine = createMachine({
|
|
|
372
366
|
getInputElAtIndex(scope, focusedIndex)?.select();
|
|
373
367
|
});
|
|
374
368
|
},
|
|
375
|
-
invokeOnComplete({
|
|
369
|
+
invokeOnComplete({ computed, prop }) {
|
|
376
370
|
if (!computed("isValueComplete")) return;
|
|
377
371
|
prop("onValueComplete")?.({
|
|
378
|
-
value:
|
|
372
|
+
value: computed("_value"),
|
|
379
373
|
valueAsString: computed("valueAsString")
|
|
380
374
|
});
|
|
381
375
|
},
|
|
@@ -392,64 +386,58 @@ var machine = createMachine({
|
|
|
392
386
|
context.set("focusedIndex", event.index);
|
|
393
387
|
},
|
|
394
388
|
setValue({ context, event }) {
|
|
395
|
-
context.
|
|
389
|
+
const value = fill(event.value, context.get("count"));
|
|
390
|
+
context.set("value", value);
|
|
396
391
|
},
|
|
397
392
|
setFocusedValue({ context, event, computed }) {
|
|
398
393
|
const focusedValue = computed("focusedValue");
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
next[context.get("focusedIndex")] = nextValue;
|
|
403
|
-
return next;
|
|
404
|
-
});
|
|
394
|
+
const focusedIndex = context.get("focusedIndex");
|
|
395
|
+
const value = getNextValue(focusedValue, event.value);
|
|
396
|
+
context.set("value", setValueAtIndex(computed("_value"), focusedIndex, value));
|
|
405
397
|
},
|
|
406
398
|
revertInputValue({ context, computed, scope }) {
|
|
407
399
|
const inputEl = getInputElAtIndex(scope, context.get("focusedIndex"));
|
|
408
|
-
|
|
400
|
+
inputEl.value = computed("focusedValue");
|
|
409
401
|
},
|
|
410
402
|
syncInputValue({ context, event, scope }) {
|
|
411
403
|
const value = context.get("value");
|
|
412
404
|
const inputEl = getInputElAtIndex(scope, event.index);
|
|
413
|
-
|
|
405
|
+
inputEl.value = value[event.index];
|
|
414
406
|
},
|
|
415
407
|
syncInputElements({ context, scope }) {
|
|
416
408
|
const inputEls = getInputEls(scope);
|
|
409
|
+
const value = context.get("value");
|
|
417
410
|
inputEls.forEach((inputEl, index) => {
|
|
418
|
-
|
|
411
|
+
inputEl.value = value[index];
|
|
419
412
|
});
|
|
420
413
|
},
|
|
421
|
-
setPastedValue({ context, event, computed }) {
|
|
414
|
+
setPastedValue({ context, event, computed, flush }) {
|
|
422
415
|
raf(() => {
|
|
423
416
|
const valueAsString = computed("valueAsString");
|
|
424
417
|
const focusedIndex = context.get("focusedIndex");
|
|
418
|
+
const valueLength = computed("valueLength");
|
|
425
419
|
const filledValueLength = computed("filledValueLength");
|
|
426
420
|
const startIndex = Math.min(focusedIndex, filledValueLength);
|
|
427
421
|
const left = startIndex > 0 ? valueAsString.substring(0, focusedIndex) : "";
|
|
428
|
-
const right = event.value.substring(0,
|
|
429
|
-
const value = left
|
|
430
|
-
|
|
422
|
+
const right = event.value.substring(0, valueLength - startIndex);
|
|
423
|
+
const value = fill(`${left}${right}`.split(""), valueLength);
|
|
424
|
+
flush(() => {
|
|
425
|
+
context.set("value", value);
|
|
426
|
+
});
|
|
431
427
|
});
|
|
432
428
|
},
|
|
433
429
|
setValueAtIndex({ context, event, computed }) {
|
|
434
430
|
const nextValue = getNextValue(computed("focusedValue"), event.value);
|
|
435
|
-
context.set("value", (
|
|
436
|
-
const next = [...prev];
|
|
437
|
-
next[event.index] = nextValue;
|
|
438
|
-
return next;
|
|
439
|
-
});
|
|
431
|
+
context.set("value", setValueAtIndex(computed("_value"), event.index, nextValue));
|
|
440
432
|
},
|
|
441
|
-
clearValue({ context
|
|
442
|
-
const nextValue = Array.from({ length:
|
|
433
|
+
clearValue({ context }) {
|
|
434
|
+
const nextValue = Array.from({ length: context.get("count") }).fill("");
|
|
443
435
|
context.set("value", nextValue);
|
|
444
436
|
},
|
|
445
|
-
clearFocusedValue({ context }) {
|
|
437
|
+
clearFocusedValue({ context, computed }) {
|
|
446
438
|
const focusedIndex = context.get("focusedIndex");
|
|
447
439
|
if (focusedIndex === -1) return;
|
|
448
|
-
context.set("value", (
|
|
449
|
-
const next = [...prev];
|
|
450
|
-
next[focusedIndex] = "";
|
|
451
|
-
return next;
|
|
452
|
-
});
|
|
440
|
+
context.set("value", setValueAtIndex(computed("_value"), focusedIndex, ""));
|
|
453
441
|
},
|
|
454
442
|
setFocusIndexToFirst({ context }) {
|
|
455
443
|
context.set("focusedIndex", 0);
|
|
@@ -485,9 +473,14 @@ function getNextValue(current, next) {
|
|
|
485
473
|
else if (current[0] === next[1]) nextValue = next[0];
|
|
486
474
|
return nextValue.split("")[nextValue.length - 1];
|
|
487
475
|
}
|
|
476
|
+
function fill(value, count) {
|
|
477
|
+
return Array.from({ length: count }).fill("").map((v, i) => value[i] || v);
|
|
478
|
+
}
|
|
488
479
|
var props = createProps()([
|
|
489
480
|
"autoFocus",
|
|
490
481
|
"blurOnComplete",
|
|
482
|
+
"count",
|
|
483
|
+
"defaultValue",
|
|
491
484
|
"dir",
|
|
492
485
|
"disabled",
|
|
493
486
|
"form",
|
|
@@ -501,15 +494,14 @@ var props = createProps()([
|
|
|
501
494
|
"onValueComplete",
|
|
502
495
|
"onValueInvalid",
|
|
503
496
|
"otp",
|
|
504
|
-
"readOnly",
|
|
505
497
|
"pattern",
|
|
506
498
|
"placeholder",
|
|
499
|
+
"readOnly",
|
|
507
500
|
"required",
|
|
508
501
|
"selectOnFocus",
|
|
509
502
|
"translations",
|
|
510
503
|
"type",
|
|
511
|
-
"value"
|
|
512
|
-
"defaultValue"
|
|
504
|
+
"value"
|
|
513
505
|
]);
|
|
514
506
|
var splitProps = createSplitProps(props);
|
|
515
507
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/pin-input",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Core logic for the pin-input widget implemented as a state machine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
"url": "https://github.com/chakra-ui/zag/issues"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@zag-js/anatomy": "1.0
|
|
30
|
-
"@zag-js/dom-query": "1.0
|
|
31
|
-
"@zag-js/utils": "1.0
|
|
32
|
-
"@zag-js/core": "1.0
|
|
33
|
-
"@zag-js/types": "1.0
|
|
29
|
+
"@zag-js/anatomy": "1.2.0",
|
|
30
|
+
"@zag-js/dom-query": "1.2.0",
|
|
31
|
+
"@zag-js/utils": "1.2.0",
|
|
32
|
+
"@zag-js/core": "1.2.0",
|
|
33
|
+
"@zag-js/types": "1.2.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"clean-package": "2.2.0"
|