Skip to content

Commit b13440b

Browse files
authored
feat(dropdown): reintroduce parity changes from reverted PR #20863 (#21048)
* feat(dropdown): reintroduce parity changes from reverted PR #20863 * fix(multi-select): ensure input reflects aria-expanded state
1 parent 9c563ed commit b13440b

File tree

9 files changed

+1239
-191
lines changed

9 files changed

+1239
-191
lines changed

packages/web-components/src/components/combo-box/combo-box.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright IBM Corp. 2019, 2024
2+
* Copyright IBM Corp. 2019, 2025
33
*
44
* This source code is licensed under the Apache-2.0 license found in the
55
* LICENSE file in the root directory of this source tree.
@@ -55,6 +55,18 @@ class CDSComboBox extends CDSDropdown {
5555
@query('input')
5656
private _filterInputNode!: HTMLInputElement;
5757

58+
protected get _supportsMenuInputFiltering() {
59+
return true;
60+
}
61+
62+
protected get _menuInputNode(): HTMLInputElement | null {
63+
return this._filterInputNode ?? null;
64+
}
65+
66+
protected _clearMenuInputFiltering() {
67+
this._handleUserInitiatedClearInput();
68+
}
69+
5870
/**
5971
* The menu containing all selectable items.
6072
*/
@@ -219,6 +231,24 @@ class CDSComboBox extends CDSDropdown {
219231
return firstMatchIndex;
220232
}
221233

234+
protected _handleMouseoverInner(event: MouseEvent) {
235+
const item = this._getDropdownItemFromEvent(event);
236+
if (!item?.hasAttribute('selected')) {
237+
return;
238+
}
239+
240+
super._handleMouseoverInner(event);
241+
}
242+
243+
protected _handleMouseleaveInner(event: MouseEvent) {
244+
const isFiltering = Boolean(this._filterInputNode?.value.length);
245+
if (isFiltering) {
246+
return;
247+
}
248+
249+
super._handleMouseleaveInner(event);
250+
}
251+
222252
protected _scrollItemIntoView(item: HTMLElement) {
223253
if (!this._itemMenu) {
224254
return;

packages/web-components/src/components/dropdown/__tests__/dropdown-test.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -540,10 +540,11 @@ describe('cds-dropdown-skeleton', function () {
540540
html`<cds-dropdown-skeleton></cds-dropdown-skeleton>`
541541
);
542542
expect(el).to.exist;
543-
expect(el.shadowRoot.querySelector('.cds--skeleton')).to.exist;
544-
expect(el.shadowRoot.querySelector('.cds--dropdown-v2')).to.exist;
545-
expect(el.shadowRoot.querySelector('.cds--list-box')).to.exist;
546-
expect(el.shadowRoot.querySelector('.cds--form-item')).to.exist;
543+
const skeletonRoot = el.shadowRoot.querySelector('.cds--dropdown');
544+
expect(skeletonRoot).to.exist;
545+
expect(skeletonRoot.classList.contains('cds--skeleton')).to.be.true;
546+
expect(skeletonRoot.classList.contains('cds--list-box--md')).to.be.true;
547+
expect(el.shadowRoot.querySelector('.cds--label.cds--skeleton')).to.exist;
547548
});
548549

549550
it('should respect size attribute', async () => {

packages/web-components/src/components/dropdown/dropdown-skeleton.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
/**
2-
* Copyright IBM Corp. 2019, 2023
2+
* Copyright IBM Corp. 2019, 2025
33
*
44
* This source code is licensed under the Apache-2.0 license found in the
55
* LICENSE file in the root directory of this source tree.
66
*/
77

88
import { LitElement, html } from 'lit';
9+
import { classMap } from 'lit/directives/class-map.js';
10+
import { property } from 'lit/decorators.js';
911
import { prefix } from '../../globals/settings';
12+
import { DROPDOWN_SIZE } from './defs';
1013
import styles from './dropdown.scss?lit';
1114
import { carbonElement as customElement } from '../../globals/decorators/carbon-element';
1215

@@ -15,14 +18,31 @@ import { carbonElement as customElement } from '../../globals/decorators/carbon-
1518
*/
1619
@customElement(`${prefix}-dropdown-skeleton`)
1720
class CDSDropdownSkeleton extends LitElement {
21+
/**
22+
* Specify whether the label should be hidden, or not.
23+
*/
24+
@property({ type: Boolean, reflect: true, attribute: 'hide-label' })
25+
hideLabel = false;
26+
27+
/**
28+
* Specify the size of the ListBox.
29+
*/
30+
@property({ reflect: true })
31+
size = DROPDOWN_SIZE.MEDIUM;
32+
1833
render() {
34+
const { hideLabel, size } = this;
35+
const classes = classMap({
36+
[`${prefix}--skeleton`]: true,
37+
[`${prefix}--dropdown`]: true,
38+
[`${prefix}--list-box--${size}`]: Boolean(size),
39+
});
40+
1941
return html`
20-
<div
21-
class="${prefix}--skeleton ${prefix}--dropdown-v2 ${prefix}--list-box ${prefix}--form-item">
22-
<div class="${prefix}--list-box__field">
23-
<span class="${prefix}--list-box__label"></span>
24-
</div>
25-
</div>
42+
${!hideLabel
43+
? html`<span class="${prefix}--label ${prefix}--skeleton"></span>`
44+
: null}
45+
<div class=${classes}></div>
2646
`;
2747
}
2848

0 commit comments

Comments
 (0)