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

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/README.md CHANGED
@@ -1,18 +1,20 @@
1
1
  # @vaadin/multi-select-combo-box
2
2
 
3
- > ⚠️ Work in progress, please do not use this component yet.
4
-
5
3
  A web component that wraps `<vaadin-combo-box>` and allows selecting multiple items.
6
4
 
5
+ [Documentation + Live Demo ↗](https://vaadin.com/docs/latest/components/multi-select-combo-box)
6
+
7
7
  ```html
8
- <vaadin-multi-select-combo-box id="fruit"></vaadin-multi-select-combo-box>
8
+ <vaadin-multi-select-combo-box style="width: 300px"></vaadin-multi-select-combo-box>
9
9
  <script>
10
- const comboBox = document.querySelector('#fruit');
10
+ const comboBox = document.querySelector('vaadin-multi-select-combo-box');
11
11
  comboBox.items = ['apple', 'banana', 'lemon', 'orange'];
12
- comboBox.selectedItems = ['lemon', 'orange'];
12
+ comboBox.selectedItems = ['apple', 'banana'];
13
13
  </script>
14
14
  ```
15
15
 
16
+ [<img src="https://raw.githubusercontent.com/vaadin/web-components/master/packages/multi-select-combo-box/screenshot.png" width="300" alt="Screenshot of vaadin-multi-select-combo-box">](https://vaadin.com/docs/latest/components/multi-select-combo-box)
17
+
16
18
  ## Installation
17
19
 
18
20
  Install the component:
@@ -29,7 +31,7 @@ import '@vaadin/multi-select-combo-box';
29
31
 
30
32
  ## Themes
31
33
 
32
- Vaadin components come with two built-in [themes](https://vaadin.com/docs/latest/ds/customization/using-themes), Lumo and Material.
34
+ Vaadin components come with two built-in [themes](https://vaadin.com/docs/latest/styling), Lumo and Material.
33
35
  The [main entrypoint](https://github.com/vaadin/web-components/blob/master/packages/multi-select-combo-box/vaadin-multi-select-combo-box.js) of the package uses the Lumo theme.
34
36
 
35
37
  To use the Material theme, import the component from the `theme/material` folder:
@@ -52,7 +54,7 @@ import '@vaadin/multi-select-combo-box/src/vaadin-multi-select-combo-box.js';
52
54
 
53
55
  ## Contributing
54
56
 
55
- Read the [contributing guide](https://vaadin.com/docs/latest/guide/contributing/overview) to learn about our development process, how to propose bugfixes and improvements, and how to test your changes to Vaadin components.
57
+ Read the [contributing guide](https://vaadin.com/docs/latest/contributing/overview) to learn about our development process, how to propose bugfixes and improvements, and how to test your changes to Vaadin components.
56
58
 
57
59
  ## License
58
60
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/multi-select-combo-box",
3
- "version": "23.2.0-dev.8a7678b70",
3
+ "version": "23.2.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -24,7 +24,9 @@
24
24
  "src",
25
25
  "theme",
26
26
  "vaadin-*.d.ts",
27
- "vaadin-*.js"
27
+ "vaadin-*.js",
28
+ "web-types.json",
29
+ "web-types.lit.json"
28
30
  ],
29
31
  "keywords": [
30
32
  "Vaadin",
@@ -35,19 +37,23 @@
35
37
  ],
36
38
  "dependencies": {
37
39
  "@polymer/polymer": "^3.0.0",
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"
40
+ "@vaadin/combo-box": "~23.2.1",
41
+ "@vaadin/component-base": "~23.2.1",
42
+ "@vaadin/field-base": "~23.2.1",
43
+ "@vaadin/input-container": "~23.2.1",
44
+ "@vaadin/lit-renderer": "~23.2.1",
45
+ "@vaadin/vaadin-lumo-styles": "~23.2.1",
46
+ "@vaadin/vaadin-material-styles": "~23.2.1",
47
+ "@vaadin/vaadin-themable-mixin": "~23.2.1"
46
48
  },
47
49
  "devDependencies": {
48
50
  "@esm-bundle/chai": "^4.3.4",
49
51
  "@vaadin/testing-helpers": "^0.3.2",
50
52
  "sinon": "^13.0.2"
51
53
  },
52
- "gitHead": "85b403f96d8282f262322b56c0ff4289f843d02a"
54
+ "web-types": [
55
+ "web-types.json",
56
+ "web-types.lit.json"
57
+ ],
58
+ "gitHead": "a6c314f6927bfd3309fc735eae6c6dc72ab8367a"
53
59
  }
@@ -3,11 +3,11 @@
3
3
  * Copyright (c) 2017 - 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 { TemplateResult } from 'lit';
7
- import { DirectiveResult } from 'lit/directive.js';
8
- import { ComboBoxItemModel } from '@vaadin/combo-box/src/vaadin-combo-box.js';
6
+ import type { TemplateResult } from 'lit';
7
+ import type { DirectiveResult } from 'lit/directive.js';
8
+ import type { ComboBoxItemModel } from '@vaadin/combo-box/src/vaadin-combo-box.js';
9
9
  import { LitRendererDirective } from '@vaadin/lit-renderer';
10
- import { MultiSelectComboBox } from '../vaadin-multi-select-combo-box.js';
10
+ import type { MultiSelectComboBox } from '../vaadin-multi-select-combo-box.js';
11
11
 
12
12
  export type MultiSelectComboBoxLitRenderer<TItem> = (
13
13
  item: TItem,
@@ -18,7 +18,7 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
18
18
  * `label` | Element containing the label
19
19
  * `remove-button` | Remove button
20
20
  *
21
- * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
21
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
22
22
  *
23
23
  * @extends HTMLElement
24
24
  * @private
@@ -38,7 +38,6 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
38
38
 
39
39
  <vaadin-multi-select-combo-box-overlay
40
40
  id="overlay"
41
- hidden$="[[_isOverlayHidden(filteredItems, loading)]]"
42
41
  opened="[[_overlayOpened]]"
43
42
  loading$="[[loading]]"
44
43
  theme$="[[_theme]]"
@@ -87,6 +86,15 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
87
86
  value: () => [],
88
87
  },
89
88
 
89
+ /**
90
+ * Last input value entered by the user before value is updated.
91
+ * Used to store `filter` property value before clearing it.
92
+ */
93
+ lastFilter: {
94
+ type: String,
95
+ notify: true,
96
+ },
97
+
90
98
  _target: {
91
99
  type: Object,
92
100
  },
@@ -195,6 +203,18 @@ class MultiSelectComboBoxInternal extends ComboBoxDataProviderMixin(ComboBoxMixi
195
203
  super._closeOrCommit();
196
204
  }
197
205
 
206
+ /**
207
+ * @protected
208
+ * @override
209
+ */
210
+ _commitValue() {
211
+ // Store filter value for checking if user input is matching
212
+ // an item which is already selected, to not un-select it.
213
+ this.lastFilter = this.filter;
214
+
215
+ super._commitValue();
216
+ }
217
+
198
218
  /**
199
219
  * Override method inherited from the combo-box
200
220
  * to not update focused item when readonly.
@@ -23,7 +23,7 @@ import { ComboBoxItem } from '@vaadin/combo-box/src/vaadin-combo-box-item.js';
23
23
  * `selected` | Set when the item is selected | :host
24
24
  * `focused` | Set when the item is focused | :host
25
25
  *
26
- * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
26
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
27
27
  *
28
28
  * @extends ComboBoxItem
29
29
  * @private
@@ -3,26 +3,28 @@
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 {
6
+ import type {
7
7
  ComboBoxDataProvider,
8
8
  ComboBoxDefaultItem,
9
9
  ComboBoxItemModel,
10
10
  } from '@vaadin/combo-box/src/vaadin-combo-box.js';
11
- import { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js';
12
- import { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js';
13
- import { ElementMixinClass } from '@vaadin/component-base/src/element-mixin.js';
14
- import { FocusMixinClass } from '@vaadin/component-base/src/focus-mixin.js';
15
- import { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js';
16
- import { ResizeMixinClass } from '@vaadin/component-base/src/resize-mixin.js';
17
- import { DelegateFocusMixinClass } from '@vaadin/field-base/src/delegate-focus-mixin.js';
18
- import { DelegateStateMixinClass } from '@vaadin/field-base/src/delegate-state-mixin.js';
19
- import { FieldMixinClass } from '@vaadin/field-base/src/field-mixin.js';
20
- import { InputConstraintsMixinClass } from '@vaadin/field-base/src/input-constraints-mixin.js';
21
- import { InputControlMixinClass } from '@vaadin/field-base/src/input-control-mixin.js';
22
- import { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
23
- import { LabelMixinClass } from '@vaadin/field-base/src/label-mixin.js';
24
- import { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js';
25
- import { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
11
+ import type { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js';
12
+ import type { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js';
13
+ import type { ElementMixinClass } from '@vaadin/component-base/src/element-mixin.js';
14
+ import type { FocusMixinClass } from '@vaadin/component-base/src/focus-mixin.js';
15
+ import type { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js';
16
+ import type { ResizeMixinClass } from '@vaadin/component-base/src/resize-mixin.js';
17
+ import type { DelegateFocusMixinClass } from '@vaadin/field-base/src/delegate-focus-mixin.js';
18
+ import type { DelegateStateMixinClass } from '@vaadin/field-base/src/delegate-state-mixin.js';
19
+ import type { FieldMixinClass } from '@vaadin/field-base/src/field-mixin.js';
20
+ import type { InputConstraintsMixinClass } from '@vaadin/field-base/src/input-constraints-mixin.js';
21
+ import type { InputControlMixinClass } from '@vaadin/field-base/src/input-control-mixin.js';
22
+ import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
23
+ import type { LabelMixinClass } from '@vaadin/field-base/src/label-mixin.js';
24
+ import type { SlotStylesMixinClass } from '@vaadin/field-base/src/slot-styles-mixin.js';
25
+ import type { ValidateMixinClass } from '@vaadin/field-base/src/validate-mixin.js';
26
+ import type { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
27
+ import type { ThemePropertyMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
26
28
 
27
29
  export type MultiSelectComboBoxRenderer<TItem> = (
28
30
  root: HTMLElement,
@@ -65,6 +67,11 @@ export type MultiSelectComboBoxInvalidChangedEvent = CustomEvent<{ value: boolea
65
67
  */
66
68
  export type MultiSelectComboBoxSelectedItemsChangedEvent<TItem> = CustomEvent<{ value: TItem[] }>;
67
69
 
70
+ /**
71
+ * Fired whenever the field is validated.
72
+ */
73
+ export type MultiSelectComboBoxValidatedEvent = CustomEvent<{ valid: boolean }>;
74
+
68
75
  export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap {
69
76
  change: MultiSelectComboBoxChangeEvent<TItem>;
70
77
 
@@ -75,6 +82,8 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
75
82
  'invalid-changed': MultiSelectComboBoxInvalidChangedEvent;
76
83
 
77
84
  'selected-items-changed': MultiSelectComboBoxSelectedItemsChangedEvent<TItem>;
85
+
86
+ validated: MultiSelectComboBoxValidatedEvent;
78
87
  }
79
88
 
80
89
  /**
@@ -131,6 +140,7 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
131
140
  * Custom property | Description | Default
132
141
  * -----------------------------------------------------|----------------------------|--------
133
142
  * `--vaadin-field-default-width` | Default width of the field | `12em`
143
+ * `--vaadin-multi-select-combo-box-overlay-width` | Width of the overlay | `auto`
134
144
  * `--vaadin-multi-select-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
135
145
  * `--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`
136
146
  *
@@ -146,13 +156,14 @@ export interface MultiSelectComboBoxEventMap<TItem> extends HTMLElementEventMap
146
156
  * Note: the `theme` attribute value set on `<vaadin-multi-select-combo-box>` is
147
157
  * propagated to these components.
148
158
  *
149
- * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
159
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
150
160
  *
151
161
  * @fires {Event} change - Fired when the user commits a value change.
152
162
  * @fires {CustomEvent} custom-value-set - Fired when the user sets a custom value.
153
163
  * @fires {CustomEvent} filter-changed - Fired when the `filter` property changes.
154
164
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
155
165
  * @fires {CustomEvent} selected-items-changed - Fired when the `selectedItems` property changes.
166
+ * @fires {CustomEvent} validated - Fired whenever the field is validated.
156
167
  */
157
168
  declare class MultiSelectComboBox<TItem = ComboBoxDefaultItem> extends HTMLElement {
158
169
  /**
@@ -294,6 +305,11 @@ declare class MultiSelectComboBox<TItem = ComboBoxDefaultItem> extends HTMLEleme
294
305
  */
295
306
  clearCache(): void;
296
307
 
308
+ /**
309
+ * Clears the selected items.
310
+ */
311
+ clear(): void;
312
+
297
313
  /**
298
314
  * Requests an update for the content of items.
299
315
  * While performing the update, it invokes the renderer (passed in the `renderer` property) once an item.
@@ -305,21 +321,22 @@ declare class MultiSelectComboBox<TItem = ComboBoxDefaultItem> extends HTMLEleme
305
321
  addEventListener<K extends keyof MultiSelectComboBoxEventMap<TItem>>(
306
322
  type: K,
307
323
  listener: (this: MultiSelectComboBox<TItem>, ev: MultiSelectComboBoxEventMap<TItem>[K]) => void,
308
- options?: boolean | AddEventListenerOptions,
324
+ options?: AddEventListenerOptions | boolean,
309
325
  ): void;
310
326
 
311
327
  removeEventListener<K extends keyof MultiSelectComboBoxEventMap<TItem>>(
312
328
  type: K,
313
329
  listener: (this: MultiSelectComboBox<TItem>, ev: MultiSelectComboBoxEventMap<TItem>[K]) => void,
314
- options?: boolean | EventListenerOptions,
330
+ options?: EventListenerOptions | boolean,
315
331
  ): void;
316
332
  }
317
333
 
318
334
  interface MultiSelectComboBox
319
335
  extends ValidateMixinClass,
336
+ SlotStylesMixinClass,
320
337
  LabelMixinClass,
321
338
  KeyboardMixinClass,
322
- InputMixinClass,
339
+ Omit<InputMixinClass, 'value'>,
323
340
  InputControlMixinClass,
324
341
  InputConstraintsMixinClass,
325
342
  FocusMixinClass,
@@ -329,6 +346,7 @@ interface MultiSelectComboBox
329
346
  DelegateFocusMixinClass,
330
347
  ResizeMixinClass,
331
348
  ThemableMixinClass,
349
+ ThemePropertyMixinClass,
332
350
  ElementMixinClass,
333
351
  ControllerMixinClass {}
334
352
 
@@ -31,10 +31,6 @@ const multiSelectComboBox = css`
31
31
  align-items: center;
32
32
  }
33
33
 
34
- :host([has-value]) ::slotted(input:placeholder-shown) {
35
- color: transparent !important;
36
- }
37
-
38
34
  ::slotted(input) {
39
35
  box-sizing: border-box;
40
36
  flex: 1 0 var(--input-min-width);
@@ -109,6 +105,7 @@ registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectCo
109
105
  * Custom property | Description | Default
110
106
  * -----------------------------------------------------|----------------------------|--------
111
107
  * `--vaadin-field-default-width` | Default width of the field | `12em`
108
+ * `--vaadin-multi-select-combo-box-overlay-width` | Width of the overlay | `auto`
112
109
  * `--vaadin-multi-select-combo-box-overlay-max-height` | Max height of the overlay | `65vh`
113
110
  * `--vaadin-multi-select-combo-box-input-min-width` | Min width of the input | `4em`
114
111
  *
@@ -124,13 +121,14 @@ registerStyles('vaadin-multi-select-combo-box', [inputFieldShared, multiSelectCo
124
121
  * Note: the `theme` attribute value set on `<vaadin-multi-select-combo-box>` is
125
122
  * propagated to these components.
126
123
  *
127
- * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
124
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
128
125
  *
129
126
  * @fires {Event} change - Fired when the user commits a value change.
130
127
  * @fires {CustomEvent} custom-value-set - Fired when the user sets a custom value.
131
128
  * @fires {CustomEvent} filter-changed - Fired when the `filter` property changes.
132
129
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
133
130
  * @fires {CustomEvent} selected-items-changed - Fired when the `selectedItems` property changes.
131
+ * @fires {CustomEvent} validated - Fired whenever the field is validated.
134
132
  *
135
133
  * @extends HTMLElement
136
134
  * @mixes ElementMixin
@@ -163,6 +161,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
163
161
  allow-custom-value="[[allowCustomValue]]"
164
162
  data-provider="[[dataProvider]]"
165
163
  filter="{{filter}}"
164
+ last-filter="{{_lastFilter}}"
166
165
  loading="{{loading}}"
167
166
  size="{{size}}"
168
167
  filtered-items="[[__effectiveFilteredItems]]"
@@ -195,7 +194,13 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
195
194
  ></vaadin-multi-select-combo-box-chip>
196
195
  <div id="chips" part="chips" slot="prefix"></div>
197
196
  <slot name="input"></slot>
198
- <div id="clearButton" part="clear-button" slot="suffix" aria-hidden="true"></div>
197
+ <div
198
+ id="clearButton"
199
+ part="clear-button"
200
+ slot="suffix"
201
+ on-touchend="_onClearButtonTouchend"
202
+ aria-hidden="true"
203
+ ></div>
199
204
  <div id="toggleButton" class="toggle-button" part="toggle-button" slot="suffix" aria-hidden="true"></div>
200
205
  </vaadin-multi-select-combo-box-container>
201
206
  </vaadin-multi-select-combo-box-internal>
@@ -423,6 +428,11 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
423
428
  */
424
429
  filteredItems: Array,
425
430
 
431
+ /** @private */
432
+ value: {
433
+ type: String,
434
+ },
435
+
426
436
  /** @private */
427
437
  __effectiveItems: {
428
438
  type: Array,
@@ -435,12 +445,6 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
435
445
  computed: '__computeEffectiveFilteredItems(items, filteredItems, selectedItems, readonly)',
436
446
  },
437
447
 
438
- /** @protected */
439
- _hasValue: {
440
- type: Boolean,
441
- value: false,
442
- },
443
-
444
448
  /** @private */
445
449
  _overflowItems: {
446
450
  type: Array,
@@ -453,6 +457,11 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
453
457
  value: -1,
454
458
  observer: '_focusedChipIndexChanged',
455
459
  },
460
+
461
+ /** @private */
462
+ _lastFilter: {
463
+ type: String,
464
+ },
456
465
  };
457
466
  }
458
467
 
@@ -460,6 +469,19 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
460
469
  return ['_selectedItemsChanged(selectedItems, selectedItems.*)'];
461
470
  }
462
471
 
472
+ /** @protected */
473
+ get slotStyles() {
474
+ const tag = this.localName;
475
+ return [
476
+ ...super.slotStyles,
477
+ `
478
+ ${tag}[has-value] input::placeholder {
479
+ color: transparent !important;
480
+ }
481
+ `,
482
+ ];
483
+ }
484
+
463
485
  /**
464
486
  * Used by `InputControlMixin` as a reference to the clear button element.
465
487
  * @protected
@@ -502,6 +524,15 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
502
524
  return this.required && !this.readonly ? this._hasValue : true;
503
525
  }
504
526
 
527
+ /**
528
+ * Clears the selected items.
529
+ */
530
+ clear() {
531
+ this.__updateSelection([]);
532
+
533
+ announce(this.i18n.cleared);
534
+ }
535
+
505
536
  /**
506
537
  * Clears the cached pages and reloads data from data provider when needed.
507
538
  */
@@ -561,21 +592,6 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
561
592
  this._focusedChipIndex = -1;
562
593
  this.validate();
563
594
  }
564
-
565
- // Propagate focused attribute to internal combo box
566
- if (this.$ && this.$.comboBox) {
567
- this.$.comboBox.toggleAttribute('focused', focused);
568
- }
569
- }
570
-
571
- /**
572
- * Override method inherited from `InputMixin`
573
- * to keep attribute after clearing the input.
574
- * @protected
575
- * @override
576
- */
577
- _toggleHasValue() {
578
- super._toggleHasValue(this._hasValue);
579
595
  }
580
596
 
581
597
  /**
@@ -664,9 +680,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
664
680
 
665
681
  /** @private */
666
682
  _selectedItemsChanged(selectedItems) {
667
- this._hasValue = Boolean(selectedItems && selectedItems.length);
668
-
669
- this._toggleHasValue();
683
+ this._toggleHasValue(this._hasValue);
670
684
 
671
685
  // Use placeholder for announcing items
672
686
  if (this._hasValue) {
@@ -755,7 +769,8 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
755
769
  const itemsCopy = [...this.selectedItems];
756
770
  itemsCopy.splice(itemsCopy.indexOf(item), 1);
757
771
  this.__updateSelection(itemsCopy);
758
- this.__announceItem(item, false, itemsCopy.length);
772
+ const itemLabel = this._getItemLabel(item);
773
+ this.__announceItem(itemLabel, false, itemsCopy.length);
759
774
  }
760
775
 
761
776
  /** @private */
@@ -768,8 +783,9 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
768
783
  let isSelected = false;
769
784
 
770
785
  if (index !== -1) {
786
+ const lastFilter = this._lastFilter;
771
787
  // Do not unselect when manually typing and committing an already selected item.
772
- if (this.filter.toLowerCase() === itemLabel.toLowerCase()) {
788
+ if (lastFilter && lastFilter.toLowerCase() === itemLabel.toLowerCase()) {
773
789
  this.__clearFilter();
774
790
  return;
775
791
  }
@@ -877,6 +893,14 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
877
893
  this._overflowItems = items;
878
894
  }
879
895
 
896
+ /** @private */
897
+ _onClearButtonTouchend(event) {
898
+ // Cancel the following click and focus events
899
+ event.preventDefault();
900
+
901
+ this.clear();
902
+ }
903
+
880
904
  /**
881
905
  * Override method inherited from `InputControlMixin` and clear items.
882
906
  * @protected
@@ -885,9 +909,7 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
885
909
  _onClearButtonClick(event) {
886
910
  event.stopPropagation();
887
911
 
888
- this.__updateSelection([]);
889
-
890
- announce(this.i18n.cleared);
912
+ this.clear();
891
913
  }
892
914
 
893
915
  /**
@@ -1092,6 +1114,17 @@ class MultiSelectComboBox extends ResizeMixin(InputControlMixin(ThemableMixin(El
1092
1114
  __computeEffectiveFilteredItems(items, filteredItems, selectedItems, readonly) {
1093
1115
  return !items && readonly ? selectedItems : filteredItems;
1094
1116
  }
1117
+
1118
+ /**
1119
+ * Override a method from `InputMixin` to
1120
+ * compute the presence of value based on `selectedItems`.
1121
+ *
1122
+ * @protected
1123
+ * @override
1124
+ */
1125
+ get _hasValue() {
1126
+ return this.selectedItems && this.selectedItems.length > 0;
1127
+ }
1095
1128
  }
1096
1129
 
1097
1130
  customElements.define(MultiSelectComboBox.is, MultiSelectComboBox);