@zag-js/pin-input 1.1.0 → 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,6 +125,7 @@ interface PinInputSchema {
120
125
  context: {
121
126
  value: string[];
122
127
  focusedIndex: number;
128
+ count: number;
123
129
  };
124
130
  computed: {
125
131
  _value: string[];
@@ -129,9 +135,6 @@ interface PinInputSchema {
129
135
  valueAsString: string;
130
136
  focusedValue: string;
131
137
  };
132
- refs: {
133
- count: number;
134
- };
135
138
  event: EventObject;
136
139
  action: string;
137
140
  effect: string;
@@ -155,6 +158,14 @@ interface PinInputApi<T extends PropTypes = PropTypes> {
155
158
  * Whether all inputs are filled.
156
159
  */
157
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[];
158
169
  /**
159
170
  * Function to set the value of the inputs.
160
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,6 +125,7 @@ interface PinInputSchema {
120
125
  context: {
121
126
  value: string[];
122
127
  focusedIndex: number;
128
+ count: number;
123
129
  };
124
130
  computed: {
125
131
  _value: string[];
@@ -129,9 +135,6 @@ interface PinInputSchema {
129
135
  valueAsString: string;
130
136
  focusedValue: string;
131
137
  };
132
- refs: {
133
- count: number;
134
- };
135
138
  event: EventObject;
136
139
  action: string;
137
140
  effect: string;
@@ -155,6 +158,14 @@ interface PinInputApi<T extends PropTypes = PropTypes> {
155
158
  * Whether all inputs are filled.
156
159
  */
157
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[];
158
169
  /**
159
170
  * Function to set the value of the inputs.
160
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,7 +232,6 @@ 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
237
  onChange(value) {
@@ -240,16 +241,15 @@ var machine = createMachine({
240
241
  focusedIndex: bindable(() => ({
241
242
  sync: true,
242
243
  defaultValue: -1
244
+ })),
245
+ // TODO: Move this to `props` in next major version
246
+ count: bindable(() => ({
247
+ defaultValue: prop("count")
243
248
  }))
244
249
  };
245
250
  },
246
- refs() {
247
- return {
248
- count: 0
249
- };
250
- },
251
251
  computed: {
252
- _value: ({ context, refs }) => fill(context.get("value"), refs.get("count")),
252
+ _value: ({ context }) => fill(context.get("value"), context.get("count")),
253
253
  valueLength: ({ computed }) => computed("_value").length,
254
254
  filledValueLength: ({ computed }) => computed("_value").filter((v) => v?.trim() !== "").length,
255
255
  isValueComplete: ({ computed }) => computed("valueLength") === computed("filledValueLength"),
@@ -351,9 +351,10 @@ var machine = createMachine({
351
351
  const inputEl = getHiddenInputEl(scope);
352
352
  domQuery.dispatchInputValueEvent(inputEl, { value: computed("valueAsString") });
353
353
  },
354
- setInputCount({ scope, refs }) {
354
+ setInputCount({ scope, context, prop }) {
355
+ if (prop("count")) return;
355
356
  const inputEls = getInputEls(scope);
356
- refs.set("count", inputEls.length);
357
+ context.set("count", inputEls.length);
357
358
  },
358
359
  focusInput({ context, scope }) {
359
360
  const focusedIndex = context.get("focusedIndex");
@@ -386,8 +387,8 @@ var machine = createMachine({
386
387
  setFocusedIndex({ context, event }) {
387
388
  context.set("focusedIndex", event.index);
388
389
  },
389
- setValue({ context, event, refs }) {
390
- const value = fill(event.value, refs.get("count"));
390
+ setValue({ context, event }) {
391
+ const value = fill(event.value, context.get("count"));
391
392
  context.set("value", value);
392
393
  },
393
394
  setFocusedValue({ context, event, computed }) {
@@ -412,24 +413,27 @@ var machine = createMachine({
412
413
  inputEl.value = value[index];
413
414
  });
414
415
  },
415
- setPastedValue({ context, event, computed }) {
416
+ setPastedValue({ context, event, computed, flush }) {
416
417
  domQuery.raf(() => {
417
418
  const valueAsString = computed("valueAsString");
418
419
  const focusedIndex = context.get("focusedIndex");
420
+ const valueLength = computed("valueLength");
419
421
  const filledValueLength = computed("filledValueLength");
420
422
  const startIndex = Math.min(focusedIndex, filledValueLength);
421
423
  const left = startIndex > 0 ? valueAsString.substring(0, focusedIndex) : "";
422
- const right = event.value.substring(0, computed("valueLength") - startIndex);
423
- const value = fill(`${left}${right}`.split(""), computed("valueLength"));
424
- context.set("value", value);
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
+ });
425
429
  });
426
430
  },
427
431
  setValueAtIndex({ context, event, computed }) {
428
432
  const nextValue = getNextValue(computed("focusedValue"), event.value);
429
433
  context.set("value", utils.setValueAtIndex(computed("_value"), event.index, nextValue));
430
434
  },
431
- clearValue({ context, refs }) {
432
- const nextValue = Array.from({ length: refs.get("count") }).fill("");
435
+ clearValue({ context }) {
436
+ const nextValue = Array.from({ length: context.get("count") }).fill("");
433
437
  context.set("value", nextValue);
434
438
  },
435
439
  clearFocusedValue({ context, computed }) {
@@ -477,6 +481,8 @@ function fill(value, count) {
477
481
  var props = types.createProps()([
478
482
  "autoFocus",
479
483
  "blurOnComplete",
484
+ "count",
485
+ "defaultValue",
480
486
  "dir",
481
487
  "disabled",
482
488
  "form",
@@ -490,15 +496,14 @@ var props = types.createProps()([
490
496
  "onValueComplete",
491
497
  "onValueInvalid",
492
498
  "otp",
493
- "readOnly",
494
499
  "pattern",
495
500
  "placeholder",
501
+ "readOnly",
496
502
  "required",
497
503
  "selectOnFocus",
498
504
  "translations",
499
505
  "type",
500
- "value",
501
- "defaultValue"
506
+ "value"
502
507
  ]);
503
508
  var splitProps = utils.createSplitProps(props);
504
509
 
package/dist/index.mjs CHANGED
@@ -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,7 +230,6 @@ 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
235
  onChange(value) {
@@ -238,16 +239,15 @@ var machine = createMachine({
238
239
  focusedIndex: bindable(() => ({
239
240
  sync: true,
240
241
  defaultValue: -1
242
+ })),
243
+ // TODO: Move this to `props` in next major version
244
+ count: bindable(() => ({
245
+ defaultValue: prop("count")
241
246
  }))
242
247
  };
243
248
  },
244
- refs() {
245
- return {
246
- count: 0
247
- };
248
- },
249
249
  computed: {
250
- _value: ({ context, refs }) => fill(context.get("value"), refs.get("count")),
250
+ _value: ({ context }) => fill(context.get("value"), context.get("count")),
251
251
  valueLength: ({ computed }) => computed("_value").length,
252
252
  filledValueLength: ({ computed }) => computed("_value").filter((v) => v?.trim() !== "").length,
253
253
  isValueComplete: ({ computed }) => computed("valueLength") === computed("filledValueLength"),
@@ -349,9 +349,10 @@ var machine = createMachine({
349
349
  const inputEl = getHiddenInputEl(scope);
350
350
  dispatchInputValueEvent(inputEl, { value: computed("valueAsString") });
351
351
  },
352
- setInputCount({ scope, refs }) {
352
+ setInputCount({ scope, context, prop }) {
353
+ if (prop("count")) return;
353
354
  const inputEls = getInputEls(scope);
354
- refs.set("count", inputEls.length);
355
+ context.set("count", inputEls.length);
355
356
  },
356
357
  focusInput({ context, scope }) {
357
358
  const focusedIndex = context.get("focusedIndex");
@@ -384,8 +385,8 @@ var machine = createMachine({
384
385
  setFocusedIndex({ context, event }) {
385
386
  context.set("focusedIndex", event.index);
386
387
  },
387
- setValue({ context, event, refs }) {
388
- const value = fill(event.value, refs.get("count"));
388
+ setValue({ context, event }) {
389
+ const value = fill(event.value, context.get("count"));
389
390
  context.set("value", value);
390
391
  },
391
392
  setFocusedValue({ context, event, computed }) {
@@ -410,24 +411,27 @@ var machine = createMachine({
410
411
  inputEl.value = value[index];
411
412
  });
412
413
  },
413
- setPastedValue({ context, event, computed }) {
414
+ setPastedValue({ context, event, computed, flush }) {
414
415
  raf(() => {
415
416
  const valueAsString = computed("valueAsString");
416
417
  const focusedIndex = context.get("focusedIndex");
418
+ const valueLength = computed("valueLength");
417
419
  const filledValueLength = computed("filledValueLength");
418
420
  const startIndex = Math.min(focusedIndex, filledValueLength);
419
421
  const left = startIndex > 0 ? valueAsString.substring(0, focusedIndex) : "";
420
- const right = event.value.substring(0, computed("valueLength") - startIndex);
421
- const value = fill(`${left}${right}`.split(""), computed("valueLength"));
422
- context.set("value", value);
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
+ });
423
427
  });
424
428
  },
425
429
  setValueAtIndex({ context, event, computed }) {
426
430
  const nextValue = getNextValue(computed("focusedValue"), event.value);
427
431
  context.set("value", setValueAtIndex(computed("_value"), event.index, nextValue));
428
432
  },
429
- clearValue({ context, refs }) {
430
- const nextValue = Array.from({ length: refs.get("count") }).fill("");
433
+ clearValue({ context }) {
434
+ const nextValue = Array.from({ length: context.get("count") }).fill("");
431
435
  context.set("value", nextValue);
432
436
  },
433
437
  clearFocusedValue({ context, computed }) {
@@ -475,6 +479,8 @@ function fill(value, count) {
475
479
  var props = createProps()([
476
480
  "autoFocus",
477
481
  "blurOnComplete",
482
+ "count",
483
+ "defaultValue",
478
484
  "dir",
479
485
  "disabled",
480
486
  "form",
@@ -488,15 +494,14 @@ var props = createProps()([
488
494
  "onValueComplete",
489
495
  "onValueInvalid",
490
496
  "otp",
491
- "readOnly",
492
497
  "pattern",
493
498
  "placeholder",
499
+ "readOnly",
494
500
  "required",
495
501
  "selectOnFocus",
496
502
  "translations",
497
503
  "type",
498
- "value",
499
- "defaultValue"
504
+ "value"
500
505
  ]);
501
506
  var splitProps = createSplitProps(props);
502
507
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zag-js/pin-input",
3
- "version": "1.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.1.0",
30
- "@zag-js/utils": "1.1.0",
31
- "@zag-js/dom-query": "1.1.0",
32
- "@zag-js/core": "1.1.0",
33
- "@zag-js/types": "1.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"