Skip to content

Commit ddb6d7f

Browse files
authored
fix(ui-shell): prevent header panel from closing on internal clicks (#19992)
* fix(ui-shell): prevent header panel from closing on internal clicks * fix(dropdown): prevent page scroll on arrow key navigation * fix(ui-shell): close panel when tabbing out of dropdown * chore(test): remove example test
1 parent 3a61095 commit ddb6d7f

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ class CDSDropdown extends ValidityMixin(
179179
this._handleUserInitiatedToggle(false);
180180
break;
181181
case DROPDOWN_KEYBOARD_ACTION.NAVIGATING:
182+
event.preventDefault();
182183
this._navigate(NAVIGATION_DIRECTION[key]);
183184
break;
184185
default:

packages/web-components/src/components/ui-shell/header-global-action.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,37 @@ class CDSHeaderGlobalAction extends CDSButton {
6161

6262
firstUpdated() {
6363
document.addEventListener('click', this._handleDocumentClick, true);
64+
document.addEventListener('focusin', this._handleDocumentFocusIn, true);
6465
}
6566

6667
disconnectedCallback() {
6768
document.removeEventListener('click', this._handleDocumentClick, true);
69+
document.removeEventListener('focusin', this._handleDocumentFocusIn, true);
6870
super.disconnectedCallback();
6971
}
7072

7173
private _handleDocumentClick = (event: MouseEvent) => {
74+
const path = event.composedPath();
75+
this._handlePanelCloseIfFocusOutside(path);
76+
};
77+
78+
private _handleDocumentFocusIn = (event: FocusEvent) => {
79+
const path = event.composedPath();
80+
this._handlePanelCloseIfFocusOutside(path);
81+
};
82+
83+
private _handlePanelCloseIfFocusOutside(path: EventTarget[]) {
7284
const panel = this.ownerDocument?.querySelector(`#${this.panelId}`);
73-
const target = event.composedPath()[0] as HTMLElement;
85+
const isInside = path.some(
86+
(el) =>
87+
el instanceof HTMLElement && (panel?.contains(el) || this.contains(el))
88+
);
7489

75-
if (panel && !this.contains(target) && !panel.contains(target)) {
90+
if (panel && !isInside) {
7691
panel.removeAttribute('expanded');
7792
this.active = false;
7893
}
79-
};
94+
}
8095

8196
@HostListener('focusout')
8297
// @ts-ignore

0 commit comments

Comments
 (0)