@zag-js/number-input 0.10.4 → 0.11.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.
package/dist/index.js CHANGED
@@ -1,13 +1,800 @@
1
- 'use strict';
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
2
19
 
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ anatomy: () => anatomy,
24
+ connect: () => connect,
25
+ machine: () => machine
26
+ });
27
+ module.exports = __toCommonJS(src_exports);
4
28
 
5
- const numberInput_anatomy = require('./number-input.anatomy.js');
6
- const numberInput_connect = require('./number-input.connect.js');
7
- const numberInput_machine = require('./number-input.machine.js');
29
+ // src/number-input.anatomy.ts
30
+ var import_anatomy = require("@zag-js/anatomy");
31
+ var anatomy = (0, import_anatomy.createAnatomy)("numberInput").parts(
32
+ "root",
33
+ "label",
34
+ "input",
35
+ "control",
36
+ "incrementTrigger",
37
+ "decrementTrigger",
38
+ "scrubber"
39
+ );
40
+ var parts = anatomy.build();
8
41
 
42
+ // src/number-input.connect.ts
43
+ var import_dom_event2 = require("@zag-js/dom-event");
44
+ var import_dom_query2 = require("@zag-js/dom-query");
45
+ var import_number_utils3 = require("@zag-js/number-utils");
9
46
 
47
+ // src/number-input.dom.ts
48
+ var import_dom_query = require("@zag-js/dom-query");
49
+ var import_number_utils = require("@zag-js/number-utils");
50
+ var dom = (0, import_dom_query.createScope)({
51
+ getRootId: (ctx) => ctx.ids?.root ?? `number-input:${ctx.id}`,
52
+ getInputId: (ctx) => ctx.ids?.input ?? `number-input:${ctx.id}:input`,
53
+ getIncrementTriggerId: (ctx) => ctx.ids?.incrementTrigger ?? `number-input:${ctx.id}:inc`,
54
+ getDecrementTriggerId: (ctx) => ctx.ids?.decrementTrigger ?? `number-input:${ctx.id}:dec`,
55
+ getScrubberId: (ctx) => ctx.ids?.scrubber ?? `number-input:${ctx.id}:scrubber`,
56
+ getCursorId: (ctx) => `number-input:${ctx.id}:cursor`,
57
+ getLabelId: (ctx) => ctx.ids?.label ?? `number-input:${ctx.id}:label`,
58
+ getInputEl: (ctx) => dom.getById(ctx, dom.getInputId(ctx)),
59
+ getIncrementTriggerEl: (ctx) => dom.getById(ctx, dom.getIncrementTriggerId(ctx)),
60
+ getDecrementTriggerEl: (ctx) => dom.getById(ctx, dom.getDecrementTriggerId(ctx)),
61
+ getScrubberEl: (ctx) => dom.getById(ctx, dom.getScrubberId(ctx)),
62
+ getCursorEl: (ctx) => dom.getDoc(ctx).getElementById(dom.getCursorId(ctx)),
63
+ getPressedTriggerEl: (ctx, hint = ctx.hint) => {
64
+ let btnEl = null;
65
+ if (hint === "increment") {
66
+ btnEl = dom.getIncrementTriggerEl(ctx);
67
+ }
68
+ if (hint === "decrement") {
69
+ btnEl = dom.getDecrementTriggerEl(ctx);
70
+ }
71
+ return btnEl;
72
+ },
73
+ setupVirtualCursor(ctx) {
74
+ if ((0, import_dom_query.isSafari)())
75
+ return;
76
+ dom.createVirtualCursor(ctx);
77
+ return () => {
78
+ dom.getCursorEl(ctx)?.remove();
79
+ };
80
+ },
81
+ preventTextSelection(ctx) {
82
+ const doc = dom.getDoc(ctx);
83
+ const html = doc.documentElement;
84
+ const body = doc.body;
85
+ body.style.pointerEvents = "none";
86
+ html.style.userSelect = "none";
87
+ html.style.cursor = "ew-resize";
88
+ return () => {
89
+ body.style.pointerEvents = "";
90
+ html.style.userSelect = "";
91
+ html.style.cursor = "";
92
+ if (!html.style.length) {
93
+ html.removeAttribute("style");
94
+ }
95
+ if (!body.style.length) {
96
+ body.removeAttribute("style");
97
+ }
98
+ };
99
+ },
100
+ getMousementValue(ctx, event) {
101
+ const x = (0, import_number_utils.roundToDevicePixel)(event.movementX);
102
+ const y = (0, import_number_utils.roundToDevicePixel)(event.movementY);
103
+ let hint = x > 0 ? "increment" : x < 0 ? "decrement" : null;
104
+ if (ctx.isRtl && hint === "increment")
105
+ hint = "decrement";
106
+ if (ctx.isRtl && hint === "decrement")
107
+ hint = "increment";
108
+ const point = {
109
+ x: ctx.scrubberCursorPoint.x + x,
110
+ y: ctx.scrubberCursorPoint.y + y
111
+ };
112
+ const win = dom.getWin(ctx);
113
+ const width = win.innerWidth;
114
+ const half = (0, import_number_utils.roundToDevicePixel)(7.5);
115
+ point.x = (0, import_number_utils.wrap)(point.x + half, width) - half;
116
+ return { hint, point };
117
+ },
118
+ createVirtualCursor(ctx) {
119
+ const doc = dom.getDoc(ctx);
120
+ const el = doc.createElement("div");
121
+ el.className = "scrubber--cursor";
122
+ el.id = dom.getCursorId(ctx);
123
+ Object.assign(el.style, {
124
+ width: "15px",
125
+ height: "15px",
126
+ position: "fixed",
127
+ pointerEvents: "none",
128
+ left: "0px",
129
+ top: "0px",
130
+ zIndex: import_dom_query.MAX_Z_INDEX,
131
+ transform: ctx.scrubberCursorPoint ? `translate3d(${ctx.scrubberCursorPoint.x}px, ${ctx.scrubberCursorPoint.y}px, 0px)` : void 0,
132
+ willChange: "transform"
133
+ });
134
+ el.innerHTML = `
135
+ <svg width="46" height="15" style="left: -15.5px; position: absolute; top: 0; filter: drop-shadow(rgba(0, 0, 0, 0.4) 0px 1px 1.1px);">
136
+ <g transform="translate(2 3)">
137
+ <path fill-rule="evenodd" d="M 15 4.5L 15 2L 11.5 5.5L 15 9L 15 6.5L 31 6.5L 31 9L 34.5 5.5L 31 2L 31 4.5Z" style="stroke-width: 2px; stroke: white;"></path>
138
+ <path fill-rule="evenodd" d="M 15 4.5L 15 2L 11.5 5.5L 15 9L 15 6.5L 31 6.5L 31 9L 34.5 5.5L 31 2L 31 4.5Z"></path>
139
+ </g>
140
+ </svg>`;
141
+ doc.body.appendChild(el);
142
+ }
143
+ });
10
144
 
11
- exports.anatomy = numberInput_anatomy.anatomy;
12
- exports.connect = numberInput_connect.connect;
13
- exports.machine = numberInput_machine.machine;
145
+ // src/number-input.utils.ts
146
+ var import_dom_event = require("@zag-js/dom-event");
147
+ var import_number_utils2 = require("@zag-js/number-utils");
148
+ var utils = {
149
+ isValidNumericEvent: (ctx, event) => {
150
+ if (event.key == null)
151
+ return true;
152
+ const isModifier = (0, import_dom_event.isModifiedEvent)(event);
153
+ const isSingleKey = event.key.length === 1;
154
+ if (isModifier || !isSingleKey)
155
+ return true;
156
+ return ctx.validateCharacter?.(event.key) ?? utils.isFloatingPoint(event.key);
157
+ },
158
+ isFloatingPoint: (v) => /^[0-9+\-.]$/.test(v),
159
+ sanitize: (ctx, value) => {
160
+ return value.split("").filter(ctx.validateCharacter ?? utils.isFloatingPoint).join("");
161
+ },
162
+ increment: (ctx, step) => {
163
+ const value = (0, import_number_utils2.increment)(ctx.value, step ?? ctx.step);
164
+ return (0, import_number_utils2.formatDecimal)((0, import_number_utils2.clamp)(value, ctx), ctx);
165
+ },
166
+ decrement: (ctx, step) => {
167
+ const value = (0, import_number_utils2.decrement)(ctx.value, step ?? ctx.step);
168
+ return (0, import_number_utils2.formatDecimal)((0, import_number_utils2.clamp)(value, ctx), ctx);
169
+ },
170
+ clamp: (ctx) => {
171
+ return (0, import_number_utils2.formatDecimal)((0, import_number_utils2.clamp)(ctx.value, ctx), ctx);
172
+ },
173
+ parse: (ctx, value) => {
174
+ return ctx.parse?.(value) ?? value;
175
+ },
176
+ format: (ctx, value) => {
177
+ const _val = value.toString();
178
+ return ctx.format?.(_val) ?? _val;
179
+ },
180
+ round: (ctx) => {
181
+ return (0, import_number_utils2.formatDecimal)(ctx.value, ctx);
182
+ }
183
+ };
184
+
185
+ // src/number-input.connect.ts
186
+ function connect(state, send, normalize) {
187
+ const isFocused = state.hasTag("focus");
188
+ const isInvalid = state.context.isOutOfRange || !!state.context.invalid;
189
+ const isDisabled = !!state.context.disabled;
190
+ const isValueEmpty = state.context.isValueEmpty;
191
+ const isIncrementDisabled = isDisabled || !state.context.canIncrement;
192
+ const isDecrementDisabled = isDisabled || !state.context.canDecrement;
193
+ const translations = state.context.translations;
194
+ return {
195
+ /**
196
+ * Whether the input is focused.
197
+ */
198
+ isFocused,
199
+ /**
200
+ * Whether the input is invalid.
201
+ */
202
+ isInvalid,
203
+ /**
204
+ * Whether the input value is empty.
205
+ */
206
+ isValueEmpty,
207
+ /**
208
+ * The formatted value of the input.
209
+ */
210
+ value: state.context.formattedValue,
211
+ /**
212
+ * The value of the input as a number.
213
+ */
214
+ valueAsNumber: state.context.valueAsNumber,
215
+ /**
216
+ * Function to set the value of the input.
217
+ */
218
+ setValue(value) {
219
+ send({ type: "SET_VALUE", value: value.toString() });
220
+ },
221
+ /**
222
+ * Function to clear the value of the input.
223
+ */
224
+ clearValue() {
225
+ send("CLEAR_VALUE");
226
+ },
227
+ /**
228
+ * Function to increment the value of the input by the step.
229
+ */
230
+ increment() {
231
+ send("INCREMENT");
232
+ },
233
+ /**
234
+ * Function to decrement the value of the input by the step.
235
+ */
236
+ decrement() {
237
+ send("DECREMENT");
238
+ },
239
+ /**
240
+ * Function to set the value of the input to the max.
241
+ */
242
+ setToMax() {
243
+ send({ type: "SET_VALUE", value: state.context.max });
244
+ },
245
+ /**
246
+ * Function to set the value of the input to the min.
247
+ */
248
+ setToMin() {
249
+ send({ type: "SET_VALUE", value: state.context.min });
250
+ },
251
+ /**
252
+ * Function to focus the input.
253
+ */
254
+ focus() {
255
+ dom.getInputEl(state.context)?.focus();
256
+ },
257
+ /**
258
+ * Function to blur the input.
259
+ */
260
+ blur() {
261
+ dom.getInputEl(state.context)?.blur();
262
+ },
263
+ rootProps: normalize.element({
264
+ id: dom.getRootId(state.context),
265
+ ...parts.root.attrs,
266
+ "data-disabled": (0, import_dom_query2.dataAttr)(isDisabled)
267
+ }),
268
+ labelProps: normalize.label({
269
+ ...parts.label.attrs,
270
+ "data-disabled": (0, import_dom_query2.dataAttr)(isDisabled),
271
+ "data-invalid": (0, import_dom_query2.dataAttr)(isInvalid),
272
+ id: dom.getLabelId(state.context),
273
+ htmlFor: dom.getInputId(state.context)
274
+ }),
275
+ controlProps: normalize.element({
276
+ ...parts.control.attrs,
277
+ role: "group",
278
+ "aria-disabled": isDisabled,
279
+ "data-disabled": (0, import_dom_query2.dataAttr)(isDisabled),
280
+ "data-invalid": (0, import_dom_query2.dataAttr)(isInvalid),
281
+ "aria-invalid": (0, import_dom_query2.ariaAttr)(state.context.invalid)
282
+ }),
283
+ inputProps: normalize.input({
284
+ ...parts.input.attrs,
285
+ name: state.context.name,
286
+ form: state.context.form,
287
+ id: dom.getInputId(state.context),
288
+ role: "spinbutton",
289
+ defaultValue: state.context.formattedValue,
290
+ pattern: state.context.pattern,
291
+ inputMode: state.context.inputMode,
292
+ "aria-invalid": (0, import_dom_query2.ariaAttr)(isInvalid),
293
+ "data-invalid": (0, import_dom_query2.dataAttr)(isInvalid),
294
+ disabled: isDisabled,
295
+ "data-disabled": (0, import_dom_query2.dataAttr)(isDisabled),
296
+ readOnly: !!state.context.readOnly,
297
+ autoComplete: "off",
298
+ autoCorrect: "off",
299
+ spellCheck: "false",
300
+ type: "text",
301
+ "aria-roledescription": "numberfield",
302
+ "aria-valuemin": state.context.min,
303
+ "aria-valuemax": state.context.max,
304
+ "aria-valuenow": isNaN(state.context.valueAsNumber) ? void 0 : state.context.valueAsNumber,
305
+ "aria-valuetext": state.context.valueText,
306
+ onFocus() {
307
+ send("FOCUS");
308
+ },
309
+ onBlur() {
310
+ send("BLUR");
311
+ },
312
+ onChange(event) {
313
+ send({ type: "CHANGE", target: event.currentTarget, hint: "set" });
314
+ },
315
+ onKeyDown(event) {
316
+ const evt = (0, import_dom_event2.getNativeEvent)(event);
317
+ if (evt.isComposing)
318
+ return;
319
+ if (!utils.isValidNumericEvent(state.context, event)) {
320
+ event.preventDefault();
321
+ }
322
+ const step = (0, import_dom_event2.getEventStep)(event) * state.context.step;
323
+ const keyMap = {
324
+ ArrowUp() {
325
+ send({ type: "ARROW_UP", step });
326
+ },
327
+ ArrowDown() {
328
+ send({ type: "ARROW_DOWN", step });
329
+ },
330
+ Home() {
331
+ send("HOME");
332
+ },
333
+ End() {
334
+ send("END");
335
+ }
336
+ };
337
+ const exec = keyMap[event.key];
338
+ if (exec) {
339
+ exec(event);
340
+ event.preventDefault();
341
+ }
342
+ }
343
+ }),
344
+ decrementTriggerProps: normalize.button({
345
+ ...parts.decrementTrigger.attrs,
346
+ id: dom.getDecrementTriggerId(state.context),
347
+ disabled: isDecrementDisabled,
348
+ "data-disabled": (0, import_dom_query2.dataAttr)(isDecrementDisabled),
349
+ "aria-label": translations.decrementLabel,
350
+ type: "button",
351
+ tabIndex: -1,
352
+ "aria-controls": dom.getInputId(state.context),
353
+ onPointerDown(event) {
354
+ if (isDecrementDisabled)
355
+ return;
356
+ send((0, import_dom_event2.isLeftClick)(event) ? { type: "PRESS_DOWN", hint: "decrement" } : { type: "FOCUS" });
357
+ event.preventDefault();
358
+ },
359
+ onPointerUp() {
360
+ send({ type: "PRESS_UP", hint: "decrement" });
361
+ },
362
+ onPointerLeave() {
363
+ if (isDecrementDisabled)
364
+ return;
365
+ send({ type: "PRESS_UP", hint: "decrement" });
366
+ }
367
+ }),
368
+ incrementTriggerProps: normalize.button({
369
+ ...parts.incrementTrigger.attrs,
370
+ id: dom.getIncrementTriggerId(state.context),
371
+ disabled: isIncrementDisabled,
372
+ "data-disabled": (0, import_dom_query2.dataAttr)(isIncrementDisabled),
373
+ "aria-label": translations.incrementLabel,
374
+ type: "button",
375
+ tabIndex: -1,
376
+ "aria-controls": dom.getInputId(state.context),
377
+ onPointerDown(event) {
378
+ if (isIncrementDisabled)
379
+ return;
380
+ send((0, import_dom_event2.isLeftClick)(event) ? { type: "PRESS_DOWN", hint: "increment" } : { type: "FOCUS" });
381
+ event.preventDefault();
382
+ },
383
+ onPointerUp() {
384
+ send({ type: "PRESS_UP", hint: "increment" });
385
+ },
386
+ onPointerLeave() {
387
+ send({ type: "PRESS_UP", hint: "increment" });
388
+ }
389
+ }),
390
+ scrubberProps: normalize.element({
391
+ ...parts.scrubber.attrs,
392
+ "data-disabled": (0, import_dom_query2.dataAttr)(isDisabled),
393
+ id: dom.getScrubberId(state.context),
394
+ role: "presentation",
395
+ onMouseDown(event) {
396
+ if (isDisabled)
397
+ return;
398
+ const evt = (0, import_dom_event2.getNativeEvent)(event);
399
+ const point = (0, import_dom_event2.getEventPoint)(evt);
400
+ point.x = point.x - (0, import_number_utils3.roundToDevicePixel)(7.5);
401
+ point.y = point.y - (0, import_number_utils3.roundToDevicePixel)(7.5);
402
+ send({ type: "PRESS_DOWN_SCRUBBER", point });
403
+ event.preventDefault();
404
+ },
405
+ style: {
406
+ cursor: isDisabled ? void 0 : "ew-resize"
407
+ }
408
+ })
409
+ };
410
+ }
411
+
412
+ // src/number-input.machine.ts
413
+ var import_core = require("@zag-js/core");
414
+ var import_dom_event3 = require("@zag-js/dom-event");
415
+ var import_dom_query3 = require("@zag-js/dom-query");
416
+ var import_form_utils = require("@zag-js/form-utils");
417
+ var import_mutation_observer = require("@zag-js/mutation-observer");
418
+ var import_number_utils4 = require("@zag-js/number-utils");
419
+ var import_utils = require("@zag-js/utils");
420
+ var { not, and } = import_core.guards;
421
+ function machine(userContext) {
422
+ const ctx = (0, import_utils.compact)(userContext);
423
+ return (0, import_core.createMachine)(
424
+ {
425
+ id: "number-input",
426
+ initial: "idle",
427
+ context: {
428
+ dir: "ltr",
429
+ focusInputOnChange: true,
430
+ clampValueOnBlur: true,
431
+ allowOverflow: false,
432
+ inputMode: "decimal",
433
+ pattern: "[0-9]*(.[0-9]+)?",
434
+ hint: null,
435
+ value: "",
436
+ step: 1,
437
+ min: Number.MIN_SAFE_INTEGER,
438
+ max: Number.MAX_SAFE_INTEGER,
439
+ scrubberCursorPoint: null,
440
+ invalid: false,
441
+ spinOnPress: true,
442
+ ...ctx,
443
+ translations: {
444
+ incrementLabel: "increment value",
445
+ decrementLabel: "decrease value",
446
+ ...ctx.translations
447
+ }
448
+ },
449
+ computed: {
450
+ isRtl: (ctx2) => ctx2.dir === "rtl",
451
+ valueAsNumber: (ctx2) => (0, import_number_utils4.valueOf)(ctx2.value),
452
+ isAtMin: (ctx2) => (0, import_number_utils4.isAtMin)(ctx2.value, ctx2),
453
+ isAtMax: (ctx2) => (0, import_number_utils4.isAtMax)(ctx2.value, ctx2),
454
+ isOutOfRange: (ctx2) => !(0, import_number_utils4.isWithinRange)(ctx2.value, ctx2),
455
+ isValueEmpty: (ctx2) => ctx2.value === "",
456
+ canIncrement: (ctx2) => ctx2.allowOverflow || !ctx2.isAtMax,
457
+ canDecrement: (ctx2) => ctx2.allowOverflow || !ctx2.isAtMin,
458
+ valueText: (ctx2) => ctx2.translations.valueText?.(ctx2.value),
459
+ formattedValue: (ctx2) => ctx2.format?.(ctx2.value).toString() ?? ctx2.value
460
+ },
461
+ watch: {
462
+ value: ["invokeOnChange", "dispatchChangeEvent"],
463
+ isOutOfRange: ["invokeOnInvalid"],
464
+ scrubberCursorPoint: ["setVirtualCursorPosition"]
465
+ },
466
+ entry: ["syncInputValue"],
467
+ on: {
468
+ SET_VALUE: [
469
+ {
470
+ guard: "clampOnBlur",
471
+ actions: ["setValue", "clampValue", "setHintToSet"]
472
+ },
473
+ {
474
+ actions: ["setValue", "setHintToSet"]
475
+ }
476
+ ],
477
+ CLEAR_VALUE: {
478
+ actions: ["clearValue"]
479
+ },
480
+ INCREMENT: {
481
+ actions: ["increment"]
482
+ },
483
+ DECREMENT: {
484
+ actions: ["decrement"]
485
+ }
486
+ },
487
+ states: {
488
+ idle: {
489
+ exit: "invokeOnFocus",
490
+ on: {
491
+ PRESS_DOWN: {
492
+ target: "before:spin",
493
+ actions: ["focusInput", "setHint"]
494
+ },
495
+ PRESS_DOWN_SCRUBBER: {
496
+ target: "scrubbing",
497
+ actions: ["focusInput", "setHint", "setCursorPoint"]
498
+ },
499
+ FOCUS: "focused"
500
+ }
501
+ },
502
+ focused: {
503
+ tags: "focus",
504
+ entry: "focusInput",
505
+ activities: "attachWheelListener",
506
+ on: {
507
+ PRESS_DOWN: {
508
+ target: "before:spin",
509
+ actions: ["focusInput", "setHint"]
510
+ },
511
+ PRESS_DOWN_SCRUBBER: {
512
+ target: "scrubbing",
513
+ actions: ["focusInput", "setHint", "setCursorPoint"]
514
+ },
515
+ ARROW_UP: {
516
+ actions: "increment"
517
+ },
518
+ ARROW_DOWN: {
519
+ actions: "decrement"
520
+ },
521
+ HOME: {
522
+ actions: "setToMin"
523
+ },
524
+ END: {
525
+ actions: "setToMax"
526
+ },
527
+ CHANGE: {
528
+ actions: ["setValue", "setHint"]
529
+ },
530
+ BLUR: [
531
+ {
532
+ guard: "isInvalidExponential",
533
+ target: "idle",
534
+ actions: ["clearValue", "clearHint", "invokeOnBlur"]
535
+ },
536
+ {
537
+ guard: and("clampOnBlur", not("isInRange"), not("isEmptyValue")),
538
+ target: "idle",
539
+ actions: ["clampValue", "clearHint", "invokeOnBlur"]
540
+ },
541
+ {
542
+ target: "idle",
543
+ actions: ["roundValue", "invokeOnBlur"]
544
+ }
545
+ ]
546
+ }
547
+ },
548
+ "before:spin": {
549
+ tags: "focus",
550
+ activities: "trackButtonDisabled",
551
+ entry: (0, import_core.choose)([
552
+ { guard: "isIncrementHint", actions: "increment" },
553
+ { guard: "isDecrementHint", actions: "decrement" }
554
+ ]),
555
+ after: {
556
+ CHANGE_DELAY: {
557
+ target: "spinning",
558
+ guard: and("isInRange", "spinOnPress")
559
+ }
560
+ },
561
+ on: {
562
+ PRESS_UP: {
563
+ target: "focused",
564
+ actions: "clearHint"
565
+ }
566
+ }
567
+ },
568
+ spinning: {
569
+ tags: "focus",
570
+ activities: "trackButtonDisabled",
571
+ every: [
572
+ {
573
+ delay: "CHANGE_INTERVAL",
574
+ guard: and(not("isAtMin"), "isIncrementHint"),
575
+ actions: "increment"
576
+ },
577
+ {
578
+ delay: "CHANGE_INTERVAL",
579
+ guard: and(not("isAtMax"), "isDecrementHint"),
580
+ actions: "decrement"
581
+ }
582
+ ],
583
+ on: {
584
+ PRESS_UP: {
585
+ target: "focused",
586
+ actions: "clearHint"
587
+ }
588
+ }
589
+ },
590
+ scrubbing: {
591
+ tags: "focus",
592
+ exit: "clearCursorPoint",
593
+ activities: ["activatePointerLock", "trackMousemove", "setupVirtualCursor", "preventTextSelection"],
594
+ on: {
595
+ POINTER_UP_SCRUBBER: "focused",
596
+ POINTER_MOVE_SCRUBBER: [
597
+ {
598
+ guard: "isIncrementHint",
599
+ actions: ["increment", "setCursorPoint"]
600
+ },
601
+ {
602
+ guard: "isDecrementHint",
603
+ actions: ["decrement", "setCursorPoint"]
604
+ }
605
+ ]
606
+ }
607
+ }
608
+ }
609
+ },
610
+ {
611
+ delays: {
612
+ CHANGE_INTERVAL: 50,
613
+ CHANGE_DELAY: 300
614
+ },
615
+ guards: {
616
+ clampOnBlur: (ctx2) => !!ctx2.clampValueOnBlur,
617
+ isAtMin: (ctx2) => ctx2.isAtMin,
618
+ spinOnPress: (ctx2) => !!ctx2.spinOnPress,
619
+ isAtMax: (ctx2) => ctx2.isAtMax,
620
+ isInRange: (ctx2) => !ctx2.isOutOfRange,
621
+ isDecrementHint: (ctx2, evt) => (evt.hint ?? ctx2.hint) === "decrement",
622
+ isEmptyValue: (ctx2) => ctx2.isValueEmpty,
623
+ isIncrementHint: (ctx2, evt) => (evt.hint ?? ctx2.hint) === "increment",
624
+ isInvalidExponential: (ctx2) => ctx2.value.toString().startsWith("e")
625
+ },
626
+ activities: {
627
+ setupVirtualCursor(ctx2) {
628
+ return dom.setupVirtualCursor(ctx2);
629
+ },
630
+ preventTextSelection(ctx2) {
631
+ return dom.preventTextSelection(ctx2);
632
+ },
633
+ trackButtonDisabled(ctx2, _evt, { send }) {
634
+ const btn = dom.getPressedTriggerEl(ctx2, ctx2.hint);
635
+ return (0, import_mutation_observer.observeAttributes)(btn, ["disabled"], () => {
636
+ send("PRESS_UP");
637
+ });
638
+ },
639
+ attachWheelListener(ctx2, _evt, { send }) {
640
+ const input = dom.getInputEl(ctx2);
641
+ if (!input)
642
+ return;
643
+ function onWheel(event) {
644
+ const isInputFocused = dom.getDoc(ctx2).activeElement === input;
645
+ if (!ctx2.allowMouseWheel || !isInputFocused)
646
+ return;
647
+ event.preventDefault();
648
+ const dir = Math.sign(event.deltaY) * -1;
649
+ if (dir === 1) {
650
+ send("INCREMENT");
651
+ } else if (dir === -1) {
652
+ send("DECREMENT");
653
+ }
654
+ }
655
+ return (0, import_dom_event3.addDomEvent)(input, "wheel", onWheel, { passive: false });
656
+ },
657
+ activatePointerLock(ctx2) {
658
+ if ((0, import_dom_query3.isSafari)())
659
+ return;
660
+ return (0, import_dom_event3.requestPointerLock)(dom.getDoc(ctx2));
661
+ },
662
+ trackMousemove(ctx2, _evt, { send }) {
663
+ const doc = dom.getDoc(ctx2);
664
+ function onMousemove(event) {
665
+ if (!ctx2.scrubberCursorPoint)
666
+ return;
667
+ const value = dom.getMousementValue(ctx2, event);
668
+ if (!value.hint)
669
+ return;
670
+ send({
671
+ type: "POINTER_MOVE_SCRUBBER",
672
+ hint: value.hint,
673
+ point: value.point
674
+ });
675
+ }
676
+ function onMouseup() {
677
+ send("POINTER_UP_SCRUBBER");
678
+ }
679
+ return (0, import_utils.callAll)(
680
+ (0, import_dom_event3.addDomEvent)(doc, "mousemove", onMousemove, false),
681
+ (0, import_dom_event3.addDomEvent)(doc, "mouseup", onMouseup, false)
682
+ );
683
+ }
684
+ },
685
+ actions: {
686
+ focusInput(ctx2) {
687
+ if (!ctx2.focusInputOnChange)
688
+ return;
689
+ const input = dom.getInputEl(ctx2);
690
+ (0, import_dom_query3.raf)(() => input?.focus());
691
+ },
692
+ increment(ctx2, evt) {
693
+ ctx2.value = utils.increment(ctx2, evt.step);
694
+ },
695
+ decrement(ctx2, evt) {
696
+ ctx2.value = utils.decrement(ctx2, evt.step);
697
+ },
698
+ clampValue(ctx2) {
699
+ ctx2.value = utils.clamp(ctx2);
700
+ },
701
+ roundValue(ctx2) {
702
+ if (ctx2.value !== "") {
703
+ ctx2.value = utils.round(ctx2);
704
+ }
705
+ },
706
+ setValue(ctx2, evt) {
707
+ const value = evt.target?.value ?? evt.value;
708
+ ctx2.value = utils.sanitize(ctx2, utils.parse(ctx2, value.toString()));
709
+ },
710
+ clearValue(ctx2) {
711
+ ctx2.value = "";
712
+ },
713
+ setToMax(ctx2) {
714
+ ctx2.value = ctx2.max.toString();
715
+ },
716
+ setToMin(ctx2) {
717
+ ctx2.value = ctx2.min.toString();
718
+ },
719
+ setHint(ctx2, evt) {
720
+ ctx2.hint = evt.hint;
721
+ },
722
+ clearHint(ctx2) {
723
+ ctx2.hint = null;
724
+ },
725
+ setHintToSet(ctx2) {
726
+ ctx2.hint = "set";
727
+ },
728
+ invokeOnChange(ctx2) {
729
+ ctx2.onChange?.({
730
+ value: ctx2.value,
731
+ valueAsNumber: ctx2.valueAsNumber
732
+ });
733
+ },
734
+ invokeOnFocus(ctx2, evt) {
735
+ let srcElement = null;
736
+ if (evt.type === "PRESS_DOWN") {
737
+ srcElement = dom.getPressedTriggerEl(ctx2, evt.hint);
738
+ } else if (evt.type === "FOCUS") {
739
+ srcElement = dom.getInputEl(ctx2);
740
+ } else if (evt.type === "PRESS_DOWN_SCRUBBER") {
741
+ srcElement = dom.getScrubberEl(ctx2);
742
+ }
743
+ ctx2.onFocus?.({
744
+ value: ctx2.value,
745
+ valueAsNumber: ctx2.valueAsNumber,
746
+ srcElement
747
+ });
748
+ },
749
+ invokeOnBlur(ctx2) {
750
+ ctx2.onBlur?.({
751
+ value: ctx2.value,
752
+ valueAsNumber: ctx2.valueAsNumber
753
+ });
754
+ },
755
+ invokeOnInvalid(ctx2) {
756
+ if (!ctx2.isOutOfRange)
757
+ return;
758
+ const reason = ctx2.valueAsNumber > ctx2.max ? "rangeOverflow" : "rangeUnderflow";
759
+ ctx2.onInvalid?.({
760
+ reason,
761
+ value: ctx2.formattedValue,
762
+ valueAsNumber: ctx2.valueAsNumber
763
+ });
764
+ },
765
+ // sync input value, in event it was set from form libraries via `ref`, `bind:this`, etc.
766
+ syncInputValue(ctx2) {
767
+ const input = dom.getInputEl(ctx2);
768
+ if (!input || input.value == ctx2.value)
769
+ return;
770
+ const value = utils.parse(ctx2, input.value);
771
+ ctx2.value = utils.sanitize(ctx2, value);
772
+ },
773
+ setCursorPoint(ctx2, evt) {
774
+ ctx2.scrubberCursorPoint = evt.point;
775
+ },
776
+ clearCursorPoint(ctx2) {
777
+ ctx2.scrubberCursorPoint = null;
778
+ },
779
+ setVirtualCursorPosition(ctx2) {
780
+ const cursor = dom.getCursorEl(ctx2);
781
+ if (!cursor || !ctx2.scrubberCursorPoint)
782
+ return;
783
+ const { x, y } = ctx2.scrubberCursorPoint;
784
+ cursor.style.transform = `translate3d(${x}px, ${y}px, 0px)`;
785
+ },
786
+ dispatchChangeEvent(ctx2) {
787
+ const inputEl = dom.getInputEl(ctx2);
788
+ (0, import_form_utils.dispatchInputValueEvent)(inputEl, { value: ctx2.formattedValue });
789
+ }
790
+ }
791
+ }
792
+ );
793
+ }
794
+ // Annotate the CommonJS export names for ESM import in node:
795
+ 0 && (module.exports = {
796
+ anatomy,
797
+ connect,
798
+ machine
799
+ });
800
+ //# sourceMappingURL=index.js.map