From e9405d33a8ca6a9c8fca5e8a097ff11bf987632d Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Tue, 20 Feb 2024 13:55:50 -0500 Subject: [PATCH] Fix close behavior when select is in a shadow root; fixes #1859 (#1878) * fix close behavior when select is in a shadow root * add pr --- docs/pages/resources/changelog.md | 1 + src/components/select/select.component.ts | 24 +++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index 9390e63781..e56e960206 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -16,6 +16,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti - Added support for `contextElement` to `VirtualElements` in `` [#1874] - Fixed a bug in `` that caused the rating to not reset in some circumstances [#1877] +- Fixed a bug in `` that caused the menu to not close when rendered in a shadow root [#1878] ## 2.14.0 diff --git a/src/components/select/select.component.ts b/src/components/select/select.component.ts index 44f18cac48..a0ea2f530f 100644 --- a/src/components/select/select.component.ts +++ b/src/components/select/select.component.ts @@ -224,7 +224,6 @@ export default class SlSelect extends ShoelaceElement implements ShoelaceFormCon // // https://github.com/shoelace-style/shoelace/issues/1763 // - const root = this.getRootNode(); if ('CloseWatcher' in window) { this.closeWatcher?.destroy(); this.closeWatcher = new CloseWatcher(); @@ -235,16 +234,25 @@ export default class SlSelect extends ShoelaceElement implements ShoelaceFormCon } }; } - root.addEventListener('focusin', this.handleDocumentFocusIn); - root.addEventListener('keydown', this.handleDocumentKeyDown); - root.addEventListener('mousedown', this.handleDocumentMouseDown); + document.addEventListener('focusin', this.handleDocumentFocusIn); + document.addEventListener('keydown', this.handleDocumentKeyDown); + document.addEventListener('mousedown', this.handleDocumentMouseDown); + + // If the component is rendered in a shadow root, we need to attach the focusin listener there too + if (this.getRootNode() !== document) { + this.getRootNode().addEventListener('focusin', this.handleDocumentFocusIn); + } } private removeOpenListeners() { - const root = this.getRootNode(); - root.removeEventListener('focusin', this.handleDocumentFocusIn); - root.removeEventListener('keydown', this.handleDocumentKeyDown); - root.removeEventListener('mousedown', this.handleDocumentMouseDown); + document.removeEventListener('focusin', this.handleDocumentFocusIn); + document.removeEventListener('keydown', this.handleDocumentKeyDown); + document.removeEventListener('mousedown', this.handleDocumentMouseDown); + + if (this.getRootNode() !== document) { + this.getRootNode().removeEventListener('focusin', this.handleDocumentFocusIn); + } + this.closeWatcher?.destroy(); }