@descope/web-components-ui 1.0.250 → 1.0.251

Sign up to get free protection for your applications and to get access to all the features.
@@ -35,6 +35,33 @@ const isUrl = (maybeUrl) => {
35
35
  }
36
36
  };
37
37
 
38
+ /**
39
+ * Compares two arrays unorderedly.
40
+ * @param {Array} arr1 - The first array to compare.
41
+ * @param {Array} arr2 - The second array to compare.
42
+ * @returns {boolean} - Returns true if the arrays are equal unorderedly, false otherwise.
43
+ */
44
+ const compareArraysUnordered = (arr1, arr2) => {
45
+ if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
46
+ return false;
47
+ }
48
+
49
+ if (arr1.length !== arr2.length) {
50
+ return false;
51
+ }
52
+
53
+ const sortedArr1 = arr1.slice().sort();
54
+ const sortedArr2 = arr2.slice().sort();
55
+
56
+ for (let i = 0; i < sortedArr1.length; i++) {
57
+ if (sortedArr1[i] !== sortedArr2[i]) {
58
+ return false;
59
+ }
60
+ }
61
+
62
+ return true;
63
+ };
64
+
38
65
  const observeAttributes = (ele, callback, { excludeAttrs = [], includeAttrs = [] }) => {
39
66
  // sync all attrs on init
40
67
  const filteredAttrs = Array.from(ele.attributes)
@@ -8918,6 +8945,8 @@ const multiSelectComboBoxMixin = (superclass) =>
8918
8945
 
8919
8946
  #data;
8920
8947
 
8948
+ #value = [];
8949
+
8921
8950
  get defaultValues() {
8922
8951
  const defaultValuesAttr = this.getAttribute('default-values');
8923
8952
  if (defaultValuesAttr) {
@@ -9002,14 +9031,14 @@ const multiSelectComboBoxMixin = (superclass) =>
9002
9031
  if (template) this.innerHTML = template;
9003
9032
  }
9004
9033
 
9005
- handleSelectedItems() {
9034
+ updateSelectedItems() {
9035
+ // This is a list of all the selected items, including ones that may have been removed from the DOM
9006
9036
  const currentSelected =
9007
9037
  this.baseElement.selectedItems?.map((item) => item.getAttribute('data-id')) || [];
9008
9038
 
9009
- this.baseElement.selectedItems = [];
9010
-
9011
- // if previously selected item ID exists in current children, set it as selected
9039
+ // if there are selected items, we want to trigger a potential update to the value if some child elements were removed
9012
9040
  if (currentSelected.length > 0) {
9041
+ // setting the value checks that the selected items are still in the DOM and will not set the value if they are not
9013
9042
  this.value = currentSelected;
9014
9043
  }
9015
9044
 
@@ -9078,7 +9107,7 @@ const multiSelectComboBoxMixin = (superclass) =>
9078
9107
 
9079
9108
  setTimeout(() => {
9080
9109
  // set timeout to ensure this runs after customValueTransformFn had the chance to be overriden
9081
- this.handleSelectedItems();
9110
+ this.updateSelectedItems();
9082
9111
  }, 0);
9083
9112
  } else {
9084
9113
  this.baseElement.items = [];
@@ -9117,6 +9146,9 @@ const multiSelectComboBoxMixin = (superclass) =>
9117
9146
  value: e.detail,
9118
9147
  });
9119
9148
  this.innerHTML += newItemHtml;
9149
+ // The internal filter needs to be removed, otherwise there's a bug where a new custom item
9150
+ // added can't be removed from the dropdown because of how the vaadin component is implemented
9151
+ this.baseElement._lastFilter = '';
9120
9152
  // The value needs to be set with a timeout because it needs to execute after
9121
9153
  // the custom value is added to items by the children change observer
9122
9154
  setTimeout(() => {
@@ -9151,6 +9183,15 @@ const multiSelectComboBoxMixin = (superclass) =>
9151
9183
  }
9152
9184
  return {};
9153
9185
  };
9186
+
9187
+ // This is required to override the default validity check of the vaadin component
9188
+ // which is triggered when the component is checked for validity after blur
9189
+ // Without this, our minItemsSelection and maxItemsSelection constraints will not be checked
9190
+ const that = this;
9191
+ // eslint-disable-next-line func-names
9192
+ this.baseElement.checkValidity = () => {
9193
+ return that.validity.valid;
9194
+ };
9154
9195
  }
9155
9196
 
9156
9197
  init() {
@@ -9175,18 +9216,40 @@ const multiSelectComboBoxMixin = (superclass) =>
9175
9216
  forwardAttrs(this, this.baseElement, { includeAttrs: ['placeholder'] });
9176
9217
 
9177
9218
  this.setDefaultValues();
9219
+
9220
+ this.baseElement.addEventListener('selected-items-changed', () => {
9221
+ this.#updateInternalValue();
9222
+ this.dispatchEvent(new CustomEvent('input', { bubbles: true }));
9223
+ });
9178
9224
  }
9179
9225
 
9180
9226
  setDefaultValues() {
9181
- this.value = this.defaultValues;
9227
+ const initialDefaultValues = this.defaultValues;
9228
+ if (initialDefaultValues.length > 0) {
9229
+ this.value = this.defaultValues;
9230
+ }
9231
+ }
9232
+
9233
+ #updateInternalValue() {
9234
+ // This is done here because we don't want to return a different copy of the same array
9235
+ // every time get value is called if a new value wasn't set
9236
+ this.#value =
9237
+ this.baseElement.selectedItems?.map((elem) => elem.getAttribute('data-id')) || [];
9182
9238
  }
9183
9239
 
9240
+ // Updating the value will update the selectedItems, which will trigger an event 'selected-items-changed'
9241
+ // which we listen to in the init function to update the internal value
9184
9242
  set value(vals) {
9185
9243
  if (vals && vals.length > 0) {
9186
- const children = this.baseElement.items?.filter((item) => vals.includes(item['data-id']));
9187
-
9188
- if (children?.length > 0) {
9189
- this.baseElement.selectedItems = children;
9244
+ // Filters the children of the component to find the ones that match the values,
9245
+ // since it's possible that some values that are trying to set are not in the children
9246
+ const selectedChildren = this.baseElement.items?.filter((item) =>
9247
+ vals.includes(item['data-id'])
9248
+ );
9249
+ const newSelectedValues =
9250
+ selectedChildren?.map((child) => child.getAttribute('data-id')) || [];
9251
+ if (!compareArraysUnordered(this.#value, newSelectedValues)) {
9252
+ this.baseElement.selectedItems = selectedChildren;
9190
9253
  }
9191
9254
  } else {
9192
9255
  this.baseElement.selectedItems = [];
@@ -9194,7 +9257,7 @@ const multiSelectComboBoxMixin = (superclass) =>
9194
9257
  }
9195
9258
 
9196
9259
  get value() {
9197
- return this.baseElement.selectedItems.map((elem) => elem.getAttribute('data-id')) || [];
9260
+ return this.#value;
9198
9261
  }
9199
9262
  };
9200
9263
 
@@ -9331,6 +9394,7 @@ const MultiSelectComboBoxClass = compose(
9331
9394
  },
9332
9395
  }),
9333
9396
  composedProxyInputMixin({ proxyProps: ['selectionStart'], inputEvent: 'selected-items-changed' }),
9397
+ changeMixin,
9334
9398
  componentNameValidationMixin,
9335
9399
  multiSelectComboBoxMixin
9336
9400
  )(