@zag-js/number-input 0.1.2 → 0.1.3

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.js CHANGED
@@ -58,6 +58,12 @@ function nextTick(fn) {
58
58
  });
59
59
  };
60
60
  }
61
+ function raf(fn) {
62
+ const id = globalThis.requestAnimationFrame(fn);
63
+ return function cleanup() {
64
+ globalThis.cancelAnimationFrame(id);
65
+ };
66
+ }
61
67
  var noop = () => {
62
68
  };
63
69
  var pipe = (...fns) => (v) => fns.reduce((a, b) => b(a), v);
@@ -161,6 +167,30 @@ function observeAttributes(node, attributes, fn) {
161
167
  obs.observe(node, { attributes: true, attributeFilter: attrs });
162
168
  return () => obs.disconnect();
163
169
  }
170
+ function itemById(v, id) {
171
+ return v.find((node) => node.id === id);
172
+ }
173
+ function indexOfId(v, id) {
174
+ const item = itemById(v, id);
175
+ return item ? v.indexOf(item) : -1;
176
+ }
177
+ var getValueText = (item) => {
178
+ var _a, _b;
179
+ return (_b = (_a = item.dataset.valuetext) != null ? _a : item.textContent) != null ? _b : "";
180
+ };
181
+ var match = (valueText, query2) => valueText.toLowerCase().startsWith(query2.toLowerCase());
182
+ var wrap = (v, idx) => {
183
+ return v.map((_, index) => v[(Math.max(idx, 0) + index) % v.length]);
184
+ };
185
+ function findByText(v, text, currentId) {
186
+ const index = currentId ? indexOfId(v, currentId) : -1;
187
+ let items = currentId ? wrap(v, index) : v;
188
+ const isSingleKey = text.length === 1;
189
+ if (isSingleKey) {
190
+ items = items.filter((item) => item.id !== currentId);
191
+ }
192
+ return items.find((item) => match(getValueText(item), text));
193
+ }
164
194
  function addPointerlockChangeListener(doc, fn) {
165
195
  return addDomEvent(doc, "pointerlockchange", fn, false);
166
196
  }
@@ -201,6 +231,34 @@ function requestPointerLock(doc, handlers = {}) {
201
231
  exit();
202
232
  };
203
233
  }
234
+ function findByTypeahead(_items, options) {
235
+ const { state: state2, activeId, key, timeout = 350 } = options;
236
+ const search = state2.keysSoFar + key;
237
+ const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
238
+ const query2 = isRepeated ? search[0] : search;
239
+ let items = _items.slice();
240
+ const next = findByText(items, query2, activeId);
241
+ function cleanup() {
242
+ clearTimeout(state2.timer);
243
+ state2.timer = -1;
244
+ }
245
+ function update(value) {
246
+ state2.keysSoFar = value;
247
+ cleanup();
248
+ if (value !== "") {
249
+ state2.timer = +setTimeout(() => {
250
+ update("");
251
+ cleanup();
252
+ }, timeout);
253
+ }
254
+ }
255
+ update(search);
256
+ return next;
257
+ }
258
+ findByTypeahead.defaultOptions = {
259
+ keysSoFar: "",
260
+ timer: -1
261
+ };
204
262
 
205
263
  // ../../utilities/number/dist/index.mjs
206
264
  var __defProp2 = Object.defineProperty;
@@ -223,11 +281,11 @@ var __spreadValues2 = (a, b) => {
223
281
  return a;
224
282
  };
225
283
  var __spreadProps2 = (a, b) => __defProps2(a, __getOwnPropDescs2(b));
226
- var nf = new Intl.NumberFormat("en-US", { style: "decimal" });
284
+ var nf = new Intl.NumberFormat("en-US", { style: "decimal", maximumFractionDigits: 20 });
227
285
  function formatter(n) {
228
286
  return parseFloat(nf.format(n));
229
287
  }
230
- function wrap(num, max) {
288
+ function wrap2(num, max) {
231
289
  return (num % max + max) % max;
232
290
  }
233
291
  function round(v, t2) {
@@ -245,9 +303,16 @@ function roundToPx(num) {
245
303
  function clamp(v, o) {
246
304
  return Math.min(Math.max(valueOf(v), o.min), o.max);
247
305
  }
248
- function countDecimals(v) {
249
- var _a, _b;
250
- return (_b = (_a = nf.formatToParts(v).find((p) => p.type === "fraction")) == null ? void 0 : _a.value.length) != null ? _b : 0;
306
+ function countDecimals(value) {
307
+ if (!Number.isFinite(value))
308
+ return 0;
309
+ let e = 1;
310
+ let p = 0;
311
+ while (Math.round(value * e) / e !== value) {
312
+ e *= 10;
313
+ p += 1;
314
+ }
315
+ return p;
251
316
  }
252
317
  var increment = (v, s) => formatter(valueOf(v) + s);
253
318
  var decrement = (v, s) => formatter(valueOf(v) - s);
@@ -261,9 +326,7 @@ function valueOf(v) {
261
326
  function getMaxPrecision(o) {
262
327
  var _a;
263
328
  const stepPrecision = countDecimals(o.step);
264
- const val = valueOf(o.value);
265
- const valuePrecision = Number.isNaN(val) ? stepPrecision : Math.max(countDecimals(val), stepPrecision);
266
- return Math.max(valuePrecision, (_a = o.precision) != null ? _a : 0);
329
+ return Math.max(stepPrecision, (_a = o.precision) != null ? _a : 0);
267
330
  }
268
331
  function roundToPrecision(v, o) {
269
332
  return round(v, getMaxPrecision(__spreadProps2(__spreadValues2({}, o), { value: v })));
@@ -352,7 +415,7 @@ var dom = {
352
415
  const win = dom.getWin(ctx);
353
416
  const width = win.innerWidth;
354
417
  const half = roundToPx(7.5);
355
- point.x = wrap(point.x + half, width) - half;
418
+ point.x = wrap2(point.x + half, width) - half;
356
419
  return { hint, point };
357
420
  },
358
421
  createVirtualCursor(ctx) {
@@ -382,15 +445,23 @@ var dom = {
382
445
  }
383
446
  };
384
447
 
448
+ // ../../utilities/core/dist/index.mjs
449
+ var pipe2 = (...fns) => (v) => fns.reduce((a, b) => b(a), v);
450
+ var ua = (v) => isDom() && v.test(navigator.userAgent);
451
+ var isDom = () => !!(typeof window !== "undefined");
452
+ var isSafari = () => ua(/^((?!chrome|android).)*safari/i);
453
+ var supportsPointerEvent = () => isDom() && window.onpointerdown === null;
454
+ var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
455
+
385
456
  // src/number-input.utils.ts
386
457
  var utils = {
387
458
  isValidNumericEvent: (ctx, event) => {
388
459
  var _a, _b;
389
460
  if (event.key == null)
390
461
  return true;
391
- const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
392
- const isSingleCharacterKey = event.key.length === 1;
393
- if (isModifierKey || !isSingleCharacterKey)
462
+ const isModifier = isModifiedEvent(event);
463
+ const isSingleKey = event.key.length === 1;
464
+ if (isModifier || !isSingleKey)
394
465
  return true;
395
466
  return (_b = (_a = ctx.validateCharacter) == null ? void 0 : _a.call(ctx, event.key)) != null ? _b : utils.isFloatingPoint(event.key);
396
467
  },
@@ -459,10 +530,8 @@ function connect(state, send, normalize = normalizeProp) {
459
530
  send({ type: "SET_VALUE", value: state.context.min });
460
531
  },
461
532
  focus() {
462
- nextTick(() => {
463
- var _a;
464
- (_a = dom.getInputEl(state.context)) == null ? void 0 : _a.focus();
465
- });
533
+ var _a;
534
+ (_a = dom.getInputEl(state.context)) == null ? void 0 : _a.focus();
466
535
  },
467
536
  rootProps: normalize.element({
468
537
  id: dom.getRootId(state.context),
@@ -609,15 +678,6 @@ function connect(state, send, normalize = normalizeProp) {
609
678
 
610
679
  // src/number-input.machine.ts
611
680
  var import_core = require("@zag-js/core");
612
-
613
- // ../../utilities/core/dist/index.mjs
614
- var pipe2 = (...fns) => (v) => fns.reduce((a, b) => b(a), v);
615
- var ua = (v) => isDom() && v.test(navigator.userAgent);
616
- var isDom = () => !!(typeof window !== "undefined");
617
- var isSafari = () => ua(/^((?!chrome|android).)*safari/i);
618
- var supportsPointerEvent = () => isDom() && window.onpointerdown === null;
619
-
620
- // src/number-input.machine.ts
621
681
  var { not, and } = import_core.guards;
622
682
  function machine(ctx = {}) {
623
683
  return (0, import_core.createMachine)({
@@ -722,7 +782,7 @@ function machine(ctx = {}) {
722
782
  actions: "setToMax"
723
783
  },
724
784
  CHANGE: {
725
- actions: ["setValue", "setSelectionRange", "setHint"]
785
+ actions: ["setValue", "setHint"]
726
786
  },
727
787
  BLUR: [
728
788
  {
@@ -736,6 +796,7 @@ function machine(ctx = {}) {
736
796
  actions: ["clampValue", "clearHint"]
737
797
  },
738
798
  {
799
+ target: "idle",
739
800
  actions: ["roundValue"]
740
801
  }
741
802
  ]
@@ -756,7 +817,7 @@ function machine(ctx = {}) {
756
817
  on: {
757
818
  PRESS_UP: {
758
819
  target: "focused",
759
- actions: ["clearHint", "restoreSelection"]
820
+ actions: "clearHint"
760
821
  }
761
822
  }
762
823
  },
@@ -778,7 +839,7 @@ function machine(ctx = {}) {
778
839
  on: {
779
840
  PRESS_UP: {
780
841
  target: "focused",
781
- actions: ["clearHint", "restoreSelection"]
842
+ actions: "clearHint"
782
843
  }
783
844
  }
784
845
  },
@@ -890,7 +951,7 @@ function machine(ctx = {}) {
890
951
  if (!ctx2.focusInputOnChange)
891
952
  return;
892
953
  const input = dom.getInputEl(ctx2);
893
- nextTick(() => input == null ? void 0 : input.focus());
954
+ raf(() => input == null ? void 0 : input.focus());
894
955
  },
895
956
  increment(ctx2, evt) {
896
957
  ctx2.value = utils.increment(ctx2, evt.step);
@@ -927,20 +988,6 @@ function machine(ctx = {}) {
927
988
  setHintToSet(ctx2) {
928
989
  ctx2.hint = "set";
929
990
  },
930
- setSelectionRange(ctx2, evt) {
931
- ctx2.inputSelection = {
932
- start: evt.target.selectionStart,
933
- end: evt.target.selectionEnd
934
- };
935
- },
936
- restoreSelection(ctx2) {
937
- var _a, _b, _c;
938
- const input = dom.getInputEl(ctx2);
939
- if (!input || !ctx2.inputSelection)
940
- return;
941
- input.selectionStart = (_b = ctx2.inputSelection.start) != null ? _b : (_a = input.value) == null ? void 0 : _a.length;
942
- input.selectionEnd = (_c = ctx2.inputSelection.end) != null ? _c : input.selectionStart;
943
- },
944
991
  invokeOnChange(ctx2) {
945
992
  var _a;
946
993
  (_a = ctx2.onChange) == null ? void 0 : _a.call(ctx2, { value: ctx2.value, valueAsNumber: ctx2.valueAsNumber });