@zag-js/number-input 1.34.0 → 1.35.0

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.
Files changed (37) hide show
  1. package/dist/cursor.d.mts +12 -0
  2. package/dist/cursor.d.ts +12 -0
  3. package/dist/cursor.js +111 -0
  4. package/dist/cursor.mjs +84 -0
  5. package/dist/index.d.mts +9 -314
  6. package/dist/index.d.ts +9 -314
  7. package/dist/index.js +37 -931
  8. package/dist/index.mjs +9 -926
  9. package/dist/number-input.anatomy.d.mts +6 -0
  10. package/dist/number-input.anatomy.d.ts +6 -0
  11. package/dist/number-input.anatomy.js +43 -0
  12. package/dist/number-input.anatomy.mjs +17 -0
  13. package/dist/number-input.connect.d.mts +8 -0
  14. package/dist/number-input.connect.d.ts +8 -0
  15. package/dist/number-input.connect.js +308 -0
  16. package/dist/number-input.connect.mjs +284 -0
  17. package/dist/number-input.dom.d.mts +34 -0
  18. package/dist/number-input.dom.d.ts +34 -0
  19. package/dist/number-input.dom.js +150 -0
  20. package/dist/number-input.dom.mjs +109 -0
  21. package/dist/number-input.machine.d.mts +8 -0
  22. package/dist/number-input.machine.d.ts +8 -0
  23. package/dist/number-input.machine.js +460 -0
  24. package/dist/number-input.machine.mjs +441 -0
  25. package/dist/number-input.props.d.mts +9 -0
  26. package/dist/number-input.props.d.ts +9 -0
  27. package/dist/number-input.props.js +65 -0
  28. package/dist/number-input.props.mjs +39 -0
  29. package/dist/number-input.types.d.mts +303 -0
  30. package/dist/number-input.types.d.ts +303 -0
  31. package/dist/number-input.types.js +18 -0
  32. package/dist/number-input.types.mjs +0 -0
  33. package/dist/number-input.utils.d.mts +13 -0
  34. package/dist/number-input.utils.d.ts +13 -0
  35. package/dist/number-input.utils.js +63 -0
  36. package/dist/number-input.utils.mjs +34 -0
  37. package/package.json +17 -7
@@ -0,0 +1,460 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/number-input.machine.ts
31
+ var number_input_machine_exports = {};
32
+ __export(number_input_machine_exports, {
33
+ machine: () => machine
34
+ });
35
+ module.exports = __toCommonJS(number_input_machine_exports);
36
+ var import_core = require("@zag-js/core");
37
+ var import_dom_query = require("@zag-js/dom-query");
38
+ var import_utils = require("@zag-js/utils");
39
+ var import_cursor = require("./cursor.cjs");
40
+ var dom = __toESM(require("./number-input.dom.cjs"));
41
+ var import_number_input = require("./number-input.utils.cjs");
42
+ var { choose, guards, createMachine } = (0, import_core.setup)();
43
+ var { not, and } = guards;
44
+ var machine = createMachine({
45
+ props({ props }) {
46
+ const step = (0, import_number_input.getDefaultStep)(props.step, props.formatOptions);
47
+ return {
48
+ dir: "ltr",
49
+ locale: "en-US",
50
+ focusInputOnChange: true,
51
+ clampValueOnBlur: !props.allowOverflow,
52
+ allowOverflow: false,
53
+ inputMode: "decimal",
54
+ pattern: "-?[0-9]*(.[0-9]+)?",
55
+ defaultValue: "",
56
+ step,
57
+ min: Number.MIN_SAFE_INTEGER,
58
+ max: Number.MAX_SAFE_INTEGER,
59
+ spinOnPress: true,
60
+ ...props,
61
+ translations: {
62
+ incrementLabel: "increment value",
63
+ decrementLabel: "decrease value",
64
+ ...props.translations
65
+ }
66
+ };
67
+ },
68
+ initialState() {
69
+ return "idle";
70
+ },
71
+ context({ prop, bindable, getComputed }) {
72
+ return {
73
+ value: bindable(() => ({
74
+ defaultValue: prop("defaultValue"),
75
+ value: prop("value"),
76
+ onChange(value) {
77
+ const computed = getComputed();
78
+ const valueAsNumber = (0, import_number_input.parseValue)(value, { computed, prop });
79
+ prop("onValueChange")?.({ value, valueAsNumber });
80
+ }
81
+ })),
82
+ hint: bindable(() => ({ defaultValue: null })),
83
+ scrubberCursorPoint: bindable(() => ({
84
+ defaultValue: null,
85
+ hash(value) {
86
+ return value ? `x:${value.x}, y:${value.y}` : "";
87
+ }
88
+ })),
89
+ fieldsetDisabled: bindable(() => ({ defaultValue: false }))
90
+ };
91
+ },
92
+ computed: {
93
+ isRtl: ({ prop }) => prop("dir") === "rtl",
94
+ valueAsNumber: ({ context, computed, prop }) => (0, import_number_input.parseValue)(context.get("value"), { computed, prop }),
95
+ formattedValue: ({ computed, prop }) => (0, import_number_input.formatValue)(computed("valueAsNumber"), { computed, prop }),
96
+ isAtMin: ({ computed, prop }) => (0, import_utils.isValueAtMin)(computed("valueAsNumber"), prop("min")),
97
+ isAtMax: ({ computed, prop }) => (0, import_utils.isValueAtMax)(computed("valueAsNumber"), prop("max")),
98
+ isOutOfRange: ({ computed, prop }) => !(0, import_utils.isValueWithinRange)(computed("valueAsNumber"), prop("min"), prop("max")),
99
+ isValueEmpty: ({ context }) => context.get("value") === "",
100
+ isDisabled: ({ prop, context }) => !!prop("disabled") || context.get("fieldsetDisabled"),
101
+ canIncrement: ({ prop, computed }) => prop("allowOverflow") || !computed("isAtMax"),
102
+ canDecrement: ({ prop, computed }) => prop("allowOverflow") || !computed("isAtMin"),
103
+ valueText: ({ prop, context }) => prop("translations").valueText?.(context.get("value")),
104
+ formatter: (0, import_core.memo)(
105
+ ({ prop }) => [prop("locale"), prop("formatOptions")],
106
+ ([locale, formatOptions]) => (0, import_number_input.createFormatter)(locale, formatOptions)
107
+ ),
108
+ parser: (0, import_core.memo)(
109
+ ({ prop }) => [prop("locale"), prop("formatOptions")],
110
+ ([locale, formatOptions]) => (0, import_number_input.createParser)(locale, formatOptions)
111
+ )
112
+ },
113
+ watch({ track, action, context, computed, prop }) {
114
+ track([() => context.get("value"), () => prop("locale"), () => JSON.stringify(prop("formatOptions"))], () => {
115
+ action(["syncInputElement"]);
116
+ });
117
+ track([() => computed("isOutOfRange")], () => {
118
+ action(["invokeOnInvalid"]);
119
+ });
120
+ track([() => context.hash("scrubberCursorPoint")], () => {
121
+ action(["setVirtualCursorPosition"]);
122
+ });
123
+ },
124
+ effects: ["trackFormControl"],
125
+ on: {
126
+ "VALUE.SET": {
127
+ actions: ["setRawValue"]
128
+ },
129
+ "VALUE.CLEAR": {
130
+ actions: ["clearValue"]
131
+ },
132
+ "VALUE.INCREMENT": {
133
+ actions: ["increment"]
134
+ },
135
+ "VALUE.DECREMENT": {
136
+ actions: ["decrement"]
137
+ }
138
+ },
139
+ states: {
140
+ idle: {
141
+ on: {
142
+ "TRIGGER.PRESS_DOWN": [
143
+ { guard: "isTouchPointer", target: "before:spin", actions: ["setHint"] },
144
+ {
145
+ target: "before:spin",
146
+ actions: ["focusInput", "invokeOnFocus", "setHint"]
147
+ }
148
+ ],
149
+ "SCRUBBER.PRESS_DOWN": {
150
+ target: "scrubbing",
151
+ actions: ["focusInput", "invokeOnFocus", "setHint", "setCursorPoint"]
152
+ },
153
+ "INPUT.FOCUS": {
154
+ target: "focused",
155
+ actions: ["focusInput", "invokeOnFocus"]
156
+ }
157
+ }
158
+ },
159
+ focused: {
160
+ tags: ["focus"],
161
+ effects: ["attachWheelListener"],
162
+ on: {
163
+ "TRIGGER.PRESS_DOWN": [
164
+ { guard: "isTouchPointer", target: "before:spin", actions: ["setHint"] },
165
+ { target: "before:spin", actions: ["focusInput", "setHint"] }
166
+ ],
167
+ "SCRUBBER.PRESS_DOWN": {
168
+ target: "scrubbing",
169
+ actions: ["focusInput", "setHint", "setCursorPoint"]
170
+ },
171
+ "INPUT.ARROW_UP": {
172
+ actions: ["increment"]
173
+ },
174
+ "INPUT.ARROW_DOWN": {
175
+ actions: ["decrement"]
176
+ },
177
+ "INPUT.HOME": {
178
+ actions: ["decrementToMin"]
179
+ },
180
+ "INPUT.END": {
181
+ actions: ["incrementToMax"]
182
+ },
183
+ "INPUT.CHANGE": {
184
+ actions: ["setValue", "setHint"]
185
+ },
186
+ "INPUT.BLUR": [
187
+ {
188
+ guard: and("clampValueOnBlur", not("isInRange")),
189
+ target: "idle",
190
+ actions: ["setClampedValue", "clearHint", "invokeOnBlur", "invokeOnValueCommit"]
191
+ },
192
+ {
193
+ guard: not("isInRange"),
194
+ target: "idle",
195
+ actions: ["setFormattedValue", "clearHint", "invokeOnBlur", "invokeOnInvalid", "invokeOnValueCommit"]
196
+ },
197
+ {
198
+ target: "idle",
199
+ actions: ["setFormattedValue", "clearHint", "invokeOnBlur", "invokeOnValueCommit"]
200
+ }
201
+ ],
202
+ "INPUT.ENTER": {
203
+ actions: ["setFormattedValue", "clearHint", "invokeOnBlur", "invokeOnValueCommit"]
204
+ }
205
+ }
206
+ },
207
+ "before:spin": {
208
+ tags: ["focus"],
209
+ effects: ["trackButtonDisabled", "waitForChangeDelay"],
210
+ entry: choose([
211
+ { guard: "isIncrementHint", actions: ["increment"] },
212
+ { guard: "isDecrementHint", actions: ["decrement"] }
213
+ ]),
214
+ on: {
215
+ CHANGE_DELAY: {
216
+ target: "spinning",
217
+ guard: and("isInRange", "spinOnPress")
218
+ },
219
+ "TRIGGER.PRESS_UP": [
220
+ { guard: "isTouchPointer", target: "focused", actions: ["clearHint"] },
221
+ { target: "focused", actions: ["focusInput", "clearHint"] }
222
+ ]
223
+ }
224
+ },
225
+ spinning: {
226
+ tags: ["focus"],
227
+ effects: ["trackButtonDisabled", "spinValue"],
228
+ on: {
229
+ SPIN: [
230
+ {
231
+ guard: "isIncrementHint",
232
+ actions: ["increment"]
233
+ },
234
+ {
235
+ guard: "isDecrementHint",
236
+ actions: ["decrement"]
237
+ }
238
+ ],
239
+ "TRIGGER.PRESS_UP": {
240
+ target: "focused",
241
+ actions: ["focusInput", "clearHint"]
242
+ }
243
+ }
244
+ },
245
+ scrubbing: {
246
+ tags: ["focus"],
247
+ effects: ["activatePointerLock", "trackMousemove", "setupVirtualCursor", "preventTextSelection"],
248
+ on: {
249
+ "SCRUBBER.POINTER_UP": {
250
+ target: "focused",
251
+ actions: ["focusInput", "clearCursorPoint"]
252
+ },
253
+ "SCRUBBER.POINTER_MOVE": [
254
+ {
255
+ guard: "isIncrementHint",
256
+ actions: ["increment", "setCursorPoint"]
257
+ },
258
+ {
259
+ guard: "isDecrementHint",
260
+ actions: ["decrement", "setCursorPoint"]
261
+ }
262
+ ]
263
+ }
264
+ }
265
+ },
266
+ implementations: {
267
+ guards: {
268
+ clampValueOnBlur: ({ prop }) => prop("clampValueOnBlur"),
269
+ spinOnPress: ({ prop }) => !!prop("spinOnPress"),
270
+ isInRange: ({ computed }) => !computed("isOutOfRange"),
271
+ isDecrementHint: ({ context, event }) => (event.hint ?? context.get("hint")) === "decrement",
272
+ isIncrementHint: ({ context, event }) => (event.hint ?? context.get("hint")) === "increment",
273
+ isTouchPointer: ({ event }) => event.pointerType === "touch"
274
+ },
275
+ effects: {
276
+ waitForChangeDelay({ send }) {
277
+ const id = setTimeout(() => {
278
+ send({ type: "CHANGE_DELAY" });
279
+ }, 300);
280
+ return () => clearTimeout(id);
281
+ },
282
+ spinValue({ send }) {
283
+ const id = setInterval(() => {
284
+ send({ type: "SPIN" });
285
+ }, 50);
286
+ return () => clearInterval(id);
287
+ },
288
+ trackFormControl({ context, scope }) {
289
+ const inputEl = dom.getInputEl(scope);
290
+ return (0, import_dom_query.trackFormControl)(inputEl, {
291
+ onFieldsetDisabledChange(disabled) {
292
+ context.set("fieldsetDisabled", disabled);
293
+ },
294
+ onFormReset() {
295
+ context.set("value", context.initial("value"));
296
+ }
297
+ });
298
+ },
299
+ setupVirtualCursor({ context, scope }) {
300
+ const point = context.get("scrubberCursorPoint");
301
+ return dom.setupVirtualCursor(scope, point);
302
+ },
303
+ preventTextSelection({ scope }) {
304
+ return dom.preventTextSelection(scope);
305
+ },
306
+ trackButtonDisabled({ context, scope, send }) {
307
+ const hint = context.get("hint");
308
+ const btn = dom.getPressedTriggerEl(scope, hint);
309
+ return (0, import_dom_query.observeAttributes)(btn, {
310
+ attributes: ["disabled"],
311
+ callback() {
312
+ send({ type: "TRIGGER.PRESS_UP", src: "attr" });
313
+ }
314
+ });
315
+ },
316
+ attachWheelListener({ scope, send, prop }) {
317
+ const inputEl = dom.getInputEl(scope);
318
+ if (!inputEl || !scope.isActiveElement(inputEl) || !prop("allowMouseWheel")) return;
319
+ function onWheel(event) {
320
+ event.preventDefault();
321
+ const dir = Math.sign(event.deltaY) * -1;
322
+ if (dir === 1) {
323
+ send({ type: "VALUE.INCREMENT" });
324
+ } else if (dir === -1) {
325
+ send({ type: "VALUE.DECREMENT" });
326
+ }
327
+ }
328
+ return (0, import_dom_query.addDomEvent)(inputEl, "wheel", onWheel, { passive: false });
329
+ },
330
+ activatePointerLock({ scope }) {
331
+ if ((0, import_dom_query.isSafari)()) return;
332
+ return (0, import_dom_query.requestPointerLock)(scope.getDoc());
333
+ },
334
+ trackMousemove({ scope, send, context, computed }) {
335
+ const doc = scope.getDoc();
336
+ function onMousemove(event) {
337
+ const point = context.get("scrubberCursorPoint");
338
+ const isRtl = computed("isRtl");
339
+ const value = dom.getMousemoveValue(scope, { point, isRtl, event });
340
+ if (!value.hint) return;
341
+ send({
342
+ type: "SCRUBBER.POINTER_MOVE",
343
+ hint: value.hint,
344
+ point: value.point
345
+ });
346
+ }
347
+ function onMouseup() {
348
+ send({ type: "SCRUBBER.POINTER_UP" });
349
+ }
350
+ return (0, import_utils.callAll)((0, import_dom_query.addDomEvent)(doc, "mousemove", onMousemove, false), (0, import_dom_query.addDomEvent)(doc, "mouseup", onMouseup, false));
351
+ }
352
+ },
353
+ actions: {
354
+ focusInput({ scope, prop }) {
355
+ if (!prop("focusInputOnChange")) return;
356
+ const inputEl = dom.getInputEl(scope);
357
+ if (scope.isActiveElement(inputEl)) return;
358
+ (0, import_dom_query.raf)(() => inputEl?.focus({ preventScroll: true }));
359
+ },
360
+ increment({ context, event, prop, computed }) {
361
+ let nextValue = (0, import_utils.incrementValue)(computed("valueAsNumber"), event.step ?? prop("step"));
362
+ if (!prop("allowOverflow")) nextValue = (0, import_utils.clampValue)(nextValue, prop("min"), prop("max"));
363
+ context.set("value", (0, import_number_input.formatValue)(nextValue, { computed, prop }));
364
+ },
365
+ decrement({ context, event, prop, computed }) {
366
+ let nextValue = (0, import_utils.decrementValue)(computed("valueAsNumber"), event.step ?? prop("step"));
367
+ if (!prop("allowOverflow")) nextValue = (0, import_utils.clampValue)(nextValue, prop("min"), prop("max"));
368
+ context.set("value", (0, import_number_input.formatValue)(nextValue, { computed, prop }));
369
+ },
370
+ setClampedValue({ context, prop, computed }) {
371
+ const nextValue = (0, import_utils.clampValue)(computed("valueAsNumber"), prop("min"), prop("max"));
372
+ context.set("value", (0, import_number_input.formatValue)(nextValue, { computed, prop }));
373
+ },
374
+ setRawValue({ context, event, prop, computed }) {
375
+ let nextValue = (0, import_number_input.parseValue)(event.value, { computed, prop });
376
+ if (!prop("allowOverflow")) nextValue = (0, import_utils.clampValue)(nextValue, prop("min"), prop("max"));
377
+ context.set("value", (0, import_number_input.formatValue)(nextValue, { computed, prop }));
378
+ },
379
+ setValue({ context, event }) {
380
+ const value = event.target?.value ?? event.value;
381
+ context.set("value", value);
382
+ },
383
+ clearValue({ context }) {
384
+ context.set("value", "");
385
+ },
386
+ incrementToMax({ context, prop, computed }) {
387
+ const value = (0, import_number_input.formatValue)(prop("max"), { computed, prop });
388
+ context.set("value", value);
389
+ },
390
+ decrementToMin({ context, prop, computed }) {
391
+ const value = (0, import_number_input.formatValue)(prop("min"), { computed, prop });
392
+ context.set("value", value);
393
+ },
394
+ setHint({ context, event }) {
395
+ context.set("hint", event.hint);
396
+ },
397
+ clearHint({ context }) {
398
+ context.set("hint", null);
399
+ },
400
+ invokeOnFocus({ computed, prop }) {
401
+ prop("onFocusChange")?.({
402
+ focused: true,
403
+ value: computed("formattedValue"),
404
+ valueAsNumber: computed("valueAsNumber")
405
+ });
406
+ },
407
+ invokeOnBlur({ computed, prop }) {
408
+ prop("onFocusChange")?.({
409
+ focused: false,
410
+ value: computed("formattedValue"),
411
+ valueAsNumber: computed("valueAsNumber")
412
+ });
413
+ },
414
+ invokeOnInvalid({ computed, prop, event }) {
415
+ if (event.type === "INPUT.CHANGE") return;
416
+ const reason = computed("valueAsNumber") > prop("max") ? "rangeOverflow" : "rangeUnderflow";
417
+ prop("onValueInvalid")?.({
418
+ reason,
419
+ value: computed("formattedValue"),
420
+ valueAsNumber: computed("valueAsNumber")
421
+ });
422
+ },
423
+ invokeOnValueCommit({ computed, prop }) {
424
+ prop("onValueCommit")?.({
425
+ value: computed("formattedValue"),
426
+ valueAsNumber: computed("valueAsNumber")
427
+ });
428
+ },
429
+ syncInputElement({ context, event, computed, scope }) {
430
+ const value = event.type.endsWith("CHANGE") ? context.get("value") : computed("formattedValue");
431
+ const inputEl = dom.getInputEl(scope);
432
+ const sel = event.selection ?? (0, import_cursor.recordCursor)(inputEl, scope);
433
+ (0, import_dom_query.raf)(() => {
434
+ (0, import_dom_query.setElementValue)(inputEl, value);
435
+ (0, import_cursor.restoreCursor)(inputEl, sel, scope);
436
+ });
437
+ },
438
+ setFormattedValue({ context, computed, action }) {
439
+ context.set("value", computed("formattedValue"));
440
+ action(["syncInputElement"]);
441
+ },
442
+ setCursorPoint({ context, event }) {
443
+ context.set("scrubberCursorPoint", event.point);
444
+ },
445
+ clearCursorPoint({ context }) {
446
+ context.set("scrubberCursorPoint", null);
447
+ },
448
+ setVirtualCursorPosition({ context, scope }) {
449
+ const cursorEl = dom.getCursorEl(scope);
450
+ const point = context.get("scrubberCursorPoint");
451
+ if (!cursorEl || !point) return;
452
+ cursorEl.style.transform = `translate3d(${point.x}px, ${point.y}px, 0px)`;
453
+ }
454
+ }
455
+ }
456
+ });
457
+ // Annotate the CommonJS export names for ESM import in node:
458
+ 0 && (module.exports = {
459
+ machine
460
+ });