@vaadin/multi-select-combo-box 25.0.0-alpha1 → 25.0.0-alpha11

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.
Files changed (27) hide show
  1. package/package.json +15 -16
  2. package/src/{vaadin-multi-select-combo-box-styles.d.ts → styles/vaadin-multi-select-combo-box-base-styles.d.ts} +1 -3
  3. package/src/styles/vaadin-multi-select-combo-box-base-styles.js +58 -0
  4. package/src/styles/vaadin-multi-select-combo-box-chip-base-styles.js +112 -0
  5. package/src/styles/vaadin-multi-select-combo-box-overlay-base-styles.js +19 -0
  6. package/src/styles/vaadin-multi-select-combo-box-scroller-base-styles.js +8 -0
  7. package/src/vaadin-multi-select-combo-box-chip.js +4 -3
  8. package/src/vaadin-multi-select-combo-box-container.js +1 -0
  9. package/src/vaadin-multi-select-combo-box-item.js +7 -11
  10. package/src/vaadin-multi-select-combo-box-mixin.d.ts +9 -80
  11. package/src/vaadin-multi-select-combo-box-mixin.js +396 -267
  12. package/src/vaadin-multi-select-combo-box-overlay.js +5 -19
  13. package/src/vaadin-multi-select-combo-box-scroller.js +3 -24
  14. package/src/vaadin-multi-select-combo-box.d.ts +13 -7
  15. package/src/vaadin-multi-select-combo-box.js +40 -90
  16. package/vaadin-multi-select-combo-box.js +1 -1
  17. package/web-types.json +207 -230
  18. package/web-types.lit.json +78 -78
  19. package/src/vaadin-multi-select-combo-box-internal-mixin.js +0 -449
  20. package/src/vaadin-multi-select-combo-box-internal.js +0 -56
  21. package/src/vaadin-multi-select-combo-box-styles.js +0 -74
  22. package/theme/lumo/vaadin-multi-select-combo-box-chip-styles.d.ts +0 -10
  23. package/theme/lumo/vaadin-multi-select-combo-box-chip-styles.js +0 -107
  24. package/theme/lumo/vaadin-multi-select-combo-box-styles.d.ts +0 -10
  25. package/theme/lumo/vaadin-multi-select-combo-box-styles.js +0 -118
  26. package/theme/lumo/vaadin-multi-select-combo-box.d.ts +0 -8
  27. package/theme/lumo/vaadin-multi-select-combo-box.js +0 -8
@@ -1,449 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { ComboBoxDataProviderMixin } from '@vaadin/combo-box/src/vaadin-combo-box-data-provider-mixin.js';
7
- import { ComboBoxMixin } from '@vaadin/combo-box/src/vaadin-combo-box-mixin.js';
8
- import { ComboBoxPlaceholder } from '@vaadin/combo-box/src/vaadin-combo-box-placeholder.js';
9
-
10
- /**
11
- * @polymerMixin
12
- * @mixes ComboBoxDataProviderMixin
13
- * @mixes ComboBoxMixin
14
- */
15
- export const MultiSelectComboBoxInternalMixin = (superClass) =>
16
- class MultiSelectComboBoxInternalMixinClass extends ComboBoxDataProviderMixin(ComboBoxMixin(superClass)) {
17
- static get properties() {
18
- return {
19
- /**
20
- * A subset of items, filtered based on the user input.
21
- */
22
- filteredItems: {
23
- type: Array,
24
- notify: true,
25
- sync: true,
26
- },
27
-
28
- /**
29
- * When true, filter string isn't cleared after selecting an item.
30
- */
31
- keepFilter: {
32
- type: Boolean,
33
- value: false,
34
- },
35
-
36
- /**
37
- * When set to `true`, "loading" attribute is set
38
- * on the host and the overlay element.
39
- * @type {boolean}
40
- */
41
- loading: {
42
- type: Boolean,
43
- notify: true,
44
- sync: true,
45
- },
46
-
47
- /**
48
- * Total number of items.
49
- * @type {number | undefined}
50
- */
51
- size: {
52
- type: Number,
53
- notify: true,
54
- observer: '_sizeChanged',
55
- sync: true,
56
- },
57
-
58
- /**
59
- * Selected items to render in the dropdown
60
- * when the component is read-only.
61
- */
62
- selectedItems: {
63
- type: Array,
64
- value: () => [],
65
- },
66
-
67
- /**
68
- * Set to true to group selected items at the top of the overlay.
69
- * @attr {boolean} selected-items-on-top
70
- */
71
- selectedItemsOnTop: {
72
- type: Boolean,
73
- value: false,
74
- sync: true,
75
- },
76
-
77
- /**
78
- * Last input value entered by the user before value is updated.
79
- * Used to store `filter` property value before clearing it.
80
- */
81
- lastFilter: {
82
- type: String,
83
- notify: true,
84
- sync: true,
85
- },
86
-
87
- /**
88
- * A subset of items to be shown at the top of the overlay.
89
- */
90
- topGroup: {
91
- type: Array,
92
- observer: '_topGroupChanged',
93
- sync: true,
94
- },
95
-
96
- _target: {
97
- type: Object,
98
- },
99
- };
100
- }
101
-
102
- static get observers() {
103
- return ['_readonlyChanged(readonly)'];
104
- }
105
-
106
- /**
107
- * Reference to the clear button element.
108
- * @protected
109
- * @return {!HTMLElement}
110
- */
111
- get clearElement() {
112
- return this.querySelector('[part="clear-button"]');
113
- }
114
-
115
- /**
116
- * Tag name prefix used by scroller and items.
117
- * @protected
118
- * @return {string}
119
- */
120
- get _tagNamePrefix() {
121
- return 'vaadin-multi-select-combo-box';
122
- }
123
-
124
- constructor() {
125
- super();
126
-
127
- this.addEventListener('custom-value-set', this.__onCustomValueSet.bind(this));
128
- }
129
-
130
- /**
131
- * Override method inherited from the combo-box
132
- * to allow opening dropdown when readonly.
133
- * @override
134
- */
135
- open() {
136
- if (!this.disabled && !(this.readonly && this.selectedItems.length === 0)) {
137
- this.opened = true;
138
- }
139
- }
140
-
141
- /** @protected */
142
- ready() {
143
- super.ready();
144
-
145
- this._target = this;
146
- this._toggleElement = this.querySelector('.toggle-button');
147
- }
148
-
149
- /** @protected */
150
- _updateOverlayWidth() {
151
- this.$.overlay._updateOverlayWidth();
152
- }
153
-
154
- /** @private */
155
- _readonlyChanged() {
156
- this._setDropdownItems(this.filteredItems);
157
- }
158
-
159
- /**
160
- * Override combo-box method to group selected
161
- * items at the top of the overlay.
162
- *
163
- * @protected
164
- * @override
165
- */
166
- _setDropdownItems(items) {
167
- if (this.readonly) {
168
- super._setDropdownItems(this.selectedItems);
169
- return;
170
- }
171
-
172
- if (this.filter || !this.selectedItemsOnTop) {
173
- super._setDropdownItems(items);
174
- return;
175
- }
176
-
177
- if (items && items.length && this.topGroup && this.topGroup.length) {
178
- // Filter out items included to the top group.
179
- const filteredItems = items.filter(
180
- (item) => this._comboBox._findIndex(item, this.topGroup, this.itemIdPath) === -1,
181
- );
182
-
183
- super._setDropdownItems(this.topGroup.concat(filteredItems));
184
- return;
185
- }
186
-
187
- super._setDropdownItems(items);
188
- }
189
-
190
- /** @private */
191
- _topGroupChanged(topGroup) {
192
- if (topGroup) {
193
- this._setDropdownItems(this.filteredItems);
194
- }
195
- }
196
-
197
- /**
198
- * Override combo-box method to set correct owner for using by item renderers.
199
- * This needs to be done before the scroller gets added to the DOM to ensure
200
- * Lit directive works in case when combo-box is opened using attribute.
201
- *
202
- * @protected
203
- * @override
204
- */
205
- _initScroller() {
206
- const comboBox = this.getRootNode().host;
207
-
208
- this._comboBox = comboBox;
209
-
210
- super._initScroller(comboBox);
211
- }
212
-
213
- /**
214
- * Override Enter handler to keep overlay open
215
- * when item is selected or unselected.
216
- * @param {!Event} event
217
- * @protected
218
- * @override
219
- */
220
- _onEnter(event) {
221
- if (this.opened) {
222
- // Do not submit the surrounding form.
223
- event.preventDefault();
224
- // Do not trigger global listeners.
225
- event.stopPropagation();
226
-
227
- if (this.readonly) {
228
- this.close();
229
- } else if (this._hasValidInputValue()) {
230
- // Keep selected item focused after committing on Enter.
231
- const focusedItem = this._dropdownItems[this._focusedIndex];
232
- this._commitValue();
233
- this._focusedIndex = this._dropdownItems.indexOf(focusedItem);
234
- }
235
-
236
- return;
237
- }
238
-
239
- super._onEnter(event);
240
- }
241
-
242
- /**
243
- * Override Escape handler to not clear
244
- * selected items when readonly.
245
- * @param {!Event} event
246
- * @protected
247
- * @override
248
- */
249
- _onEscape(event) {
250
- if (this.readonly) {
251
- event.stopPropagation();
252
- if (this.opened) {
253
- this.close();
254
- }
255
- return;
256
- }
257
-
258
- super._onEscape(event);
259
- }
260
-
261
- /**
262
- * Override from combo-box to ignore requests to clear the filter if the
263
- * keepFilter option is enabled. Exceptions are when the dropdown is closed,
264
- * so the filter is still cleared on cancel and focus out.
265
- * @protected
266
- * @override
267
- */
268
- _clearFilter() {
269
- if (!this.keepFilter || !this.opened) {
270
- super._clearFilter();
271
- }
272
- }
273
-
274
- /**
275
- * Override method from combo-box to always clear the filter when reverting
276
- * the input value, regardless of the keepFilter option.
277
- * @override
278
- * @protected
279
- */
280
- _revertInputValueToValue() {
281
- super._revertInputValueToValue();
282
- this.filter = '';
283
- }
284
-
285
- /**
286
- * @protected
287
- * @override
288
- */
289
- _commitValue() {
290
- // Store filter value for checking if user input is matching
291
- // an item which is already selected, to not un-select it.
292
- this.lastFilter = this.filter;
293
-
294
- super._commitValue();
295
- }
296
-
297
- /**
298
- * Override method inherited from the combo-box
299
- * to not update focused item when readonly.
300
- * @protected
301
- * @override
302
- */
303
- _onArrowDown() {
304
- if (!this.readonly) {
305
- super._onArrowDown();
306
- } else if (!this.opened) {
307
- this.open();
308
- }
309
- }
310
-
311
- /**
312
- * Override method inherited from the combo-box
313
- * to not update focused item when readonly.
314
- * @protected
315
- * @override
316
- */
317
- _onArrowUp() {
318
- if (!this.readonly) {
319
- super._onArrowUp();
320
- } else if (!this.opened) {
321
- this.open();
322
- }
323
- }
324
-
325
- /**
326
- * Override method inherited from the combo-box
327
- * to close dropdown on blur when readonly.
328
- * @param {boolean} focused
329
- * @protected
330
- * @override
331
- */
332
- _setFocused(focused) {
333
- // Disable combo-box logic that updates selectedItem
334
- // based on the overlay focused index on input blur
335
- if (!focused) {
336
- this._ignoreCommitValue = true;
337
- }
338
-
339
- super._setFocused(focused);
340
-
341
- if (!focused && this.readonly && !this._closeOnBlurIsPrevented) {
342
- this.close();
343
- }
344
- }
345
-
346
- /**
347
- * Override method inherited from the combo-box
348
- * to not commit an already selected item again
349
- * after closing overlay on outside click.
350
- * @protected
351
- * @override
352
- */
353
- _onClosed() {
354
- this._ignoreCommitValue = true;
355
-
356
- super._onClosed();
357
- }
358
-
359
- /**
360
- * Override method inherited from the combo-box
361
- * to not commit an already selected item again
362
- * on blur, which would result in un-selecting.
363
- * @protected
364
- * @override
365
- */
366
- _detectAndDispatchChange() {
367
- if (this._ignoreCommitValue) {
368
- this._ignoreCommitValue = false;
369
-
370
- // Reset internal combo-box state
371
- this.clear();
372
- this._inputElementValue = '';
373
- return;
374
- }
375
-
376
- super._detectAndDispatchChange();
377
- }
378
-
379
- /**
380
- * @param {CustomEvent} event
381
- * @protected
382
- * @override
383
- */
384
- _overlaySelectedItemChanged(event) {
385
- event.stopPropagation();
386
-
387
- // Do not un-select on click when readonly
388
- if (this.readonly) {
389
- return;
390
- }
391
-
392
- if (event.detail.item instanceof ComboBoxPlaceholder) {
393
- return;
394
- }
395
-
396
- if (this.opened) {
397
- // Store filter value for checking if user input is matching
398
- // an item which is already selected, to not un-select it.
399
- this.lastFilter = this.filter;
400
-
401
- this.dispatchEvent(
402
- new CustomEvent('combo-box-item-selected', {
403
- detail: {
404
- item: event.detail.item,
405
- },
406
- }),
407
- );
408
- }
409
- }
410
-
411
- /**
412
- * Override method inherited from the combo-box
413
- * to not request data provider when read-only.
414
- *
415
- * @protected
416
- * @override
417
- */
418
- _shouldFetchData() {
419
- if (this.readonly) {
420
- return false;
421
- }
422
-
423
- return super._shouldFetchData();
424
- }
425
-
426
- /**
427
- * Override method inherited from the combo-box
428
- * to not clear the data provider cache when read-only.
429
- *
430
- * @protected
431
- * @override
432
- */
433
- clearCache() {
434
- if (this.readonly) {
435
- return;
436
- }
437
-
438
- super.clearCache();
439
- }
440
-
441
- /** @private */
442
- __onCustomValueSet(event) {
443
- // Prevent setting custom value on input blur or outside click,
444
- // so it can be only committed explicitly by pressing Enter.
445
- if (this._ignoreCommitValue) {
446
- event.stopImmediatePropagation();
447
- }
448
- }
449
- };
@@ -1,56 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2025 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 { css, html, LitElement } from 'lit';
10
- import { ifDefined } from 'lit/directives/if-defined.js';
11
- import { defineCustomElement } from '@vaadin/component-base/src/define.js';
12
- import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
13
- import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
14
- import { MultiSelectComboBoxInternalMixin } from './vaadin-multi-select-combo-box-internal-mixin.js';
15
-
16
- /**
17
- * An element used internally by `<vaadin-multi-select-combo-box>`. Not intended to be used separately.
18
- *
19
- * @customElement
20
- * @extends HTMLElement
21
- * @mixes MultiSelectComboBoxInternalMixin
22
- * @mixes ThemableMixin
23
- * @private
24
- */
25
- class MultiSelectComboBoxInternal extends MultiSelectComboBoxInternalMixin(ThemableMixin(PolylitMixin(LitElement))) {
26
- static get is() {
27
- return 'vaadin-multi-select-combo-box-internal';
28
- }
29
-
30
- static get styles() {
31
- return css`
32
- :host([opened]) {
33
- pointer-events: auto;
34
- }
35
- `;
36
- }
37
-
38
- /** @protected */
39
- render() {
40
- return html`
41
- <slot></slot>
42
-
43
- <vaadin-multi-select-combo-box-overlay
44
- id="overlay"
45
- .opened="${this._overlayOpened}"
46
- ?loading="${this.loading}"
47
- theme="${ifDefined(this._theme)}"
48
- .positionTarget="${this._target}"
49
- no-vertical-overlap
50
- .restoreFocusNode="${this.inputElement}"
51
- ></vaadin-multi-select-combo-box-overlay>
52
- `;
53
- }
54
- }
55
-
56
- defineCustomElement(MultiSelectComboBoxInternal);
@@ -1,74 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { css } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
7
-
8
- export const multiSelectComboBox = css`
9
- :host {
10
- max-width: 100%;
11
- --input-min-width: var(--vaadin-multi-select-combo-box-input-min-width, 4em);
12
- --_chip-min-width: var(--vaadin-multi-select-combo-box-chip-min-width, 50px);
13
- }
14
-
15
- #chips {
16
- display: flex;
17
- align-items: center;
18
- }
19
-
20
- ::slotted(input) {
21
- box-sizing: border-box;
22
- flex: 1 0 var(--input-min-width);
23
- }
24
-
25
- ::slotted([slot='chip']),
26
- ::slotted([slot='overflow']) {
27
- flex: 0 1 auto;
28
- }
29
-
30
- ::slotted([slot='chip']) {
31
- overflow: hidden;
32
- }
33
-
34
- :host(:is([readonly], [disabled])) ::slotted(input) {
35
- flex-grow: 0;
36
- flex-basis: 0;
37
- padding: 0;
38
- }
39
-
40
- :host([auto-expand-vertically]) #chips {
41
- display: contents;
42
- }
43
-
44
- :host([auto-expand-horizontally]) [class$='container'] {
45
- width: auto;
46
- }
47
- `;
48
-
49
- export const multiSelectComboBoxChip = css`
50
- :host {
51
- display: inline-flex;
52
- align-items: center;
53
- align-self: center;
54
- white-space: nowrap;
55
- box-sizing: border-box;
56
- }
57
-
58
- [part='label'] {
59
- overflow: hidden;
60
- text-overflow: ellipsis;
61
- }
62
-
63
- :host([hidden]),
64
- :host(:is([readonly], [disabled], [slot='overflow'])) [part='remove-button'] {
65
- display: none !important;
66
- }
67
-
68
- @media (forced-colors: active) {
69
- :host {
70
- outline: 1px solid;
71
- outline-offset: -1px;
72
- }
73
- }
74
- `;
@@ -1,10 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import '@vaadin/vaadin-lumo-styles/color.js';
7
- import '@vaadin/vaadin-lumo-styles/font-icons.js';
8
- import '@vaadin/vaadin-lumo-styles/spacing.js';
9
- import '@vaadin/vaadin-lumo-styles/style.js';
10
- import '@vaadin/vaadin-lumo-styles/typography.js';
@@ -1,107 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import '@vaadin/vaadin-lumo-styles/color.js';
7
- import '@vaadin/vaadin-lumo-styles/font-icons.js';
8
- import '@vaadin/vaadin-lumo-styles/spacing.js';
9
- import '@vaadin/vaadin-lumo-styles/style.js';
10
- import '@vaadin/vaadin-lumo-styles/typography.js';
11
- import { fieldButton } from '@vaadin/vaadin-lumo-styles/mixins/field-button.js';
12
- import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
13
-
14
- const chip = css`
15
- :host {
16
- font-size: var(--lumo-font-size-xxs);
17
- line-height: 1;
18
- color: var(--lumo-body-text-color);
19
- border-radius: var(--lumo-border-radius-s);
20
- background-color: var(--lumo-contrast-20pct);
21
- cursor: var(--lumo-clickable-cursor);
22
- -webkit-font-smoothing: antialiased;
23
- -moz-osx-font-smoothing: grayscale;
24
- }
25
-
26
- :host([disabled]) {
27
- background-color: var(--lumo-contrast-10pct);
28
- }
29
-
30
- :host([focused]) [part='remove-button'] {
31
- color: inherit;
32
- }
33
-
34
- :host([slot='overflow']) {
35
- position: relative;
36
- min-width: var(--lumo-size-xxs);
37
- margin-inline-start: var(--lumo-space-s);
38
- }
39
-
40
- :host([slot='overflow'])::before,
41
- :host([slot='overflow'])::after {
42
- position: absolute;
43
- content: '';
44
- width: 100%;
45
- height: 100%;
46
- border-left: calc(var(--lumo-space-s) / 4) solid;
47
- border-radius: var(--lumo-border-radius-s);
48
- border-color: var(--lumo-contrast-30pct);
49
- }
50
-
51
- :host([slot='overflow'])::before {
52
- left: calc(-1 * var(--lumo-space-s) / 2);
53
- }
54
-
55
- :host([slot='overflow'])::after {
56
- left: calc(-1 * var(--lumo-space-s));
57
- }
58
-
59
- :host([count='2']) {
60
- margin-inline-start: calc(var(--lumo-space-s) / 2);
61
- }
62
-
63
- :host([count='2'])::after {
64
- display: none;
65
- }
66
-
67
- :host([count='1']) {
68
- margin-inline-start: 0;
69
- }
70
-
71
- :host([count='1'])::before,
72
- :host([count='1'])::after {
73
- display: none;
74
- }
75
-
76
- [part='label'] {
77
- font-weight: 500;
78
- line-height: 1.25;
79
- }
80
-
81
- [part='remove-button'] {
82
- display: flex;
83
- align-items: center;
84
- justify-content: center;
85
- margin-top: -0.3125em;
86
- margin-bottom: -0.3125em;
87
- margin-inline-start: auto;
88
- width: 1.25em;
89
- height: 1.25em;
90
- font-size: 1.5em;
91
- transition: none;
92
- }
93
-
94
- [part='remove-button']::before {
95
- content: var(--lumo-icons-cross);
96
- }
97
-
98
- :host([disabled]) [part='label'] {
99
- color: var(--lumo-disabled-text-color);
100
- -webkit-text-fill-color: var(--lumo-disabled-text-color);
101
- pointer-events: none;
102
- }
103
- `;
104
-
105
- registerStyles('vaadin-multi-select-combo-box-chip', [fieldButton, chip], {
106
- moduleId: 'lumo-multi-select-combo-box-chip',
107
- });
@@ -1,10 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2021 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import '@vaadin/input-container/theme/lumo/vaadin-input-container-styles.js';
7
- import '@vaadin/vaadin-lumo-styles/color.js';
8
- import '@vaadin/vaadin-lumo-styles/font-icons.js';
9
- import '@vaadin/vaadin-lumo-styles/style.js';
10
- import '@vaadin/vaadin-lumo-styles/typography.js';