@vaadin/multi-select-combo-box 23.1.2 → 23.2.0-dev.48e5e3967

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.2",
3
+ "version": "23.2.0-dev.48e5e3967",
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.2",
37
- "@vaadin/component-base": "^23.1.2",
38
- "@vaadin/field-base": "^23.1.2",
39
- "@vaadin/input-container": "^23.1.2",
40
- "@vaadin/vaadin-lumo-styles": "^23.1.2",
41
- "@vaadin/vaadin-material-styles": "^23.1.2",
42
- "@vaadin/vaadin-themable-mixin": "^23.1.2"
38
+ "@vaadin/combo-box": "23.2.0-dev.48e5e3967",
39
+ "@vaadin/component-base": "23.2.0-dev.48e5e3967",
40
+ "@vaadin/field-base": "23.2.0-dev.48e5e3967",
41
+ "@vaadin/input-container": "23.2.0-dev.48e5e3967",
42
+ "@vaadin/lit-renderer": "23.2.0-dev.48e5e3967",
43
+ "@vaadin/vaadin-lumo-styles": "23.2.0-dev.48e5e3967",
44
+ "@vaadin/vaadin-material-styles": "23.2.0-dev.48e5e3967",
45
+ "@vaadin/vaadin-themable-mixin": "23.2.0-dev.48e5e3967"
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": "6fb205c6e9a761feadfb779dd5d7af96d3102e56"
52
+ "gitHead": "961bc4ae5b707c3c02f12b99819b3c12c9b478aa"
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
 
@@ -101,10 +102,6 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
101
102
  };
102
103
  }
103
104
 
104
- static get observers() {
105
- return ['_readonlyItemsChanged(readonly, selectedItems)'];
106
- }
107
-
108
105
  /**
109
106
  * Reference to the clear button element.
110
107
  * @protected
@@ -114,6 +111,15 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
114
111
  return this.querySelector('[part="clear-button"]');
115
112
  }
116
113
 
114
+ /**
115
+ * Tag name prefix used by scroller and items.
116
+ * @protected
117
+ * @return {string}
118
+ */
119
+ get _tagNamePrefix() {
120
+ return 'vaadin-multi-select-combo-box';
121
+ }
122
+
117
123
  /**
118
124
  * Override method inherited from the combo-box
119
125
  * to allow opening dropdown when readonly.
@@ -125,14 +131,6 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
125
131
  }
126
132
  }
127
133
 
128
- /**
129
- * @protected
130
- * @override
131
- */
132
- _getItemElements() {
133
- return Array.from(this.$.dropdown._scroller.querySelectorAll('vaadin-multi-select-combo-box-item'));
134
- }
135
-
136
134
  /** @protected */
137
135
  ready() {
138
136
  super.ready();
@@ -141,6 +139,20 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
141
139
  this._toggleElement = this.querySelector('.toggle-button');
142
140
  }
143
141
 
142
+ /**
143
+ * Override combo-box method to set correct owner for using by item renderers.
144
+ * This needs to be done before the scroller gets added to the DOM to ensure
145
+ * Lit directive works in case when combo-box is opened using attribute.
146
+ *
147
+ * @protected
148
+ * @override
149
+ */
150
+ _initScroller() {
151
+ const comboBox = this.getRootNode().host;
152
+
153
+ super._initScroller(comboBox);
154
+ }
155
+
144
156
  /**
145
157
  * Override method from `InputMixin`.
146
158
  *
@@ -299,19 +311,6 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
299
311
  }
300
312
  }
301
313
 
302
- /**
303
- * Override method inherited from the combo-box
304
- * to render only selected items when read-only,
305
- * even if a different set of items is provided.
306
- *
307
- * @protected
308
- * @override
309
- */
310
- _setOverlayItems(items) {
311
- const effectiveItems = this.readonly ? this.selectedItems : items;
312
- super._setOverlayItems(effectiveItems);
313
- }
314
-
315
314
  /**
316
315
  * Override method inherited from the combo-box
317
316
  * to not request data provider when read-only.
@@ -328,20 +327,6 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
328
327
 
329
328
  return super._shouldLoadPage(page);
330
329
  }
331
-
332
- /** @private */
333
- _readonlyItemsChanged(readonly, selectedItems) {
334
- if (readonly && selectedItems) {
335
- this.__savedItems = this._getOverlayItems();
336
- this._setOverlayItems(selectedItems);
337
- }
338
-
339
- // Restore the original dropdown items
340
- if (readonly === false && this.__savedItems) {
341
- this._setOverlayItems(this.__savedItems);
342
- this.__savedItems = null;
343
- }
344
- }
345
330
  }
346
331
 
347
332
  customElements.define(MultiSelectComboBoxInternal.is, MultiSelectComboBoxInternal);
@@ -131,6 +131,7 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
131
131
  * Custom property | Description | Default
132
132
  * -----------------------------------------------------|----------------------------|--------
133
133
  * `--vaadin-field-default-width` | Default width of the field | `12em`
134
+ * `--vaadin-multi-select-combo-box-overlay-width` | Width of the overlay | `auto`
134
135
  * `--vaadin-multi-select-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
135
136
  * `--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`
136
137
  *
@@ -109,6 +109,7 @@ registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectCo
109
109
  * Custom property | Description | Default
110
110
  * -----------------------------------------------------|----------------------------|--------
111
111
  * `--vaadin-field-default-width` | Default width of the field | `12em`
112
+ * `--vaadin-multi-select-combo-box-overlay-width` | Width of the overlay | `auto`
112
113
  * `--vaadin-multi-select-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
113
114
  * `--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`
114
115
  *
@@ -153,7 +154,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
153
154
 
154
155
  <vaadin-multi-select-combo-box-internal
155
156
  id="comboBox"
156
- items="[[items]]"
157
+ items="[[__effectiveItems]]"
157
158
  item-id-path="[[itemIdPath]]"
158
159
  item-label-path="[[itemLabelPath]]"
159
160
  item-value-path="[[itemValuePath]]"
@@ -166,7 +167,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
166
167
  last-filter="{{_lastFilter}}"
167
168
  loading="{{loading}}"
168
169
  size="{{size}}"
169
- filtered-items="[[filteredItems]]"
170
+ filtered-items="[[__effectiveFilteredItems]]"
170
171
  selected-items="[[selectedItems]]"
171
172
  opened="{{opened}}"
172
173
  renderer="[[renderer]]"
@@ -424,6 +425,18 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
424
425
  */
425
426
  filteredItems: Array,
426
427
 
428
+ /** @private */
429
+ __effectiveItems: {
430
+ type: Array,
431
+ computed: '__computeEffectiveItems(items, selectedItems, readonly)',
432
+ },
433
+
434
+ /** @private */
435
+ __effectiveFilteredItems: {
436
+ type: Array,
437
+ computed: '__computeEffectiveFilteredItems(items, filteredItems, selectedItems, readonly)',
438
+ },
439
+
427
440
  /** @protected */
428
441
  _hasValue: {
429
442
  type: Boolean,
@@ -681,7 +694,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
681
694
 
682
695
  /** @private */
683
696
  _getItemLabel(item) {
684
- return item && Object.prototype.hasOwnProperty.call(item, this.itemLabelPath) ? item[this.itemLabelPath] : item;
697
+ return this.$.comboBox._getItemLabel(item);
685
698
  }
686
699
 
687
700
  /** @private */
@@ -1077,6 +1090,16 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
1077
1090
  // and keep the overlay opened when clicking a chip.
1078
1091
  event.preventDefault();
1079
1092
  }
1093
+
1094
+ /** @private */
1095
+ __computeEffectiveItems(items, selectedItems, readonly) {
1096
+ return items && readonly ? selectedItems : items;
1097
+ }
1098
+
1099
+ /** @private */
1100
+ __computeEffectiveFilteredItems(items, filteredItems, selectedItems, readonly) {
1101
+ return !items && readonly ? selectedItems : filteredItems;
1102
+ }
1080
1103
  }
1081
1104
 
1082
1105
  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);