akveo / nebular

:boom: Customizable Angular UI Library based on Eva Design System :new_moon_with_face::sparkles:Dark Mode
https://akveo.github.io/nebular
MIT License
8.06k stars 1.51k forks source link

overlay-trigger can not handle clicks when inside Shadow DOM #1652

Open dragonbane0 opened 5 years ago

dragonbane0 commented 5 years ago

Issue type

I'm submitting a ... (check one with "x")

Issue description

Current behavior: Due being forced to mix my Angular app with legacy HTML code for the time being, I was compelled to put my root Angular component in a Shadow DOM via ViewEncapsulation. This avoids style conflicts with the legacy website code, which relies on an older version of bootstrap.

Nebular mostly plays nice with this out of the box, I just had to re-import the required global stylesheets inside the Shadow DOM and add the active theme to the class list of my app tag inside the Shadow DOM, as Nebular always applies it to the body tag which is ignored in the Shadow DOM.

However my nb-selects no longer work when clicked. It seems the overlay-trigger.ts captures clicks on the root document, but since my app is in a Shadow DOM this gets re-directed and the click target is now always the Shadow DOM, not the actual element clicked. This results in nb-selects not opening.

As an aside, is this way of click capturing really optimal? I have 50 nb-selects across 7 different tabs and every single click fires all 50 listeners checking if its element was clicked or not which seems a bit overkill.

I was able to hackily fix this for now by changing the document tag the overlay-trigger.ts uses to my app root Shadow DOM element.

Additionally I want to mention that on-hover events mostly fire properly without any changes, as my tooltips worked without issue, presumably because those capture events directly based on the host element.

Expected behavior: It would be nice if Nebular could either capture clicks differently to get around this issue or offer a way to override the used document tag dynamically to support Shadow DOMs.

Steps to reproduce: Use encapsulation: ViewEncapsulation.ShadowDom on your root Angular component and watch nb-selects no longer open when clicked.

fifarafka commented 5 years ago

How did you change the overlay document tag to use your shadow root element?

dragonbane0 commented 5 years ago

@fifarafka Please see my fork how I modified the "src/framework/theme/components/cdk/overlay/overlay-trigger.ts" to make this work: https://github.com/dragonbane0/nebular/commit/a29b77fb52413ea9fc16b7cd0c9b9bcec5118dc4#diff-4d18f7055ee0e36ba7a07e9f64aa2b20

Just a small hack that instead of using this._document uses the Angular root app tag instead if it happens to be a Shadow Root! This has obvious limitations, but works for my use case :)

fifarafka commented 5 years ago

Thanks, your solution helped me :)

xouqoa commented 2 years ago

This is still a problem even with the latest version and the changes that have been made to the trigger strategy builder service.

I don't think you can override it for a specific nb-select either since the property is protected. You'd have to probably extend the whole select component or something.