@ni/nimble-components 33.12.0 → 34.0.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.
@@ -11476,7 +11476,7 @@
11476
11476
  return;
11477
11477
  }
11478
11478
  if (this.control && !this.isUserInput) {
11479
- this.control.value = this.value;
11479
+ this.syncValueToInnerControl();
11480
11480
  }
11481
11481
  super.valueChanged(previous, this.value);
11482
11482
  if (previous !== undefined && !this.isUserInput) {
@@ -11551,7 +11551,7 @@
11551
11551
  super.connectedCallback();
11552
11552
  this.proxy.setAttribute("type", "number");
11553
11553
  this.validate();
11554
- this.control.value = this.value;
11554
+ this.syncValueToInnerControl();
11555
11555
  if (this.autofocus) {
11556
11556
  DOM.queueUpdate(() => {
11557
11557
  this.focus();
@@ -11578,9 +11578,9 @@
11578
11578
  * @internal
11579
11579
  */
11580
11580
  handleTextInput() {
11581
- this.control.value = this.control.value.replace(/[^0-9\-+e.]/g, "");
11581
+ this.control.value = this.sanitizeInput(this.control.value);
11582
11582
  this.isUserInput = true;
11583
- this.value = this.control.value;
11583
+ this.syncValueFromInnerControl();
11584
11584
  }
11585
11585
  /**
11586
11586
  * Change event handler for inner control.
@@ -11616,6 +11616,26 @@
11616
11616
  * @internal
11617
11617
  */
11618
11618
  handleBlur() {
11619
+ this.syncValueToInnerControl();
11620
+ }
11621
+ /**
11622
+ * Sanitizes the text input by the user.
11623
+ * @param inputText The user-input text to sanitize
11624
+ * @returns The sanitized text, containing only valid characters for a number field
11625
+ */
11626
+ sanitizeInput(inputText) {
11627
+ return inputText.replace(/[^0-9\-+e.]/g, "");
11628
+ }
11629
+ /**
11630
+ * Synchronizes the value from the input control in the shadow DOM to the host component.
11631
+ */
11632
+ syncValueFromInnerControl() {
11633
+ this.value = this.control.value;
11634
+ }
11635
+ /**
11636
+ * Synchronizes the value from the host component to the input control in the shadow DOM.
11637
+ */
11638
+ syncValueToInnerControl() {
11619
11639
  this.control.value = this.value;
11620
11640
  }
11621
11641
  };
@@ -16257,7 +16277,7 @@
16257
16277
  const end = getColorForTheme(element, hexToRgbaCssColor(Black15, 0), hexToRgbaCssColor(Black82, 0), hexToRgbaCssColor(ForestGreen, 0));
16258
16278
  return `linear-gradient(${start}, ${end})`;
16259
16279
  });
16260
- DesignToken.create(styleNameFromTokenName(tokenNames.dividerBackgroundColor)).withDefault((element) => getColorForTheme(element, hexToRgbaCssColor(Black91, 0.2), hexToRgbaCssColor(Black15, 0.2), hexToRgbaCssColor(White, 0.2)));
16280
+ DesignToken.create(styleNameFromTokenName(tokenNames.dividerBackgroundColor)).withDefault((element) => getColorForTheme(element, Black15, Black80, ForestGreen));
16261
16281
  const fillSelectedColor = DesignToken.create(styleNameFromTokenName(tokenNames.fillSelectedColor)).withDefault((element) => hexToRgbaCssColor(getFillSelectedColorForTheme(element), 0.2));
16262
16282
  const fillSelectedRgbPartialColor = DesignToken.create(styleNameFromTokenName(tokenNames.fillSelectedRgbPartialColor)).withDefault((element) => hexToRgbPartial(getFillSelectedColorForTheme(element)));
16263
16283
  const fillHoverSelectedColor = DesignToken.create(styleNameFromTokenName(tokenNames.fillHoverSelectedColor)).withDefault((element) => hexToRgbaCssColor(getFillSelectedColorForTheme(element), 0.15));
@@ -26807,7 +26827,7 @@ so this becomes the fallback color for the slot */ ''}
26807
26827
  ?required="${x => x.required}"
26808
26828
  size="${x => x.size}"
26809
26829
  type="text"
26810
- inputmode="numeric"
26830
+ inputmode="text"
26811
26831
  min="${x => x.min}"
26812
26832
  max="${x => x.max}"
26813
26833
  step="${x => x.step}"
@@ -26869,11 +26889,53 @@ so this becomes the fallback color for the slot */ ''}
26869
26889
  this.appearance = NumberFieldAppearance.underline;
26870
26890
  this.fullBleed = false;
26871
26891
  this.appearanceReadOnly = false;
26892
+ this.decimalSeparator = '.';
26893
+ this.inputFilterRegExp = this.buildFilterRegExp(this.decimalSeparator);
26894
+ this.langSubscriber = {
26895
+ handleChange: () => this.updateDecimalSeparatorAndInputFilter()
26896
+ };
26872
26897
  }
26873
26898
  connectedCallback() {
26874
26899
  super.connectedCallback();
26875
26900
  // This is a workaround for FAST issue: https://github.com/microsoft/fast/issues/6148
26876
26901
  this.control.setAttribute('role', 'spinbutton');
26902
+ this.updateDecimalSeparatorAndInputFilter();
26903
+ lang.subscribe(this.langSubscriber, this);
26904
+ }
26905
+ disconnectedCallback() {
26906
+ super.disconnectedCallback();
26907
+ lang.unsubscribe(this.langSubscriber, this);
26908
+ }
26909
+ sanitizeInput(inputText) {
26910
+ return inputText.replace(this.inputFilterRegExp, '');
26911
+ }
26912
+ // this.value <-- this.control.value
26913
+ syncValueFromInnerControl() {
26914
+ this.value = this.decimalSeparator !== '.'
26915
+ ? this.control.value.replace(this.decimalSeparator, '.')
26916
+ : this.control.value;
26917
+ }
26918
+ // this.value --> this.control.value
26919
+ syncValueToInnerControl() {
26920
+ this.control.value = this.decimalSeparator !== '.'
26921
+ ? this.value.replace('.', this.decimalSeparator)
26922
+ : this.value;
26923
+ }
26924
+ updateDecimalSeparatorAndInputFilter() {
26925
+ const previousSeparator = this.decimalSeparator;
26926
+ this.decimalSeparator = this.getSeparatorForLanguange(lang.getValueFor(this));
26927
+ if (this.decimalSeparator !== previousSeparator) {
26928
+ this.inputFilterRegExp = this.buildFilterRegExp(this.decimalSeparator);
26929
+ this.control.value = this.control.value.replace(previousSeparator, this.decimalSeparator);
26930
+ }
26931
+ }
26932
+ getSeparatorForLanguange(language) {
26933
+ return Intl.NumberFormat(language)
26934
+ .formatToParts(1.1)
26935
+ .find(x => x.type === 'decimal').value;
26936
+ }
26937
+ buildFilterRegExp(decimalSeparator) {
26938
+ return new RegExp(`[^0-9\\-+e${decimalSeparator}]`, 'g');
26877
26939
  }
26878
26940
  }
26879
26941
  __decorate([