@zag-js/pin-input 0.2.11 → 0.2.13

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,23 @@
1
+ // src/pin-input.dom.ts
2
+ import { createScope, queryAll } from "@zag-js/dom-query";
3
+ var dom = createScope({
4
+ getRootId: (ctx) => ctx.ids?.root ?? `pin-input:${ctx.id}`,
5
+ getInputId: (ctx, id) => ctx.ids?.input?.(id) ?? `pin-input:${ctx.id}:${id}`,
6
+ getHiddenInputId: (ctx) => ctx.ids?.hiddenInput ?? `pin-input:${ctx.id}:hidden`,
7
+ getLabelId: (ctx) => ctx.ids?.label ?? `pin-input:${ctx.id}:label`,
8
+ getControlId: (ctx) => ctx.ids?.control ?? `pin-input:${ctx.id}:control`,
9
+ getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
10
+ getElements: (ctx) => {
11
+ const ownerId = CSS.escape(dom.getRootId(ctx));
12
+ const selector = `input[data-ownedby=${ownerId}]`;
13
+ return queryAll(dom.getRootEl(ctx), selector);
14
+ },
15
+ getInputEl: (ctx, id) => dom.getById(ctx, dom.getInputId(ctx, id)),
16
+ getFocusedInputEl: (ctx) => dom.getElements(ctx)[ctx.focusedIndex],
17
+ getFirstInputEl: (ctx) => dom.getElements(ctx)[0],
18
+ getHiddenInputEl: (ctx) => dom.getById(ctx, dom.getHiddenInputId(ctx))
19
+ });
20
+
21
+ export {
22
+ dom
23
+ };
@@ -1,50 +1,12 @@
1
1
  import {
2
- isObject
3
- } from "./chunk-NT4W6JYX.mjs";
4
- import {
5
- dom,
6
- getWindow
7
- } from "./chunk-T5OKDF74.mjs";
2
+ dom
3
+ } from "./chunk-CPXMEVTH.mjs";
8
4
 
9
5
  // src/pin-input.machine.ts
10
6
  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
- const { type, property = "value" } = options;
32
- const proto = getWindow(el)[type].prototype;
33
- return Object.getOwnPropertyDescriptor(proto, property) ?? {};
34
- }
35
- function dispatchInputValueEvent(el, value) {
36
- if (!el)
37
- return;
38
- const win = getWindow(el);
39
- if (!(el instanceof win.HTMLInputElement))
40
- return;
41
- const desc = getDescriptor(el, { type: "HTMLInputElement", property: "value" });
42
- desc.set?.call(el, value);
43
- const event = new win.Event("input", { bubbles: true });
44
- el.dispatchEvent(event);
45
- }
46
-
47
- // src/pin-input.machine.ts
7
+ import { raf } from "@zag-js/dom-query";
8
+ import { dispatchInputValueEvent } from "@zag-js/form-utils";
9
+ import { compact } from "@zag-js/utils";
48
10
  var { and, not } = guards;
49
11
  function machine(userContext) {
50
12
  const ctx = compact(userContext);
@@ -73,7 +35,7 @@ function machine(userContext) {
73
35
  },
74
36
  watch: {
75
37
  focusedIndex: ["focusInput", "setInputSelection"],
76
- value: ["dispatchInputEvent"],
38
+ value: ["dispatchInputEvent", "syncInputElements"],
77
39
  isValueComplete: ["invokeOnComplete", "blurFocusedInputIfNeeded"]
78
40
  },
79
41
  entry: ctx.autoFocus ? ["setupValue", "setFocusIndexToFirst"] : ["setupValue"],
@@ -187,14 +149,14 @@ function machine(userContext) {
187
149
  raf(() => {
188
150
  if (ctx2.focusedIndex === -1)
189
151
  return;
190
- dom.getFocusedEl(ctx2)?.focus();
152
+ dom.getFocusedInputEl(ctx2)?.focus();
191
153
  });
192
154
  },
193
155
  setInputSelection: (ctx2) => {
194
156
  raf(() => {
195
157
  if (ctx2.focusedIndex === -1)
196
158
  return;
197
- const input = dom.getFocusedEl(ctx2);
159
+ const input = dom.getFocusedInputEl(ctx2);
198
160
  const length = input.value.length;
199
161
  input.selectionStart = ctx2.selectOnFocus ? 0 : length;
200
162
  input.selectionEnd = length;
@@ -205,20 +167,11 @@ function machine(userContext) {
205
167
  return;
206
168
  ctx2.onComplete?.({ value: Array.from(ctx2.value), valueAsString: ctx2.valueAsString });
207
169
  },
208
- invokeOnChange: (ctx2, evt) => {
209
- if (evt.type === "SETUP")
210
- return;
170
+ invokeOnChange: (ctx2) => {
211
171
  ctx2.onChange?.({ value: Array.from(ctx2.value) });
212
172
  },
213
- dispatchInputEvent: (ctx2, evt) => {
214
- if (evt.type === "SETUP")
215
- return;
173
+ dispatchInputEvent: (ctx2) => {
216
174
  dispatchInputValueEvent(dom.getHiddenInputEl(ctx2), ctx2.valueAsString);
217
- const inputs = dom.getElements(ctx2);
218
- ctx2.value.forEach((val, index) => {
219
- const input = inputs[index];
220
- input.value = val || "";
221
- });
222
175
  },
223
176
  invokeOnInvalid: (ctx2, evt) => {
224
177
  ctx2.onInvalid?.({ value: evt.value, index: ctx2.focusedIndex });
@@ -235,14 +188,17 @@ function machine(userContext) {
235
188
  setFocusedValue: (ctx2, evt) => {
236
189
  ctx2.value[ctx2.focusedIndex] = getNextValue(ctx2.focusedValue, evt.value);
237
190
  },
238
- syncInputValue: (ctx2, evt) => {
239
- const nextValue = getNextValue(ctx2.focusedValue, evt.value);
240
- const changed = nextValue !== ctx2.focusedValue;
241
- if (evt.value.length <= 1 || changed)
191
+ syncInputValue(ctx2, evt) {
192
+ const input = dom.getInputEl(ctx2, evt.index.toString());
193
+ if (!input)
242
194
  return;
195
+ input.value = ctx2.value[evt.index];
196
+ },
197
+ syncInputElements(ctx2) {
243
198
  const inputs = dom.getElements(ctx2);
244
- const input = inputs[ctx2.focusedIndex];
245
- input.value = nextValue;
199
+ inputs.forEach((input, index) => {
200
+ input.value = ctx2.value[index];
201
+ });
246
202
  },
247
203
  setPastedValue(ctx2, evt) {
248
204
  raf(() => {
@@ -262,7 +218,7 @@ function machine(userContext) {
262
218
  ctx2.value[ctx2.focusedIndex] = "";
263
219
  },
264
220
  resetFocusedValue: (ctx2) => {
265
- const input = dom.getFocusedEl(ctx2);
221
+ const input = dom.getFocusedInputEl(ctx2);
266
222
  input.value = ctx2.focusedValue;
267
223
  },
268
224
  setFocusIndexToFirst: (ctx2) => {
@@ -286,7 +242,7 @@ function machine(userContext) {
286
242
  if (!ctx2.blurOnComplete)
287
243
  return;
288
244
  raf(() => {
289
- dom.getFocusedEl(ctx2)?.blur();
245
+ dom.getFocusedInputEl(ctx2)?.blur();
290
246
  });
291
247
  },
292
248
  requestFormSubmit(ctx2) {
@@ -3,71 +3,13 @@ import {
3
3
  } from "./chunk-BJXKBZJG.mjs";
4
4
  import {
5
5
  dom
6
- } from "./chunk-T5OKDF74.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
- return e.nativeEvent ?? e;
28
- }
29
- var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
30
-
31
- // ../../utilities/dom/src/keyboard-event.ts
32
- var rtlKeyMap = {
33
- ArrowLeft: "ArrowRight",
34
- ArrowRight: "ArrowLeft"
35
- };
36
- var sameKeyMap = {
37
- Up: "ArrowUp",
38
- Down: "ArrowDown",
39
- Esc: "Escape",
40
- " ": "Space",
41
- ",": "Comma",
42
- Left: "ArrowLeft",
43
- Right: "ArrowRight"
44
- };
45
- function getEventKey(event, options = {}) {
46
- const { dir = "ltr", orientation = "horizontal" } = options;
47
- let { key } = event;
48
- key = sameKeyMap[key] ?? key;
49
- const isRtl = dir === "rtl" && orientation === "horizontal";
50
- if (isRtl && key in rtlKeyMap) {
51
- key = rtlKeyMap[key];
52
- }
53
- return key;
54
- }
55
-
56
- // ../../utilities/dom/src/visually-hidden.ts
57
- var visuallyHiddenStyle = {
58
- border: "0",
59
- clip: "rect(0 0 0 0)",
60
- height: "1px",
61
- margin: "-1px",
62
- overflow: "hidden",
63
- padding: "0",
64
- position: "absolute",
65
- width: "1px",
66
- whiteSpace: "nowrap",
67
- wordWrap: "normal"
68
- };
6
+ } from "./chunk-CPXMEVTH.mjs";
69
7
 
70
8
  // src/pin-input.connect.ts
9
+ import { getEventKey, getNativeEvent, isModifiedEvent } from "@zag-js/dom-event";
10
+ import { ariaAttr, dataAttr } from "@zag-js/dom-query";
11
+ import { invariant } from "@zag-js/utils";
12
+ import { visuallyHiddenStyle } from "@zag-js/visually-hidden";
71
13
  function connect(state, send, normalize) {
72
14
  const isValueComplete = state.context.isValueComplete;
73
15
  const isInvalid = state.context.invalid;
@@ -77,21 +19,42 @@ function connect(state, send, normalize) {
77
19
  dom.getFirstInputEl(state.context)?.focus();
78
20
  }
79
21
  return {
22
+ /**
23
+ * The value of the input as an array of strings.
24
+ */
80
25
  value: state.context.value,
26
+ /**
27
+ * The value of the input as a string.
28
+ */
81
29
  valueAsString: state.context.valueAsString,
30
+ /**
31
+ * Whether all inputs are filled.
32
+ */
82
33
  isValueComplete,
34
+ /**
35
+ * Function to set the value of the inputs.
36
+ */
83
37
  setValue(value) {
84
38
  if (!Array.isArray(value)) {
85
39
  invariant("[pin-input/setValue] value must be an array");
86
40
  }
87
41
  send({ type: "SET_VALUE", value });
88
42
  },
43
+ /**
44
+ * Function to clear the value of the inputs.
45
+ */
89
46
  clearValue() {
90
47
  send({ type: "CLEAR_VALUE" });
91
48
  },
49
+ /**
50
+ * Function to set the value of the input at a specific index.
51
+ */
92
52
  setValueAtIndex(index, value) {
93
53
  send({ type: "SET_VALUE", value, index });
94
54
  },
55
+ /**
56
+ * Function to focus the pin-input. This will focus the first input.
57
+ */
95
58
  focus,
96
59
  rootProps: normalize.element({
97
60
  dir: state.context.dir,
@@ -159,7 +122,7 @@ function connect(state, send, normalize) {
159
122
  send("BACKSPACE");
160
123
  return;
161
124
  }
162
- send({ type: "INPUT", value });
125
+ send({ type: "INPUT", value, index });
163
126
  },
164
127
  onKeyDown(event) {
165
128
  const evt = getNativeEvent(event);