@descope/web-components-ui 1.0.194 → 1.0.196

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
@@ -841,6 +841,10 @@ const inputValidationMixin = (superclass) =>
841
841
  return this.hasAttribute('readonly') && this.getAttribute('readonly') !== 'false';
842
842
  }
843
843
 
844
+ get isDisabled() {
845
+ return this.hasAttribute('disabled') && this.getAttribute('disabled') !== 'false';
846
+ }
847
+
844
848
  get pattern() {
845
849
  return this.getAttribute('pattern');
846
850
  }
@@ -2330,8 +2334,8 @@ const createCssVarImageClass = ({ componentName, varName, fallbackVarName }) =>
2330
2334
  const CssVarImageClass = compose(
2331
2335
  createStyleMixin({
2332
2336
  mappings: {
2333
- height: { selector: () => ':host' },
2334
- width: { selector: () => ':host' },
2337
+ height: { selector: () => ':host > div' },
2338
+ width: { selector: () => ':host > div' },
2335
2339
  [varName]: { property: 'content' },
2336
2340
  [fallbackVarName]: { property: 'content' },
2337
2341
  },
@@ -2735,7 +2739,7 @@ const PasscodeClass = compose(
2735
2739
  mappings: {
2736
2740
  fontSize: [{ ...digitField, property: textVars$2.fontSize }, host$8],
2737
2741
  hostWidth: { property: 'width' },
2738
- fontFamily: host$8,
2742
+ fontFamily: [host$8, { ...label$7 }],
2739
2743
  labelTextColor: [
2740
2744
  { ...label$7, property: 'color' },
2741
2745
  { ...requiredIndicator$7, property: 'color' },
@@ -3142,6 +3146,135 @@ const componentName$c = getComponentName('combo-box');
3142
3146
 
3143
3147
  const ComboBoxMixin = (superclass) =>
3144
3148
  class ComboBoxMixinClass extends superclass {
3149
+ // eslint-disable-next-line class-methods-use-this
3150
+ #renderItem = ({ displayName, value, label }) => {
3151
+ return `<span data-name="${label}" data-id="${value}">${displayName}</span>`;
3152
+ };
3153
+
3154
+ #data;
3155
+
3156
+ get defaultValue() {
3157
+ return this.getAttribute('default-value');
3158
+ }
3159
+
3160
+ get renderItem() {
3161
+ return this.#renderItem;
3162
+ }
3163
+
3164
+ set renderItem(renderFn) {
3165
+ this.#renderItem = renderFn;
3166
+ this.renderItems();
3167
+ }
3168
+
3169
+ get data() {
3170
+ if (this.#data) return this.#data;
3171
+
3172
+ const dataAttr = this.getAttribute('data');
3173
+
3174
+ if (dataAttr) {
3175
+ try {
3176
+ const data = JSON.parse(dataAttr);
3177
+ if (this.isValidDataType(data)) {
3178
+ return data;
3179
+ }
3180
+ } catch (e) {
3181
+ // eslint-disable-next-line no-console
3182
+ console.error('could not parse data string from attribute "data" -', e.message);
3183
+ }
3184
+ }
3185
+
3186
+ return [];
3187
+ }
3188
+
3189
+ set data(data) {
3190
+ if (this.isValidDataType(data)) {
3191
+ this.#data = data;
3192
+ this.renderItems();
3193
+ }
3194
+ }
3195
+
3196
+ // eslint-disable-next-line class-methods-use-this
3197
+ isValidDataType(data) {
3198
+ const isValid = Array.isArray(data);
3199
+ if (!isValid) {
3200
+ // eslint-disable-next-line no-console
3201
+ console.error('data must be an array, received:', data);
3202
+ }
3203
+
3204
+ return isValid;
3205
+ }
3206
+
3207
+ getItemsTemplate() {
3208
+ return this.data?.reduce?.((acc, item) => acc + (this.renderItem?.(item || {}) || ''), '');
3209
+ }
3210
+
3211
+ renderItems() {
3212
+ const template = this.getItemsTemplate();
3213
+ if (template) this.innerHTML = template;
3214
+ }
3215
+
3216
+ handleSelectedItem() {
3217
+ if (this.isDisabled || this.isReadOnly) {
3218
+ this.baseElement.selectedItem = undefined;
3219
+ return;
3220
+ }
3221
+
3222
+ const currentSelected = this.selectedItem?.['data-id'];
3223
+
3224
+ this.baseElement.selectedItem = undefined;
3225
+
3226
+ // if previously selected item ID exists in current children, set it as selected
3227
+ if (currentSelected) {
3228
+ this.value = currentSelected;
3229
+ }
3230
+
3231
+ // otherwise, if default value is specified, set default value as selected item
3232
+ if (!this.value) {
3233
+ this.setDefaultValue();
3234
+ }
3235
+
3236
+ // otherwise, set first item as selected item
3237
+ if (!this.value) {
3238
+ this.value = this.items?.[0]?.['data-id'];
3239
+ }
3240
+ }
3241
+
3242
+ // eslint-disable-next-line class-methods-use-this
3243
+ customValueTransformFn(val) {
3244
+ return val;
3245
+ }
3246
+
3247
+ // We want to override Vaadin's Combo Box value setter. This is needed since Vaadin couples between the
3248
+ // field that it searches the value, and the finaly display value of the input.
3249
+ // We provide a custom transform function to override that behavior.
3250
+ setComboBoxDescriptor() {
3251
+ const valueDescriptor = Object.getOwnPropertyDescriptor(
3252
+ this.inputElement.constructor.prototype,
3253
+ 'value'
3254
+ );
3255
+
3256
+ const comboBox = this;
3257
+
3258
+ Object.defineProperties(this.inputElement, {
3259
+ value: {
3260
+ ...valueDescriptor,
3261
+ set(val) {
3262
+ if (!comboBox.items?.length) {
3263
+ return;
3264
+ }
3265
+
3266
+ const transformedValue = comboBox.customValueTransformFn(val) || '';
3267
+
3268
+ if (transformedValue === this.value) {
3269
+ return;
3270
+ }
3271
+
3272
+ valueDescriptor.set.call(this, transformedValue);
3273
+ },
3274
+ },
3275
+ });
3276
+ }
3277
+
3145
3278
  // vaadin api is to set props on their combo box node,
3146
3279
  // in order to avoid it, we are passing the children of this component
3147
3280
  // to the items & renderer props, so it will be used as the combo box items
@@ -3162,11 +3295,16 @@ const ComboBoxMixin = (superclass) =>
3162
3295
 
3163
3296
  baseElement.items = items;
3164
3297
 
3165
- baseElement.renderer = (root, combo, model) => {
3166
- // eslint-disable-next-line no-param-reassign
3167
- root.innerHTML = model.item.outerHTML;
3168
- };
3298
+ setTimeout(() => {
3299
+ // set timeout to ensure this runs after customValueTransformFn had the chance to be overriden
3300
+ this.handleSelectedItem();
3301
+ }, 0);
3169
3302
  }
3303
+
3304
+ baseElement.renderer = (root, combo, model) => {
3305
+ // eslint-disable-next-line no-param-reassign
3306
+ root.innerHTML = model.item.outerHTML;
3307
+ };
3170
3308
  }
3171
3309
 
3172
3310
  // the default vaadin behavior is to attach the overlay to the body when opened
@@ -3184,14 +3322,31 @@ const ComboBoxMixin = (superclass) =>
3184
3322
  init() {
3185
3323
  super.init?.();
3186
3324
 
3325
+ this.setComboBoxDescriptor();
3326
+
3187
3327
  this.#overrideOverlaySettings();
3328
+
3329
+ this.renderItems();
3330
+
3331
+ observeAttributes(this, this.renderItems.bind(this), { includeAttrs: ['data'] });
3332
+
3188
3333
  observeChildren(this, this.#onChildrenChange.bind(this));
3334
+
3335
+ this.setDefaultValue();
3336
+ }
3337
+
3338
+ setDefaultValue() {
3339
+ this.value = this.defaultValue;
3189
3340
  }
3190
3341
 
3191
3342
  set value(val) {
3192
- this.baseElement.selectedItem = this.baseElement.items.find(
3193
- (item) => item['data-id'] === val
3194
- );
3343
+ const child = this.baseElement.items.find((item) => item['data-id'] === val);
3344
+
3345
+ if (!child) {
3346
+ return;
3347
+ }
3348
+
3349
+ this.baseElement.selectedItem = child;
3195
3350
  }
3196
3351
 
3197
3352
  get value() {
@@ -3328,7 +3483,7 @@ const ComboBoxClass = compose(
3328
3483
  // with the same name. Including it will cause Vaadin to calculate NaN size,
3329
3484
  // and reset items to an empty array, and opening the list box with no items
3330
3485
  // to display.
3331
- excludeAttrsSync: ['tabindex', 'size'],
3486
+ excludeAttrsSync: ['tabindex', 'size', 'data'],
3332
3487
  componentName: componentName$c,
3333
3488
  includeForwardProps: ['items', 'renderer', 'selectedItem'],
3334
3489
  })
@@ -4598,20 +4753,26 @@ let PhoneFieldInternal$1 = class PhoneFieldInternal extends BaseInputClass$3 {
4598
4753
 
4599
4754
  this.innerHTML = `
4600
4755
  <div>
4601
- <descope-combo-box
4602
- item-label-path="data-name"
4603
- item-value-path="data-id"
4604
- >
4605
- ${CountryCodes.map((item) => comboBoxItem(item)).join('')}
4606
- </descope-combo-box>
4607
- <div class="separator"></div>
4608
- <descope-text-field type="tel"></descope-text-field>
4756
+ <descope-combo-box
4757
+ item-label-path="data-name"
4758
+ item-value-path="data-id"
4759
+ >
4760
+ ${CountryCodes.map((item) => comboBoxItem(item)).join('')}
4761
+ </descope-combo-box>
4762
+ <div class="separator"></div>
4763
+ <descope-text-field type="tel"></descope-text-field>
4609
4764
  </div>
4610
4765
  `;
4611
4766
 
4612
4767
  this.countryCodeInput = this.querySelector('descope-combo-box');
4613
4768
  this.phoneNumberInput = this.querySelector('descope-text-field');
4614
4769
  this.inputs = [this.countryCodeInput, this.phoneNumberInput];
4770
+
4771
+ // override combo box setter to display dialCode value in input
4772
+ this.countryCodeInput.customValueTransformFn = (val) => {
4773
+ const [, dialCode] = val.split(' ');
4774
+ return dialCode;
4775
+ };
4615
4776
  }
4616
4777
 
4617
4778
  get value() {
@@ -4669,7 +4830,6 @@ let PhoneFieldInternal$1 = class PhoneFieldInternal extends BaseInputClass$3 {
4669
4830
 
4670
4831
  super.init?.();
4671
4832
  this.initInputs();
4672
- this.setComboBoxDescriptor();
4673
4833
  }
4674
4834
 
4675
4835
  getRestrictedCountries() {
@@ -4711,34 +4871,6 @@ let PhoneFieldInternal$1 = class PhoneFieldInternal extends BaseInputClass$3 {
4711
4871
  }
4712
4872
  }
4713
4873
 
4714
- // We want to override Vaadin's Combo Box value setter. This is needed since Vaadin couples between the
4715
- // field that it searches the value, and the finaly display value of the input. We want to search ALL
4716
- // the values (so we made a field with all the values), but display ONLY the dial code, so we added
4717
- // this setter, which does that.
4718
- setComboBoxDescriptor() {
4719
- const comboBox = this.countryCodeInput;
4720
- const input = comboBox.shadowRoot.querySelector('input');
4721
- const valueDescriptor = Object.getOwnPropertyDescriptor(input.constructor.prototype, 'value');
4722
- Object.defineProperties(input, {
4723
- value: {
4724
- ...valueDescriptor,
4725
- set(val) {
4726
- if (!comboBox.items?.length) {
4727
- return;
4728
- }
4729
-
4730
- const [, dialCode] = val.split(' ');
4731
-
4732
- if (val === this.value) {
4733
- return;
4734
- }
4735
-
4736
- valueDescriptor.set.call(this, dialCode || '');
4737
- },
4738
- },
4739
- });
4740
- }
4741
-
4742
4874
  initInputs() {
4743
4875
  // Sanitize phone input value to filter everything but digits
4744
4876
  this.phoneNumberInput.addEventListener('input', (e) => {
@@ -6182,14 +6314,18 @@ const customMixin = (superclass) =>
6182
6314
  get data() {
6183
6315
  if (this.#data) return this.#data;
6184
6316
 
6185
- try {
6186
- const data = JSON.parse(this.getAttribute('data'));
6187
- if (this.isValidDataType(data)) {
6188
- return data;
6317
+ const dataAttr = this.getAttribute('data');
6318
+
6319
+ if (dataAttr) {
6320
+ try {
6321
+ const data = JSON.parse(dataAttr);
6322
+ if (this.isValidDataType(data)) {
6323
+ return data;
6324
+ }
6325
+ } catch (e) {
6326
+ // eslint-disable-next-line no-console
6327
+ console.error('could not parse data string from attribute "data" - ', e.message);
6189
6328
  }
6190
- } catch (e) {
6191
- // eslint-disable-next-line no-console
6192
- console.error('could not parse data string from attribute "data" - ', e.message);
6193
6329
  }
6194
6330
 
6195
6331
  return [];
@@ -6219,7 +6355,7 @@ const customMixin = (superclass) =>
6219
6355
 
6220
6356
  renderItems() {
6221
6357
  const template = this.getItemsTemplate();
6222
- if (template) this.innerHTML = this.getItemsTemplate();
6358
+ if (template) this.innerHTML = template;
6223
6359
  }
6224
6360
 
6225
6361
  init() {