@descope/web-components-ui 1.0.249 → 1.0.251

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
@@ -42,6 +42,33 @@ const isUrl = (maybeUrl) => {
42
42
  }
43
43
  };
44
44
 
45
+ /**
46
+ * Compares two arrays unorderedly.
47
+ * @param {Array} arr1 - The first array to compare.
48
+ * @param {Array} arr2 - The second array to compare.
49
+ * @returns {boolean} - Returns true if the arrays are equal unorderedly, false otherwise.
50
+ */
51
+ const compareArraysUnordered = (arr1, arr2) => {
52
+ if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
53
+ return false;
54
+ }
55
+
56
+ if (arr1.length !== arr2.length) {
57
+ return false;
58
+ }
59
+
60
+ const sortedArr1 = arr1.slice().sort();
61
+ const sortedArr2 = arr2.slice().sort();
62
+
63
+ for (let i = 0; i < sortedArr1.length; i++) {
64
+ if (sortedArr1[i] !== sortedArr2[i]) {
65
+ return false;
66
+ }
67
+ }
68
+
69
+ return true;
70
+ };
71
+
45
72
  const DESCOPE_PREFIX = 'descope';
46
73
  const CSS_SELECTOR_SPECIFIER_MULTIPLY = 3;
47
74
  const BASE_THEME_SECTION = 'host';
@@ -7433,6 +7460,8 @@ const multiSelectComboBoxMixin = (superclass) =>
7433
7460
 
7434
7461
  #data;
7435
7462
 
7463
+ #value = [];
7464
+
7436
7465
  get defaultValues() {
7437
7466
  const defaultValuesAttr = this.getAttribute('default-values');
7438
7467
  if (defaultValuesAttr) {
@@ -7517,14 +7546,14 @@ const multiSelectComboBoxMixin = (superclass) =>
7517
7546
  if (template) this.innerHTML = template;
7518
7547
  }
7519
7548
 
7520
- handleSelectedItems() {
7549
+ updateSelectedItems() {
7550
+ // This is a list of all the selected items, including ones that may have been removed from the DOM
7521
7551
  const currentSelected =
7522
7552
  this.baseElement.selectedItems?.map((item) => item.getAttribute('data-id')) || [];
7523
7553
 
7524
- this.baseElement.selectedItems = [];
7525
-
7526
- // if previously selected item ID exists in current children, set it as selected
7554
+ // if there are selected items, we want to trigger a potential update to the value if some child elements were removed
7527
7555
  if (currentSelected.length > 0) {
7556
+ // setting the value checks that the selected items are still in the DOM and will not set the value if they are not
7528
7557
  this.value = currentSelected;
7529
7558
  }
7530
7559
 
@@ -7593,7 +7622,7 @@ const multiSelectComboBoxMixin = (superclass) =>
7593
7622
 
7594
7623
  setTimeout(() => {
7595
7624
  // set timeout to ensure this runs after customValueTransformFn had the chance to be overriden
7596
- this.handleSelectedItems();
7625
+ this.updateSelectedItems();
7597
7626
  }, 0);
7598
7627
  } else {
7599
7628
  this.baseElement.items = [];
@@ -7632,6 +7661,9 @@ const multiSelectComboBoxMixin = (superclass) =>
7632
7661
  value: e.detail,
7633
7662
  });
7634
7663
  this.innerHTML += newItemHtml;
7664
+ // The internal filter needs to be removed, otherwise there's a bug where a new custom item
7665
+ // added can't be removed from the dropdown because of how the vaadin component is implemented
7666
+ this.baseElement._lastFilter = '';
7635
7667
  // The value needs to be set with a timeout because it needs to execute after
7636
7668
  // the custom value is added to items by the children change observer
7637
7669
  setTimeout(() => {
@@ -7666,6 +7698,15 @@ const multiSelectComboBoxMixin = (superclass) =>
7666
7698
  }
7667
7699
  return {};
7668
7700
  };
7701
+
7702
+ // This is required to override the default validity check of the vaadin component
7703
+ // which is triggered when the component is checked for validity after blur
7704
+ // Without this, our minItemsSelection and maxItemsSelection constraints will not be checked
7705
+ const that = this;
7706
+ // eslint-disable-next-line func-names
7707
+ this.baseElement.checkValidity = () => {
7708
+ return that.validity.valid;
7709
+ };
7669
7710
  }
7670
7711
 
7671
7712
  init() {
@@ -7690,18 +7731,40 @@ const multiSelectComboBoxMixin = (superclass) =>
7690
7731
  forwardAttrs(this, this.baseElement, { includeAttrs: ['placeholder'] });
7691
7732
 
7692
7733
  this.setDefaultValues();
7734
+
7735
+ this.baseElement.addEventListener('selected-items-changed', () => {
7736
+ this.#updateInternalValue();
7737
+ this.dispatchEvent(new CustomEvent('input', { bubbles: true }));
7738
+ });
7693
7739
  }
7694
7740
 
7695
7741
  setDefaultValues() {
7696
- this.value = this.defaultValues;
7742
+ const initialDefaultValues = this.defaultValues;
7743
+ if (initialDefaultValues.length > 0) {
7744
+ this.value = this.defaultValues;
7745
+ }
7746
+ }
7747
+
7748
+ #updateInternalValue() {
7749
+ // This is done here because we don't want to return a different copy of the same array
7750
+ // every time get value is called if a new value wasn't set
7751
+ this.#value =
7752
+ this.baseElement.selectedItems?.map((elem) => elem.getAttribute('data-id')) || [];
7697
7753
  }
7698
7754
 
7755
+ // Updating the value will update the selectedItems, which will trigger an event 'selected-items-changed'
7756
+ // which we listen to in the init function to update the internal value
7699
7757
  set value(vals) {
7700
7758
  if (vals && vals.length > 0) {
7701
- const children = this.baseElement.items?.filter((item) => vals.includes(item['data-id']));
7702
-
7703
- if (children?.length > 0) {
7704
- this.baseElement.selectedItems = children;
7759
+ // Filters the children of the component to find the ones that match the values,
7760
+ // since it's possible that some values that are trying to set are not in the children
7761
+ const selectedChildren = this.baseElement.items?.filter((item) =>
7762
+ vals.includes(item['data-id'])
7763
+ );
7764
+ const newSelectedValues =
7765
+ selectedChildren?.map((child) => child.getAttribute('data-id')) || [];
7766
+ if (!compareArraysUnordered(this.#value, newSelectedValues)) {
7767
+ this.baseElement.selectedItems = selectedChildren;
7705
7768
  }
7706
7769
  } else {
7707
7770
  this.baseElement.selectedItems = [];
@@ -7709,7 +7772,7 @@ const multiSelectComboBoxMixin = (superclass) =>
7709
7772
  }
7710
7773
 
7711
7774
  get value() {
7712
- return this.baseElement.selectedItems.map((elem) => elem.getAttribute('data-id')) || [];
7775
+ return this.#value;
7713
7776
  }
7714
7777
  };
7715
7778
 
@@ -7846,6 +7909,7 @@ const MultiSelectComboBoxClass = compose(
7846
7909
  },
7847
7910
  }),
7848
7911
  composedProxyInputMixin({ proxyProps: ['selectionStart'], inputEvent: 'selected-items-changed' }),
7912
+ changeMixin,
7849
7913
  componentNameValidationMixin,
7850
7914
  multiSelectComboBoxMixin
7851
7915
  )(