@spectrum-web-components/number-field 1.1.0 → 1.1.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 (49) hide show
  1. package/package.json +9 -9
  2. package/sp-number-field.d.ts +6 -0
  3. package/sp-number-field.dev.js +5 -0
  4. package/sp-number-field.dev.js.map +7 -0
  5. package/sp-number-field.js +2 -0
  6. package/sp-number-field.js.map +7 -0
  7. package/src/NumberField.d.ts +117 -0
  8. package/src/NumberField.dev.js +675 -0
  9. package/src/NumberField.dev.js.map +7 -0
  10. package/src/NumberField.js +57 -0
  11. package/src/NumberField.js.map +7 -0
  12. package/src/index.d.ts +1 -0
  13. package/src/index.dev.js +3 -0
  14. package/src/index.dev.js.map +7 -0
  15. package/src/index.js +2 -0
  16. package/src/index.js.map +7 -0
  17. package/src/number-field-overrides.css.d.ts +2 -0
  18. package/src/number-field-overrides.css.dev.js +7 -0
  19. package/src/number-field-overrides.css.dev.js.map +7 -0
  20. package/src/number-field-overrides.css.js +4 -0
  21. package/src/number-field-overrides.css.js.map +7 -0
  22. package/src/number-field.css.d.ts +2 -0
  23. package/src/number-field.css.dev.js +7 -0
  24. package/src/number-field.css.dev.js.map +7 -0
  25. package/src/number-field.css.js +4 -0
  26. package/src/number-field.css.js.map +7 -0
  27. package/src/spectrum-number-field.css.d.ts +2 -0
  28. package/src/spectrum-number-field.css.dev.js +7 -0
  29. package/src/spectrum-number-field.css.dev.js.map +7 -0
  30. package/src/spectrum-number-field.css.js +4 -0
  31. package/src/spectrum-number-field.css.js.map +7 -0
  32. package/stories/number-field-sizes.stories.js +29 -0
  33. package/stories/number-field-sizes.stories.js.map +7 -0
  34. package/stories/number-field.stories.js +425 -0
  35. package/stories/number-field.stories.js.map +7 -0
  36. package/test/benchmark/basic-test.js +8 -0
  37. package/test/benchmark/basic-test.js.map +7 -0
  38. package/test/helpers.js +45 -0
  39. package/test/helpers.js.map +7 -0
  40. package/test/inputs.test.js +433 -0
  41. package/test/inputs.test.js.map +7 -0
  42. package/test/number-field-memory.test.js +5 -0
  43. package/test/number-field-memory.test.js.map +7 -0
  44. package/test/number-field-sizes.test-vrt.js +5 -0
  45. package/test/number-field-sizes.test-vrt.js.map +7 -0
  46. package/test/number-field.test-vrt.js +5 -0
  47. package/test/number-field.test-vrt.js.map +7 -0
  48. package/test/number-field.test.js +1739 -0
  49. package/test/number-field.test.js.map +7 -0
@@ -0,0 +1,675 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __decorateClass = (decorators, target, key, kind) => {
5
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
6
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
7
+ if (decorator = decorators[i])
8
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
9
+ if (kind && result) __defProp(target, key, result);
10
+ return result;
11
+ };
12
+ import { NumberFormatter, NumberParser } from "@internationalized/number";
13
+ import {
14
+ html,
15
+ nothing
16
+ } from "@spectrum-web-components/base";
17
+ import {
18
+ property,
19
+ query
20
+ } from "@spectrum-web-components/base/src/decorators.js";
21
+ import { streamingListener } from "@spectrum-web-components/base/src/streaming-listener.js";
22
+ import {
23
+ LanguageResolutionController,
24
+ languageResolverUpdatedSymbol
25
+ } from "@spectrum-web-components/reactive-controllers/src/LanguageResolution.js";
26
+ import chevronStyles from "@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js";
27
+ import "@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js";
28
+ import "@spectrum-web-components/icons-ui/icons/sp-icon-chevron200.js";
29
+ import "@spectrum-web-components/icons-ui/icons/sp-icon-chevron50.js";
30
+ import "@spectrum-web-components/icons-ui/icons/sp-icon-chevron75.js";
31
+ import "@spectrum-web-components/infield-button/sp-infield-button.js";
32
+ import {
33
+ isAndroid,
34
+ isIOS,
35
+ isIPhone
36
+ } from "@spectrum-web-components/shared/src/platform.js";
37
+ import { TextfieldBase } from "@spectrum-web-components/textfield";
38
+ import chevronIconOverrides from "@spectrum-web-components/icon/src/icon-chevron-overrides.css.js";
39
+ import styles from "./number-field.css.js";
40
+ export const FRAMES_PER_CHANGE = 5;
41
+ export const CHANGE_DEBOUNCE_MS = 100;
42
+ export const indeterminatePlaceholder = "-";
43
+ export const remapMultiByteCharacters = {
44
+ "\uFF11": "1",
45
+ "\uFF12": "2",
46
+ "\uFF13": "3",
47
+ "\uFF14": "4",
48
+ "\uFF15": "5",
49
+ "\uFF16": "6",
50
+ "\uFF17": "7",
51
+ "\uFF18": "8",
52
+ "\uFF19": "9",
53
+ "\uFF10": "0",
54
+ "\u3001": ",",
55
+ "\uFF0C": ",",
56
+ "\u3002": ".",
57
+ "\uFF0E": ".",
58
+ "\uFF05": "%",
59
+ "\uFF0B": "+",
60
+ \u30FC: "-",
61
+ \u4E00: "1",
62
+ \u4E8C: "2",
63
+ \u4E09: "3",
64
+ \u56DB: "4",
65
+ \u4E94: "5",
66
+ \u516D: "6",
67
+ \u4E03: "7",
68
+ \u516B: "8",
69
+ \u4E5D: "9",
70
+ \u96F6: "0"
71
+ };
72
+ const chevronIcon = {
73
+ s: (dir) => html`
74
+ <sp-icon-chevron50
75
+ class="stepper-icon spectrum-UIIcon-Chevron${dir}50"
76
+ ></sp-icon-chevron50>
77
+ `,
78
+ m: (dir) => html`
79
+ <sp-icon-chevron75
80
+ class="stepper-icon spectrum-UIIcon-Chevron${dir}75"
81
+ ></sp-icon-chevron75>
82
+ `,
83
+ l: (dir) => html`
84
+ <sp-icon-chevron100
85
+ class="stepper-icon spectrum-UIIcon-Chevron${dir}100"
86
+ ></sp-icon-chevron100>
87
+ `,
88
+ xl: (dir) => html`
89
+ <sp-icon-chevron200
90
+ class="stepper-icon spectrum-UIIcon-Chevron${dir}200"
91
+ ></sp-icon-chevron200>
92
+ `
93
+ };
94
+ export class NumberField extends TextfieldBase {
95
+ constructor() {
96
+ super(...arguments);
97
+ this.focused = false;
98
+ this._forcedUnit = "";
99
+ this.formatOptions = {};
100
+ this.hideStepper = false;
101
+ this.indeterminate = false;
102
+ this.keyboardFocused = false;
103
+ this.managedInput = false;
104
+ this.stepModifier = 10;
105
+ this._value = NaN;
106
+ this._trackingValue = "";
107
+ this.decimalsChars = /* @__PURE__ */ new Set([".", ","]);
108
+ this.valueBeforeFocus = "";
109
+ this.isIntentDecimal = false;
110
+ this.changeCount = 0;
111
+ this.languageResolver = new LanguageResolutionController(this);
112
+ this.wasIndeterminate = false;
113
+ this.hasRecentlyReceivedPointerDown = false;
114
+ this.applyFocusElementLabel = (value) => {
115
+ this.appliedLabel = value;
116
+ };
117
+ this.isComposing = false;
118
+ }
119
+ static get styles() {
120
+ return [...super.styles, styles, chevronStyles, chevronIconOverrides];
121
+ }
122
+ set value(rawValue) {
123
+ const value = this.validateInput(rawValue);
124
+ if (value === this.value) {
125
+ return;
126
+ }
127
+ this.lastCommitedValue = value;
128
+ const oldValue = this._value;
129
+ this._value = value;
130
+ this.requestUpdate("value", oldValue);
131
+ }
132
+ get value() {
133
+ return this._value;
134
+ }
135
+ get inputValue() {
136
+ return this.indeterminate ? this.formattedValue : this.inputElement.value;
137
+ }
138
+ setValue(newValue = this.value) {
139
+ const previousValue = this.lastCommitedValue;
140
+ this.value = newValue;
141
+ if (typeof previousValue === "undefined" || previousValue === this.value) {
142
+ return;
143
+ }
144
+ this.lastCommitedValue = this.value;
145
+ this.dispatchEvent(
146
+ new Event("change", { bubbles: true, composed: true })
147
+ );
148
+ }
149
+ /**
150
+ * Retreive the value of the element parsed to a Number.
151
+ */
152
+ get valueAsString() {
153
+ return this._value.toString();
154
+ }
155
+ set valueAsString(value) {
156
+ this.value = this.numberParser.parse(value);
157
+ }
158
+ get formattedValue() {
159
+ if (isNaN(this.value)) return "";
160
+ return this.numberFormatter.format(this.value) + (this.focused ? "" : this._forcedUnit);
161
+ }
162
+ convertValueToNumber(inputValue) {
163
+ let normalizedValue = inputValue.split("").map((char) => remapMultiByteCharacters[char] || char).join("");
164
+ const separators = this.valueBeforeFocus.split("").filter((char) => this.decimalsChars.has(char));
165
+ const uniqueSeparators = new Set(separators);
166
+ if (isIOS() && this.inputElement.inputMode === "decimal" && normalizedValue !== this.valueBeforeFocus) {
167
+ const parts = this.numberFormatter.formatToParts(1000.1);
168
+ const replacementDecimal = parts.find(
169
+ (part) => part.type === "decimal"
170
+ ).value;
171
+ for (const separator of uniqueSeparators) {
172
+ const isDecimalSeparator = separator === replacementDecimal;
173
+ if (!isDecimalSeparator && !this.isIntentDecimal) {
174
+ normalizedValue = normalizedValue.replace(
175
+ new RegExp(separator, "g"),
176
+ ""
177
+ );
178
+ }
179
+ }
180
+ let hasReplacedDecimal = false;
181
+ const valueChars = normalizedValue.split("");
182
+ for (let index = valueChars.length - 1; index >= 0; index--) {
183
+ const char = valueChars[index];
184
+ if (this.decimalsChars.has(char)) {
185
+ if (!hasReplacedDecimal) {
186
+ valueChars[index] = replacementDecimal;
187
+ hasReplacedDecimal = true;
188
+ } else valueChars[index] = "";
189
+ }
190
+ }
191
+ normalizedValue = valueChars.join("");
192
+ }
193
+ return this.numberParser.parse(normalizedValue);
194
+ }
195
+ get _step() {
196
+ var _a;
197
+ if (typeof this.step !== "undefined") {
198
+ return this.step;
199
+ }
200
+ if (((_a = this.formatOptions) == null ? void 0 : _a.style) === "percent") {
201
+ return 0.01;
202
+ }
203
+ return 1;
204
+ }
205
+ handlePointerdown(event) {
206
+ if (event.button !== 0) {
207
+ event.preventDefault();
208
+ return;
209
+ }
210
+ this.managedInput = true;
211
+ this.buttons.setPointerCapture(event.pointerId);
212
+ const stepUpRect = this.buttons.children[0].getBoundingClientRect();
213
+ const stepDownRect = this.buttons.children[1].getBoundingClientRect();
214
+ this.findChange = (event2) => {
215
+ if (event2.clientX >= stepUpRect.x && event2.clientY >= stepUpRect.y && event2.clientX <= stepUpRect.x + stepUpRect.width && event2.clientY <= stepUpRect.y + stepUpRect.height) {
216
+ this.change = (event3) => this.increment(event3.shiftKey ? this.stepModifier : 1);
217
+ } else if (event2.clientX >= stepDownRect.x && event2.clientY >= stepDownRect.y && event2.clientX <= stepDownRect.x + stepDownRect.width && event2.clientY <= stepDownRect.y + stepDownRect.height) {
218
+ this.change = (event3) => this.decrement(event3.shiftKey ? this.stepModifier : 1);
219
+ }
220
+ };
221
+ this.findChange(event);
222
+ this.startChange(event);
223
+ }
224
+ startChange(event) {
225
+ this.changeCount = 0;
226
+ this.doChange(event);
227
+ this.safty = setTimeout(() => {
228
+ this.doNextChange(event);
229
+ }, 400);
230
+ }
231
+ doChange(event) {
232
+ this.change(event);
233
+ }
234
+ handlePointermove(event) {
235
+ this.findChange(event);
236
+ }
237
+ handlePointerup(event) {
238
+ this.buttons.releasePointerCapture(event.pointerId);
239
+ cancelAnimationFrame(this.nextChange);
240
+ clearTimeout(this.safty);
241
+ this.managedInput = false;
242
+ this.setValue();
243
+ }
244
+ doNextChange(event) {
245
+ this.changeCount += 1;
246
+ if (this.changeCount % FRAMES_PER_CHANGE === 0) {
247
+ this.doChange(event);
248
+ }
249
+ return requestAnimationFrame(() => {
250
+ this.nextChange = this.doNextChange(event);
251
+ });
252
+ }
253
+ stepBy(count) {
254
+ if (this.disabled || this.readonly) {
255
+ return;
256
+ }
257
+ const min = typeof this.min !== "undefined" ? this.min : 0;
258
+ let value = this.value;
259
+ value += count * this._step;
260
+ if (isNaN(this.value)) {
261
+ value = min;
262
+ }
263
+ value = this.valueWithLimits(value);
264
+ this.requestUpdate();
265
+ this._value = this.validateInput(value);
266
+ this.inputElement.value = this.numberFormatter.format(value);
267
+ this.inputElement.dispatchEvent(
268
+ new Event("input", { bubbles: true, composed: true })
269
+ );
270
+ this.indeterminate = false;
271
+ this.focus();
272
+ }
273
+ increment(factor = 1) {
274
+ this.stepBy(1 * factor);
275
+ }
276
+ decrement(factor = 1) {
277
+ this.stepBy(-1 * factor);
278
+ }
279
+ handleKeydown(event) {
280
+ if (this.isComposing) return;
281
+ switch (event.code) {
282
+ case "ArrowUp":
283
+ event.preventDefault();
284
+ this.increment(event.shiftKey ? this.stepModifier : 1);
285
+ this.setValue();
286
+ break;
287
+ case "ArrowDown":
288
+ event.preventDefault();
289
+ this.decrement(event.shiftKey ? this.stepModifier : 1);
290
+ this.setValue();
291
+ break;
292
+ }
293
+ }
294
+ onScroll(event) {
295
+ event.preventDefault();
296
+ this.managedInput = true;
297
+ const direction = event.shiftKey ? event.deltaX / Math.abs(event.deltaX) : event.deltaY / Math.abs(event.deltaY);
298
+ if (direction !== 0 && !isNaN(direction)) {
299
+ this.stepBy(direction * (event.shiftKey ? this.stepModifier : 1));
300
+ clearTimeout(this.queuedChangeEvent);
301
+ this.queuedChangeEvent = setTimeout(() => {
302
+ this.setValue();
303
+ }, CHANGE_DEBOUNCE_MS);
304
+ }
305
+ this.managedInput = false;
306
+ }
307
+ onFocus() {
308
+ super.onFocus();
309
+ this._trackingValue = this.inputValue;
310
+ this.keyboardFocused = !this.readonly && true;
311
+ this.addEventListener("wheel", this.onScroll, { passive: false });
312
+ this.valueBeforeFocus = this.inputElement.value;
313
+ }
314
+ onBlur(_event) {
315
+ super.onBlur(_event);
316
+ this.keyboardFocused = !this.readonly && false;
317
+ this.removeEventListener("wheel", this.onScroll);
318
+ this.isIntentDecimal = false;
319
+ }
320
+ handleFocusin() {
321
+ this.focused = !this.readonly && true;
322
+ this.keyboardFocused = !this.readonly && true;
323
+ }
324
+ handleFocusout() {
325
+ this.focused = !this.readonly && false;
326
+ this.keyboardFocused = !this.readonly && false;
327
+ }
328
+ handleChange() {
329
+ const value = this.convertValueToNumber(this.inputValue);
330
+ if (this.wasIndeterminate) {
331
+ this.wasIndeterminate = false;
332
+ this.indeterminateValue = void 0;
333
+ if (isNaN(value)) {
334
+ this.indeterminate = true;
335
+ return;
336
+ }
337
+ }
338
+ this.setValue(value);
339
+ this.inputElement.value = this.formattedValue;
340
+ }
341
+ handleCompositionStart() {
342
+ this.isComposing = true;
343
+ }
344
+ handleCompositionEnd() {
345
+ this.isComposing = false;
346
+ requestAnimationFrame(() => {
347
+ this.inputElement.dispatchEvent(
348
+ new Event("input", {
349
+ composed: true,
350
+ bubbles: true
351
+ })
352
+ );
353
+ });
354
+ }
355
+ handleInputElementPointerdown() {
356
+ this.hasRecentlyReceivedPointerDown = true;
357
+ this.updateComplete.then(() => {
358
+ requestAnimationFrame(() => {
359
+ this.hasRecentlyReceivedPointerDown = false;
360
+ });
361
+ });
362
+ }
363
+ handleInput(event) {
364
+ var _a;
365
+ if (this.isComposing) {
366
+ if (event.data) {
367
+ const partialValue = this.convertValueToNumber(event.data);
368
+ if (Number.isNaN(partialValue)) {
369
+ this.inputElement.value = this.indeterminate ? indeterminatePlaceholder : this._trackingValue;
370
+ this.isComposing = false;
371
+ }
372
+ }
373
+ event.stopPropagation();
374
+ return;
375
+ }
376
+ if (this.indeterminate) {
377
+ this.wasIndeterminate = true;
378
+ this.indeterminateValue = this.value;
379
+ this.inputElement.value = this.inputElement.value.replace(
380
+ indeterminatePlaceholder,
381
+ ""
382
+ );
383
+ }
384
+ if (event.data && this.decimalsChars.has(event.data))
385
+ this.isIntentDecimal = true;
386
+ const { value: originalValue, selectionStart } = this.inputElement;
387
+ const value = originalValue.split("").map((char) => remapMultiByteCharacters[char] || char).join("");
388
+ if (this.numberParser.isValidPartialNumber(value)) {
389
+ this.lastCommitedValue = (_a = this.lastCommitedValue) != null ? _a : this.value;
390
+ const valueAsNumber = this.convertValueToNumber(value);
391
+ if (!value && this.indeterminateValue) {
392
+ this.indeterminate = true;
393
+ this._value = this.indeterminateValue;
394
+ } else {
395
+ this.indeterminate = false;
396
+ this._value = this.validateInput(valueAsNumber);
397
+ }
398
+ this._trackingValue = value;
399
+ this.inputElement.value = value;
400
+ this.inputElement.setSelectionRange(selectionStart, selectionStart);
401
+ return;
402
+ } else {
403
+ this.inputElement.value = this.indeterminate ? indeterminatePlaceholder : this._trackingValue;
404
+ event.stopPropagation();
405
+ }
406
+ const currentLength = value.length;
407
+ const previousLength = this._trackingValue.length;
408
+ const nextSelectStart = (selectionStart || currentLength) - (currentLength - previousLength);
409
+ this.inputElement.setSelectionRange(nextSelectStart, nextSelectStart);
410
+ }
411
+ valueWithLimits(nextValue) {
412
+ let value = nextValue;
413
+ if (typeof this.min !== "undefined") {
414
+ value = Math.max(this.min, value);
415
+ }
416
+ if (typeof this.max !== "undefined") {
417
+ value = Math.min(this.max, value);
418
+ }
419
+ return value;
420
+ }
421
+ validateInput(value) {
422
+ value = this.valueWithLimits(value);
423
+ const signMultiplier = value < 0 ? -1 : 1;
424
+ value *= signMultiplier;
425
+ if (this.step) {
426
+ const min = typeof this.min !== "undefined" ? this.min : 0;
427
+ const moduloStep = parseFloat(
428
+ this.valueFormatter.format((value - min) % this.step)
429
+ );
430
+ const fallsOnStep = moduloStep === 0;
431
+ if (!fallsOnStep) {
432
+ const overUnder = Math.round(moduloStep / this.step);
433
+ if (overUnder === 1) {
434
+ value += this.step - moduloStep;
435
+ } else {
436
+ value -= moduloStep;
437
+ }
438
+ }
439
+ if (typeof this.max !== "undefined") {
440
+ while (value > this.max) {
441
+ value -= this.step;
442
+ }
443
+ }
444
+ value = parseFloat(this.valueFormatter.format(value));
445
+ }
446
+ value *= signMultiplier;
447
+ return value;
448
+ }
449
+ get displayValue() {
450
+ const indeterminateValue = this.focused ? "" : indeterminatePlaceholder;
451
+ return this.indeterminate ? indeterminateValue : this.formattedValue;
452
+ }
453
+ clearNumberFormatterCache() {
454
+ this._numberFormatter = void 0;
455
+ this._numberParser = void 0;
456
+ }
457
+ get numberFormatter() {
458
+ if (!this._numberFormatter || !this._numberFormatterFocused) {
459
+ const {
460
+ style,
461
+ unit,
462
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
463
+ unitDisplay,
464
+ ...formatOptionsNoUnit
465
+ } = this.formatOptions;
466
+ if (style !== "unit") {
467
+ formatOptionsNoUnit.style = style;
468
+ }
469
+ this._numberFormatterFocused = new NumberFormatter(
470
+ this.languageResolver.language,
471
+ formatOptionsNoUnit
472
+ );
473
+ try {
474
+ this._numberFormatter = new NumberFormatter(
475
+ this.languageResolver.language,
476
+ this.formatOptions
477
+ );
478
+ this._forcedUnit = "";
479
+ this._numberFormatter.format(1);
480
+ } catch (error) {
481
+ if (style === "unit") {
482
+ this._forcedUnit = unit;
483
+ }
484
+ this._numberFormatter = this._numberFormatterFocused;
485
+ }
486
+ }
487
+ return this.focused ? this._numberFormatterFocused : this._numberFormatter;
488
+ }
489
+ clearValueFormatterCache() {
490
+ this._valueFormatter = void 0;
491
+ }
492
+ get valueFormatter() {
493
+ if (!this._valueFormatter) {
494
+ const digitsAfterDecimal = this.step ? this.step != Math.floor(this.step) ? this.step.toString().split(".")[1].length : 0 : 0;
495
+ this._valueFormatter = new NumberFormatter("en", {
496
+ useGrouping: false,
497
+ maximumFractionDigits: digitsAfterDecimal
498
+ });
499
+ }
500
+ return this._valueFormatter;
501
+ }
502
+ get numberParser() {
503
+ if (!this._numberParser || !this._numberParserFocused) {
504
+ const {
505
+ style,
506
+ unit,
507
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
508
+ unitDisplay,
509
+ ...formatOptionsNoUnit
510
+ } = this.formatOptions;
511
+ if (style !== "unit") {
512
+ formatOptionsNoUnit.style = style;
513
+ }
514
+ this._numberParserFocused = new NumberParser(
515
+ this.languageResolver.language,
516
+ formatOptionsNoUnit
517
+ );
518
+ try {
519
+ this._numberParser = new NumberParser(
520
+ this.languageResolver.language,
521
+ this.formatOptions
522
+ );
523
+ this._forcedUnit = "";
524
+ this._numberParser.parse("0");
525
+ } catch (error) {
526
+ if (style === "unit") {
527
+ this._forcedUnit = unit;
528
+ }
529
+ this._numberParser = this._numberParserFocused;
530
+ }
531
+ }
532
+ return this.focused ? this._numberParserFocused : this._numberParser;
533
+ }
534
+ renderField() {
535
+ this.autocomplete = "off";
536
+ return html`
537
+ ${super.renderField()}
538
+ ${this.hideStepper ? nothing : html`
539
+ <span
540
+ class="buttons"
541
+ @focusin=${this.handleFocusin}
542
+ @focusout=${this.handleFocusout}
543
+ ${streamingListener({
544
+ start: ["pointerdown", this.handlePointerdown],
545
+ streamInside: [
546
+ [
547
+ "pointermove",
548
+ "pointerenter",
549
+ "pointerleave",
550
+ "pointerover",
551
+ "pointerout"
552
+ ],
553
+ this.handlePointermove
554
+ ],
555
+ end: [
556
+ [
557
+ "pointerup",
558
+ "pointercancel",
559
+ "pointerleave"
560
+ ],
561
+ this.handlePointerup
562
+ ]
563
+ })}
564
+ >
565
+ <sp-infield-button
566
+ inline="end"
567
+ block="start"
568
+ class="button step-up"
569
+ aria-hidden="true"
570
+ label=${"Increase " + this.appliedLabel}
571
+ size=${this.size}
572
+ tabindex="-1"
573
+ ?focused=${this.focused}
574
+ ?disabled=${this.disabled || this.readonly || typeof this.max !== "undefined" && this.value === this.max}
575
+ ?quiet=${this.quiet}
576
+ >
577
+ ${chevronIcon[this.size]("Up")}
578
+ </sp-infield-button>
579
+ <sp-infield-button
580
+ inline="end"
581
+ block="end"
582
+ class="button step-down"
583
+ aria-hidden="true"
584
+ label=${"Decrease " + this.appliedLabel}
585
+ size=${this.size}
586
+ tabindex="-1"
587
+ ?focused=${this.focused}
588
+ ?disabled=${this.disabled || this.readonly || typeof this.min !== "undefined" && this.value === this.min}
589
+ ?quiet=${this.quiet}
590
+ >
591
+ ${chevronIcon[this.size]("Down")}
592
+ </sp-infield-button>
593
+ </span>
594
+ `}
595
+ `;
596
+ }
597
+ update(changes) {
598
+ if (changes.has("formatOptions") || changes.has("resolvedLanguage")) {
599
+ this.clearNumberFormatterCache();
600
+ }
601
+ if (changes.has("value") || changes.has("max") || changes.has("min") || changes.has("step")) {
602
+ const value = this.numberParser.parse(
603
+ this.formattedValue.replace(this._forcedUnit, "")
604
+ );
605
+ this.value = value;
606
+ this.clearValueFormatterCache();
607
+ }
608
+ super.update(changes);
609
+ }
610
+ willUpdate(changes) {
611
+ this.multiline = false;
612
+ if (changes.has(languageResolverUpdatedSymbol)) {
613
+ this.clearNumberFormatterCache();
614
+ }
615
+ }
616
+ firstUpdated(changes) {
617
+ super.firstUpdated(changes);
618
+ this.addEventListener("keydown", this.handleKeydown);
619
+ this.addEventListener("compositionstart", this.handleCompositionStart);
620
+ this.addEventListener("compositionend", this.handleCompositionEnd);
621
+ }
622
+ updated(changes) {
623
+ if (!this.inputElement || !this.isConnected) {
624
+ return;
625
+ }
626
+ if (changes.has("min") || changes.has("formatOptions")) {
627
+ const hasOnlyPositives = typeof this.min !== "undefined" && this.min >= 0;
628
+ const { maximumFractionDigits } = this.numberFormatter.resolvedOptions();
629
+ const hasDecimals = maximumFractionDigits && maximumFractionDigits > 0;
630
+ let inputMode = "numeric";
631
+ if (isIPhone() && !hasOnlyPositives) inputMode = "text";
632
+ else if (isIOS() && hasDecimals) inputMode = "decimal";
633
+ else if (isAndroid() && hasDecimals && hasOnlyPositives)
634
+ inputMode = "decimal";
635
+ this.inputElement.inputMode = inputMode;
636
+ }
637
+ if (changes.has("focused") && this.focused && !this.hasRecentlyReceivedPointerDown && !!this.formatOptions.unit) {
638
+ this.setSelectionRange(0, this.displayValue.length);
639
+ }
640
+ }
641
+ }
642
+ __decorateClass([
643
+ query(".buttons")
644
+ ], NumberField.prototype, "buttons", 2);
645
+ __decorateClass([
646
+ property({ type: Boolean, reflect: true })
647
+ ], NumberField.prototype, "focused", 2);
648
+ __decorateClass([
649
+ property({ type: Object, attribute: "format-options" })
650
+ ], NumberField.prototype, "formatOptions", 2);
651
+ __decorateClass([
652
+ property({ type: Boolean, reflect: true, attribute: "hide-stepper" })
653
+ ], NumberField.prototype, "hideStepper", 2);
654
+ __decorateClass([
655
+ property({ type: Boolean, reflect: true })
656
+ ], NumberField.prototype, "indeterminate", 2);
657
+ __decorateClass([
658
+ property({ type: Boolean, reflect: true, attribute: "keyboard-focused" })
659
+ ], NumberField.prototype, "keyboardFocused", 2);
660
+ __decorateClass([
661
+ property({ type: Number })
662
+ ], NumberField.prototype, "max", 2);
663
+ __decorateClass([
664
+ property({ type: Number })
665
+ ], NumberField.prototype, "min", 2);
666
+ __decorateClass([
667
+ property({ type: Number })
668
+ ], NumberField.prototype, "step", 2);
669
+ __decorateClass([
670
+ property({ type: Number, reflect: true, attribute: "step-modifier" })
671
+ ], NumberField.prototype, "stepModifier", 2);
672
+ __decorateClass([
673
+ property({ type: Number })
674
+ ], NumberField.prototype, "value", 1);
675
+ //# sourceMappingURL=NumberField.dev.js.map