@zag-js/number-input 0.1.3 → 0.1.4

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.mjs CHANGED
@@ -22,19 +22,9 @@ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
22
22
  var dataAttr = (guard) => {
23
23
  return guard ? "" : void 0;
24
24
  };
25
- function nextTick(fn) {
26
- const set = /* @__PURE__ */ new Set();
27
- function raf2(fn2) {
28
- const id = globalThis.requestAnimationFrame(fn2);
29
- set.add(() => globalThis.cancelAnimationFrame(id));
30
- }
31
- raf2(() => raf2(fn));
32
- return function cleanup() {
33
- set.forEach(function(fn2) {
34
- fn2();
35
- });
36
- };
37
- }
25
+ var ariaAttr = (guard) => {
26
+ return guard ? "true" : void 0;
27
+ };
38
28
  function raf(fn) {
39
29
  const id = globalThis.requestAnimationFrame(fn);
40
30
  return function cleanup() {
@@ -238,40 +228,11 @@ findByTypeahead.defaultOptions = {
238
228
  };
239
229
 
240
230
  // ../../utilities/number/dist/index.mjs
241
- var __defProp2 = Object.defineProperty;
242
- var __defProps2 = Object.defineProperties;
243
- var __getOwnPropDescs2 = Object.getOwnPropertyDescriptors;
244
- var __getOwnPropSymbols2 = Object.getOwnPropertySymbols;
245
- var __hasOwnProp2 = Object.prototype.hasOwnProperty;
246
- var __propIsEnum2 = Object.prototype.propertyIsEnumerable;
247
231
  var __pow = Math.pow;
248
- var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
249
- var __spreadValues2 = (a, b) => {
250
- for (var prop in b || (b = {}))
251
- if (__hasOwnProp2.call(b, prop))
252
- __defNormalProp2(a, prop, b[prop]);
253
- if (__getOwnPropSymbols2)
254
- for (var prop of __getOwnPropSymbols2(b)) {
255
- if (__propIsEnum2.call(b, prop))
256
- __defNormalProp2(a, prop, b[prop]);
257
- }
258
- return a;
259
- };
260
- var __spreadProps2 = (a, b) => __defProps2(a, __getOwnPropDescs2(b));
261
- var nf = new Intl.NumberFormat("en-US", { style: "decimal", maximumFractionDigits: 20 });
262
- function formatter(n) {
263
- return parseFloat(nf.format(n));
264
- }
265
232
  function wrap2(num, max) {
266
233
  return (num % max + max) % max;
267
234
  }
268
- function round(v, t2) {
269
- let num = valueOf(v);
270
- const p = __pow(10, t2 != null ? t2 : 10);
271
- num = Math.round(num * p) / p;
272
- return t2 ? num.toFixed(t2) : v.toString();
273
- }
274
- function roundToPx(num) {
235
+ function roundToDevicePixel(num) {
275
236
  if (typeof window === "undefined")
276
237
  return Math.round(num);
277
238
  const dp = window.devicePixelRatio;
@@ -283,30 +244,28 @@ function clamp(v, o) {
283
244
  function countDecimals(value) {
284
245
  if (!Number.isFinite(value))
285
246
  return 0;
286
- let e = 1;
287
- let p = 0;
247
+ let e = 1, p = 0;
288
248
  while (Math.round(value * e) / e !== value) {
289
249
  e *= 10;
290
250
  p += 1;
291
251
  }
292
252
  return p;
293
253
  }
294
- var increment = (v, s) => formatter(valueOf(v) + s);
295
- var decrement = (v, s) => formatter(valueOf(v) - s);
296
- var multiply = (v, s) => formatter(valueOf(v) * s);
254
+ var increment = (v, s) => decimalOperation(valueOf(v), "+", s);
255
+ var decrement = (v, s) => decimalOperation(valueOf(v), "-", s);
297
256
  function valueOf(v) {
298
257
  if (typeof v === "number")
299
258
  return v;
300
259
  const num = parseFloat(v.toString().replace(/[^\w.-]+/g, ""));
301
260
  return !Number.isNaN(num) ? num : 0;
302
261
  }
303
- function getMaxPrecision(o) {
304
- var _a;
305
- const stepPrecision = countDecimals(o.step);
306
- return Math.max(stepPrecision, (_a = o.precision) != null ? _a : 0);
307
- }
308
- function roundToPrecision(v, o) {
309
- return round(v, getMaxPrecision(__spreadProps2(__spreadValues2({}, o), { value: v })));
262
+ function formatDecimal(v, o) {
263
+ return new Intl.NumberFormat("en-US", {
264
+ useGrouping: false,
265
+ style: "decimal",
266
+ minimumFractionDigits: o.minFractionDigits,
267
+ maximumFractionDigits: o.maxFractionDigits
268
+ }).format(valueOf(v));
310
269
  }
311
270
  function isAtMax(v, o) {
312
271
  const val = valueOf(v);
@@ -320,6 +279,18 @@ function isWithinRange(v, o) {
320
279
  const val = valueOf(v);
321
280
  return val >= o.min && val <= o.max;
322
281
  }
282
+ function decimalOperation(a, op, b) {
283
+ let result = op === "+" ? a + b : a - b;
284
+ if (a % 1 !== 0 || b % 1 !== 0) {
285
+ const multiplier = __pow(10, Math.max(countDecimals(a), countDecimals(b)));
286
+ a = Math.round(a * multiplier);
287
+ b = Math.round(b * multiplier);
288
+ result = op === "+" ? a + b : a - b;
289
+ result /= multiplier;
290
+ }
291
+ return result;
292
+ }
293
+ var nf = new Intl.NumberFormat("en-US", { style: "decimal", maximumFractionDigits: 20 });
323
294
 
324
295
  // ../../utilities/rect/dist/index.mjs
325
296
  var isArray = (v) => Array.isArray(v);
@@ -337,6 +308,19 @@ function createNormalizer(fn) {
337
308
  }
338
309
  var normalizeProp = createNormalizer((v) => v);
339
310
 
311
+ // ../../utilities/core/dist/index.mjs
312
+ var pipe2 = (...fns) => (v) => fns.reduce((a, b) => b(a), v);
313
+ var platform = (v) => isDom() && v.test(navigator.platform);
314
+ var ua = (v) => isDom() && v.test(navigator.userAgent);
315
+ var isDom = () => !!(typeof window !== "undefined");
316
+ var isMac = () => platform(/^Mac/);
317
+ var isIPhone = () => platform(/^iPhone/);
318
+ var isIPad = () => platform(/^iPad/) || isMac() && navigator.maxTouchPoints > 1;
319
+ var isIos = () => isIPhone() || isIPad();
320
+ var isSafari = () => ua(/^((?!chrome|android).)*safari/i);
321
+ var supportsPointerEvent = () => isDom() && window.onpointerdown === null;
322
+ var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
323
+
340
324
  // src/number-input.dom.ts
341
325
  var dom = {
342
326
  getDoc: (ctx) => {
@@ -347,6 +331,10 @@ var dom = {
347
331
  var _a;
348
332
  return (_a = dom.getDoc(ctx).defaultView) != null ? _a : window;
349
333
  },
334
+ getRootNode: (ctx) => {
335
+ var _a;
336
+ return (_a = ctx.rootNode) != null ? _a : dom.getDoc(ctx);
337
+ },
350
338
  getRootId: (ctx) => {
351
339
  var _a, _b;
352
340
  return (_b = (_a = ctx.ids) == null ? void 0 : _a.root) != null ? _b : `number-input:${ctx.uid}`;
@@ -372,14 +360,14 @@ var dom = {
372
360
  var _a, _b;
373
361
  return (_b = (_a = ctx.ids) == null ? void 0 : _a.label) != null ? _b : `number-input:${ctx.uid}:label`;
374
362
  },
375
- getInputEl: (ctx) => dom.getDoc(ctx).getElementById(dom.getInputId(ctx)),
376
- getIncButtonEl: (ctx) => dom.getDoc(ctx).getElementById(dom.getIncButtonId(ctx)),
377
- getDecButtonEl: (ctx) => dom.getDoc(ctx).getElementById(dom.getDecButtonId(ctx)),
378
- getScrubberEl: (ctx) => dom.getDoc(ctx).getElementById(dom.getScrubberId(ctx)),
363
+ getInputEl: (ctx) => dom.getRootNode(ctx).getElementById(dom.getInputId(ctx)),
364
+ getIncButtonEl: (ctx) => dom.getRootNode(ctx).getElementById(dom.getIncButtonId(ctx)),
365
+ getDecButtonEl: (ctx) => dom.getRootNode(ctx).getElementById(dom.getDecButtonId(ctx)),
366
+ getScrubberEl: (ctx) => dom.getRootNode(ctx).getElementById(dom.getScrubberId(ctx)),
379
367
  getCursorEl: (ctx) => dom.getDoc(ctx).getElementById(dom.getCursorId(ctx)),
380
368
  getMousementValue(ctx, event) {
381
- const x = roundToPx(event.movementX);
382
- const y = roundToPx(event.movementY);
369
+ const x = roundToDevicePixel(event.movementX);
370
+ const y = roundToDevicePixel(event.movementY);
383
371
  let hint = x > 0 ? "increment" : x < 0 ? "decrement" : null;
384
372
  if (ctx.isRtl && hint === "increment")
385
373
  hint = "decrement";
@@ -391,7 +379,7 @@ var dom = {
391
379
  };
392
380
  const win = dom.getWin(ctx);
393
381
  const width = win.innerWidth;
394
- const half = roundToPx(7.5);
382
+ const half = roundToDevicePixel(7.5);
395
383
  point.x = wrap2(point.x + half, width) - half;
396
384
  return { hint, point };
397
385
  },
@@ -422,14 +410,6 @@ var dom = {
422
410
  }
423
411
  };
424
412
 
425
- // ../../utilities/core/dist/index.mjs
426
- var pipe2 = (...fns) => (v) => fns.reduce((a, b) => b(a), v);
427
- var ua = (v) => isDom() && v.test(navigator.userAgent);
428
- var isDom = () => !!(typeof window !== "undefined");
429
- var isSafari = () => ua(/^((?!chrome|android).)*safari/i);
430
- var supportsPointerEvent = () => isDom() && window.onpointerdown === null;
431
- var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
432
-
433
413
  // src/number-input.utils.ts
434
414
  var utils = {
435
415
  isValidNumericEvent: (ctx, event) => {
@@ -448,18 +428,15 @@ var utils = {
448
428
  return value.split("").filter((_a = ctx.validateCharacter) != null ? _a : utils.isFloatingPoint).join("");
449
429
  },
450
430
  increment: (ctx, step) => {
451
- let value = increment(ctx.value, step != null ? step : ctx.step);
452
- value = clamp(value, ctx);
453
- return roundToPrecision(value, ctx);
431
+ const value = increment(ctx.value, step != null ? step : ctx.step);
432
+ return formatDecimal(clamp(value, ctx), ctx);
454
433
  },
455
434
  decrement: (ctx, step) => {
456
- let value = decrement(ctx.value, step != null ? step : ctx.step);
457
- value = clamp(value, ctx);
458
- return roundToPrecision(value, ctx);
435
+ const value = decrement(ctx.value, step != null ? step : ctx.step);
436
+ return formatDecimal(clamp(value, ctx), ctx);
459
437
  },
460
438
  clamp: (ctx) => {
461
- let value = clamp(ctx.value, ctx);
462
- return roundToPrecision(value, ctx);
439
+ return formatDecimal(clamp(ctx.value, ctx), ctx);
463
440
  },
464
441
  parse: (ctx, value) => {
465
442
  var _a, _b;
@@ -471,7 +448,7 @@ var utils = {
471
448
  return (_b = (_a = ctx.format) == null ? void 0 : _a.call(ctx, _val)) != null ? _b : _val;
472
449
  },
473
450
  round: (ctx) => {
474
- return roundToPrecision(ctx.value, ctx);
451
+ return formatDecimal(ctx.value, ctx);
475
452
  }
476
453
  };
477
454
 
@@ -492,7 +469,7 @@ function connect(state, send, normalize = normalizeProp) {
492
469
  send({ type: "SET_VALUE", value: value.toString() });
493
470
  },
494
471
  clearValue() {
495
- send({ type: "SET_VALUE", value: "" });
472
+ send("CLEAR_VALUE");
496
473
  },
497
474
  increment() {
498
475
  send("INCREMENT");
@@ -522,6 +499,14 @@ function connect(state, send, normalize = normalizeProp) {
522
499
  id: dom.getLabelId(state.context),
523
500
  htmlFor: dom.getInputId(state.context)
524
501
  }),
502
+ groupProps: normalize.element({
503
+ "data-part": "group",
504
+ role: "group",
505
+ "aria-disabled": isDisabled,
506
+ "data-disabled": dataAttr(isDisabled),
507
+ "data-invalid": dataAttr(isInvalid),
508
+ "aria-invalid": ariaAttr(state.context.invalid)
509
+ }),
525
510
  inputProps: normalize.input({
526
511
  "data-part": "input",
527
512
  name: state.context.name,
@@ -539,7 +524,7 @@ function connect(state, send, normalize = normalizeProp) {
539
524
  autoCorrect: "off",
540
525
  spellCheck: "false",
541
526
  type: "text",
542
- "aria-roledescription": "number field",
527
+ "aria-roledescription": !isIos() ? "number field" : void 0,
543
528
  "aria-valuemin": state.context.min,
544
529
  "aria-valuemax": state.context.max,
545
530
  "aria-valuenow": isNaN(state.context.valueAsNumber) ? void 0 : state.context.valueAsNumber,
@@ -563,7 +548,7 @@ function connect(state, send, normalize = normalizeProp) {
563
548
  if (!utils.isValidNumericEvent(state.context, event)) {
564
549
  event.preventDefault();
565
550
  }
566
- const step = multiply(getEventStep(event), state.context.step);
551
+ const step = getEventStep(event) * state.context.step;
567
552
  const keyMap = {
568
553
  ArrowUp() {
569
554
  send({ type: "ARROW_UP", step });
@@ -642,8 +627,8 @@ function connect(state, send, normalize = normalizeProp) {
642
627
  const evt = getNativeEvent(event);
643
628
  event.preventDefault();
644
629
  const point = getEventPoint(evt);
645
- point.x = point.x - roundToPx(7.5);
646
- point.y = point.y - roundToPx(7.5);
630
+ point.x = point.x - roundToDevicePixel(7.5);
631
+ point.y = point.y - roundToDevicePixel(7.5);
647
632
  send({ type: "PRESS_DOWN_SCRUBBER", point });
648
633
  },
649
634
  style: {
@@ -673,8 +658,6 @@ function machine(ctx = {}) {
673
658
  step: 1,
674
659
  min: Number.MIN_SAFE_INTEGER,
675
660
  max: Number.MAX_SAFE_INTEGER,
676
- precision: 0,
677
- inputSelection: null,
678
661
  scrubberCursorPoint: null,
679
662
  invalid: false
680
663
  }, ctx), {
@@ -704,20 +687,26 @@ function machine(ctx = {}) {
704
687
  value: ["invokeOnChange"],
705
688
  isOutOfRange: ["invokeOnInvalid"]
706
689
  },
707
- entry: ["syncInputValue"],
708
690
  on: {
709
691
  SET_VALUE: {
710
692
  actions: ["setValue", "setHintToSet"]
711
693
  },
712
- INCREMENT: { actions: ["increment"] },
713
- DECREMENT: { actions: ["decrement"] }
694
+ CLEAR_VALUE: {
695
+ actions: ["clearValue"]
696
+ },
697
+ INCREMENT: {
698
+ actions: ["increment"]
699
+ },
700
+ DECREMENT: {
701
+ actions: ["decrement"]
702
+ }
714
703
  },
715
704
  states: {
716
705
  unknown: {
717
706
  on: {
718
707
  SETUP: {
719
708
  target: "idle",
720
- actions: "setupDocument"
709
+ actions: ["setupDocument", "syncInputValue"]
721
710
  }
722
711
  }
723
712
  },
@@ -876,26 +865,23 @@ function machine(ctx = {}) {
876
865
  send("PRESS_UP");
877
866
  });
878
867
  },
879
- attachWheelListener(ctx2) {
880
- const cleanups = [];
881
- cleanups.push(nextTick(() => {
882
- const input = dom.getInputEl(ctx2);
883
- if (!input)
868
+ attachWheelListener(ctx2, _evt, { send }) {
869
+ const input = dom.getInputEl(ctx2);
870
+ if (!input)
871
+ return;
872
+ function onWheel(event) {
873
+ const isInputFocused = dom.getDoc(ctx2).activeElement === input;
874
+ if (!ctx2.allowMouseWheel || !isInputFocused)
884
875
  return;
885
- function onWheel(event) {
886
- const isInputFocused = dom.getDoc(ctx2).activeElement === input;
887
- if (!ctx2.allowMouseWheel || !isInputFocused)
888
- return;
889
- event.preventDefault();
890
- const dir = Math.sign(event.deltaY) * -1;
891
- if (dir === 1)
892
- ctx2.value = utils.increment(ctx2);
893
- else if (dir === -1)
894
- ctx2.value = utils.decrement(ctx2);
876
+ event.preventDefault();
877
+ const dir = Math.sign(event.deltaY) * -1;
878
+ if (dir === 1) {
879
+ send("INCREMENT");
880
+ } else if (dir === -1) {
881
+ send("DECREMENT");
895
882
  }
896
- cleanups.push(addDomEvent(input, "wheel", onWheel, { passive: false }));
897
- }));
898
- return () => cleanups.forEach((c) => c());
883
+ }
884
+ return addDomEvent(input, "wheel", onWheel, { passive: false });
899
885
  },
900
886
  activatePointerLock(ctx2) {
901
887
  if (isSafari() || !supportsPointerEvent())
@@ -910,7 +896,11 @@ function machine(ctx = {}) {
910
896
  const value = dom.getMousementValue(ctx2, event);
911
897
  if (!value.hint)
912
898
  return;
913
- send({ type: "POINTER_MOVE_SCRUBBER", hint: value.hint, point: value.point });
899
+ send({
900
+ type: "POINTER_MOVE_SCRUBBER",
901
+ hint: value.hint,
902
+ point: value.point
903
+ });
914
904
  }
915
905
  function onMouseup() {
916
906
  send("POINTER_UP_SCRUBBER");
@@ -922,6 +912,8 @@ function machine(ctx = {}) {
922
912
  setupDocument: (ctx2, evt) => {
923
913
  if (evt.doc)
924
914
  ctx2.doc = ref(evt.doc);
915
+ if (evt.root)
916
+ ctx2.rootNode = ref(evt.root);
925
917
  ctx2.uid = evt.id;
926
918
  },
927
919
  focusInput(ctx2) {
@@ -940,7 +932,9 @@ function machine(ctx = {}) {
940
932
  ctx2.value = utils.clamp(ctx2);
941
933
  },
942
934
  roundValue(ctx2) {
943
- ctx2.value = utils.round(ctx2);
935
+ if (ctx2.value !== "") {
936
+ ctx2.value = utils.round(ctx2);
937
+ }
944
938
  },
945
939
  setValue(ctx2, evt) {
946
940
  var _a, _b;
@@ -967,14 +961,21 @@ function machine(ctx = {}) {
967
961
  },
968
962
  invokeOnChange(ctx2) {
969
963
  var _a;
970
- (_a = ctx2.onChange) == null ? void 0 : _a.call(ctx2, { value: ctx2.value, valueAsNumber: ctx2.valueAsNumber });
964
+ (_a = ctx2.onChange) == null ? void 0 : _a.call(ctx2, {
965
+ value: ctx2.value,
966
+ valueAsNumber: ctx2.valueAsNumber
967
+ });
971
968
  },
972
969
  invokeOnInvalid(ctx2) {
973
970
  var _a;
974
971
  if (!ctx2.isOutOfRange)
975
972
  return;
976
973
  const reason = ctx2.valueAsNumber > ctx2.max ? "rangeOverflow" : "rangeUnderflow";
977
- (_a = ctx2.onInvalid) == null ? void 0 : _a.call(ctx2, { reason, value: ctx2.formattedValue, valueAsNumber: ctx2.valueAsNumber });
974
+ (_a = ctx2.onInvalid) == null ? void 0 : _a.call(ctx2, {
975
+ reason,
976
+ value: ctx2.formattedValue,
977
+ valueAsNumber: ctx2.valueAsNumber
978
+ });
978
979
  },
979
980
  syncInputValue(ctx2) {
980
981
  const input = dom.getInputEl(ctx2);
@@ -993,7 +994,8 @@ function machine(ctx = {}) {
993
994
  const cursor = dom.getCursorEl(ctx2);
994
995
  if (!cursor || !ctx2.scrubberCursorPoint)
995
996
  return;
996
- cursor.style.transform = `translate3d(${ctx2.scrubberCursorPoint.x}px, ${ctx2.scrubberCursorPoint.y}px, 0px)`;
997
+ const { x, y } = ctx2.scrubberCursorPoint;
998
+ cursor.style.transform = `translate3d(${x}px, ${y}px, 0px)`;
997
999
  },
998
1000
  addCustomCursor(ctx2) {
999
1001
  if (isSafari() || !supportsPointerEvent())
@@ -1001,11 +1003,10 @@ function machine(ctx = {}) {
1001
1003
  dom.createVirtualCursor(ctx2);
1002
1004
  },
1003
1005
  removeCustomCursor(ctx2) {
1006
+ var _a;
1004
1007
  if (isSafari() || !supportsPointerEvent())
1005
1008
  return;
1006
- const doc = dom.getDoc(ctx2);
1007
- const el = doc.getElementById(dom.getCursorId(ctx2));
1008
- el == null ? void 0 : el.remove();
1009
+ (_a = dom.getCursorEl(ctx2)) == null ? void 0 : _a.remove();
1009
1010
  },
1010
1011
  disableTextSelection(ctx2) {
1011
1012
  const doc = dom.getDoc(ctx2);