@zag-js/number-input 0.1.8 → 0.1.11

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
@@ -25,92 +25,43 @@ var dataAttr = (guard) => {
25
25
  var ariaAttr = (guard) => {
26
26
  return guard ? "true" : void 0;
27
27
  };
28
- function raf(fn) {
29
- const id = globalThis.requestAnimationFrame(fn);
30
- return function cleanup() {
31
- globalThis.cancelAnimationFrame(id);
32
- };
33
- }
34
- var noop = () => {
28
+ var MAX_Z_INDEX = 2147483647;
29
+ var runIfFn = (v, ...a) => {
30
+ const res = typeof v === "function" ? v(...a) : v;
31
+ return res != null ? res : void 0;
35
32
  };
36
- var pipe = (...fns) => (v) => fns.reduce((a, b) => b(a), v);
37
- function getListenerElements() {
38
- ;
39
- globalThis.__listenerElements__ = globalThis.__listenerElements__ || /* @__PURE__ */ new Map();
40
- return globalThis.__listenerElements__;
41
- }
42
- function getListenerCache() {
43
- ;
44
- globalThis.__listenerCache__ = globalThis.__listenerCache__ || /* @__PURE__ */ new Map();
45
- return globalThis.__listenerCache__;
46
- }
47
- function globalEventBus(node, type, handler, options) {
33
+ var callAll = (...fns) => (...a) => {
34
+ fns.forEach(function(fn) {
35
+ fn == null ? void 0 : fn(...a);
36
+ });
37
+ };
38
+ var isArray = (v) => Array.isArray(v);
39
+ var isObject = (v) => !(v == null || typeof v !== "object" || isArray(v));
40
+ var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
41
+ var isDom = () => typeof window !== "undefined";
42
+ function getPlatform() {
48
43
  var _a;
49
- if (!node)
50
- return noop;
51
- const hash = JSON.stringify({ type, options });
52
- const listenerElements = getListenerElements();
53
- const listenerCache = getListenerCache();
54
- const group = listenerElements.get(node);
55
- if (!listenerElements.has(node)) {
56
- const group2 = /* @__PURE__ */ new Map([[hash, /* @__PURE__ */ new Set([handler])]]);
57
- listenerElements.set(node, group2);
58
- } else if (group == null ? void 0 : group.has(hash)) {
59
- (_a = group == null ? void 0 : group.get(hash)) == null ? void 0 : _a.add(handler);
60
- } else {
61
- group == null ? void 0 : group.set(hash, /* @__PURE__ */ new Set([handler]));
62
- }
63
- function attach(node2) {
64
- var _a2, _b;
65
- function listener(event) {
66
- var _a3;
67
- const group2 = listenerElements.get(node2);
68
- (_a3 = group2 == null ? void 0 : group2.get(hash)) == null ? void 0 : _a3.forEach((fn) => fn(event));
69
- }
70
- if (!(listenerCache == null ? void 0 : listenerCache.has(node2))) {
71
- listenerCache.set(node2, /* @__PURE__ */ new Map([[hash, listener]]));
72
- node2.addEventListener(type, listener, options);
73
- return;
74
- }
75
- if (!((_a2 = listenerCache == null ? void 0 : listenerCache.get(node2)) == null ? void 0 : _a2.has(hash))) {
76
- (_b = listenerCache.get(node2)) == null ? void 0 : _b.set(hash, listener);
77
- node2.addEventListener(type, listener, options);
78
- }
79
- }
80
- attach(node);
81
- return function remove() {
82
- var _a2, _b, _c, _d;
83
- if (!listenerElements.has(node))
84
- return;
85
- const group2 = listenerElements.get(node);
86
- (_a2 = group2 == null ? void 0 : group2.get(hash)) == null ? void 0 : _a2.delete(handler);
87
- if (((_b = group2 == null ? void 0 : group2.get(hash)) == null ? void 0 : _b.size) === 0) {
88
- const listener = (_c = listenerCache.get(node)) == null ? void 0 : _c.get(hash);
89
- node.removeEventListener(type, listener, options);
90
- group2 == null ? void 0 : group2.delete(hash);
91
- (_d = listenerCache.get(node)) == null ? void 0 : _d.delete(hash);
92
- if ((group2 == null ? void 0 : group2.size) === 0) {
93
- listenerElements.delete(node);
94
- listenerCache.delete(node);
95
- }
96
- }
97
- };
98
- }
99
- var t = (v) => Object.prototype.toString.call(v).slice(8, -1);
100
- var isRef = (v) => t(v) === "Object" && "current" in v;
101
- var runIfFn = (fn) => t(fn) === "Function" ? fn() : fn;
102
- function addDomEvent(target, event, listener, options) {
103
- const node = isRef(target) ? target.current : runIfFn(target);
104
- return globalEventBus(node, event, listener, options);
44
+ const agent = navigator.userAgentData;
45
+ return (_a = agent == null ? void 0 : agent.platform) != null ? _a : navigator.platform;
105
46
  }
106
- var MAX_Z_INDEX = 2147483647;
107
- function getNativeEvent(event) {
47
+ var pt = (v) => isDom() && v.test(getPlatform());
48
+ var vn = (v) => isDom() && v.test(navigator.vendor);
49
+ var isTouchDevice = () => isDom() && !!navigator.maxTouchPoints;
50
+ var isMac = () => pt(/^Mac/) && !isTouchDevice;
51
+ var isSafari = () => isApple() && vn(/apple/i);
52
+ var isApple = () => pt(/mac|iphone|ipad|ipod/i);
53
+ var isIos = () => isApple() && !isMac();
54
+ function getNativeEvent(e) {
108
55
  var _a;
109
- return (_a = event.nativeEvent) != null ? _a : event;
56
+ return (_a = e.nativeEvent) != null ? _a : e;
110
57
  }
58
+ var supportsPointerEvent = () => isDom() && window.onpointerdown === null;
59
+ var isTouchEvent = (v) => isObject(v) && hasProp(v, "touches");
60
+ var isLeftClick = (v) => v.button === 0;
61
+ var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
111
62
  function observeAttributes(node, attributes, fn) {
112
63
  if (!node)
113
- return noop;
64
+ return;
114
65
  const attrs = Array.isArray(attributes) ? attributes : [attributes];
115
66
  const win = node.ownerDocument.defaultView || window;
116
67
  const obs = new win.MutationObserver((changes) => {
@@ -123,6 +74,17 @@ function observeAttributes(node, attributes, fn) {
123
74
  obs.observe(node, { attributes: true, attributeFilter: attrs });
124
75
  return () => obs.disconnect();
125
76
  }
77
+ var fallback = {
78
+ pageX: 0,
79
+ pageY: 0,
80
+ clientX: 0,
81
+ clientY: 0
82
+ };
83
+ function getEventPoint(event, type = "page") {
84
+ var _a, _b;
85
+ const point = isTouchEvent(event) ? (_b = (_a = event.touches[0]) != null ? _a : event.changedTouches[0]) != null ? _b : fallback : event;
86
+ return { x: point[`${type}X`], y: point[`${type}Y`] };
87
+ }
126
88
  var PAGE_KEYS = /* @__PURE__ */ new Set(["PageUp", "PageDown"]);
127
89
  var ARROW_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"]);
128
90
  function getEventStep(event) {
@@ -134,29 +96,19 @@ function getEventStep(event) {
134
96
  return isSkipKey ? 10 : 1;
135
97
  }
136
98
  }
137
- function itemById(v, id) {
138
- return v.find((node) => node.id === id);
139
- }
140
- function indexOfId(v, id) {
141
- const item = itemById(v, id);
142
- return item ? v.indexOf(item) : -1;
99
+ var isRef = (v) => hasProp(v, "current");
100
+ function addDomEvent(target, eventName, handler, options) {
101
+ const node = isRef(target) ? target.current : runIfFn(target);
102
+ node == null ? void 0 : node.addEventListener(eventName, handler, options);
103
+ return () => {
104
+ node == null ? void 0 : node.removeEventListener(eventName, handler, options);
105
+ };
143
106
  }
144
- var getValueText = (item) => {
145
- var _a, _b;
146
- return (_b = (_a = item.dataset.valuetext) != null ? _a : item.textContent) != null ? _b : "";
147
- };
148
- var match = (valueText, query2) => valueText.toLowerCase().startsWith(query2.toLowerCase());
149
- var wrap = (v, idx) => {
150
- return v.map((_, index) => v[(Math.max(idx, 0) + index) % v.length]);
151
- };
152
- function findByText(v, text, currentId) {
153
- const index = currentId ? indexOfId(v, currentId) : -1;
154
- let items = currentId ? wrap(v, index) : v;
155
- const isSingleKey = text.length === 1;
156
- if (isSingleKey) {
157
- items = items.filter((item) => item.id !== currentId);
158
- }
159
- return items.find((item) => match(getValueText(item), text));
107
+ function raf(fn) {
108
+ const id = globalThis.requestAnimationFrame(fn);
109
+ return function cleanup() {
110
+ globalThis.cancelAnimationFrame(id);
111
+ };
160
112
  }
161
113
  function addPointerlockChangeListener(doc, fn) {
162
114
  return addDomEvent(doc, "pointerlockchange", fn, false);
@@ -190,7 +142,7 @@ function requestPointerLock(doc, handlers = {}) {
190
142
  if (!supported)
191
143
  return;
192
144
  body.requestPointerLock();
193
- const cleanup = pipe(addPointerlockChangeListener(doc, onPointerChange), addPointerlockErrorListener(doc, onPointerError));
145
+ const cleanup = callAll(addPointerlockChangeListener(doc, onPointerChange), addPointerlockErrorListener(doc, onPointerError));
194
146
  return function dispose() {
195
147
  if (!supported)
196
148
  return;
@@ -198,38 +150,10 @@ function requestPointerLock(doc, handlers = {}) {
198
150
  exit();
199
151
  };
200
152
  }
201
- function findByTypeahead(_items, options) {
202
- const { state: state2, activeId, key, timeout = 350 } = options;
203
- const search = state2.keysSoFar + key;
204
- const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
205
- const query2 = isRepeated ? search[0] : search;
206
- let items = _items.slice();
207
- const next = findByText(items, query2, activeId);
208
- function cleanup() {
209
- clearTimeout(state2.timer);
210
- state2.timer = -1;
211
- }
212
- function update(value) {
213
- state2.keysSoFar = value;
214
- cleanup();
215
- if (value !== "") {
216
- state2.timer = +setTimeout(() => {
217
- update("");
218
- cleanup();
219
- }, timeout);
220
- }
221
- }
222
- update(search);
223
- return next;
224
- }
225
- findByTypeahead.defaultOptions = {
226
- keysSoFar: "",
227
- timer: -1
228
- };
229
153
 
230
154
  // ../../utilities/number/dist/index.mjs
231
155
  var __pow = Math.pow;
232
- function wrap2(num, max) {
156
+ function wrap(num, max) {
233
157
  return (num % max + max) % max;
234
158
  }
235
159
  function roundToDevicePixel(num) {
@@ -292,40 +216,6 @@ function decimalOperation(a, op, b) {
292
216
  }
293
217
  var nf = new Intl.NumberFormat("en-US", { style: "decimal", maximumFractionDigits: 20 });
294
218
 
295
- // ../../utilities/rect/dist/index.mjs
296
- var isArray = (v) => Array.isArray(v);
297
- var isObject = (v) => !(v == null || typeof v !== "object" || isArray(v));
298
- var isTouchEvent = (v) => isObject(v) && "touches" in v;
299
- var fallback = { pageX: 0, pageY: 0, clientX: 0, clientY: 0 };
300
- function getEventPoint(e, t2 = "page") {
301
- const p = isTouchEvent(e) ? e.touches[0] || e.changedTouches[0] || fallback : e;
302
- return { x: p[`${t2}X`], y: p[`${t2}Y`] };
303
- }
304
-
305
- // ../../types/dist/index.mjs
306
- function createNormalizer(fn) {
307
- return new Proxy({}, {
308
- get() {
309
- return fn;
310
- }
311
- });
312
- }
313
- var normalizeProp = createNormalizer((v) => v);
314
-
315
- // ../../utilities/core/dist/index.mjs
316
- var pipe2 = (...fns) => (v) => fns.reduce((a, b) => b(a), v);
317
- var platform = (v) => isDom() && v.test(navigator.platform);
318
- var ua = (v) => isDom() && v.test(navigator.userAgent);
319
- var isDom = () => !!(typeof window !== "undefined");
320
- var isMac = () => platform(/^Mac/);
321
- var isIPhone = () => platform(/^iPhone/);
322
- var isIPad = () => platform(/^iPad/) || isMac() && navigator.maxTouchPoints > 1;
323
- var isIos = () => isIPhone() || isIPad();
324
- var isSafari = () => ua(/^((?!chrome|android).)*safari/i);
325
- var supportsPointerEvent = () => isDom() && window.onpointerdown === null;
326
- var isLeftClick = (v) => v.button === 0;
327
- var isModifiedEvent = (v) => v.ctrlKey || v.altKey || v.metaKey;
328
-
329
219
  // src/number-input.dom.ts
330
220
  var dom = {
331
221
  getDoc: (ctx) => {
@@ -385,7 +275,7 @@ var dom = {
385
275
  const win = dom.getWin(ctx);
386
276
  const width = win.innerWidth;
387
277
  const half = roundToDevicePixel(7.5);
388
- point.x = wrap2(point.x + half, width) - half;
278
+ point.x = wrap(point.x + half, width) - half;
389
279
  return { hint, point };
390
280
  },
391
281
  createVirtualCursor(ctx) {
@@ -458,16 +348,18 @@ var utils = {
458
348
  };
459
349
 
460
350
  // src/number-input.connect.ts
461
- function connect(state, send, normalize = normalizeProp) {
351
+ function connect(state, send, normalize) {
462
352
  const isFocused = state.hasTag("focus");
463
353
  const isInvalid = state.context.isOutOfRange || !!state.context.invalid;
464
354
  const isDisabled = !!state.context.disabled;
355
+ const isValueEmpty = state.context.isValueEmpty;
465
356
  const isIncrementDisabled = isDisabled || !state.context.canIncrement;
466
357
  const isDecrementDisabled = isDisabled || !state.context.canDecrement;
467
358
  const messages = state.context.messages;
468
359
  return {
469
360
  isFocused,
470
361
  isInvalid,
362
+ isValueEmpty,
471
363
  value: state.context.formattedValue,
472
364
  valueAsNumber: state.context.valueAsNumber,
473
365
  setValue(value) {
@@ -647,6 +539,15 @@ function connect(state, send, normalize = normalizeProp) {
647
539
 
648
540
  // src/number-input.machine.ts
649
541
  import { choose, createMachine, guards, ref } from "@zag-js/core";
542
+
543
+ // ../../utilities/core/dist/index.mjs
544
+ var callAll2 = (...fns) => (...a) => {
545
+ fns.forEach(function(fn) {
546
+ fn == null ? void 0 : fn(...a);
547
+ });
548
+ };
549
+
550
+ // src/number-input.machine.ts
650
551
  var { not, and } = guards;
651
552
  function machine(ctx = {}) {
652
553
  return createMachine({
@@ -679,6 +580,7 @@ function machine(ctx = {}) {
679
580
  isAtMin: (ctx2) => isAtMin(ctx2.value, ctx2),
680
581
  isAtMax: (ctx2) => isAtMax(ctx2.value, ctx2),
681
582
  isOutOfRange: (ctx2) => !isWithinRange(ctx2.value, ctx2),
583
+ isValueEmpty: (ctx2) => ctx2.value === "",
682
584
  canIncrement: (ctx2) => ctx2.allowOverflow || !ctx2.isAtMax,
683
585
  canDecrement: (ctx2) => ctx2.allowOverflow || !ctx2.isAtMin,
684
586
  valueText: (ctx2) => {
@@ -765,7 +667,7 @@ function machine(ctx = {}) {
765
667
  actions: ["clearValue", "clearHint"]
766
668
  },
767
669
  {
768
- guard: and("clampOnBlur", not("isInRange")),
670
+ guard: and("clampOnBlur", not("isInRange"), not("isEmptyValue")),
769
671
  target: "idle",
770
672
  actions: ["clampValue", "clearHint"]
771
673
  },
@@ -855,6 +757,7 @@ function machine(ctx = {}) {
855
757
  var _a;
856
758
  return ((_a = evt.hint) != null ? _a : ctx2.hint) === "decrement";
857
759
  },
760
+ isEmptyValue: (ctx2) => ctx2.isValueEmpty,
858
761
  isIncrementHint: (ctx2, evt) => {
859
762
  var _a;
860
763
  return ((_a = evt.hint) != null ? _a : ctx2.hint) === "increment";
@@ -914,7 +817,7 @@ function machine(ctx = {}) {
914
817
  function onMouseup() {
915
818
  send("POINTER_UP_SCRUBBER");
916
819
  }
917
- return pipe2(addDomEvent(doc, "mousemove", onMousemove, false), addDomEvent(doc, "mouseup", onMouseup, false));
820
+ return callAll2(addDomEvent(doc, "mousemove", onMousemove, false), addDomEvent(doc, "mouseup", onMouseup, false));
918
821
  }
919
822
  },
920
823
  actions: {
@@ -948,7 +851,7 @@ function machine(ctx = {}) {
948
851
  setValue(ctx2, evt) {
949
852
  var _a, _b;
950
853
  const value = (_b = (_a = evt.target) == null ? void 0 : _a.value) != null ? _b : evt.value;
951
- ctx2.value = utils.sanitize(ctx2, utils.parse(ctx2, value));
854
+ ctx2.value = utils.sanitize(ctx2, utils.parse(ctx2, value.toString()));
952
855
  },
953
856
  clearValue(ctx2) {
954
857
  ctx2.value = "";
@@ -1037,4 +940,3 @@ export {
1037
940
  connect,
1038
941
  machine
1039
942
  };
1040
- //# sourceMappingURL=index.mjs.map
@@ -1,8 +1,9 @@
1
- import { PropTypes, ReactPropTypes } from "@zag-js/types";
2
- import { Send, State } from "./number-input.types";
3
- export declare function connect<T extends PropTypes = ReactPropTypes>(state: State, send: Send, normalize?: import("@zag-js/types").NormalizeProps): {
1
+ import type { NormalizeProps, PropTypes } from "@zag-js/types";
2
+ import type { Send, State } from "./number-input.types";
3
+ export declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): {
4
4
  isFocused: boolean;
5
5
  isInvalid: boolean;
6
+ isValueEmpty: boolean;
6
7
  value: string;
7
8
  valueAsNumber: number;
8
9
  setValue(value: string | number): void;
@@ -20,4 +21,3 @@ export declare function connect<T extends PropTypes = ReactPropTypes>(state: Sta
20
21
  incrementButtonProps: T["button"];
21
22
  scrubberProps: T["element"];
22
23
  };
23
- //# sourceMappingURL=number-input.connect.d.ts.map
@@ -1,4 +1,4 @@
1
- import { MachineContext as Ctx } from "./number-input.types";
1
+ import type { MachineContext as Ctx } from "./number-input.types";
2
2
  export declare const dom: {
3
3
  getDoc: (ctx: Ctx) => Document;
4
4
  getWin: (ctx: Ctx) => Window & typeof globalThis;
@@ -24,4 +24,3 @@ export declare const dom: {
24
24
  };
25
25
  createVirtualCursor(ctx: Ctx): void;
26
26
  };
27
- //# sourceMappingURL=number-input.dom.d.ts.map
@@ -1,3 +1,2 @@
1
1
  import type { MachineContext, MachineState, UserDefinedContext } from "./number-input.types";
2
2
  export declare function machine(ctx?: UserDefinedContext): import("@zag-js/core").Machine<MachineContext, MachineState, import("@zag-js/core").StateMachine.AnyEventObject>;
3
- //# sourceMappingURL=number-input.machine.d.ts.map
@@ -1,6 +1,5 @@
1
1
  import type { StateMachine as S } from "@zag-js/core";
2
- import { FormatDecimalOptions } from "@zag-js/number-utils";
3
- import type { Point } from "@zag-js/rect-utils";
2
+ import type { FormatDecimalOptions } from "@zag-js/number-utils";
4
3
  import type { Context, DirectionProperty } from "@zag-js/types";
5
4
  declare type ValidityState = "rangeUnderflow" | "rangeOverflow";
6
5
  declare type ElementIds = Partial<{
@@ -150,6 +149,11 @@ declare type ComputedContext = Readonly<{
150
149
  * Whether the value is out of the min/max range
151
150
  */
152
151
  isOutOfRange: boolean;
152
+ /**
153
+ * @computed
154
+ * Whether the value is empty
155
+ */
156
+ isValueEmpty: boolean;
153
157
  /**
154
158
  * @computed
155
159
  * Whether the increment button is enabled
@@ -186,7 +190,10 @@ declare type PrivateContext = Context<{
186
190
  * @internal
187
191
  * The scrubber cursor position
188
192
  */
189
- scrubberCursorPoint: Point | null;
193
+ scrubberCursorPoint: {
194
+ x: number;
195
+ y: number;
196
+ } | null;
190
197
  }>;
191
198
  export declare type MachineContext = PublicContext & PrivateContext & ComputedContext;
192
199
  export declare type MachineState = {
@@ -196,4 +203,3 @@ export declare type MachineState = {
196
203
  export declare type State = S.State<MachineContext, MachineState>;
197
204
  export declare type Send = S.Send<S.AnyEventObject>;
198
205
  export {};
199
- //# sourceMappingURL=number-input.types.d.ts.map
@@ -1,7 +1,6 @@
1
- import type { KeyboardEvent } from "react";
2
1
  import type { MachineContext as Ctx } from "./number-input.types";
3
2
  export declare const utils: {
4
- isValidNumericEvent: (ctx: Ctx, event: KeyboardEvent) => boolean;
3
+ isValidNumericEvent: (ctx: Ctx, event: JSX.KeyboardEvent) => boolean;
5
4
  isFloatingPoint: (v: string) => boolean;
6
5
  sanitize: (ctx: Ctx, value: string) => string;
7
6
  increment: (ctx: Ctx, step?: number) => string;
@@ -11,4 +10,3 @@ export declare const utils: {
11
10
  format: (ctx: Ctx, value: string | number) => string | number;
12
11
  round: (ctx: Ctx) => string;
13
12
  };
14
- //# sourceMappingURL=number-input.utils.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zag-js/number-input",
3
- "version": "0.1.8",
3
+ "version": "0.1.11",
4
4
  "description": "Core logic for the number-input widget implemented as a state machine",
5
5
  "keywords": [
6
6
  "js",
@@ -29,12 +29,11 @@
29
29
  "url": "https://github.com/chakra-ui/zag/issues"
30
30
  },
31
31
  "dependencies": {
32
- "@zag-js/core": "0.1.5",
33
- "@zag-js/dom-utils": "0.1.3",
32
+ "@zag-js/core": "0.1.7",
33
+ "@zag-js/dom-utils": "0.1.6",
34
34
  "@zag-js/number-utils": "0.1.2",
35
- "@zag-js/rect-utils": "0.1.1",
36
- "@zag-js/types": "0.1.2",
37
- "@zag-js/utils": "0.1.1"
35
+ "@zag-js/types": "0.2.1",
36
+ "@zag-js/utils": "0.1.2"
38
37
  },
39
38
  "scripts": {
40
39
  "build:fast": "zag build",
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAChD,YAAY,EAAE,kBAAkB,IAAI,OAAO,EAAE,MAAM,sBAAsB,CAAA"}