@descope-ui/descope-combo-box 0.0.1 → 0.0.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/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
1
+ # Changelog
2
+
3
+ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
+
5
+ ## [0.0.3](https://github.com/descope/web-components-ui/compare/@descope-ui/descope-combo-box-0.0.2...@descope-ui/descope-combo-box-0.0.3) (2025-02-04)
6
+
7
+ ### Dependency Updates
8
+
9
+ * `@descope-ui/theme-globals` updated to version `0.0.3`
10
+ * `@descope-ui/theme-input-wrapper` updated to version `0.0.3`
11
+ * `@descope-ui/common` updated to version `0.0.3`
12
+ ## [0.0.2](https://github.com/descope/web-components-ui/compare/@descope-ui/descope-combo-box-0.0.1...@descope-ui/descope-combo-box-0.0.2) (2025-01-28)
13
+
14
+ ### Dependency Updates
15
+
16
+ * `@descope-ui/theme-globals` updated to version `0.0.2`
17
+ * `@descope-ui/theme-input-wrapper` updated to version `0.0.2`
18
+ * `@descope-ui/common` updated to version `0.0.2`
19
+ ## 0.0.1 (2025-01-28)
20
+
21
+ ### Dependency Updates
22
+
23
+ * `e2e-utils` updated to version `0.0.1`
24
+ * `test-drivers` updated to version `0.0.1`
25
+ * `@descope-ui/theme-globals` updated to version `0.0.1`
26
+ * `@descope-ui/theme-input-wrapper` updated to version `0.0.1`
27
+ * `@descope-ui/common` updated to version `0.0.1`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descope-ui/descope-combo-box",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "exports": {
5
5
  ".": {
6
6
  "import": "./src/component/index.js"
@@ -19,9 +19,9 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@vaadin/combo-box": "24.3.4",
22
- "@descope-ui/common": "0.0.1",
23
- "@descope-ui/theme-globals": "0.0.1",
24
- "theme-input-wrapper": "0.0.1"
22
+ "@descope-ui/common": "0.0.3",
23
+ "@descope-ui/theme-globals": "0.0.3",
24
+ "@descope-ui/theme-input-wrapper": "0.0.3"
25
25
  },
26
26
  "publishConfig": {
27
27
  "link-workspace-packages": false
package/project.json CHANGED
@@ -3,5 +3,15 @@
3
3
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
4
  "sourceRoot": "packages/web-components/components/descope-combo-box/src",
5
5
  "projectType": "library",
6
+ "targets": {
7
+ "version": {
8
+ "executor": "@jscutlery/semver:version",
9
+ "options": {
10
+ "trackDeps": true,
11
+ "push": false,
12
+ "preset": "conventional"
13
+ }
14
+ }
15
+ },
6
16
  "tags": []
7
17
  }
@@ -123,6 +123,14 @@ const ComboBoxMixin = (superclass) =>
123
123
  }
124
124
  }
125
125
 
126
+ get hasDynamicData() {
127
+ return this.getAttribute('has-dynamic-data') === 'true';
128
+ }
129
+
130
+ get shouldSelectItemOnItemsChange() {
131
+ return !this.hasDynamicData || this.allowCustomValue;
132
+ }
133
+
126
134
  handleSelectedItem() {
127
135
  const { selectedItem } = this.baseElement;
128
136
  const currentSelected = selectedItem?.['data-id'];
@@ -133,7 +141,7 @@ const ComboBoxMixin = (superclass) =>
133
141
  }
134
142
 
135
143
  // if previously selected item ID exists in current children, set it as selected
136
- if (currentSelected) {
144
+ if (currentSelected && this.shouldSelectItemOnItemsChange) {
137
145
  this.value = currentSelected;
138
146
  }
139
147
 
@@ -233,6 +241,15 @@ const ComboBoxMixin = (superclass) =>
233
241
  };
234
242
  }
235
243
 
244
+ #disableDataProviderFilterEventIfNeeded() {
245
+ if (this.hasDynamicData) {
246
+ // For the autocomplete field, we don't want to trigger the data provider filter changed event
247
+ // because it changes the loading state on every keystroke, making the overlay open and close
248
+ // on every keystroke, causing a flickering effect in the loading state.
249
+ this.baseElement._dataProviderFilterChanged = () => {};
250
+ }
251
+ }
252
+
236
253
  init() {
237
254
  super.init?.();
238
255
 
@@ -249,6 +266,7 @@ const ComboBoxMixin = (superclass) =>
249
266
  this.setComboBoxDescriptor();
250
267
  this.#overrideOverlaySettings();
251
268
  this.#overrideRenderer();
269
+ this.#disableDataProviderFilterEventIfNeeded();
252
270
 
253
271
  // Set up observers - order matters here since renderItems can clear innerHTML
254
272
  observeAttributes(this, this.renderItems.bind(this), {
@@ -258,11 +276,23 @@ const ComboBoxMixin = (superclass) =>
258
276
 
259
277
  this.setDefaultValue();
260
278
 
261
- this.baseElement.addEventListener('selected-item-changed', () => {
279
+ // Using "value-changed" event instead of "selected-item-changed" event to avoid
280
+ // the issue of the value not being updated in the input field when the user enter a custom value
281
+ this.baseElement.addEventListener('value-changed', () => {
262
282
  this.dispatchEvent(
263
283
  new Event('input', { bubbles: true, composed: true }),
264
284
  );
265
285
  });
286
+
287
+ this.baseElement.addEventListener('filter-changed', (e) => {
288
+ this.dispatchEvent(
289
+ new CustomEvent('filter-changed', {
290
+ bubbles: true,
291
+ composed: true,
292
+ detail: e.detail,
293
+ }),
294
+ );
295
+ });
266
296
  }
267
297
 
268
298
  onLabelClick() {
@@ -270,7 +300,9 @@ const ComboBoxMixin = (superclass) =>
270
300
  return;
271
301
  }
272
302
  this.focus();
273
- this.setAttribute('opened', 'true');
303
+ if (!this.autoOpenDisabled) {
304
+ this.setAttribute('opened', 'true');
305
+ }
274
306
  }
275
307
 
276
308
  attributeChangedCallback(attrName, oldValue, newValue) {
@@ -334,6 +366,10 @@ const ComboBoxMixin = (superclass) =>
334
366
  get allowCustomValue() {
335
367
  return this.getAttribute('allow-custom-value') === 'true';
336
368
  }
369
+
370
+ get autoOpenDisabled() {
371
+ return this.getAttribute('auto-open-disabled') === 'true';
372
+ }
337
373
  };
338
374
 
339
375
  const {
@@ -347,6 +383,8 @@ const {
347
383
  requiredIndicator,
348
384
  helperText,
349
385
  errorMessage,
386
+ loader,
387
+ overlayContent,
350
388
  } = {
351
389
  host: { selector: () => ':host' },
352
390
  inputField: { selector: '::part(input-field)' },
@@ -360,6 +398,8 @@ const {
360
398
  },
361
399
  helperText: { selector: '::part(helper-text)' },
362
400
  errorMessage: { selector: '::part(error-message)' },
401
+ loader: { selector: 'vaadin-combo-box-overlay::part(loader)' },
402
+ overlayContent: { selector: 'vaadin-combo-box-overlay::part(content)' },
363
403
  };
364
404
 
365
405
  export const ComboBoxClass = compose(
@@ -470,6 +510,26 @@ export const ComboBoxClass = compose(
470
510
  overlayItemPaddingInlineEnd: {
471
511
  property: () => ComboBoxClass.cssVarList.overlay.itemPaddingInlineEnd,
472
512
  },
513
+ overlayCheckmarkDisplay: {
514
+ property: () => ComboBoxClass.cssVarList.overlay.checkmarkDisplay,
515
+ },
516
+ overlaySelectedItemBackground: {
517
+ property: () => ComboBoxClass.cssVarList.overlay.selectedItemBackground,
518
+ },
519
+ overlaySelectedItemHoverBackground: {
520
+ property: () =>
521
+ ComboBoxClass.cssVarList.overlay.selectedItemHoverBackground,
522
+ },
523
+ overlaySelectedItemFocusBackground: {
524
+ property: () =>
525
+ ComboBoxClass.cssVarList.overlay.selectedItemFocusBackground,
526
+ },
527
+ overlayItemHoverBackground: {
528
+ property: () => ComboBoxClass.cssVarList.overlay.itemHoverBackground,
529
+ },
530
+ overlayItemFocusBackground: {
531
+ property: () => ComboBoxClass.cssVarList.overlay.itemFocusBackground,
532
+ },
473
533
  },
474
534
  }),
475
535
  draggableMixin,
@@ -499,50 +559,46 @@ export const ComboBoxClass = compose(
499
559
  selector: 'vaadin-combo-box-item',
500
560
  property: 'padding-inline-end',
501
561
  },
502
-
503
- loaderTop: {
504
- selector: 'vaadin-combo-box-overlay::part(loader)',
505
- property: 'top',
506
- },
507
- loaderLeft: {
508
- selector: 'vaadin-combo-box-overlay::part(loader)',
509
- property: 'left',
510
- },
511
- loaderRight: {
512
- selector: 'vaadin-combo-box-overlay::part(loader)',
513
- property: 'right',
562
+ checkmarkDisplay: {
563
+ selector: 'vaadin-combo-box-item::part(checkmark)',
564
+ property: 'display',
514
565
  },
515
- loaderMargin: {
516
- selector: 'vaadin-combo-box-overlay::part(loader)',
517
- property: 'margin',
566
+ selectedItemBackground: {
567
+ selector: 'vaadin-combo-box-item[selected]',
568
+ property: 'background-color',
518
569
  },
519
- loaderWidth: {
520
- selector: 'vaadin-combo-box-overlay::part(loader)',
521
- property: 'width',
570
+ selectedItemHoverBackground: {
571
+ selector: 'vaadin-combo-box-item[selected]:hover:not([disabled])',
572
+ property: 'background-color',
522
573
  },
523
- loaderHeight: {
524
- selector: 'vaadin-combo-box-overlay::part(loader)',
525
- property: 'height',
574
+ selectedItemFocusBackground: {
575
+ selector: 'vaadin-combo-box-item[selected][focused]:not([disabled])',
576
+ property: 'background-color',
526
577
  },
527
- loaderBorder: {
528
- selector: 'vaadin-combo-box-overlay::part(loader)',
529
- property: 'border',
578
+ itemHoverBackground: {
579
+ selector: 'vaadin-combo-box-item:hover:not([selected]):not([disabled])',
580
+ property: 'background-color',
530
581
  },
531
- loaderBorderColor: {
532
- selector: 'vaadin-combo-box-overlay::part(loader)',
533
- property: 'border-color',
582
+ itemFocusBackground: {
583
+ selector:
584
+ 'vaadin-combo-box-item[focused]:not([selected]):not([disabled])',
585
+ property: 'background-color',
534
586
  },
535
- loaderBorderRadius: {
536
- selector: 'vaadin-combo-box-overlay::part(loader)',
537
- property: 'border-radius',
538
- },
539
- contentHeight: {
540
- selector: 'vaadin-combo-box-overlay::part(content)',
541
- property: 'height',
542
- },
543
- contentOpacity: {
544
- selector: 'vaadin-combo-box-overlay::part(content)',
545
- property: 'opacity',
587
+
588
+ loaderTop: { ...loader, property: 'top' },
589
+ loaderLeft: { ...loader, property: 'left' },
590
+ loaderRight: { ...loader, property: 'right' },
591
+ loaderMargin: { ...loader, property: 'margin' },
592
+ loaderWidth: { ...loader, property: 'width' },
593
+ loaderHeight: { ...loader, property: 'height' },
594
+ loaderBorder: { ...loader, property: 'border' },
595
+ loaderBorderColor: { ...loader, property: 'border-color' },
596
+ loaderBorderRadius: { ...loader, property: 'border-radius' },
597
+ contentHeight: { ...overlayContent, property: 'height' },
598
+ contentOpacity: { ...overlayContent, property: 'opacity' },
599
+ scrollerMinHeight: {
600
+ selector: 'vaadin-combo-box-scroller',
601
+ property: 'min-height',
546
602
  },
547
603
  },
548
604
  forward: {
@@ -552,7 +608,7 @@ export const ComboBoxClass = compose(
552
608
  }),
553
609
  proxyInputMixin({
554
610
  proxyProps: ['selectionStart'],
555
- inputEvent: 'selected-item-changed',
611
+ inputEvent: 'value-changed',
556
612
  }),
557
613
  componentNameValidationMixin,
558
614
  ComboBoxMixin,
@@ -3,4 +3,4 @@ import { componentName, ComboBoxClass } from './ComboBoxClass';
3
3
 
4
4
  customElements.define(componentName, ComboBoxClass);
5
5
 
6
- export { ComboBoxClass };
6
+ export { ComboBoxClass, componentName };
package/src/theme.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import globals from '@descope-ui/theme-globals';
2
2
  import { ComboBoxClass } from './component/ComboBoxClass';
3
3
  import { getThemeRefs } from '@descope-ui/common/theme-helpers';
4
- import { refs } from 'theme-input-wrapper';
4
+ import { refs } from '@descope-ui/theme-input-wrapper';
5
5
 
6
6
  const globalRefs = getThemeRefs(globals);
7
7
  const vars = ComboBoxClass.cssVarList;
@@ -64,6 +64,14 @@ export const comboBox = {
64
64
  [vars.overlayItemBoxShadow]: 'none',
65
65
  [vars.overlayBackground]: refs.backgroundColor,
66
66
  [vars.overlayTextColor]: refs.valueTextColor,
67
+ [vars.overlayCheckmarkDisplay]: 'initial',
68
+ [vars.overlaySelectedItemBackground]: 'initial',
69
+ [vars.overlaySelectedItemHoverBackground]:
70
+ globalRefs.colors.primary.highlight,
71
+ [vars.overlaySelectedItemFocusBackground]:
72
+ globalRefs.colors.primary.highlight,
73
+ [vars.overlayItemHoverBackground]: globalRefs.colors.primary.highlight,
74
+ [vars.overlayItemFocusBackground]: globalRefs.colors.primary.highlight,
67
75
 
68
76
  // Overlay direct theme:
69
77
  [vars.overlay.minHeight]: '400px',
@@ -71,6 +79,7 @@ export const comboBox = {
71
79
 
72
80
  [vars.overlay.contentHeight]: '100%',
73
81
  [vars.overlay.contentOpacity]: '1',
82
+ [vars.overlay.scrollerMinHeight]: '1px',
74
83
  _loading: {
75
84
  [vars.overlay.loaderTop]: '50%',
76
85
  [vars.overlay.loaderLeft]: '50%',
@@ -81,10 +90,11 @@ export const comboBox = {
81
90
  [vars.overlay.loaderWidth]: '30px',
82
91
  [vars.overlay.loaderHeight]: '30px',
83
92
  [vars.overlay.loaderBorder]: '2px solid transparent',
84
- [vars.overlay
85
- .loaderBorderColor]: `${globalRefs.colors.primary.highlight} ${globalRefs.colors.primary.highlight} ${globalRefs.colors.primary.main} ${globalRefs.colors.primary.main}`,
93
+ [vars.overlay.loaderBorderColor]:
94
+ `${globalRefs.colors.primary.highlight} ${globalRefs.colors.primary.highlight} ${globalRefs.colors.primary.main} ${globalRefs.colors.primary.main}`,
86
95
  [vars.overlay.loaderBorderRadius]: '50%',
87
96
  [vars.overlay.contentHeight]: '100px',
97
+ [vars.overlay.scrollerMinHeight]: '100px',
88
98
  [vars.overlay.contentOpacity]: '0',
89
99
  },
90
100
  };
@@ -1,6 +1,6 @@
1
1
  /* eslint no-param-reassign: 0 */
2
2
 
3
- import { componentName } from '../src/component/ComboBoxClass';
3
+ import { componentName } from '../src/component';
4
4
  import { withForm } from '@descope-ui/common/sb-helpers';
5
5
  import {
6
6
  labelControl,