ghiscoding/multiple-select-vanilla

Dropdown closes on option selection when used in shadow DOM

Closed this issue · 4 comments

Describe the bug

When using this library inside a shadow DOM (e.g. inside a web component), the behavior of the dropdown is different compared to when used in the "normal" DOM. When selecting an option, the dropdown disappears.

Reproduction

Here I created two custom elements, one without shadow, one with shadow DOM. Note the difference when selecting a selection option.

https://stackblitz.com/edit/vitejs-vite-czjnxx?file=filter.js

Expectation

Behavior of the dropdown should ideally be consistent and should work the same inside and outside the shadow DOM.

Environment Info

System:
    OS: Linux 6.5 Ubuntu 22.04.4 LTS 22.04.4 LTS (Jammy Jellyfish)
    CPU: (8) x64 Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
    Memory: 4.61 GB / 15.38 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 18.18.2 - ~/.nvm/versions/node/v18.18.2/bin/node
    Yarn: 1.22.21 - ~/.nvm/versions/node/v18.18.2/bin/yarn
    npm: 9.8.1 - ~/.nvm/versions/node/v18.18.2/bin/npm
  Browsers:
    Chrome: 124.0.6367.201

Validations

I never work with Shadow DOM, if you know how to fix then please provide a Pull Request because I will most probably not look at fixing this myself. All the code is in MultipleSelectInstance.ts

I also assume that you meant (but forgot to mention) that the problem is for multiple selection? Because a single selection will of course close the drop right after selecting

After some digging, it seems that the target in

(e.target === this.dropElm || (findParent(e.target, '.ms-drop') !== this.dropElm && e.target !== this.elm)) &&

behaves differently than with non-shadow DOM. When used inside a shadow DOM, the true event.target is masked and the parent element is returned instead. It is recommended to use event.composedPath()[0] instead of event.target in this case.

See also this Stack Overflow question.

@ghiscoding I'll try creating a PR for this.

providing a PR would be best, I also have E2E tests (with Playwright), so if your change is working then all tests should pass in the PR. Just make sure that your solution works for both Shadow and non-Shadow DOM. Thanks