@descope/web-components-ui 3.13.1 → 3.13.3

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.esm.js CHANGED
@@ -11463,6 +11463,14 @@ let PhoneFieldInternal$1 = class PhoneFieldInternal extends BaseInputClass$c {
11463
11463
  }
11464
11464
 
11465
11465
  set value(val) {
11466
+ this.#onValueChange(val);
11467
+ }
11468
+
11469
+ // Handles programmatic value changes only (e.g. `component.value = '...'`).
11470
+ // User edits of the inner inputs are handled by #onTextFieldChange /
11471
+ // #onComboBoxChange — Vaadin's value write-back is disabled in PhoneFieldClass
11472
+ // so it no longer routes inner edits through this setter.
11473
+ #onValueChange(val) {
11466
11474
  // reject empty or digit-free values
11467
11475
  if (!val || !/\d/.test(val)) {
11468
11476
  this.#clearValue();
@@ -11595,22 +11603,37 @@ let PhoneFieldInternal$1 = class PhoneFieldInternal extends BaseInputClass$c {
11595
11603
  }
11596
11604
 
11597
11605
  #initInputs() {
11598
- // Sanitize phone input value to filter everything but digits
11599
- this.textField.addEventListener('input', (e) => {
11600
- if (!this.allowAlphanumericInput) {
11601
- const telDigitsRegExp = /^\d$/;
11602
- const sanitizedInput = e.target.value
11603
- .split('')
11604
- .filter((char) => telDigitsRegExp.test(char))
11605
- .join('');
11606
- e.target.value = sanitizedInput;
11607
- }
11608
- });
11606
+ // Handle each inner input on its own: the phone field updates the national
11607
+ // number, the combo box updates the country/dial code. Neither rewrites the
11608
+ // other, so editing one input never clears the other.
11609
+ this.textField.addEventListener('input', this.#onTextFieldChange.bind(this));
11610
+ this.comboBox.addEventListener('change', this.#onComboBoxChange.bind(this));
11609
11611
 
11610
11612
  this.handleFocusEventsDispatching(this.inputs);
11611
11613
  this.handleInputEventDispatching();
11612
11614
  }
11613
11615
 
11616
+ // user edited the phone number: sanitize and (optionally) format it, leaving
11617
+ // the country code untouched
11618
+ #onTextFieldChange() {
11619
+ const sanitized = this.allowAlphanumericInput
11620
+ ? this.textField.value
11621
+ : this.textField.value.replace(/\D+/g, '');
11622
+
11623
+ this.textField.value = this.isFormatValue ? this.#formatNationalNumber(sanitized) : sanitized;
11624
+ }
11625
+
11626
+ // user changed the country: re-format the existing national number for the
11627
+ // new country, leaving the phone number digits untouched
11628
+ #onComboBoxChange() {
11629
+ if (!this.isFormatValue) {
11630
+ return;
11631
+ }
11632
+
11633
+ const nationalNumber = this.textField.value.replace(/\D+/g, '');
11634
+ this.textField.value = this.#formatNationalNumber(nationalNumber);
11635
+ }
11636
+
11614
11637
  #formatNationalNumber(nationalNumber = '') {
11615
11638
  // re-initialize AsYouType if country code is outdated
11616
11639
  if (!this.#ayt || this.#ayt.country !== this.selectedCountryCode) {
@@ -11737,6 +11760,12 @@ const customMixin$b = (superclass) =>
11737
11760
 
11738
11761
  this.baseElement.appendChild(template.content.cloneNode(true));
11739
11762
 
11763
+ // On every input, Vaadin writes its value back into the input element,
11764
+ // which re-runs the internal `value` setter and overwrites the combo box
11765
+ // and phone fields. PhoneFieldInternal manages those inputs itself, so
11766
+ // disable Vaadin's write-back.
11767
+ this.baseElement._forwardInputValue = () => {};
11768
+
11740
11769
  this.inputElement = this.shadowRoot.querySelector(componentName$14);
11741
11770
 
11742
11771
  forwardAttrs(this.shadowRoot.host, this.inputElement, {
@@ -25606,6 +25635,11 @@ class RawTooltip extends createBaseClass$1({
25606
25635
  componentName: componentName$9,
25607
25636
  baseSelector: 'vaadin-tooltip',
25608
25637
  }) {
25638
+ // Observes the inner descope-anchored's `class` attribute so runtime updates
25639
+ // (e.g. real-time conditional components toggling `.hidden`) keep this
25640
+ // tooltip's class in sync. Set up in connectedCallback so reconnects work.
25641
+ #anchoredClassObserver = null;
25642
+
25609
25643
  constructor() {
25610
25644
  super();
25611
25645
 
@@ -25721,9 +25755,31 @@ class RawTooltip extends createBaseClass$1({
25721
25755
  );
25722
25756
  this.#setTooltipTarget();
25723
25757
 
25758
+ setTimeout(() => this.#onOverlayReady());
25759
+ }
25760
+
25761
+ #observeAnchored() {
25762
+ this.#anchoredClassObserver?.disconnect();
25763
+ if (this.anchored) {
25764
+ this.#anchoredClassObserver = observeAttributes$1(
25765
+ this.anchored,
25766
+ () => this.#syncComponentState(),
25767
+ { includeAttrs: ['class'] },
25768
+ );
25769
+ }
25770
+ }
25771
+
25772
+ // createBaseClass gates init() to first-connect, so observing here is
25773
+ // required for the detach/reattach cycle to keep working.
25774
+ connectedCallback() {
25775
+ super.connectedCallback?.();
25724
25776
  this.#syncComponentState();
25777
+ this.#observeAnchored();
25778
+ }
25725
25779
 
25726
- setTimeout(() => this.#onOverlayReady());
25780
+ disconnectedCallback() {
25781
+ super.disconnectedCallback?.();
25782
+ this.#anchoredClassObserver?.disconnect();
25727
25783
  }
25728
25784
 
25729
25785
  #setTooltipTarget() {
@@ -27015,6 +27071,12 @@ class RawAttachment extends createBaseClass$1({
27015
27071
  componentName: componentName$6,
27016
27072
  baseSelector: 'descope-anchored',
27017
27073
  }) {
27074
+ // Observes the inner descope-anchored's `class` attribute so runtime
27075
+ // updates (e.g. real-time conditional components toggling `.hidden`) keep
27076
+ // this attachment host's class in sync. Set up in connectedCallback so
27077
+ // reconnects work (createBaseClass gates init() to first connect only).
27078
+ #anchoredClassObserver = null;
27079
+
27018
27080
  constructor() {
27019
27081
  super();
27020
27082
 
@@ -27053,8 +27115,6 @@ class RawAttachment extends createBaseClass$1({
27053
27115
  init() {
27054
27116
  super.init?.();
27055
27117
 
27056
- this.#syncComponentState();
27057
-
27058
27118
  injectStyle(
27059
27119
  `
27060
27120
  :host {
@@ -27105,6 +27165,30 @@ class RawAttachment extends createBaseClass$1({
27105
27165
  this.classList.toggle('hidden', hasHidden);
27106
27166
  }
27107
27167
 
27168
+ #observeAnchored() {
27169
+ this.#anchoredClassObserver?.disconnect();
27170
+ if (this.anchored) {
27171
+ this.#anchoredClassObserver = observeAttributes$1(
27172
+ this.anchored,
27173
+ () => this.#syncComponentState(),
27174
+ { includeAttrs: ['class'] },
27175
+ );
27176
+ }
27177
+ }
27178
+
27179
+ // createBaseClass gates init() to first-connect, so observing here is
27180
+ // required for the detach/reattach cycle to keep working.
27181
+ connectedCallback() {
27182
+ super.connectedCallback?.();
27183
+ this.#syncComponentState();
27184
+ this.#observeAnchored();
27185
+ }
27186
+
27187
+ disconnectedCallback() {
27188
+ super.disconnectedCallback?.();
27189
+ this.#anchoredClassObserver?.disconnect();
27190
+ }
27191
+
27108
27192
  #syncAvailableSizeAttr() {
27109
27193
  const anchor = this.defaultSlot?.assignedElements()?.[0];
27110
27194
 
@@ -31777,6 +31861,11 @@ class RawAnchored extends createBaseClass$1({
31777
31861
 
31778
31862
  #hostStretchSheet = null;
31779
31863
 
31864
+ // Observes the anchor's `class` attribute so runtime updates by the SDK
31865
+ // (e.g. real-time conditional components toggling `.hidden`) propagate to
31866
+ // this element. Without this, only the initial slotchange would sync.
31867
+ #anchorClassObserver = null;
31868
+
31780
31869
  get #anchor() {
31781
31870
  return this.defaultSlot.assignedElements({ flatten: true })[0];
31782
31871
  }
@@ -31879,6 +31968,28 @@ class RawAnchored extends createBaseClass$1({
31879
31968
  this.#anchored,
31880
31969
  'st-host-direction',
31881
31970
  );
31971
+
31972
+ this.#observeAnchorClass();
31973
+ }
31974
+
31975
+ #observeAnchorClass() {
31976
+ this.#anchorClassObserver?.disconnect();
31977
+ if (this.#anchor) {
31978
+ this.#anchorClassObserver = observeAttributes$1(
31979
+ this.#anchor,
31980
+ () => this.#syncComponentState(),
31981
+ { includeAttrs: ['class'] },
31982
+ );
31983
+ }
31984
+ }
31985
+
31986
+ // createBaseClass gates init() to first-connect (#isInit). Without
31987
+ // re-observing here, runtime `.hidden` toggles stop syncing after a
31988
+ // detach/reattach cycle.
31989
+ connectedCallback() {
31990
+ super.connectedCallback?.();
31991
+ this.#observeAnchorClass();
31992
+ this.#syncComponentState();
31882
31993
  }
31883
31994
 
31884
31995
  // Injects [stretch] layout rules into the containing component's shadow root (e.g. descope-attachment)
@@ -31920,6 +32031,7 @@ class RawAnchored extends createBaseClass$1({
31920
32031
  super.disconnectedCallback?.();
31921
32032
  this.#stretchObserver?.disconnect();
31922
32033
  this.#directionObserver?.disconnect();
32034
+ this.#anchorClassObserver?.disconnect();
31923
32035
  }
31924
32036
 
31925
32037
  // Track whether anything is slotted, so the host display rule can hide an