@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 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
- valueLength: ({ context }) => context.get("value").length,
249
- filledValueLength: ({ context }) => context.get("value").filter((v) => v?.trim() !== "").length,
250
- isValueComplete: ({ context }) => {
251
- const value = context.get("value");
252
- const filledValueLength = value.filter((v) => v?.trim() !== "").length;
253
- return value.length === filledValueLength;
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: ["setupValue", "setFocusIndexToFirst"]
262
+ actions: ["setInputCount", "setFocusIndexToFirst"]
262
263
  },
263
- { actions: ["setupValue"] }
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
- guard: "isFinalValue",
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
- setupValue({ context, scope }) {
358
- queueMicrotask(() => {
359
- if (context.get("value").length) return;
360
- const inputEls = getInputEls(scope);
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({ context, computed, prop }) {
371
+ invokeOnComplete({ computed, prop }) {
378
372
  if (!computed("isValueComplete")) return;
379
373
  prop("onValueComplete")?.({
380
- value: Array.from(context.get("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.set("value", event.value);
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 nextValue = getNextValue(focusedValue, event.value);
402
- context.set("value", (prev) => {
403
- const next = [...prev];
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
- domQuery.setElementValue(inputEl, computed("focusedValue"));
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
- domQuery.setElementValue(inputEl, value[event.index]);
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
- domQuery.setElementValue(inputEl, context.get("value")[index]);
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, computed("valueLength") - startIndex);
431
- const value = left + right;
432
- context.set("value", value.split(""));
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", (prev) => {
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, computed }) {
444
- const nextValue = Array.from({ length: computed("valueLength") }).fill("");
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", (prev) => {
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, setElementValue, queryAll, dataAttr, visuallyHiddenStyle, ariaAttr, getBeforeInputValue, getNativeEvent, isComposingEvent, isModifierKey, getEventKey } from '@zag-js/dom-query';
3
- import { isEqual, createSplitProps, invariant } from '@zag-js/utils';
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
- valueLength: ({ context }) => context.get("value").length,
247
- filledValueLength: ({ context }) => context.get("value").filter((v) => v?.trim() !== "").length,
248
- isValueComplete: ({ context }) => {
249
- const value = context.get("value");
250
- const filledValueLength = value.filter((v) => v?.trim() !== "").length;
251
- return value.length === filledValueLength;
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: ["setupValue", "setFocusIndexToFirst"]
260
+ actions: ["setInputCount", "setFocusIndexToFirst"]
260
261
  },
261
- { actions: ["setupValue"] }
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
- guard: "isFinalValue",
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
- setupValue({ context, scope }) {
356
- queueMicrotask(() => {
357
- if (context.get("value").length) return;
358
- const inputEls = getInputEls(scope);
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({ context, computed, prop }) {
369
+ invokeOnComplete({ computed, prop }) {
376
370
  if (!computed("isValueComplete")) return;
377
371
  prop("onValueComplete")?.({
378
- value: Array.from(context.get("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.set("value", event.value);
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 nextValue = getNextValue(focusedValue, event.value);
400
- context.set("value", (prev) => {
401
- const next = [...prev];
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
- setElementValue(inputEl, computed("focusedValue"));
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
- setElementValue(inputEl, value[event.index]);
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
- setElementValue(inputEl, context.get("value")[index]);
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, computed("valueLength") - startIndex);
429
- const value = left + right;
430
- context.set("value", value.split(""));
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", (prev) => {
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, computed }) {
442
- const nextValue = Array.from({ length: computed("valueLength") }).fill("");
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", (prev) => {
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.2",
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.2",
30
- "@zag-js/dom-query": "1.0.2",
31
- "@zag-js/utils": "1.0.2",
32
- "@zag-js/core": "1.0.2",
33
- "@zag-js/types": "1.0.2"
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"