@zag-js/pin-input 0.1.7 → 0.1.10

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.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  export { connect } from "./pin-input.connect";
2
2
  export { machine } from "./pin-input.machine";
3
3
  export type { UserDefinedContext as Context } from "./pin-input.types";
4
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  var __defProp = Object.defineProperty;
2
3
  var __defProps = Object.defineProperties;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -42,37 +43,85 @@ __export(src_exports, {
42
43
  module.exports = __toCommonJS(src_exports);
43
44
 
44
45
  // ../../utilities/dom/dist/index.mjs
46
+ var __defProp2 = Object.defineProperty;
47
+ var __getOwnPropSymbols2 = Object.getOwnPropertySymbols;
48
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
49
+ var __propIsEnum2 = Object.prototype.propertyIsEnumerable;
50
+ var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
51
+ var __spreadValues2 = (a, b) => {
52
+ for (var prop in b || (b = {}))
53
+ if (__hasOwnProp2.call(b, prop))
54
+ __defNormalProp2(a, prop, b[prop]);
55
+ if (__getOwnPropSymbols2)
56
+ for (var prop of __getOwnPropSymbols2(b)) {
57
+ if (__propIsEnum2.call(b, prop))
58
+ __defNormalProp2(a, prop, b[prop]);
59
+ }
60
+ return a;
61
+ };
45
62
  var dataAttr = (guard) => {
46
63
  return guard ? "" : void 0;
47
64
  };
48
65
  var ariaAttr = (guard) => {
49
66
  return guard ? "true" : void 0;
50
67
  };
51
- function nextTick(fn) {
52
- const set = /* @__PURE__ */ new Set();
53
- function raf2(fn2) {
54
- const id = globalThis.requestAnimationFrame(fn2);
55
- set.add(() => globalThis.cancelAnimationFrame(id));
56
- }
57
- raf2(() => raf2(fn));
58
- return function cleanup() {
59
- set.forEach(function(fn2) {
60
- fn2();
61
- });
62
- };
68
+ function isDocument(el) {
69
+ return el.nodeType === Node.DOCUMENT_NODE;
63
70
  }
64
- function raf(fn) {
65
- const id = globalThis.requestAnimationFrame(fn);
66
- return function cleanup() {
67
- globalThis.cancelAnimationFrame(id);
71
+ function isWindow(value) {
72
+ return (value == null ? void 0 : value.toString()) === "[object Window]";
73
+ }
74
+ function getDocument(el) {
75
+ var _a;
76
+ if (isWindow(el))
77
+ return el.document;
78
+ if (isDocument(el))
79
+ return el;
80
+ return (_a = el == null ? void 0 : el.ownerDocument) != null ? _a : document;
81
+ }
82
+ function getWindow(el) {
83
+ var _a;
84
+ return (_a = el == null ? void 0 : el.ownerDocument.defaultView) != null ? _a : window;
85
+ }
86
+ function defineDomHelpers(helpers) {
87
+ const dom2 = {
88
+ getRootNode: (ctx) => {
89
+ var _a, _b;
90
+ return (_b = (_a = ctx.getRootNode) == null ? void 0 : _a.call(ctx)) != null ? _b : document;
91
+ },
92
+ getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
93
+ getWin: (ctx) => {
94
+ var _a;
95
+ return (_a = dom2.getDoc(ctx).defaultView) != null ? _a : window;
96
+ },
97
+ getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
98
+ getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id)
68
99
  };
100
+ return __spreadValues2(__spreadValues2({}, dom2), helpers);
69
101
  }
70
- var isDom = () => typeof window !== "undefined";
71
- var isTouchDevice = isDom() && !!navigator.maxTouchPoints;
72
102
  function getNativeEvent(e) {
73
103
  var _a;
74
104
  return (_a = e.nativeEvent) != null ? _a : e;
75
105
  }
106
+ var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
107
+ function getDescriptor(el, options) {
108
+ var _a;
109
+ const { type, property } = options;
110
+ const proto = getWindow(el)[type].prototype;
111
+ return (_a = Object.getOwnPropertyDescriptor(proto, property)) != null ? _a : {};
112
+ }
113
+ function dispatchInputValueEvent(el, value) {
114
+ var _a;
115
+ if (!el)
116
+ return;
117
+ const win = getWindow(el);
118
+ if (!(el instanceof win.HTMLInputElement))
119
+ return;
120
+ const desc = getDescriptor(el, { type: "HTMLInputElement", property: "value" });
121
+ (_a = desc.set) == null ? void 0 : _a.call(el, value);
122
+ const event = new win.Event("input", { bubbles: true });
123
+ el.dispatchEvent(event);
124
+ }
76
125
  var rtlKeyMap = {
77
126
  ArrowLeft: "ArrowRight",
78
127
  ArrowRight: "ArrowLeft",
@@ -99,78 +148,30 @@ function getEventKey(event, options = {}) {
99
148
  }
100
149
  return key;
101
150
  }
151
+ function raf(fn) {
152
+ const id = globalThis.requestAnimationFrame(fn);
153
+ return function cleanup() {
154
+ globalThis.cancelAnimationFrame(id);
155
+ };
156
+ }
102
157
  function queryAll(root, selector) {
103
158
  var _a;
104
159
  return Array.from((_a = root == null ? void 0 : root.querySelectorAll(selector)) != null ? _a : []);
105
160
  }
106
- function itemById(v, id) {
107
- return v.find((node) => node.id === id);
108
- }
109
- function indexOfId(v, id) {
110
- const item = itemById(v, id);
111
- return item ? v.indexOf(item) : -1;
112
- }
113
- var getValueText = (item) => {
114
- var _a, _b;
115
- return (_b = (_a = item.dataset.valuetext) != null ? _a : item.textContent) != null ? _b : "";
116
- };
117
- var match = (valueText, query2) => valueText.toLowerCase().startsWith(query2.toLowerCase());
118
- var wrap = (v, idx) => {
119
- return v.map((_, index) => v[(Math.max(idx, 0) + index) % v.length]);
120
- };
121
- function findByText(v, text, currentId) {
122
- const index = currentId ? indexOfId(v, currentId) : -1;
123
- let items = currentId ? wrap(v, index) : v;
124
- const isSingleKey = text.length === 1;
125
- if (isSingleKey) {
126
- items = items.filter((item) => item.id !== currentId);
127
- }
128
- return items.find((item) => match(getValueText(item), text));
129
- }
130
- function findByTypeahead(_items, options) {
131
- const { state: state2, activeId, key, timeout = 350 } = options;
132
- const search = state2.keysSoFar + key;
133
- const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
134
- const query2 = isRepeated ? search[0] : search;
135
- let items = _items.slice();
136
- const next = findByText(items, query2, activeId);
137
- function cleanup() {
138
- clearTimeout(state2.timer);
139
- state2.timer = -1;
140
- }
141
- function update(value) {
142
- state2.keysSoFar = value;
143
- cleanup();
144
- if (value !== "") {
145
- state2.timer = +setTimeout(() => {
146
- update("");
147
- cleanup();
148
- }, timeout);
149
- }
150
- }
151
- update(search);
152
- return next;
153
- }
154
- findByTypeahead.defaultOptions = {
155
- keysSoFar: "",
156
- timer: -1
161
+ var visuallyHiddenStyle = {
162
+ border: "0",
163
+ clip: "rect(0 0 0 0)",
164
+ height: "1px",
165
+ margin: "-1px",
166
+ overflow: "hidden",
167
+ padding: "0",
168
+ position: "absolute",
169
+ width: "1px",
170
+ whiteSpace: "nowrap",
171
+ wordWrap: "normal"
157
172
  };
158
173
 
159
- // ../../types/dist/index.mjs
160
- function createNormalizer(fn) {
161
- return new Proxy({}, {
162
- get() {
163
- return fn;
164
- }
165
- });
166
- }
167
- var normalizeProp = createNormalizer((v) => v);
168
-
169
174
  // ../../utilities/core/dist/index.mjs
170
- var fromLength = (length) => Array.from(Array(length).keys());
171
- var isDom2 = () => typeof window !== "undefined";
172
- var isTouchDevice2 = isDom2() && !!navigator.maxTouchPoints;
173
- var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
174
175
  function invariant(...a) {
175
176
  const m = a.length === 1 ? a[0] : a[1];
176
177
  const c = a.length === 2 ? a[0] : true;
@@ -180,35 +181,32 @@ function invariant(...a) {
180
181
  }
181
182
 
182
183
  // src/pin-input.dom.ts
183
- var dom = {
184
- getDoc: (ctx) => {
185
- var _a;
186
- return (_a = ctx.doc) != null ? _a : document;
187
- },
188
- getRootNode: (ctx) => {
189
- var _a;
190
- return (_a = ctx.rootNode) != null ? _a : dom.getDoc(ctx);
191
- },
184
+ var dom = defineDomHelpers({
192
185
  getRootId: (ctx) => {
193
186
  var _a, _b;
194
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.root) != null ? _b : `pin-input:${ctx.uid}`;
187
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.root) != null ? _b : `pin-input:${ctx.id}`;
195
188
  },
196
189
  getInputId: (ctx, id) => {
197
190
  var _a, _b, _c;
198
- return (_c = (_b = (_a = ctx.ids) == null ? void 0 : _a.input) == null ? void 0 : _b.call(_a, id)) != null ? _c : `pin-input:${ctx.uid}:${id}`;
191
+ 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}`;
192
+ },
193
+ getHiddenInputId: (ctx) => {
194
+ var _a, _b;
195
+ return (_b = (_a = ctx.ids) == null ? void 0 : _a.hiddenInput) != null ? _b : `pin-input:${ctx.id}:hidden`;
199
196
  },
200
- getRootEl: (ctx) => dom.getRootNode(ctx).getElementById(dom.getRootId(ctx)),
197
+ getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
201
198
  getElements: (ctx) => {
202
199
  const ownerId = CSS.escape(dom.getRootId(ctx));
203
200
  const selector = `input[data-ownedby=${ownerId}]`;
204
201
  return queryAll(dom.getRootEl(ctx), selector);
205
202
  },
206
203
  getFocusedEl: (ctx) => dom.getElements(ctx)[ctx.focusedIndex],
207
- getFirstInputEl: (ctx) => dom.getElements(ctx)[0]
208
- };
204
+ getFirstInputEl: (ctx) => dom.getElements(ctx)[0],
205
+ getHiddenInputEl: (ctx) => dom.getById(ctx, dom.getHiddenInputId(ctx))
206
+ });
209
207
 
210
208
  // src/pin-input.connect.ts
211
- function connect(state, send, normalize = normalizeProp) {
209
+ function connect(state, send, normalize) {
212
210
  const isValueComplete = state.context.isValueComplete;
213
211
  const isInvalid = state.context.invalid;
214
212
  const focusedIndex = state.context.focusedIndex;
@@ -241,6 +239,16 @@ function connect(state, send, normalize = normalizeProp) {
241
239
  "data-disabled": dataAttr(state.context.disabled),
242
240
  "data-complete": dataAttr(isValueComplete)
243
241
  }),
242
+ hiddenInputProps: normalize.input({
243
+ "aria-hidden": true,
244
+ type: "text",
245
+ tabIndex: -1,
246
+ id: dom.getHiddenInputId(state.context),
247
+ name: state.context.name,
248
+ style: visuallyHiddenStyle,
249
+ maxLength: state.context.valueLength,
250
+ defaultValue: state.context.valueAsString
251
+ }),
244
252
  getInputProps({ index }) {
245
253
  const inputType = state.context.type === "numeric" ? "tel" : "text";
246
254
  return normalize.input({
@@ -289,6 +297,9 @@ function connect(state, send, normalize = normalizeProp) {
289
297
  },
290
298
  ArrowRight() {
291
299
  send("ARROW_RIGHT");
300
+ },
301
+ Enter() {
302
+ send("ENTER");
292
303
  }
293
304
  };
294
305
  const key = getEventKey(event, { dir: state.context.dir });
@@ -314,12 +325,11 @@ function connect(state, send, normalize = normalizeProp) {
314
325
  // src/pin-input.machine.ts
315
326
  var import_core = require("@zag-js/core");
316
327
  var { and, not } = import_core.guards;
317
- function machine(ctx = {}) {
328
+ function machine(ctx) {
318
329
  return (0, import_core.createMachine)({
319
330
  id: "pin-input",
320
331
  initial: "unknown",
321
332
  context: __spreadProps(__spreadValues({
322
- uid: "pin-input",
323
333
  value: [],
324
334
  focusedIndex: -1,
325
335
  placeholder: "\u25CB",
@@ -339,7 +349,7 @@ function machine(ctx = {}) {
339
349
  watch: {
340
350
  focusedIndex: "focusInput",
341
351
  value: "invokeOnChange",
342
- isValueComplete: ["invokeComplete", "blurFocusedInputIfNeeded"]
352
+ isValueComplete: ["invokeOnComplete", "blurFocusedInputIfNeeded"]
343
353
  },
344
354
  on: {
345
355
  SET_VALUE: [
@@ -366,11 +376,11 @@ function machine(ctx = {}) {
366
376
  {
367
377
  guard: "autoFocus",
368
378
  target: "focused",
369
- actions: ["setupDocument", "setupValue", "setFocusIndexToFirst"]
379
+ actions: ["setupValue", "setFocusIndexToFirst"]
370
380
  },
371
381
  {
372
382
  target: "idle",
373
- actions: ["setupDocument", "setupValue"]
383
+ actions: "setupValue"
374
384
  }
375
385
  ]
376
386
  }
@@ -422,6 +432,10 @@ function machine(ctx = {}) {
422
432
  actions: ["setPrevFocusedIndex", "clearFocusedValue"]
423
433
  }
424
434
  ],
435
+ ENTER: {
436
+ guard: "isValueComplete",
437
+ actions: "requestFormSubmit"
438
+ },
425
439
  KEY_DOWN: {
426
440
  guard: not("isValidValue"),
427
441
  actions: ["preventDefault", "invokeOnInvalid"]
@@ -435,7 +449,12 @@ function machine(ctx = {}) {
435
449
  isValueEmpty: (_ctx, evt) => evt.value === "",
436
450
  hasValue: (ctx2) => ctx2.value[ctx2.focusedIndex] !== "",
437
451
  isValueComplete: (ctx2) => ctx2.isValueComplete,
438
- isValidValue: (ctx2, evt) => isValidType(evt.value, ctx2.type),
452
+ isValidValue: (ctx2, evt) => {
453
+ if (!ctx2.pattern)
454
+ return isValidType(evt.value, ctx2.type);
455
+ const regex = new RegExp(ctx2.pattern, "g");
456
+ return regex.test(evt.value);
457
+ },
439
458
  isFinalValue: (ctx2) => {
440
459
  return ctx2.filledValueLength + 1 === ctx2.valueLength && ctx2.value.findIndex((v) => v.trim() === "") === ctx2.focusedIndex;
441
460
  },
@@ -444,19 +463,10 @@ function machine(ctx = {}) {
444
463
  isDisabled: (ctx2) => !!ctx2.disabled
445
464
  },
446
465
  actions: {
447
- setupDocument: (ctx2, evt) => {
448
- if (evt.doc)
449
- ctx2.doc = (0, import_core.ref)(evt.doc);
450
- if (evt.root)
451
- ctx2.rootNode = (0, import_core.ref)(evt.root);
452
- ctx2.uid = evt.id;
453
- },
454
466
  setupValue: (ctx2) => {
455
- nextTick(() => {
456
- const inputs = dom.getElements(ctx2);
457
- const empty = fromLength(inputs.length).map(() => "");
458
- ctx2.value = Object.assign(empty, ctx2.value);
459
- });
467
+ const inputs = dom.getElements(ctx2);
468
+ const empty = Array.from({ length: inputs.length }).map(() => "");
469
+ ctx2.value = Object.assign(empty, ctx2.value);
460
470
  },
461
471
  focusInput: (ctx2) => {
462
472
  raf(() => {
@@ -466,17 +476,18 @@ function machine(ctx = {}) {
466
476
  (_a = dom.getFocusedEl(ctx2)) == null ? void 0 : _a.focus();
467
477
  });
468
478
  },
469
- invokeComplete: (ctx2) => {
479
+ invokeOnComplete: (ctx2) => {
470
480
  var _a;
471
- if (ctx2.isValueComplete) {
472
- (_a = ctx2.onComplete) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value), valueAsString: ctx2.valueAsString });
473
- }
481
+ if (!ctx2.isValueComplete)
482
+ return;
483
+ (_a = ctx2.onComplete) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value), valueAsString: ctx2.valueAsString });
474
484
  },
475
485
  invokeOnChange: (ctx2, evt) => {
476
486
  var _a;
477
- if (evt.type !== "SETUP") {
478
- (_a = ctx2.onChange) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value) });
479
- }
487
+ if (evt.type === "SETUP")
488
+ return;
489
+ (_a = ctx2.onChange) == null ? void 0 : _a.call(ctx2, { value: Array.from(ctx2.value) });
490
+ dispatchInputValueEvent(dom.getHiddenInputEl(ctx2), ctx2.valueAsString);
480
491
  },
481
492
  invokeOnInvalid: (ctx2, evt) => {
482
493
  var _a;
@@ -533,6 +544,13 @@ function machine(ctx = {}) {
533
544
  var _a;
534
545
  (_a = dom.getFocusedEl(ctx2)) == null ? void 0 : _a.blur();
535
546
  });
547
+ },
548
+ requestFormSubmit(ctx2) {
549
+ var _a;
550
+ if (!ctx2.name)
551
+ return;
552
+ const input = dom.getHiddenInputEl(ctx2);
553
+ (_a = input == null ? void 0 : input.form) == null ? void 0 : _a.requestSubmit();
536
554
  }
537
555
  }
538
556
  });
@@ -563,4 +581,3 @@ function assign(ctx, value) {
563
581
  function lastChar(value) {
564
582
  return value.charAt(value.length - 1);
565
583
  }
566
- //# sourceMappingURL=index.js.map