@zag-js/number-input 0.20.0 → 0.22.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.d.mts +9 -26
- package/dist/index.d.ts +9 -26
- package/dist/index.js +260 -176
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +249 -165
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -9
- package/src/cursor.ts +51 -0
- package/src/number-input.anatomy.ts +1 -0
- package/src/number-input.connect.ts +78 -46
- package/src/number-input.machine.ts +138 -83
- package/src/number-input.types.ts +30 -26
- package/src/number-input.utils.ts +0 -42
package/dist/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ var parts = anatomy.build();
|
|
|
13
13
|
|
|
14
14
|
// src/number-input.connect.ts
|
|
15
15
|
import { getEventPoint, getEventStep, getNativeEvent, isLeftClick } from "@zag-js/dom-event";
|
|
16
|
-
import { ariaAttr, dataAttr } from "@zag-js/dom-query";
|
|
16
|
+
import { ariaAttr, dataAttr, isHTMLElement } from "@zag-js/dom-query";
|
|
17
17
|
import { roundToDevicePixel as roundToDevicePixel2 } from "@zag-js/number-utils";
|
|
18
18
|
|
|
19
19
|
// src/number-input.dom.ts
|
|
@@ -114,54 +114,15 @@ var dom = createScope({
|
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
-
// src/number-input.utils.ts
|
|
118
|
-
import { isModifiedEvent } from "@zag-js/dom-event";
|
|
119
|
-
import { clamp, decrement, formatDecimal, increment } from "@zag-js/number-utils";
|
|
120
|
-
var utils = {
|
|
121
|
-
isValidNumericEvent: (ctx, event) => {
|
|
122
|
-
if (event.key == null)
|
|
123
|
-
return true;
|
|
124
|
-
const isModifier = isModifiedEvent(event);
|
|
125
|
-
const isSingleKey = event.key.length === 1;
|
|
126
|
-
if (isModifier || !isSingleKey)
|
|
127
|
-
return true;
|
|
128
|
-
return ctx.validateCharacter?.(event.key) ?? utils.isFloatingPoint(event.key);
|
|
129
|
-
},
|
|
130
|
-
isFloatingPoint: (v) => /^[0-9+\-.]$/.test(v),
|
|
131
|
-
sanitize: (ctx, value) => {
|
|
132
|
-
return value.split("").filter(ctx.validateCharacter ?? utils.isFloatingPoint).join("");
|
|
133
|
-
},
|
|
134
|
-
increment: (ctx, step) => {
|
|
135
|
-
const value = increment(ctx.value, step ?? ctx.step);
|
|
136
|
-
return formatDecimal(clamp(value, ctx), ctx);
|
|
137
|
-
},
|
|
138
|
-
decrement: (ctx, step) => {
|
|
139
|
-
const value = decrement(ctx.value, step ?? ctx.step);
|
|
140
|
-
return formatDecimal(clamp(value, ctx), ctx);
|
|
141
|
-
},
|
|
142
|
-
clamp: (ctx) => {
|
|
143
|
-
return formatDecimal(clamp(ctx.value, ctx), ctx);
|
|
144
|
-
},
|
|
145
|
-
parse: (ctx, value) => {
|
|
146
|
-
return ctx.parse?.(value) ?? value;
|
|
147
|
-
},
|
|
148
|
-
format: (ctx, value) => {
|
|
149
|
-
const _val = value.toString();
|
|
150
|
-
return ctx.format?.(_val) ?? _val;
|
|
151
|
-
},
|
|
152
|
-
round: (ctx) => {
|
|
153
|
-
return formatDecimal(ctx.value, ctx);
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
|
|
157
117
|
// src/number-input.connect.ts
|
|
158
118
|
function connect(state, send, normalize) {
|
|
159
119
|
const isFocused = state.hasTag("focus");
|
|
160
120
|
const isInvalid = state.context.isOutOfRange || !!state.context.invalid;
|
|
161
|
-
const isDisabled = !!state.context.disabled;
|
|
162
121
|
const isValueEmpty = state.context.isValueEmpty;
|
|
163
|
-
const
|
|
164
|
-
const
|
|
122
|
+
const isDisabled = state.context.isDisabled;
|
|
123
|
+
const isReadOnly = state.context.readOnly;
|
|
124
|
+
const isIncrementDisabled = isDisabled || !state.context.canIncrement || isReadOnly;
|
|
125
|
+
const isDecrementDisabled = isDisabled || !state.context.canDecrement || isReadOnly;
|
|
165
126
|
const translations = state.context.translations;
|
|
166
127
|
return {
|
|
167
128
|
isFocused,
|
|
@@ -170,38 +131,37 @@ function connect(state, send, normalize) {
|
|
|
170
131
|
value: state.context.formattedValue,
|
|
171
132
|
valueAsNumber: state.context.valueAsNumber,
|
|
172
133
|
setValue(value) {
|
|
173
|
-
send({ type: "
|
|
134
|
+
send({ type: "VALUE.SET", value: value.toString() });
|
|
174
135
|
},
|
|
175
136
|
clearValue() {
|
|
176
|
-
send("
|
|
137
|
+
send("VALUE.CLEAR");
|
|
177
138
|
},
|
|
178
139
|
increment() {
|
|
179
|
-
send("INCREMENT");
|
|
140
|
+
send("VALUE.INCREMENT");
|
|
180
141
|
},
|
|
181
142
|
decrement() {
|
|
182
|
-
send("DECREMENT");
|
|
143
|
+
send("VALUE.DECREMENT");
|
|
183
144
|
},
|
|
184
145
|
setToMax() {
|
|
185
|
-
send({ type: "
|
|
146
|
+
send({ type: "VALUE.SET", value: state.context.max });
|
|
186
147
|
},
|
|
187
148
|
setToMin() {
|
|
188
|
-
send({ type: "
|
|
149
|
+
send({ type: "VALUE.SET", value: state.context.min });
|
|
189
150
|
},
|
|
190
151
|
focus() {
|
|
191
152
|
dom.getInputEl(state.context)?.focus();
|
|
192
153
|
},
|
|
193
|
-
blur() {
|
|
194
|
-
dom.getInputEl(state.context)?.blur();
|
|
195
|
-
},
|
|
196
154
|
rootProps: normalize.element({
|
|
197
155
|
id: dom.getRootId(state.context),
|
|
198
156
|
...parts.root.attrs,
|
|
157
|
+
dir: state.context.dir,
|
|
199
158
|
"data-disabled": dataAttr(isDisabled),
|
|
200
159
|
"data-focus": dataAttr(isFocused),
|
|
201
160
|
"data-invalid": dataAttr(isInvalid)
|
|
202
161
|
}),
|
|
203
162
|
labelProps: normalize.label({
|
|
204
163
|
...parts.label.attrs,
|
|
164
|
+
dir: state.context.dir,
|
|
205
165
|
"data-disabled": dataAttr(isDisabled),
|
|
206
166
|
"data-focus": dataAttr(isFocused),
|
|
207
167
|
"data-invalid": dataAttr(isInvalid),
|
|
@@ -210,6 +170,7 @@ function connect(state, send, normalize) {
|
|
|
210
170
|
}),
|
|
211
171
|
controlProps: normalize.element({
|
|
212
172
|
...parts.control.attrs,
|
|
173
|
+
dir: state.context.dir,
|
|
213
174
|
role: "group",
|
|
214
175
|
"aria-disabled": isDisabled,
|
|
215
176
|
"data-focus": dataAttr(isFocused),
|
|
@@ -219,6 +180,7 @@ function connect(state, send, normalize) {
|
|
|
219
180
|
}),
|
|
220
181
|
inputProps: normalize.input({
|
|
221
182
|
...parts.input.attrs,
|
|
183
|
+
dir: state.context.dir,
|
|
222
184
|
name: state.context.name,
|
|
223
185
|
form: state.context.form,
|
|
224
186
|
id: dom.getInputId(state.context),
|
|
@@ -238,48 +200,68 @@ function connect(state, send, normalize) {
|
|
|
238
200
|
"aria-roledescription": "numberfield",
|
|
239
201
|
"aria-valuemin": state.context.min,
|
|
240
202
|
"aria-valuemax": state.context.max,
|
|
241
|
-
"aria-valuenow": isNaN(state.context.valueAsNumber) ? void 0 : state.context.valueAsNumber,
|
|
203
|
+
"aria-valuenow": Number.isNaN(state.context.valueAsNumber) ? void 0 : state.context.valueAsNumber,
|
|
242
204
|
"aria-valuetext": state.context.valueText,
|
|
205
|
+
onCompositionStart() {
|
|
206
|
+
send("INPUT.COMPOSITION_START");
|
|
207
|
+
},
|
|
208
|
+
onCompositionEnd() {
|
|
209
|
+
send("INPUT.COMPOSITION_END");
|
|
210
|
+
},
|
|
243
211
|
onFocus() {
|
|
244
|
-
send("FOCUS");
|
|
212
|
+
send("INPUT.FOCUS");
|
|
245
213
|
},
|
|
246
214
|
onBlur() {
|
|
247
|
-
send("
|
|
215
|
+
send({ type: "INPUT.COMMIT", src: "blur" });
|
|
248
216
|
},
|
|
249
217
|
onChange(event) {
|
|
250
|
-
send({ type: "CHANGE", target: event.currentTarget, hint: "set" });
|
|
218
|
+
send({ type: "INPUT.CHANGE", target: event.currentTarget, hint: "set" });
|
|
219
|
+
},
|
|
220
|
+
onBeforeInput(event) {
|
|
221
|
+
try {
|
|
222
|
+
const { selectionStart, selectionEnd, value } = event.currentTarget;
|
|
223
|
+
const nextValue = value.slice(0, selectionStart) + event.data + value.slice(selectionEnd);
|
|
224
|
+
const isValid = state.context.parser.isValidPartialNumber(nextValue);
|
|
225
|
+
if (!isValid) {
|
|
226
|
+
event.preventDefault();
|
|
227
|
+
}
|
|
228
|
+
} catch {
|
|
229
|
+
}
|
|
251
230
|
},
|
|
252
231
|
onKeyDown(event) {
|
|
253
|
-
|
|
254
|
-
if (evt.isComposing)
|
|
232
|
+
if (state.context.readOnly)
|
|
255
233
|
return;
|
|
256
|
-
if (!utils.isValidNumericEvent(state.context, event)) {
|
|
257
|
-
event.preventDefault();
|
|
258
|
-
}
|
|
259
234
|
const step = getEventStep(event) * state.context.step;
|
|
260
235
|
const keyMap = {
|
|
261
236
|
ArrowUp() {
|
|
262
|
-
send({ type: "ARROW_UP", step });
|
|
237
|
+
send({ type: "INPUT.ARROW_UP", step });
|
|
238
|
+
event.preventDefault();
|
|
263
239
|
},
|
|
264
240
|
ArrowDown() {
|
|
265
|
-
send({ type: "ARROW_DOWN", step });
|
|
241
|
+
send({ type: "INPUT.ARROW_DOWN", step });
|
|
242
|
+
event.preventDefault();
|
|
266
243
|
},
|
|
267
244
|
Home() {
|
|
268
|
-
send("HOME");
|
|
245
|
+
send("INPUT.HOME");
|
|
246
|
+
event.preventDefault();
|
|
269
247
|
},
|
|
270
248
|
End() {
|
|
271
|
-
send("END");
|
|
249
|
+
send("INPUT.END");
|
|
250
|
+
event.preventDefault();
|
|
251
|
+
},
|
|
252
|
+
Enter() {
|
|
253
|
+
if (state.context.composing)
|
|
254
|
+
return;
|
|
255
|
+
send({ type: "INPUT.COMMIT", src: "enter" });
|
|
272
256
|
}
|
|
273
257
|
};
|
|
274
258
|
const exec = keyMap[event.key];
|
|
275
|
-
|
|
276
|
-
exec(event);
|
|
277
|
-
event.preventDefault();
|
|
278
|
-
}
|
|
259
|
+
exec?.(event);
|
|
279
260
|
}
|
|
280
261
|
}),
|
|
281
262
|
decrementTriggerProps: normalize.button({
|
|
282
263
|
...parts.decrementTrigger.attrs,
|
|
264
|
+
dir: state.context.dir,
|
|
283
265
|
id: dom.getDecrementTriggerId(state.context),
|
|
284
266
|
disabled: isDecrementDisabled,
|
|
285
267
|
"data-disabled": dataAttr(isDecrementDisabled),
|
|
@@ -288,22 +270,28 @@ function connect(state, send, normalize) {
|
|
|
288
270
|
tabIndex: -1,
|
|
289
271
|
"aria-controls": dom.getInputId(state.context),
|
|
290
272
|
onPointerDown(event) {
|
|
291
|
-
if (isDecrementDisabled)
|
|
273
|
+
if (isDecrementDisabled || !isLeftClick(event))
|
|
292
274
|
return;
|
|
293
|
-
|
|
294
|
-
|
|
275
|
+
if (event.pointerType === "mouse") {
|
|
276
|
+
send({ type: "TRIGGER.PRESS_DOWN", hint: "decrement" });
|
|
277
|
+
return event.preventDefault();
|
|
278
|
+
}
|
|
279
|
+
if (isHTMLElement(event.target)) {
|
|
280
|
+
event.target?.focus();
|
|
281
|
+
}
|
|
295
282
|
},
|
|
296
283
|
onPointerUp() {
|
|
297
|
-
send({ type: "PRESS_UP", hint: "decrement" });
|
|
284
|
+
send({ type: "TRIGGER.PRESS_UP", hint: "decrement" });
|
|
298
285
|
},
|
|
299
286
|
onPointerLeave() {
|
|
300
287
|
if (isDecrementDisabled)
|
|
301
288
|
return;
|
|
302
|
-
send({ type: "PRESS_UP", hint: "decrement" });
|
|
289
|
+
send({ type: "TRIGGER.PRESS_UP", hint: "decrement" });
|
|
303
290
|
}
|
|
304
291
|
}),
|
|
305
292
|
incrementTriggerProps: normalize.button({
|
|
306
293
|
...parts.incrementTrigger.attrs,
|
|
294
|
+
dir: state.context.dir,
|
|
307
295
|
id: dom.getIncrementTriggerId(state.context),
|
|
308
296
|
disabled: isIncrementDisabled,
|
|
309
297
|
"data-disabled": dataAttr(isIncrementDisabled),
|
|
@@ -312,16 +300,21 @@ function connect(state, send, normalize) {
|
|
|
312
300
|
tabIndex: -1,
|
|
313
301
|
"aria-controls": dom.getInputId(state.context),
|
|
314
302
|
onPointerDown(event) {
|
|
315
|
-
if (isIncrementDisabled)
|
|
303
|
+
if (isIncrementDisabled || !isLeftClick(event))
|
|
316
304
|
return;
|
|
317
|
-
|
|
318
|
-
|
|
305
|
+
if (event.pointerType === "mouse") {
|
|
306
|
+
send({ type: "TRIGGER.PRESS_DOWN", hint: "increment" });
|
|
307
|
+
return event.preventDefault();
|
|
308
|
+
}
|
|
309
|
+
if (isHTMLElement(event.target)) {
|
|
310
|
+
event.target?.focus();
|
|
311
|
+
}
|
|
319
312
|
},
|
|
320
313
|
onPointerUp() {
|
|
321
|
-
send({ type: "PRESS_UP", hint: "increment" });
|
|
314
|
+
send({ type: "TRIGGER.PRESS_UP", hint: "increment" });
|
|
322
315
|
},
|
|
323
316
|
onPointerLeave() {
|
|
324
|
-
send({ type: "PRESS_UP", hint: "increment" });
|
|
317
|
+
send({ type: "TRIGGER.PRESS_UP", hint: "increment" });
|
|
325
318
|
}
|
|
326
319
|
}),
|
|
327
320
|
scrubberProps: normalize.element({
|
|
@@ -336,7 +329,7 @@ function connect(state, send, normalize) {
|
|
|
336
329
|
const point = getEventPoint(evt);
|
|
337
330
|
point.x = point.x - roundToDevicePixel2(7.5);
|
|
338
331
|
point.y = point.y - roundToDevicePixel2(7.5);
|
|
339
|
-
send({ type: "
|
|
332
|
+
send({ type: "SCRUBBER.PRESS_DOWN", point });
|
|
340
333
|
event.preventDefault();
|
|
341
334
|
},
|
|
342
335
|
style: {
|
|
@@ -347,12 +340,57 @@ function connect(state, send, normalize) {
|
|
|
347
340
|
}
|
|
348
341
|
|
|
349
342
|
// src/number-input.machine.ts
|
|
350
|
-
import {
|
|
343
|
+
import { NumberParser } from "@internationalized/number";
|
|
344
|
+
import { choose, createMachine, guards, ref } from "@zag-js/core";
|
|
351
345
|
import { addDomEvent, requestPointerLock } from "@zag-js/dom-event";
|
|
352
346
|
import { isSafari as isSafari2, raf } from "@zag-js/dom-query";
|
|
347
|
+
import { trackFormControl } from "@zag-js/form-utils";
|
|
353
348
|
import { observeAttributes } from "@zag-js/mutation-observer";
|
|
354
|
-
import { isAtMax, isAtMin, isWithinRange
|
|
355
|
-
import { callAll, compact, isEqual
|
|
349
|
+
import { clamp, decrement, increment, isAtMax, isAtMin, isWithinRange } from "@zag-js/number-utils";
|
|
350
|
+
import { callAll, compact, isEqual } from "@zag-js/utils";
|
|
351
|
+
|
|
352
|
+
// src/cursor.ts
|
|
353
|
+
function recordCursor(inputEl) {
|
|
354
|
+
if (inputEl.ownerDocument.activeElement !== inputEl)
|
|
355
|
+
return;
|
|
356
|
+
try {
|
|
357
|
+
const { selectionStart: start, selectionEnd: end, value } = inputEl;
|
|
358
|
+
const beforeTxt = value.substring(0, start);
|
|
359
|
+
const afterTxt = value.substring(end);
|
|
360
|
+
return {
|
|
361
|
+
start,
|
|
362
|
+
end,
|
|
363
|
+
value,
|
|
364
|
+
beforeTxt,
|
|
365
|
+
afterTxt
|
|
366
|
+
};
|
|
367
|
+
} catch {
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
function restoreCursor(inputEl, selection) {
|
|
371
|
+
if (inputEl.ownerDocument.activeElement !== inputEl || !selection)
|
|
372
|
+
return;
|
|
373
|
+
try {
|
|
374
|
+
const { value } = inputEl;
|
|
375
|
+
const { beforeTxt = "", afterTxt = "", start } = selection;
|
|
376
|
+
let startPos = value.length;
|
|
377
|
+
if (value.endsWith(afterTxt)) {
|
|
378
|
+
startPos = value.length - afterTxt.length;
|
|
379
|
+
} else if (value.startsWith(beforeTxt)) {
|
|
380
|
+
startPos = beforeTxt.length;
|
|
381
|
+
} else if (start != null) {
|
|
382
|
+
const beforeLastChar = beforeTxt[start - 1];
|
|
383
|
+
const newIndex = value.indexOf(beforeLastChar, start - 1);
|
|
384
|
+
if (newIndex !== -1) {
|
|
385
|
+
startPos = newIndex + 1;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
inputEl.setSelectionRange(startPos, startPos);
|
|
389
|
+
} catch {
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// src/number-input.machine.ts
|
|
356
394
|
var { not, and } = guards;
|
|
357
395
|
function machine(userContext) {
|
|
358
396
|
const ctx = compact(userContext);
|
|
@@ -362,20 +400,25 @@ function machine(userContext) {
|
|
|
362
400
|
initial: "idle",
|
|
363
401
|
context: {
|
|
364
402
|
dir: "ltr",
|
|
403
|
+
locale: "en-US",
|
|
365
404
|
focusInputOnChange: true,
|
|
366
405
|
clampValueOnBlur: true,
|
|
367
406
|
allowOverflow: false,
|
|
368
407
|
inputMode: "decimal",
|
|
369
408
|
pattern: "[0-9]*(.[0-9]+)?",
|
|
370
|
-
hint: null,
|
|
371
409
|
value: "",
|
|
372
410
|
step: 1,
|
|
373
411
|
min: Number.MIN_SAFE_INTEGER,
|
|
374
412
|
max: Number.MAX_SAFE_INTEGER,
|
|
375
|
-
scrubberCursorPoint: null,
|
|
376
413
|
invalid: false,
|
|
377
414
|
spinOnPress: true,
|
|
378
415
|
...ctx,
|
|
416
|
+
hint: null,
|
|
417
|
+
scrubberCursorPoint: null,
|
|
418
|
+
composing: false,
|
|
419
|
+
fieldsetDisabled: false,
|
|
420
|
+
formatter: createFormatter(ctx.locale || "en-US", ctx.formatOptions),
|
|
421
|
+
parser: createParser(ctx.locale || "en-US", ctx.formatOptions),
|
|
379
422
|
translations: {
|
|
380
423
|
incrementLabel: "increment value",
|
|
381
424
|
decrementLabel: "decrease value",
|
|
@@ -384,48 +427,56 @@ function machine(userContext) {
|
|
|
384
427
|
},
|
|
385
428
|
computed: {
|
|
386
429
|
isRtl: (ctx2) => ctx2.dir === "rtl",
|
|
387
|
-
valueAsNumber: (ctx2) =>
|
|
430
|
+
valueAsNumber: (ctx2) => ctx2.parser.parse(String(ctx2.value)) ?? 0,
|
|
388
431
|
isAtMin: (ctx2) => isAtMin(ctx2.value, ctx2),
|
|
389
432
|
isAtMax: (ctx2) => isAtMax(ctx2.value, ctx2),
|
|
390
433
|
isOutOfRange: (ctx2) => !isWithinRange(ctx2.value, ctx2),
|
|
391
434
|
isValueEmpty: (ctx2) => ctx2.value === "",
|
|
435
|
+
isDisabled: (ctx2) => !!ctx2.disabled || ctx2.fieldsetDisabled,
|
|
392
436
|
canIncrement: (ctx2) => ctx2.allowOverflow || !ctx2.isAtMax,
|
|
393
437
|
canDecrement: (ctx2) => ctx2.allowOverflow || !ctx2.isAtMin,
|
|
394
438
|
valueText: (ctx2) => ctx2.translations.valueText?.(ctx2.value),
|
|
395
|
-
formattedValue: (ctx2) =>
|
|
439
|
+
formattedValue: (ctx2) => {
|
|
440
|
+
if (Number.isNaN(ctx2.valueAsNumber))
|
|
441
|
+
return ctx2.value;
|
|
442
|
+
return ctx2.formatter.format(ctx2.valueAsNumber);
|
|
443
|
+
}
|
|
396
444
|
},
|
|
397
445
|
watch: {
|
|
446
|
+
formatOptions: ["setFormatterAndParser", "syncInputElement"],
|
|
447
|
+
locale: ["setFormatterAndParser", "syncInputElement"],
|
|
398
448
|
value: ["syncInputElement"],
|
|
399
449
|
isOutOfRange: ["invokeOnInvalid"],
|
|
400
450
|
scrubberCursorPoint: ["setVirtualCursorPosition"]
|
|
401
451
|
},
|
|
402
452
|
entry: ["syncInputValue"],
|
|
453
|
+
activities: ["trackFormControl"],
|
|
403
454
|
on: {
|
|
404
|
-
|
|
455
|
+
"VALUE.SET": {
|
|
405
456
|
actions: ["setValue", "clampValue", "setHintToSet"]
|
|
406
457
|
},
|
|
407
|
-
|
|
458
|
+
"VALUE.CLEAR": {
|
|
408
459
|
actions: ["clearValue"]
|
|
409
460
|
},
|
|
410
|
-
INCREMENT: {
|
|
461
|
+
"VALUE.INCREMENT": {
|
|
411
462
|
actions: ["increment"]
|
|
412
463
|
},
|
|
413
|
-
DECREMENT: {
|
|
464
|
+
"VALUE.DECREMENT": {
|
|
414
465
|
actions: ["decrement"]
|
|
415
466
|
}
|
|
416
467
|
},
|
|
417
468
|
states: {
|
|
418
469
|
idle: {
|
|
419
470
|
on: {
|
|
420
|
-
PRESS_DOWN: {
|
|
471
|
+
"TRIGGER.PRESS_DOWN": {
|
|
421
472
|
target: "before:spin",
|
|
422
473
|
actions: ["focusInput", "invokeOnFocus", "setHint"]
|
|
423
474
|
},
|
|
424
|
-
|
|
475
|
+
"SCRUBBER.PRESS_DOWN": {
|
|
425
476
|
target: "scrubbing",
|
|
426
477
|
actions: ["focusInput", "invokeOnFocus", "setHint", "setCursorPoint"]
|
|
427
478
|
},
|
|
428
|
-
FOCUS: {
|
|
479
|
+
"INPUT.FOCUS": {
|
|
429
480
|
target: "focused",
|
|
430
481
|
actions: ["focusInput", "invokeOnFocus"]
|
|
431
482
|
}
|
|
@@ -436,45 +487,46 @@ function machine(userContext) {
|
|
|
436
487
|
entry: "focusInput",
|
|
437
488
|
activities: "attachWheelListener",
|
|
438
489
|
on: {
|
|
439
|
-
PRESS_DOWN: {
|
|
490
|
+
"TRIGGER.PRESS_DOWN": {
|
|
440
491
|
target: "before:spin",
|
|
441
492
|
actions: ["focusInput", "setHint"]
|
|
442
493
|
},
|
|
443
|
-
|
|
494
|
+
"SCRUBBER.PRESS_DOWN": {
|
|
444
495
|
target: "scrubbing",
|
|
445
496
|
actions: ["focusInput", "setHint", "setCursorPoint"]
|
|
446
497
|
},
|
|
447
|
-
ARROW_UP: {
|
|
498
|
+
"INPUT.ARROW_UP": {
|
|
448
499
|
actions: "increment"
|
|
449
500
|
},
|
|
450
|
-
ARROW_DOWN: {
|
|
501
|
+
"INPUT.ARROW_DOWN": {
|
|
451
502
|
actions: "decrement"
|
|
452
503
|
},
|
|
453
|
-
HOME: {
|
|
454
|
-
actions: "
|
|
504
|
+
"INPUT.HOME": {
|
|
505
|
+
actions: "decrementToMin"
|
|
455
506
|
},
|
|
456
|
-
END: {
|
|
457
|
-
actions: "
|
|
507
|
+
"INPUT.END": {
|
|
508
|
+
actions: "incrementToMax"
|
|
458
509
|
},
|
|
459
|
-
CHANGE: {
|
|
510
|
+
"INPUT.CHANGE": {
|
|
460
511
|
actions: ["setValue", "setHint"]
|
|
461
512
|
},
|
|
462
|
-
|
|
463
|
-
{
|
|
464
|
-
guard: "isInvalidExponential",
|
|
465
|
-
target: "idle",
|
|
466
|
-
actions: ["clearValue", "clearHint", "invokeOnBlur"]
|
|
467
|
-
},
|
|
513
|
+
"INPUT.COMMIT": [
|
|
468
514
|
{
|
|
469
|
-
guard: and("
|
|
515
|
+
guard: and("clampValueOnBlur", not("isInRange")),
|
|
470
516
|
target: "idle",
|
|
471
|
-
actions: ["clampValue", "clearHint", "invokeOnBlur"]
|
|
517
|
+
actions: ["clampValue", "syncInputElement", "clearHint", "invokeOnBlur"]
|
|
472
518
|
},
|
|
473
519
|
{
|
|
474
520
|
target: "idle",
|
|
475
|
-
actions: ["
|
|
521
|
+
actions: ["syncInputElement", "invokeOnBlur"]
|
|
476
522
|
}
|
|
477
|
-
]
|
|
523
|
+
],
|
|
524
|
+
"INPUT.COMPOSITION_START": {
|
|
525
|
+
actions: "setComposing"
|
|
526
|
+
},
|
|
527
|
+
"INPUT.COMPOSITION_END": {
|
|
528
|
+
actions: "clearComposing"
|
|
529
|
+
}
|
|
478
530
|
}
|
|
479
531
|
},
|
|
480
532
|
"before:spin": {
|
|
@@ -491,7 +543,7 @@ function machine(userContext) {
|
|
|
491
543
|
}
|
|
492
544
|
},
|
|
493
545
|
on: {
|
|
494
|
-
PRESS_UP: {
|
|
546
|
+
"TRIGGER.PRESS_UP": {
|
|
495
547
|
target: "focused",
|
|
496
548
|
actions: "clearHint"
|
|
497
549
|
}
|
|
@@ -513,7 +565,7 @@ function machine(userContext) {
|
|
|
513
565
|
}
|
|
514
566
|
],
|
|
515
567
|
on: {
|
|
516
|
-
PRESS_UP: {
|
|
568
|
+
"TRIGGER.PRESS_UP": {
|
|
517
569
|
target: "focused",
|
|
518
570
|
actions: "clearHint"
|
|
519
571
|
}
|
|
@@ -524,8 +576,8 @@ function machine(userContext) {
|
|
|
524
576
|
exit: "clearCursorPoint",
|
|
525
577
|
activities: ["activatePointerLock", "trackMousemove", "setupVirtualCursor", "preventTextSelection"],
|
|
526
578
|
on: {
|
|
527
|
-
|
|
528
|
-
|
|
579
|
+
"SCRUBBER.POINTER_UP": "focused",
|
|
580
|
+
"SCRUBBER.POINTER_MOVE": [
|
|
529
581
|
{
|
|
530
582
|
guard: "isIncrementHint",
|
|
531
583
|
actions: ["increment", "setCursorPoint"]
|
|
@@ -545,17 +597,26 @@ function machine(userContext) {
|
|
|
545
597
|
CHANGE_DELAY: 300
|
|
546
598
|
},
|
|
547
599
|
guards: {
|
|
548
|
-
|
|
600
|
+
clampValueOnBlur: (ctx2) => ctx2.clampValueOnBlur,
|
|
549
601
|
isAtMin: (ctx2) => ctx2.isAtMin,
|
|
550
602
|
spinOnPress: (ctx2) => !!ctx2.spinOnPress,
|
|
551
603
|
isAtMax: (ctx2) => ctx2.isAtMax,
|
|
552
604
|
isInRange: (ctx2) => !ctx2.isOutOfRange,
|
|
553
605
|
isDecrementHint: (ctx2, evt) => (evt.hint ?? ctx2.hint) === "decrement",
|
|
554
|
-
|
|
555
|
-
isIncrementHint: (ctx2, evt) => (evt.hint ?? ctx2.hint) === "increment",
|
|
556
|
-
isInvalidExponential: (ctx2) => ctx2.value.toString().startsWith("e")
|
|
606
|
+
isIncrementHint: (ctx2, evt) => (evt.hint ?? ctx2.hint) === "increment"
|
|
557
607
|
},
|
|
558
608
|
activities: {
|
|
609
|
+
trackFormControl(ctx2, _evt, { initialContext }) {
|
|
610
|
+
const inputEl = dom.getInputEl(ctx2);
|
|
611
|
+
return trackFormControl(inputEl, {
|
|
612
|
+
onFieldsetDisabledChange(disabled) {
|
|
613
|
+
ctx2.fieldsetDisabled = disabled;
|
|
614
|
+
},
|
|
615
|
+
onFormReset() {
|
|
616
|
+
set.value(ctx2, initialContext.value);
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
},
|
|
559
620
|
setupVirtualCursor(ctx2) {
|
|
560
621
|
return dom.setupVirtualCursor(ctx2);
|
|
561
622
|
},
|
|
@@ -565,26 +626,23 @@ function machine(userContext) {
|
|
|
565
626
|
trackButtonDisabled(ctx2, _evt, { send }) {
|
|
566
627
|
const btn = dom.getPressedTriggerEl(ctx2, ctx2.hint);
|
|
567
628
|
return observeAttributes(btn, ["disabled"], () => {
|
|
568
|
-
send("PRESS_UP");
|
|
629
|
+
send({ type: "TRIGGER.PRESS_UP", src: "attr" });
|
|
569
630
|
});
|
|
570
631
|
},
|
|
571
632
|
attachWheelListener(ctx2, _evt, { send }) {
|
|
572
|
-
const
|
|
573
|
-
if (!
|
|
633
|
+
const inputEl = dom.getInputEl(ctx2);
|
|
634
|
+
if (!inputEl || !dom.isActiveElement(ctx2, inputEl) || !ctx2.allowMouseWheel)
|
|
574
635
|
return;
|
|
575
636
|
function onWheel(event) {
|
|
576
|
-
const isInputFocused = dom.getDoc(ctx2).activeElement === input;
|
|
577
|
-
if (!ctx2.allowMouseWheel || !isInputFocused)
|
|
578
|
-
return;
|
|
579
637
|
event.preventDefault();
|
|
580
638
|
const dir = Math.sign(event.deltaY) * -1;
|
|
581
639
|
if (dir === 1) {
|
|
582
|
-
send("INCREMENT");
|
|
640
|
+
send("VALUE.INCREMENT");
|
|
583
641
|
} else if (dir === -1) {
|
|
584
|
-
send("DECREMENT");
|
|
642
|
+
send("VALUE.DECREMENT");
|
|
585
643
|
}
|
|
586
644
|
}
|
|
587
|
-
return addDomEvent(
|
|
645
|
+
return addDomEvent(inputEl, "wheel", onWheel, { passive: false });
|
|
588
646
|
},
|
|
589
647
|
activatePointerLock(ctx2) {
|
|
590
648
|
if (isSafari2())
|
|
@@ -600,13 +658,13 @@ function machine(userContext) {
|
|
|
600
658
|
if (!value.hint)
|
|
601
659
|
return;
|
|
602
660
|
send({
|
|
603
|
-
type: "
|
|
661
|
+
type: "SCRUBBER.POINTER_MOVE",
|
|
604
662
|
hint: value.hint,
|
|
605
663
|
point: value.point
|
|
606
664
|
});
|
|
607
665
|
}
|
|
608
666
|
function onMouseup() {
|
|
609
|
-
send("
|
|
667
|
+
send("SCRUBBER.POINTER_UP");
|
|
610
668
|
}
|
|
611
669
|
return callAll(
|
|
612
670
|
addDomEvent(doc, "mousemove", onMousemove, false),
|
|
@@ -619,37 +677,34 @@ function machine(userContext) {
|
|
|
619
677
|
if (!ctx2.focusInputOnChange)
|
|
620
678
|
return;
|
|
621
679
|
const inputEl = dom.getInputEl(ctx2);
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
});
|
|
680
|
+
if (dom.isActiveElement(ctx2, inputEl))
|
|
681
|
+
return;
|
|
682
|
+
raf(() => inputEl?.focus({ preventScroll: true }));
|
|
625
683
|
},
|
|
626
684
|
increment(ctx2, evt) {
|
|
627
|
-
|
|
685
|
+
const nextValue = increment(ctx2.value, evt.step ?? ctx2.step);
|
|
686
|
+
set.value(ctx2, String(clamp(nextValue, ctx2)));
|
|
628
687
|
},
|
|
629
688
|
decrement(ctx2, evt) {
|
|
630
|
-
|
|
689
|
+
const nextValue = decrement(ctx2.value, evt.step ?? ctx2.step);
|
|
690
|
+
set.value(ctx2, String(clamp(nextValue, ctx2)));
|
|
631
691
|
},
|
|
632
692
|
clampValue(ctx2) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
roundValue(ctx2) {
|
|
636
|
-
if (ctx2.value === "")
|
|
637
|
-
return;
|
|
638
|
-
set.value(ctx2, utils.round(ctx2));
|
|
693
|
+
const nextValue = clamp(ctx2.value, ctx2);
|
|
694
|
+
set.value(ctx2, String(nextValue));
|
|
639
695
|
},
|
|
640
696
|
setValue(ctx2, evt) {
|
|
641
|
-
|
|
642
|
-
value = utils.sanitize(ctx2, utils.parse(ctx2, value.toString()));
|
|
697
|
+
const value = evt.target?.value ?? evt.value;
|
|
643
698
|
set.value(ctx2, value);
|
|
644
699
|
},
|
|
645
700
|
clearValue(ctx2) {
|
|
646
701
|
set.value(ctx2, "");
|
|
647
702
|
},
|
|
648
|
-
|
|
649
|
-
set.value(ctx2, ctx2.max
|
|
703
|
+
incrementToMax(ctx2) {
|
|
704
|
+
set.value(ctx2, String(ctx2.max));
|
|
650
705
|
},
|
|
651
|
-
|
|
652
|
-
set.value(ctx2, ctx2.min
|
|
706
|
+
decrementToMin(ctx2) {
|
|
707
|
+
set.value(ctx2, String(ctx2.min));
|
|
653
708
|
},
|
|
654
709
|
setHint(ctx2, evt) {
|
|
655
710
|
ctx2.hint = evt.hint;
|
|
@@ -660,15 +715,9 @@ function machine(userContext) {
|
|
|
660
715
|
setHintToSet(ctx2) {
|
|
661
716
|
ctx2.hint = "set";
|
|
662
717
|
},
|
|
663
|
-
invokeOnFocus(ctx2
|
|
664
|
-
const srcElement = match(evt.type, {
|
|
665
|
-
PRESS_DOWN: dom.getPressedTriggerEl(ctx2, evt.hint),
|
|
666
|
-
FOCUS: dom.getInputEl(ctx2),
|
|
667
|
-
PRESS_DOWN_SCRUBBER: dom.getScrubberEl(ctx2)
|
|
668
|
-
});
|
|
718
|
+
invokeOnFocus(ctx2) {
|
|
669
719
|
ctx2.onFocusChange?.({
|
|
670
720
|
focused: true,
|
|
671
|
-
srcElement,
|
|
672
721
|
value: ctx2.formattedValue,
|
|
673
722
|
valueAsNumber: ctx2.valueAsNumber
|
|
674
723
|
});
|
|
@@ -690,16 +739,20 @@ function machine(userContext) {
|
|
|
690
739
|
valueAsNumber: ctx2.valueAsNumber
|
|
691
740
|
});
|
|
692
741
|
},
|
|
693
|
-
syncInputElement(ctx2) {
|
|
742
|
+
syncInputElement(ctx2, evt) {
|
|
694
743
|
const inputEl = dom.getInputEl(ctx2);
|
|
695
|
-
|
|
744
|
+
const inputValue = evt.type.endsWith("CHANGE") ? ctx2.value : ctx2.formattedValue;
|
|
745
|
+
const sel = recordCursor(inputEl);
|
|
746
|
+
dom.setValue(inputEl, inputValue);
|
|
747
|
+
raf(() => {
|
|
748
|
+
restoreCursor(inputEl, sel);
|
|
749
|
+
});
|
|
696
750
|
},
|
|
697
751
|
syncInputValue(ctx2) {
|
|
698
752
|
const inputEl = dom.getInputEl(ctx2);
|
|
699
753
|
if (!inputEl || inputEl.value == ctx2.value)
|
|
700
754
|
return;
|
|
701
|
-
|
|
702
|
-
set.value(ctx2, utils.sanitize(ctx2, value));
|
|
755
|
+
set.value(ctx2, ctx2.formattedValue);
|
|
703
756
|
},
|
|
704
757
|
setCursorPoint(ctx2, evt) {
|
|
705
758
|
ctx2.scrubberCursorPoint = evt.point;
|
|
@@ -708,19 +761,50 @@ function machine(userContext) {
|
|
|
708
761
|
ctx2.scrubberCursorPoint = null;
|
|
709
762
|
},
|
|
710
763
|
setVirtualCursorPosition(ctx2) {
|
|
711
|
-
const
|
|
712
|
-
if (!
|
|
764
|
+
const cursorEl = dom.getCursorEl(ctx2);
|
|
765
|
+
if (!cursorEl || !ctx2.scrubberCursorPoint)
|
|
713
766
|
return;
|
|
714
767
|
const { x, y } = ctx2.scrubberCursorPoint;
|
|
715
|
-
|
|
768
|
+
cursorEl.style.transform = `translate3d(${x}px, ${y}px, 0px)`;
|
|
769
|
+
},
|
|
770
|
+
setComposing(ctx2) {
|
|
771
|
+
ctx2.composing = true;
|
|
772
|
+
},
|
|
773
|
+
clearComposing(ctx2) {
|
|
774
|
+
ctx2.composing = false;
|
|
775
|
+
},
|
|
776
|
+
setFormatterAndParser(ctx2) {
|
|
777
|
+
if (!ctx2.locale)
|
|
778
|
+
return;
|
|
779
|
+
ctx2.formatter = createFormatter(ctx2.locale, ctx2.formatOptions);
|
|
780
|
+
ctx2.parser = createParser(ctx2.locale, ctx2.formatOptions);
|
|
716
781
|
}
|
|
782
|
+
},
|
|
783
|
+
compareFns: {
|
|
784
|
+
formatOptions: (a, b) => isEqual(a, b)
|
|
717
785
|
}
|
|
718
786
|
}
|
|
719
787
|
);
|
|
720
788
|
}
|
|
789
|
+
var defaultFormatOptions = {
|
|
790
|
+
style: "decimal",
|
|
791
|
+
minimumFractionDigits: 0,
|
|
792
|
+
maximumFractionDigits: 20
|
|
793
|
+
};
|
|
794
|
+
var createFormatter = (locale, options = {}) => {
|
|
795
|
+
const formatOptions = Object.assign({}, defaultFormatOptions, options);
|
|
796
|
+
return ref(new Intl.NumberFormat(locale, formatOptions));
|
|
797
|
+
};
|
|
798
|
+
var createParser = (locale, options = {}) => {
|
|
799
|
+
const formatOptions = Object.assign({}, defaultFormatOptions, options);
|
|
800
|
+
return ref(new NumberParser(locale, formatOptions));
|
|
801
|
+
};
|
|
721
802
|
var invoke = {
|
|
722
803
|
onChange: (ctx) => {
|
|
723
|
-
ctx.onValueChange?.({
|
|
804
|
+
ctx.onValueChange?.({
|
|
805
|
+
value: ctx.value,
|
|
806
|
+
valueAsNumber: ctx.valueAsNumber
|
|
807
|
+
});
|
|
724
808
|
}
|
|
725
809
|
};
|
|
726
810
|
var set = {
|