@zag-js/number-input 1.34.1 → 1.35.1

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
package/dist/index.js CHANGED
@@ -1,933 +1,39 @@
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 __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
2
20
 
3
- var anatomy$1 = require('@zag-js/anatomy');
4
- var domQuery = require('@zag-js/dom-query');
5
- var utils = require('@zag-js/utils');
6
- var core = require('@zag-js/core');
7
- var number = require('@internationalized/number');
8
- var types = require('@zag-js/types');
9
-
10
- // src/number-input.anatomy.ts
11
- var anatomy = anatomy$1.createAnatomy("numberInput").parts(
12
- "root",
13
- "label",
14
- "input",
15
- "control",
16
- "valueText",
17
- "incrementTrigger",
18
- "decrementTrigger",
19
- "scrubber"
20
- );
21
- var parts = anatomy.build();
22
-
23
- // src/cursor.ts
24
- function recordCursor(inputEl, scope) {
25
- if (!inputEl || !scope.isActiveElement(inputEl)) return;
26
- try {
27
- const { selectionStart: start, selectionEnd: end, value } = inputEl;
28
- if (start == null || end == null) return void 0;
29
- return { start, end, value };
30
- } catch {
31
- return void 0;
32
- }
33
- }
34
- function restoreCursor(inputEl, selection, scope) {
35
- if (!inputEl || !scope.isActiveElement(inputEl)) return;
36
- if (!selection) {
37
- const len = inputEl.value.length;
38
- inputEl.setSelectionRange(len, len);
39
- return;
40
- }
41
- try {
42
- const newValue = inputEl.value;
43
- const { start, end, value: oldValue } = selection;
44
- if (newValue === oldValue) {
45
- inputEl.setSelectionRange(start, end);
46
- return;
47
- }
48
- const newStart = getNextCursorPosition(oldValue, newValue, start);
49
- const newEnd = start === end ? newStart : getNextCursorPosition(oldValue, newValue, end);
50
- const clampedStart = Math.max(0, Math.min(newStart, newValue.length));
51
- const clampedEnd = Math.max(clampedStart, Math.min(newEnd, newValue.length));
52
- inputEl.setSelectionRange(clampedStart, clampedEnd);
53
- } catch {
54
- const len = inputEl.value.length;
55
- inputEl.setSelectionRange(len, len);
56
- }
57
- }
58
- function getNextCursorPosition(oldValue, newValue, oldPosition) {
59
- const beforeCursor = oldValue.slice(0, oldPosition);
60
- const afterCursor = oldValue.slice(oldPosition);
61
- let prefixLength = 0;
62
- const maxPrefixLength = Math.min(beforeCursor.length, newValue.length);
63
- for (let i = 0; i < maxPrefixLength; i++) {
64
- if (beforeCursor[i] === newValue[i]) {
65
- prefixLength = i + 1;
66
- } else {
67
- break;
68
- }
69
- }
70
- let suffixLength = 0;
71
- const maxSuffixLength = Math.min(afterCursor.length, newValue.length - prefixLength);
72
- for (let i = 0; i < maxSuffixLength; i++) {
73
- const oldIndex = afterCursor.length - 1 - i;
74
- const newIndex = newValue.length - 1 - i;
75
- if (afterCursor[oldIndex] === newValue[newIndex]) {
76
- suffixLength = i + 1;
77
- } else {
78
- break;
79
- }
80
- }
81
- if (beforeCursor.length > 0 && prefixLength >= beforeCursor.length) {
82
- return prefixLength;
83
- }
84
- if (suffixLength >= afterCursor.length) {
85
- return newValue.length - suffixLength;
86
- }
87
- if (prefixLength > 0) {
88
- return prefixLength;
89
- }
90
- if (suffixLength > 0) {
91
- return newValue.length - suffixLength;
92
- }
93
- if (oldPosition === 0 && prefixLength === 0 && suffixLength === 0) {
94
- return newValue.length;
95
- }
96
- if (oldValue.length > 0) {
97
- const ratio = oldPosition / oldValue.length;
98
- return Math.round(ratio * newValue.length);
99
- }
100
- return newValue.length;
101
- }
102
- var getRootId = (ctx) => ctx.ids?.root ?? `number-input:${ctx.id}`;
103
- var getInputId = (ctx) => ctx.ids?.input ?? `number-input:${ctx.id}:input`;
104
- var getIncrementTriggerId = (ctx) => ctx.ids?.incrementTrigger ?? `number-input:${ctx.id}:inc`;
105
- var getDecrementTriggerId = (ctx) => ctx.ids?.decrementTrigger ?? `number-input:${ctx.id}:dec`;
106
- var getScrubberId = (ctx) => ctx.ids?.scrubber ?? `number-input:${ctx.id}:scrubber`;
107
- var getCursorId = (ctx) => `number-input:${ctx.id}:cursor`;
108
- var getLabelId = (ctx) => ctx.ids?.label ?? `number-input:${ctx.id}:label`;
109
- var getInputEl = (ctx) => ctx.getById(getInputId(ctx));
110
- var getIncrementTriggerEl = (ctx) => ctx.getById(getIncrementTriggerId(ctx));
111
- var getDecrementTriggerEl = (ctx) => ctx.getById(getDecrementTriggerId(ctx));
112
- var getCursorEl = (ctx) => ctx.getDoc().getElementById(getCursorId(ctx));
113
- var getPressedTriggerEl = (ctx, hint) => {
114
- let btnEl = null;
115
- if (hint === "increment") {
116
- btnEl = getIncrementTriggerEl(ctx);
117
- }
118
- if (hint === "decrement") {
119
- btnEl = getDecrementTriggerEl(ctx);
120
- }
121
- return btnEl;
122
- };
123
- var setupVirtualCursor = (ctx, point) => {
124
- if (domQuery.isSafari()) return;
125
- createVirtualCursor(ctx, point);
126
- return () => {
127
- getCursorEl(ctx)?.remove();
128
- };
129
- };
130
- var preventTextSelection = (ctx) => {
131
- const doc = ctx.getDoc();
132
- const html = doc.documentElement;
133
- const body = doc.body;
134
- body.style.pointerEvents = "none";
135
- html.style.userSelect = "none";
136
- html.style.cursor = "ew-resize";
137
- return () => {
138
- body.style.pointerEvents = "";
139
- html.style.userSelect = "";
140
- html.style.cursor = "";
141
- if (!html.style.length) {
142
- html.removeAttribute("style");
143
- }
144
- if (!body.style.length) {
145
- body.removeAttribute("style");
146
- }
147
- };
148
- };
149
- var getMousemoveValue = (ctx, opts) => {
150
- const { point, isRtl, event } = opts;
151
- const win = ctx.getWin();
152
- const x = utils.roundToDpr(event.movementX, win.devicePixelRatio);
153
- const y = utils.roundToDpr(event.movementY, win.devicePixelRatio);
154
- let hint = x > 0 ? "increment" : x < 0 ? "decrement" : null;
155
- if (isRtl && hint === "increment") hint = "decrement";
156
- if (isRtl && hint === "decrement") hint = "increment";
157
- const newPoint = { x: point.x + x, y: point.y + y };
158
- const width = win.innerWidth;
159
- const half = utils.roundToDpr(7.5, win.devicePixelRatio);
160
- newPoint.x = utils.wrap(newPoint.x + half, width) - half;
161
- return { hint, point: newPoint };
162
- };
163
- var createVirtualCursor = (ctx, point) => {
164
- const doc = ctx.getDoc();
165
- const el = doc.createElement("div");
166
- el.className = "scrubber--cursor";
167
- el.id = getCursorId(ctx);
168
- Object.assign(el.style, {
169
- width: "15px",
170
- height: "15px",
171
- position: "fixed",
172
- pointerEvents: "none",
173
- left: "0px",
174
- top: "0px",
175
- zIndex: domQuery.MAX_Z_INDEX,
176
- transform: point ? `translate3d(${point.x}px, ${point.y}px, 0px)` : void 0,
177
- willChange: "transform"
178
- });
179
- el.innerHTML = `
180
- <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);">
181
- <g transform="translate(2 3)">
182
- <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>
183
- <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>
184
- </g>
185
- </svg>`;
186
- doc.body.appendChild(el);
187
- };
188
-
189
- // src/number-input.connect.ts
190
- function connect(service, normalize) {
191
- const { state, send, prop, scope, computed } = service;
192
- const focused = state.hasTag("focus");
193
- const disabled = computed("isDisabled");
194
- const readOnly = !!prop("readOnly");
195
- const required = !!prop("required");
196
- const scrubbing = state.matches("scrubbing");
197
- const empty = computed("isValueEmpty");
198
- const invalid = prop("invalid") !== void 0 ? !!prop("invalid") : computed("isOutOfRange");
199
- const isIncrementDisabled = disabled || !computed("canIncrement") || readOnly;
200
- const isDecrementDisabled = disabled || !computed("canDecrement") || readOnly;
201
- const translations = prop("translations");
202
- return {
203
- focused,
204
- invalid,
205
- empty,
206
- value: computed("formattedValue"),
207
- valueAsNumber: computed("valueAsNumber"),
208
- setValue(value) {
209
- send({ type: "VALUE.SET", value });
210
- },
211
- clearValue() {
212
- send({ type: "VALUE.CLEAR" });
213
- },
214
- increment() {
215
- send({ type: "VALUE.INCREMENT" });
216
- },
217
- decrement() {
218
- send({ type: "VALUE.DECREMENT" });
219
- },
220
- setToMax() {
221
- send({ type: "VALUE.SET", value: prop("max") });
222
- },
223
- setToMin() {
224
- send({ type: "VALUE.SET", value: prop("min") });
225
- },
226
- focus() {
227
- getInputEl(scope)?.focus();
228
- },
229
- getRootProps() {
230
- return normalize.element({
231
- id: getRootId(scope),
232
- ...parts.root.attrs,
233
- dir: prop("dir"),
234
- "data-disabled": domQuery.dataAttr(disabled),
235
- "data-focus": domQuery.dataAttr(focused),
236
- "data-invalid": domQuery.dataAttr(invalid),
237
- "data-scrubbing": domQuery.dataAttr(scrubbing)
238
- });
239
- },
240
- getLabelProps() {
241
- return normalize.label({
242
- ...parts.label.attrs,
243
- dir: prop("dir"),
244
- "data-disabled": domQuery.dataAttr(disabled),
245
- "data-focus": domQuery.dataAttr(focused),
246
- "data-invalid": domQuery.dataAttr(invalid),
247
- "data-required": domQuery.dataAttr(required),
248
- "data-scrubbing": domQuery.dataAttr(scrubbing),
249
- id: getLabelId(scope),
250
- htmlFor: getInputId(scope),
251
- onClick() {
252
- domQuery.raf(() => {
253
- domQuery.setCaretToEnd(getInputEl(scope));
254
- });
255
- }
256
- });
257
- },
258
- getControlProps() {
259
- return normalize.element({
260
- ...parts.control.attrs,
261
- dir: prop("dir"),
262
- role: "group",
263
- "aria-disabled": disabled,
264
- "data-focus": domQuery.dataAttr(focused),
265
- "data-disabled": domQuery.dataAttr(disabled),
266
- "data-invalid": domQuery.dataAttr(invalid),
267
- "data-scrubbing": domQuery.dataAttr(scrubbing),
268
- "aria-invalid": domQuery.ariaAttr(invalid)
269
- });
270
- },
271
- getValueTextProps() {
272
- return normalize.element({
273
- ...parts.valueText.attrs,
274
- dir: prop("dir"),
275
- "data-disabled": domQuery.dataAttr(disabled),
276
- "data-invalid": domQuery.dataAttr(invalid),
277
- "data-focus": domQuery.dataAttr(focused),
278
- "data-scrubbing": domQuery.dataAttr(scrubbing)
279
- });
280
- },
281
- getInputProps() {
282
- return normalize.input({
283
- ...parts.input.attrs,
284
- dir: prop("dir"),
285
- name: prop("name"),
286
- form: prop("form"),
287
- id: getInputId(scope),
288
- role: "spinbutton",
289
- defaultValue: computed("formattedValue"),
290
- pattern: prop("formatOptions") ? void 0 : prop("pattern"),
291
- inputMode: prop("inputMode"),
292
- "aria-invalid": domQuery.ariaAttr(invalid),
293
- "data-invalid": domQuery.dataAttr(invalid),
294
- disabled,
295
- "data-disabled": domQuery.dataAttr(disabled),
296
- readOnly,
297
- required: prop("required"),
298
- autoComplete: "off",
299
- autoCorrect: "off",
300
- spellCheck: "false",
301
- type: "text",
302
- "aria-roledescription": "numberfield",
303
- "aria-valuemin": prop("min"),
304
- "aria-valuemax": prop("max"),
305
- "aria-valuenow": Number.isNaN(computed("valueAsNumber")) ? void 0 : computed("valueAsNumber"),
306
- "aria-valuetext": computed("valueText"),
307
- "data-scrubbing": domQuery.dataAttr(scrubbing),
308
- onFocus() {
309
- send({ type: "INPUT.FOCUS" });
310
- },
311
- onBlur() {
312
- send({ type: "INPUT.BLUR" });
313
- },
314
- onInput(event) {
315
- const selection = recordCursor(event.currentTarget, scope);
316
- send({ type: "INPUT.CHANGE", target: event.currentTarget, hint: "set", selection });
317
- },
318
- onBeforeInput(event) {
319
- try {
320
- const { selectionStart, selectionEnd, value } = event.currentTarget;
321
- const nextValue = value.slice(0, selectionStart) + (event.data ?? "") + value.slice(selectionEnd);
322
- const isValid = computed("parser").isValidPartialNumber(nextValue);
323
- if (!isValid) {
324
- event.preventDefault();
325
- }
326
- } catch {
327
- }
328
- },
329
- onKeyDown(event) {
330
- if (event.defaultPrevented) return;
331
- if (readOnly) return;
332
- if (domQuery.isComposingEvent(event)) return;
333
- const step = domQuery.getEventStep(event) * prop("step");
334
- const keyMap = {
335
- ArrowUp() {
336
- send({ type: "INPUT.ARROW_UP", step });
337
- event.preventDefault();
338
- },
339
- ArrowDown() {
340
- send({ type: "INPUT.ARROW_DOWN", step });
341
- event.preventDefault();
342
- },
343
- Home() {
344
- if (domQuery.isModifierKey(event)) return;
345
- send({ type: "INPUT.HOME" });
346
- event.preventDefault();
347
- },
348
- End() {
349
- if (domQuery.isModifierKey(event)) return;
350
- send({ type: "INPUT.END" });
351
- event.preventDefault();
352
- },
353
- Enter(event2) {
354
- const selection = recordCursor(event2.currentTarget, scope);
355
- send({ type: "INPUT.ENTER", selection });
356
- }
357
- };
358
- const exec = keyMap[event.key];
359
- exec?.(event);
360
- }
361
- });
362
- },
363
- getDecrementTriggerProps() {
364
- return normalize.button({
365
- ...parts.decrementTrigger.attrs,
366
- dir: prop("dir"),
367
- id: getDecrementTriggerId(scope),
368
- disabled: isDecrementDisabled,
369
- "data-disabled": domQuery.dataAttr(isDecrementDisabled),
370
- "aria-label": translations.decrementLabel,
371
- type: "button",
372
- tabIndex: -1,
373
- "aria-controls": getInputId(scope),
374
- "data-scrubbing": domQuery.dataAttr(scrubbing),
375
- onPointerDown(event) {
376
- if (isDecrementDisabled) return;
377
- if (!domQuery.isLeftClick(event)) return;
378
- send({ type: "TRIGGER.PRESS_DOWN", hint: "decrement", pointerType: event.pointerType });
379
- if (event.pointerType === "mouse") {
380
- event.preventDefault();
381
- }
382
- if (event.pointerType === "touch") {
383
- event.currentTarget?.focus({ preventScroll: true });
384
- }
385
- },
386
- onPointerUp(event) {
387
- send({ type: "TRIGGER.PRESS_UP", hint: "decrement", pointerType: event.pointerType });
388
- },
389
- onPointerLeave() {
390
- if (isDecrementDisabled) return;
391
- send({ type: "TRIGGER.PRESS_UP", hint: "decrement" });
392
- }
393
- });
394
- },
395
- getIncrementTriggerProps() {
396
- return normalize.button({
397
- ...parts.incrementTrigger.attrs,
398
- dir: prop("dir"),
399
- id: getIncrementTriggerId(scope),
400
- disabled: isIncrementDisabled,
401
- "data-disabled": domQuery.dataAttr(isIncrementDisabled),
402
- "aria-label": translations.incrementLabel,
403
- type: "button",
404
- tabIndex: -1,
405
- "aria-controls": getInputId(scope),
406
- "data-scrubbing": domQuery.dataAttr(scrubbing),
407
- onPointerDown(event) {
408
- if (isIncrementDisabled || !domQuery.isLeftClick(event)) return;
409
- send({ type: "TRIGGER.PRESS_DOWN", hint: "increment", pointerType: event.pointerType });
410
- if (event.pointerType === "mouse") {
411
- event.preventDefault();
412
- }
413
- if (event.pointerType === "touch") {
414
- event.currentTarget?.focus({ preventScroll: true });
415
- }
416
- },
417
- onPointerUp(event) {
418
- send({ type: "TRIGGER.PRESS_UP", hint: "increment", pointerType: event.pointerType });
419
- },
420
- onPointerLeave(event) {
421
- send({ type: "TRIGGER.PRESS_UP", hint: "increment", pointerType: event.pointerType });
422
- }
423
- });
424
- },
425
- getScrubberProps() {
426
- return normalize.element({
427
- ...parts.scrubber.attrs,
428
- dir: prop("dir"),
429
- "data-disabled": domQuery.dataAttr(disabled),
430
- id: getScrubberId(scope),
431
- role: "presentation",
432
- "data-scrubbing": domQuery.dataAttr(scrubbing),
433
- onMouseDown(event) {
434
- if (disabled) return;
435
- if (!domQuery.isLeftClick(event)) return;
436
- const point = domQuery.getEventPoint(event);
437
- const win = domQuery.getWindow(event.currentTarget);
438
- const dpr = win.devicePixelRatio;
439
- point.x = point.x - utils.roundToDpr(7.5, dpr);
440
- point.y = point.y - utils.roundToDpr(7.5, dpr);
441
- send({ type: "SCRUBBER.PRESS_DOWN", point });
442
- event.preventDefault();
443
- domQuery.raf(() => {
444
- domQuery.setCaretToEnd(getInputEl(scope));
445
- });
446
- },
447
- style: {
448
- cursor: disabled ? void 0 : "ew-resize"
449
- }
450
- });
451
- }
452
- };
453
- }
454
- var createFormatter = (locale, options = {}) => {
455
- return new Intl.NumberFormat(locale, options);
456
- };
457
- var createParser = (locale, options = {}) => {
458
- return new number.NumberParser(locale, options);
459
- };
460
- var parseValue = (value, params) => {
461
- const { prop, computed } = params;
462
- if (!prop("formatOptions")) return parseFloat(value);
463
- if (value === "") return Number.NaN;
464
- return computed("parser").parse(value);
465
- };
466
- var formatValue = (value, params) => {
467
- const { prop, computed } = params;
468
- if (Number.isNaN(value)) return "";
469
- if (!prop("formatOptions")) return value.toString();
470
- return computed("formatter").format(value);
471
- };
472
- var getDefaultStep = (step, formatOptions) => {
473
- let defaultStep = step !== void 0 && !Number.isNaN(step) ? step : 1;
474
- if (formatOptions?.style === "percent" && (step === void 0 || Number.isNaN(step))) {
475
- defaultStep = 0.01;
476
- }
477
- return defaultStep;
478
- };
479
-
480
- // src/number-input.machine.ts
481
- var { choose, guards, createMachine } = core.setup();
482
- var { not, and } = guards;
483
- var machine = createMachine({
484
- props({ props: props2 }) {
485
- const step = getDefaultStep(props2.step, props2.formatOptions);
486
- return {
487
- dir: "ltr",
488
- locale: "en-US",
489
- focusInputOnChange: true,
490
- clampValueOnBlur: !props2.allowOverflow,
491
- allowOverflow: false,
492
- inputMode: "decimal",
493
- pattern: "-?[0-9]*(.[0-9]+)?",
494
- defaultValue: "",
495
- step,
496
- min: Number.MIN_SAFE_INTEGER,
497
- max: Number.MAX_SAFE_INTEGER,
498
- spinOnPress: true,
499
- ...props2,
500
- translations: {
501
- incrementLabel: "increment value",
502
- decrementLabel: "decrease value",
503
- ...props2.translations
504
- }
505
- };
506
- },
507
- initialState() {
508
- return "idle";
509
- },
510
- context({ prop, bindable, getComputed }) {
511
- return {
512
- value: bindable(() => ({
513
- defaultValue: prop("defaultValue"),
514
- value: prop("value"),
515
- onChange(value) {
516
- const computed = getComputed();
517
- const valueAsNumber = parseValue(value, { computed, prop });
518
- prop("onValueChange")?.({ value, valueAsNumber });
519
- }
520
- })),
521
- hint: bindable(() => ({ defaultValue: null })),
522
- scrubberCursorPoint: bindable(() => ({
523
- defaultValue: null,
524
- hash(value) {
525
- return value ? `x:${value.x}, y:${value.y}` : "";
526
- }
527
- })),
528
- fieldsetDisabled: bindable(() => ({ defaultValue: false }))
529
- };
530
- },
531
- computed: {
532
- isRtl: ({ prop }) => prop("dir") === "rtl",
533
- valueAsNumber: ({ context, computed, prop }) => parseValue(context.get("value"), { computed, prop }),
534
- formattedValue: ({ computed, prop }) => formatValue(computed("valueAsNumber"), { computed, prop }),
535
- isAtMin: ({ computed, prop }) => utils.isValueAtMin(computed("valueAsNumber"), prop("min")),
536
- isAtMax: ({ computed, prop }) => utils.isValueAtMax(computed("valueAsNumber"), prop("max")),
537
- isOutOfRange: ({ computed, prop }) => !utils.isValueWithinRange(computed("valueAsNumber"), prop("min"), prop("max")),
538
- isValueEmpty: ({ context }) => context.get("value") === "",
539
- isDisabled: ({ prop, context }) => !!prop("disabled") || context.get("fieldsetDisabled"),
540
- canIncrement: ({ prop, computed }) => prop("allowOverflow") || !computed("isAtMax"),
541
- canDecrement: ({ prop, computed }) => prop("allowOverflow") || !computed("isAtMin"),
542
- valueText: ({ prop, context }) => prop("translations").valueText?.(context.get("value")),
543
- formatter: core.memo(
544
- ({ prop }) => [prop("locale"), prop("formatOptions")],
545
- ([locale, formatOptions]) => createFormatter(locale, formatOptions)
546
- ),
547
- parser: core.memo(
548
- ({ prop }) => [prop("locale"), prop("formatOptions")],
549
- ([locale, formatOptions]) => createParser(locale, formatOptions)
550
- )
551
- },
552
- watch({ track, action, context, computed, prop }) {
553
- track([() => context.get("value"), () => prop("locale"), () => JSON.stringify(prop("formatOptions"))], () => {
554
- action(["syncInputElement"]);
555
- });
556
- track([() => computed("isOutOfRange")], () => {
557
- action(["invokeOnInvalid"]);
558
- });
559
- track([() => context.hash("scrubberCursorPoint")], () => {
560
- action(["setVirtualCursorPosition"]);
561
- });
562
- },
563
- effects: ["trackFormControl"],
564
- on: {
565
- "VALUE.SET": {
566
- actions: ["setRawValue"]
567
- },
568
- "VALUE.CLEAR": {
569
- actions: ["clearValue"]
570
- },
571
- "VALUE.INCREMENT": {
572
- actions: ["increment"]
573
- },
574
- "VALUE.DECREMENT": {
575
- actions: ["decrement"]
576
- }
577
- },
578
- states: {
579
- idle: {
580
- on: {
581
- "TRIGGER.PRESS_DOWN": [
582
- { guard: "isTouchPointer", target: "before:spin", actions: ["setHint"] },
583
- {
584
- target: "before:spin",
585
- actions: ["focusInput", "invokeOnFocus", "setHint"]
586
- }
587
- ],
588
- "SCRUBBER.PRESS_DOWN": {
589
- target: "scrubbing",
590
- actions: ["focusInput", "invokeOnFocus", "setHint", "setCursorPoint"]
591
- },
592
- "INPUT.FOCUS": {
593
- target: "focused",
594
- actions: ["focusInput", "invokeOnFocus"]
595
- }
596
- }
597
- },
598
- focused: {
599
- tags: ["focus"],
600
- effects: ["attachWheelListener"],
601
- on: {
602
- "TRIGGER.PRESS_DOWN": [
603
- { guard: "isTouchPointer", target: "before:spin", actions: ["setHint"] },
604
- { target: "before:spin", actions: ["focusInput", "setHint"] }
605
- ],
606
- "SCRUBBER.PRESS_DOWN": {
607
- target: "scrubbing",
608
- actions: ["focusInput", "setHint", "setCursorPoint"]
609
- },
610
- "INPUT.ARROW_UP": {
611
- actions: ["increment"]
612
- },
613
- "INPUT.ARROW_DOWN": {
614
- actions: ["decrement"]
615
- },
616
- "INPUT.HOME": {
617
- actions: ["decrementToMin"]
618
- },
619
- "INPUT.END": {
620
- actions: ["incrementToMax"]
621
- },
622
- "INPUT.CHANGE": {
623
- actions: ["setValue", "setHint"]
624
- },
625
- "INPUT.BLUR": [
626
- {
627
- guard: and("clampValueOnBlur", not("isInRange")),
628
- target: "idle",
629
- actions: ["setClampedValue", "clearHint", "invokeOnBlur", "invokeOnValueCommit"]
630
- },
631
- {
632
- guard: not("isInRange"),
633
- target: "idle",
634
- actions: ["setFormattedValue", "clearHint", "invokeOnBlur", "invokeOnInvalid", "invokeOnValueCommit"]
635
- },
636
- {
637
- target: "idle",
638
- actions: ["setFormattedValue", "clearHint", "invokeOnBlur", "invokeOnValueCommit"]
639
- }
640
- ],
641
- "INPUT.ENTER": {
642
- actions: ["setFormattedValue", "clearHint", "invokeOnBlur", "invokeOnValueCommit"]
643
- }
644
- }
645
- },
646
- "before:spin": {
647
- tags: ["focus"],
648
- effects: ["trackButtonDisabled", "waitForChangeDelay"],
649
- entry: choose([
650
- { guard: "isIncrementHint", actions: ["increment"] },
651
- { guard: "isDecrementHint", actions: ["decrement"] }
652
- ]),
653
- on: {
654
- CHANGE_DELAY: {
655
- target: "spinning",
656
- guard: and("isInRange", "spinOnPress")
657
- },
658
- "TRIGGER.PRESS_UP": [
659
- { guard: "isTouchPointer", target: "focused", actions: ["clearHint"] },
660
- { target: "focused", actions: ["focusInput", "clearHint"] }
661
- ]
662
- }
663
- },
664
- spinning: {
665
- tags: ["focus"],
666
- effects: ["trackButtonDisabled", "spinValue"],
667
- on: {
668
- SPIN: [
669
- {
670
- guard: "isIncrementHint",
671
- actions: ["increment"]
672
- },
673
- {
674
- guard: "isDecrementHint",
675
- actions: ["decrement"]
676
- }
677
- ],
678
- "TRIGGER.PRESS_UP": {
679
- target: "focused",
680
- actions: ["focusInput", "clearHint"]
681
- }
682
- }
683
- },
684
- scrubbing: {
685
- tags: ["focus"],
686
- effects: ["activatePointerLock", "trackMousemove", "setupVirtualCursor", "preventTextSelection"],
687
- on: {
688
- "SCRUBBER.POINTER_UP": {
689
- target: "focused",
690
- actions: ["focusInput", "clearCursorPoint"]
691
- },
692
- "SCRUBBER.POINTER_MOVE": [
693
- {
694
- guard: "isIncrementHint",
695
- actions: ["increment", "setCursorPoint"]
696
- },
697
- {
698
- guard: "isDecrementHint",
699
- actions: ["decrement", "setCursorPoint"]
700
- }
701
- ]
702
- }
703
- }
704
- },
705
- implementations: {
706
- guards: {
707
- clampValueOnBlur: ({ prop }) => prop("clampValueOnBlur"),
708
- spinOnPress: ({ prop }) => !!prop("spinOnPress"),
709
- isInRange: ({ computed }) => !computed("isOutOfRange"),
710
- isDecrementHint: ({ context, event }) => (event.hint ?? context.get("hint")) === "decrement",
711
- isIncrementHint: ({ context, event }) => (event.hint ?? context.get("hint")) === "increment",
712
- isTouchPointer: ({ event }) => event.pointerType === "touch"
713
- },
714
- effects: {
715
- waitForChangeDelay({ send }) {
716
- const id = setTimeout(() => {
717
- send({ type: "CHANGE_DELAY" });
718
- }, 300);
719
- return () => clearTimeout(id);
720
- },
721
- spinValue({ send }) {
722
- const id = setInterval(() => {
723
- send({ type: "SPIN" });
724
- }, 50);
725
- return () => clearInterval(id);
726
- },
727
- trackFormControl({ context, scope }) {
728
- const inputEl = getInputEl(scope);
729
- return domQuery.trackFormControl(inputEl, {
730
- onFieldsetDisabledChange(disabled) {
731
- context.set("fieldsetDisabled", disabled);
732
- },
733
- onFormReset() {
734
- context.set("value", context.initial("value"));
735
- }
736
- });
737
- },
738
- setupVirtualCursor({ context, scope }) {
739
- const point = context.get("scrubberCursorPoint");
740
- return setupVirtualCursor(scope, point);
741
- },
742
- preventTextSelection({ scope }) {
743
- return preventTextSelection(scope);
744
- },
745
- trackButtonDisabled({ context, scope, send }) {
746
- const hint = context.get("hint");
747
- const btn = getPressedTriggerEl(scope, hint);
748
- return domQuery.observeAttributes(btn, {
749
- attributes: ["disabled"],
750
- callback() {
751
- send({ type: "TRIGGER.PRESS_UP", src: "attr" });
752
- }
753
- });
754
- },
755
- attachWheelListener({ scope, send, prop }) {
756
- const inputEl = getInputEl(scope);
757
- if (!inputEl || !scope.isActiveElement(inputEl) || !prop("allowMouseWheel")) return;
758
- function onWheel(event) {
759
- event.preventDefault();
760
- const dir = Math.sign(event.deltaY) * -1;
761
- if (dir === 1) {
762
- send({ type: "VALUE.INCREMENT" });
763
- } else if (dir === -1) {
764
- send({ type: "VALUE.DECREMENT" });
765
- }
766
- }
767
- return domQuery.addDomEvent(inputEl, "wheel", onWheel, { passive: false });
768
- },
769
- activatePointerLock({ scope }) {
770
- if (domQuery.isSafari()) return;
771
- return domQuery.requestPointerLock(scope.getDoc());
772
- },
773
- trackMousemove({ scope, send, context, computed }) {
774
- const doc = scope.getDoc();
775
- function onMousemove(event) {
776
- const point = context.get("scrubberCursorPoint");
777
- const isRtl = computed("isRtl");
778
- const value = getMousemoveValue(scope, { point, isRtl, event });
779
- if (!value.hint) return;
780
- send({
781
- type: "SCRUBBER.POINTER_MOVE",
782
- hint: value.hint,
783
- point: value.point
784
- });
785
- }
786
- function onMouseup() {
787
- send({ type: "SCRUBBER.POINTER_UP" });
788
- }
789
- return utils.callAll(domQuery.addDomEvent(doc, "mousemove", onMousemove, false), domQuery.addDomEvent(doc, "mouseup", onMouseup, false));
790
- }
791
- },
792
- actions: {
793
- focusInput({ scope, prop }) {
794
- if (!prop("focusInputOnChange")) return;
795
- const inputEl = getInputEl(scope);
796
- if (scope.isActiveElement(inputEl)) return;
797
- domQuery.raf(() => inputEl?.focus({ preventScroll: true }));
798
- },
799
- increment({ context, event, prop, computed }) {
800
- let nextValue = utils.incrementValue(computed("valueAsNumber"), event.step ?? prop("step"));
801
- if (!prop("allowOverflow")) nextValue = utils.clampValue(nextValue, prop("min"), prop("max"));
802
- context.set("value", formatValue(nextValue, { computed, prop }));
803
- },
804
- decrement({ context, event, prop, computed }) {
805
- let nextValue = utils.decrementValue(computed("valueAsNumber"), event.step ?? prop("step"));
806
- if (!prop("allowOverflow")) nextValue = utils.clampValue(nextValue, prop("min"), prop("max"));
807
- context.set("value", formatValue(nextValue, { computed, prop }));
808
- },
809
- setClampedValue({ context, prop, computed }) {
810
- const nextValue = utils.clampValue(computed("valueAsNumber"), prop("min"), prop("max"));
811
- context.set("value", formatValue(nextValue, { computed, prop }));
812
- },
813
- setRawValue({ context, event, prop, computed }) {
814
- let nextValue = parseValue(event.value, { computed, prop });
815
- if (!prop("allowOverflow")) nextValue = utils.clampValue(nextValue, prop("min"), prop("max"));
816
- context.set("value", formatValue(nextValue, { computed, prop }));
817
- },
818
- setValue({ context, event }) {
819
- const value = event.target?.value ?? event.value;
820
- context.set("value", value);
821
- },
822
- clearValue({ context }) {
823
- context.set("value", "");
824
- },
825
- incrementToMax({ context, prop, computed }) {
826
- const value = formatValue(prop("max"), { computed, prop });
827
- context.set("value", value);
828
- },
829
- decrementToMin({ context, prop, computed }) {
830
- const value = formatValue(prop("min"), { computed, prop });
831
- context.set("value", value);
832
- },
833
- setHint({ context, event }) {
834
- context.set("hint", event.hint);
835
- },
836
- clearHint({ context }) {
837
- context.set("hint", null);
838
- },
839
- invokeOnFocus({ computed, prop }) {
840
- prop("onFocusChange")?.({
841
- focused: true,
842
- value: computed("formattedValue"),
843
- valueAsNumber: computed("valueAsNumber")
844
- });
845
- },
846
- invokeOnBlur({ computed, prop }) {
847
- prop("onFocusChange")?.({
848
- focused: false,
849
- value: computed("formattedValue"),
850
- valueAsNumber: computed("valueAsNumber")
851
- });
852
- },
853
- invokeOnInvalid({ computed, prop, event }) {
854
- if (event.type === "INPUT.CHANGE") return;
855
- const reason = computed("valueAsNumber") > prop("max") ? "rangeOverflow" : "rangeUnderflow";
856
- prop("onValueInvalid")?.({
857
- reason,
858
- value: computed("formattedValue"),
859
- valueAsNumber: computed("valueAsNumber")
860
- });
861
- },
862
- invokeOnValueCommit({ computed, prop }) {
863
- prop("onValueCommit")?.({
864
- value: computed("formattedValue"),
865
- valueAsNumber: computed("valueAsNumber")
866
- });
867
- },
868
- syncInputElement({ context, event, computed, scope }) {
869
- const value = event.type.endsWith("CHANGE") ? context.get("value") : computed("formattedValue");
870
- const inputEl = getInputEl(scope);
871
- const sel = event.selection ?? recordCursor(inputEl, scope);
872
- domQuery.raf(() => {
873
- domQuery.setElementValue(inputEl, value);
874
- restoreCursor(inputEl, sel, scope);
875
- });
876
- },
877
- setFormattedValue({ context, computed, action }) {
878
- context.set("value", computed("formattedValue"));
879
- action(["syncInputElement"]);
880
- },
881
- setCursorPoint({ context, event }) {
882
- context.set("scrubberCursorPoint", event.point);
883
- },
884
- clearCursorPoint({ context }) {
885
- context.set("scrubberCursorPoint", null);
886
- },
887
- setVirtualCursorPosition({ context, scope }) {
888
- const cursorEl = getCursorEl(scope);
889
- const point = context.get("scrubberCursorPoint");
890
- if (!cursorEl || !point) return;
891
- cursorEl.style.transform = `translate3d(${point.x}px, ${point.y}px, 0px)`;
892
- }
893
- }
894
- }
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ anatomy: () => import_number_input.anatomy,
25
+ connect: () => import_number_input2.connect,
26
+ machine: () => import_number_input3.machine
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+ var import_number_input = require("./number-input.anatomy.cjs");
30
+ var import_number_input2 = require("./number-input.connect.cjs");
31
+ var import_number_input3 = require("./number-input.machine.cjs");
32
+ __reExport(index_exports, require("./number-input.props.cjs"), module.exports);
33
+ // Annotate the CommonJS export names for ESM import in node:
34
+ 0 && (module.exports = {
35
+ anatomy,
36
+ connect,
37
+ machine,
38
+ ...require("./number-input.props.cjs")
895
39
  });
896
- var props = types.createProps()([
897
- "allowMouseWheel",
898
- "allowOverflow",
899
- "clampValueOnBlur",
900
- "dir",
901
- "disabled",
902
- "focusInputOnChange",
903
- "form",
904
- "formatOptions",
905
- "getRootNode",
906
- "id",
907
- "ids",
908
- "inputMode",
909
- "invalid",
910
- "locale",
911
- "max",
912
- "min",
913
- "name",
914
- "onFocusChange",
915
- "onValueChange",
916
- "onValueCommit",
917
- "onValueInvalid",
918
- "pattern",
919
- "required",
920
- "readOnly",
921
- "spinOnPress",
922
- "step",
923
- "translations",
924
- "value",
925
- "defaultValue"
926
- ]);
927
- var splitProps = utils.createSplitProps(props);
928
-
929
- exports.anatomy = anatomy;
930
- exports.connect = connect;
931
- exports.machine = machine;
932
- exports.props = props;
933
- exports.splitProps = splitProps;