@vaadin/multi-select-combo-box 23.1.1 → 23.2.0-dev.8a7678b70

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/lit.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './src/lit/renderer-directives.js';
package/lit.js ADDED
@@ -0,0 +1 @@
1
+ export * from './src/lit/renderer-directives.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/multi-select-combo-box",
3
- "version": "23.1.1",
3
+ "version": "23.2.0-dev.8a7678b70",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -19,6 +19,8 @@
19
19
  "main": "vaadin-multi-select-combo-box.js",
20
20
  "module": "vaadin-multi-select-combo-box.js",
21
21
  "files": [
22
+ "lit.js",
23
+ "lit.d.ts",
22
24
  "src",
23
25
  "theme",
24
26
  "vaadin-*.d.ts",
@@ -33,18 +35,19 @@
33
35
  ],
34
36
  "dependencies": {
35
37
  "@polymer/polymer": "^3.0.0",
36
- "@vaadin/combo-box": "^23.1.1",
37
- "@vaadin/component-base": "^23.1.1",
38
- "@vaadin/field-base": "^23.1.1",
39
- "@vaadin/input-container": "^23.1.1",
40
- "@vaadin/vaadin-lumo-styles": "^23.1.1",
41
- "@vaadin/vaadin-material-styles": "^23.1.1",
42
- "@vaadin/vaadin-themable-mixin": "^23.1.1"
38
+ "@vaadin/combo-box": "23.2.0-dev.8a7678b70",
39
+ "@vaadin/component-base": "23.2.0-dev.8a7678b70",
40
+ "@vaadin/field-base": "23.2.0-dev.8a7678b70",
41
+ "@vaadin/input-container": "23.2.0-dev.8a7678b70",
42
+ "@vaadin/lit-renderer": "23.2.0-dev.8a7678b70",
43
+ "@vaadin/vaadin-lumo-styles": "23.2.0-dev.8a7678b70",
44
+ "@vaadin/vaadin-material-styles": "23.2.0-dev.8a7678b70",
45
+ "@vaadin/vaadin-themable-mixin": "23.2.0-dev.8a7678b70"
43
46
  },
44
47
  "devDependencies": {
45
48
  "@esm-bundle/chai": "^4.3.4",
46
49
  "@vaadin/testing-helpers": "^0.3.2",
47
50
  "sinon": "^13.0.2"
48
51
  },
49
- "gitHead": "390458d6519433a2dd502cef90da48e84573a275"
52
+ "gitHead": "85b403f96d8282f262322b56c0ff4289f843d02a"
50
53
  }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2017 - 2022 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { TemplateResult } from 'lit';
7
+ import { DirectiveResult } from 'lit/directive.js';
8
+ import { ComboBoxItemModel } from '@vaadin/combo-box/src/vaadin-combo-box.js';
9
+ import { LitRendererDirective } from '@vaadin/lit-renderer';
10
+ import { MultiSelectComboBox } from '../vaadin-multi-select-combo-box.js';
11
+
12
+ export type MultiSelectComboBoxLitRenderer<TItem> = (
13
+ item: TItem,
14
+ model: ComboBoxItemModel<TItem>,
15
+ comboBox: MultiSelectComboBox<TItem>,
16
+ ) => TemplateResult;
17
+
18
+ export class MultiSelectComboBoxRendererDirective<TItem> extends LitRendererDirective<
19
+ MultiSelectComboBox,
20
+ MultiSelectComboBoxLitRenderer<TItem>
21
+ > {
22
+ /**
23
+ * Adds the renderer callback to the combo-box.
24
+ */
25
+ addRenderer(): void;
26
+
27
+ /**
28
+ * Runs the renderer callback on the combo-box.
29
+ */
30
+ runRenderer(): void;
31
+
32
+ /**
33
+ * Removes the renderer callback from the combo-box.
34
+ */
35
+ removeRenderer(): void;
36
+ }
37
+
38
+ /**
39
+ * A Lit directive for rendering the content of the `<vaadin-multi-select-combo-box-item>` elements.
40
+ *
41
+ * The directive accepts a renderer callback returning a Lit template and assigns it to the combo-box
42
+ * via the `renderer` property. The renderer is called for each combo-box item when assigned
43
+ * and whenever a single dependency or an array of dependencies changes.
44
+ * It is not guaranteed that the renderer will be called immediately (synchronously) in both cases.
45
+ *
46
+ * Dependencies can be a single value or an array of values.
47
+ * Values are checked against previous values with strict equality (`===`),
48
+ * so the check won't detect nested property changes inside objects or arrays.
49
+ * When dependencies are provided as an array, each item is checked against the previous value
50
+ * at the same index with strict equality. Nested arrays are also checked only by strict
51
+ * equality.
52
+ *
53
+ * Example of usage:
54
+ * ```js
55
+ * `<vaadin-multi-select-combo-box
56
+ * ${multiSelectComboBoxRenderer((item, model, comboBox) => html`...`)}
57
+ * ></vaadin-multi-select-combo-box>`
58
+ * ```
59
+ *
60
+ * @param renderer the renderer callback that returns a Lit template.
61
+ * @param dependencies a single dependency or an array of dependencies
62
+ * which trigger a re-render when changed.
63
+ */
64
+ export declare function multiSelectComboBoxRenderer<TItem>(
65
+ renderer: MultiSelectComboBoxLitRenderer<TItem>,
66
+ dependencies?: unknown,
67
+ ): DirectiveResult<typeof MultiSelectComboBoxRendererDirective>;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2017 - 2022 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { directive } from 'lit/directive.js';
7
+ import { LitRendererDirective } from '@vaadin/lit-renderer';
8
+
9
+ export class MultiSelectComboBoxRendererDirective extends LitRendererDirective {
10
+ /**
11
+ * Adds the renderer callback to the combo-box.
12
+ */
13
+ addRenderer() {
14
+ this.element.renderer = (root, comboBox, model) => {
15
+ this.renderRenderer(root, model.item, model, comboBox);
16
+ };
17
+ }
18
+
19
+ /**
20
+ * Runs the renderer callback on the combo-box.
21
+ */
22
+ runRenderer() {
23
+ this.element.requestContentUpdate();
24
+ }
25
+
26
+ /**
27
+ * Removes the renderer callback from the combo-box.
28
+ */
29
+ removeRenderer() {
30
+ this.element.renderer = null;
31
+ }
32
+ }
33
+
34
+ /**
35
+ * A Lit directive for rendering the content of the `<vaadin-multi-select-combo-box-item>` elements.
36
+ *
37
+ * The directive accepts a renderer callback returning a Lit template and assigns it to the combo-box
38
+ * via the `renderer` property. The renderer is called for each combo-box item when assigned
39
+ * and whenever a single dependency or an array of dependencies changes.
40
+ * It is not guaranteed that the renderer will be called immediately (synchronously) in both cases.
41
+ *
42
+ * Dependencies can be a single value or an array of values.
43
+ * Values are checked against previous values with strict equality (`===`),
44
+ * so the check won't detect nested property changes inside objects or arrays.
45
+ * When dependencies are provided as an array, each item is checked against the previous value
46
+ * at the same index with strict equality. Nested arrays are also checked only by strict
47
+ * equality.
48
+ *
49
+ * Example of usage:
50
+ * ```js
51
+ * `<vaadin-multi-select-combo-box
52
+ * ${multiSelectComboBoxRenderer((item, model, comboBox) => html`...`)}
53
+ * ></vaadin-multi-select-combo-box>`
54
+ * ```
55
+ *
56
+ * @param renderer the renderer callback that returns a Lit template.
57
+ * @param dependencies a single dependency or an array of dependencies
58
+ * which trigger a re-render when changed.
59
+ */
60
+ export const multiSelectComboBoxRenderer = directive(MultiSelectComboBoxRendererDirective);
@@ -3,7 +3,9 @@
3
3
  * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import './vaadin-multi-select-combo-box-dropdown.js';
6
+ import './vaadin-multi-select-combo-box-item.js';
7
+ import './vaadin-multi-select-combo-box-overlay.js';
8
+ import './vaadin-multi-select-combo-box-scroller.js';
7
9
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
8
10
  import { ComboBoxDataProviderMixin } from '@vaadin/combo-box/src/vaadin-combo-box-data-provider-mixin.js';
9
11
  import { ComboBoxMixin } from '@vaadin/combo-box/src/vaadin-combo-box-mixin.js';
@@ -34,17 +36,16 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
34
36
 
35
37
  <slot></slot>
36
38
 
37
- <vaadin-multi-select-combo-box-dropdown
38
- id="dropdown"
39
- opened="[[opened]]"
39
+ <vaadin-multi-select-combo-box-overlay
40
+ id="overlay"
41
+ hidden$="[[_isOverlayHidden(filteredItems, loading)]]"
42
+ opened="[[_overlayOpened]]"
43
+ loading$="[[loading]]"
44
+ theme$="[[_theme]]"
40
45
  position-target="[[_target]]"
41
- renderer="[[renderer]]"
42
- _focused-index="[[_focusedIndex]]"
43
- _item-id-path="[[itemIdPath]]"
44
- _item-label-path="[[itemLabelPath]]"
45
- loading="[[loading]]"
46
- theme="[[theme]]"
47
- ></vaadin-multi-select-combo-box-dropdown>
46
+ no-vertical-overlap
47
+ restore-focus-node="[[inputElement]]"
48
+ ></vaadin-multi-select-combo-box-overlay>
48
49
  `;
49
50
  }
50
51
 
@@ -92,10 +93,6 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
92
93
  };
93
94
  }
94
95
 
95
- static get observers() {
96
- return ['_readonlyItemsChanged(readonly, selectedItems)'];
97
- }
98
-
99
96
  /**
100
97
  * Reference to the clear button element.
101
98
  * @protected
@@ -105,6 +102,15 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
105
102
  return this.querySelector('[part="clear-button"]');
106
103
  }
107
104
 
105
+ /**
106
+ * Tag name prefix used by scroller and items.
107
+ * @protected
108
+ * @return {string}
109
+ */
110
+ get _tagNamePrefix() {
111
+ return 'vaadin-multi-select-combo-box';
112
+ }
113
+
108
114
  /**
109
115
  * Override method inherited from the combo-box
110
116
  * to allow opening dropdown when readonly.
@@ -116,14 +122,6 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
116
122
  }
117
123
  }
118
124
 
119
- /**
120
- * @protected
121
- * @override
122
- */
123
- _getItemElements() {
124
- return Array.from(this.$.dropdown._scroller.querySelectorAll('vaadin-multi-select-combo-box-item'));
125
- }
126
-
127
125
  /** @protected */
128
126
  ready() {
129
127
  super.ready();
@@ -132,6 +130,20 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
132
130
  this._toggleElement = this.querySelector('.toggle-button');
133
131
  }
134
132
 
133
+ /**
134
+ * Override combo-box method to set correct owner for using by item renderers.
135
+ * This needs to be done before the scroller gets added to the DOM to ensure
136
+ * Lit directive works in case when combo-box is opened using attribute.
137
+ *
138
+ * @protected
139
+ * @override
140
+ */
141
+ _initScroller() {
142
+ const comboBox = this.getRootNode().host;
143
+
144
+ super._initScroller(comboBox);
145
+ }
146
+
135
147
  /**
136
148
  * Override method from `InputMixin`.
137
149
  *
@@ -278,19 +290,6 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
278
290
  }
279
291
  }
280
292
 
281
- /**
282
- * Override method inherited from the combo-box
283
- * to render only selected items when read-only,
284
- * even if a different set of items is provided.
285
- *
286
- * @protected
287
- * @override
288
- */
289
- _setOverlayItems(items) {
290
- const effectiveItems = this.readonly ? this.selectedItems : items;
291
- super._setOverlayItems(effectiveItems);
292
- }
293
-
294
293
  /**
295
294
  * Override method inherited from the combo-box
296
295
  * to not request data provider when read-only.
@@ -307,20 +306,6 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
307
306
 
308
307
  return super._shouldLoadPage(page);
309
308
  }
310
-
311
- /** @private */
312
- _readonlyItemsChanged(readonly, selectedItems) {
313
- if (readonly && selectedItems) {
314
- this.__savedItems = this._getOverlayItems();
315
- this._setOverlayItems(selectedItems);
316
- }
317
-
318
- // Restore the original dropdown items
319
- if (readonly === false && this.__savedItems) {
320
- this._setOverlayItems(this.__savedItems);
321
- this.__savedItems = null;
322
- }
323
- }
324
309
  }
325
310
 
326
311
  customElements.define(MultiSelectComboBoxInternal.is, MultiSelectComboBoxInternal);
@@ -153,7 +153,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
153
153
 
154
154
  <vaadin-multi-select-combo-box-internal
155
155
  id="comboBox"
156
- items="[[items]]"
156
+ items="[[__effectiveItems]]"
157
157
  item-id-path="[[itemIdPath]]"
158
158
  item-label-path="[[itemLabelPath]]"
159
159
  item-value-path="[[itemValuePath]]"
@@ -165,7 +165,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
165
165
  filter="{{filter}}"
166
166
  loading="{{loading}}"
167
167
  size="{{size}}"
168
- filtered-items="[[filteredItems]]"
168
+ filtered-items="[[__effectiveFilteredItems]]"
169
169
  selected-items="[[selectedItems]]"
170
170
  opened="{{opened}}"
171
171
  renderer="[[renderer]]"
@@ -423,6 +423,18 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
423
423
  */
424
424
  filteredItems: Array,
425
425
 
426
+ /** @private */
427
+ __effectiveItems: {
428
+ type: Array,
429
+ computed: '__computeEffectiveItems(items, selectedItems, readonly)',
430
+ },
431
+
432
+ /** @private */
433
+ __effectiveFilteredItems: {
434
+ type: Array,
435
+ computed: '__computeEffectiveFilteredItems(items, filteredItems, selectedItems, readonly)',
436
+ },
437
+
426
438
  /** @protected */
427
439
  _hasValue: {
428
440
  type: Boolean,
@@ -614,7 +626,10 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
614
626
  * @private
615
627
  */
616
628
  _onFilteredItemsChanged(event) {
617
- this.filteredItems = event.detail.value;
629
+ const { value } = event.detail;
630
+ if (Array.isArray(value) || value == null) {
631
+ this.filteredItems = value;
632
+ }
618
633
  }
619
634
 
620
635
  /** @private */
@@ -672,7 +687,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
672
687
 
673
688
  /** @private */
674
689
  _getItemLabel(item) {
675
- return item && Object.prototype.hasOwnProperty.call(item, this.itemLabelPath) ? item[this.itemLabelPath] : item;
690
+ return this.$.comboBox._getItemLabel(item);
676
691
  }
677
692
 
678
693
  /** @private */
@@ -1067,6 +1082,16 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
1067
1082
  // and keep the overlay opened when clicking a chip.
1068
1083
  event.preventDefault();
1069
1084
  }
1085
+
1086
+ /** @private */
1087
+ __computeEffectiveItems(items, selectedItems, readonly) {
1088
+ return items && readonly ? selectedItems : items;
1089
+ }
1090
+
1091
+ /** @private */
1092
+ __computeEffectiveFilteredItems(items, filteredItems, selectedItems, readonly) {
1093
+ return !items && readonly ? selectedItems : filteredItems;
1094
+ }
1070
1095
  }
1071
1096
 
1072
1097
  customElements.define(MultiSelectComboBox.is, MultiSelectComboBox);
@@ -1,47 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2022 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import './vaadin-multi-select-combo-box-item.js';
7
- import './vaadin-multi-select-combo-box-overlay.js';
8
- import './vaadin-multi-select-combo-box-scroller.js';
9
- import { html } from '@polymer/polymer/lib/utils/html-tag.js';
10
- import { ComboBoxDropdown } from '@vaadin/combo-box/src/vaadin-combo-box-dropdown.js';
11
-
12
- /**
13
- * An element used internally by `<vaadin-multi-select-combo-box>`. Not intended to be used separately.
14
- *
15
- * @extends ComboBoxDropdown
16
- * @private
17
- */
18
- class MultiSelectComboBoxDropdown extends ComboBoxDropdown {
19
- static get is() {
20
- return 'vaadin-multi-select-combo-box-dropdown';
21
- }
22
-
23
- static get template() {
24
- return html`
25
- <vaadin-multi-select-combo-box-overlay
26
- id="overlay"
27
- hidden$="[[_isOverlayHidden(_items.*, loading)]]"
28
- loading$="[[loading]]"
29
- opened="{{_overlayOpened}}"
30
- theme$="[[theme]]"
31
- position-target="[[positionTarget]]"
32
- no-vertical-overlap
33
- ></vaadin-multi-select-combo-box-overlay>
34
- `;
35
- }
36
-
37
- /** @protected */
38
- ready() {
39
- super.ready();
40
-
41
- // Set owner for using by item renderers
42
- const comboBox = this.getRootNode().host;
43
- this._scroller.comboBox = comboBox.getRootNode().host;
44
- }
45
- }
46
-
47
- customElements.define(MultiSelectComboBoxDropdown.is, MultiSelectComboBoxDropdown);