Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial proposal to support usage in shadow roots #2264

Closed
wants to merge 14 commits into from

Conversation

spielzeugland
Copy link

@spielzeugland spielzeugland commented Jun 21, 2021

This change is a rough and initial proposal allowing to use this
library at least within the same parent shadow root #1659 (but not cross
shadowRoots yet). It does neither cover all functionalities yet nor
is in a quality state to be merged (missing tests etc).

This requires the following aspects

  • Make sure not using query selectors on document directly as those
    cannot find elements inside shadow roots. Therefore use specific DOM
    nodes to start searching other nodes
  • Events are handled centrally, but event.target will reference to the
    hosting element. Therefore use event.composedPath() to get the real
    nested element for that event.
  • Shadow roots isolate stylesheets, means global styles do not bleed
    into the shadow root. Therefore we need to make sure to generate the
    styles into the shadow root. As I couldn't find a way to get the
    mounted DOM node for the DragDropContext component at the point in
    time where the stylesheets are currently getting generated into the
    DOM. Therefore this changes allows consumers to specify the DOM
    location as a prop of the DragDropContext. Same approach is taken by
    JSS (see https://cssinjs.org/jss-api?v=v10.6.0#setup-jss-instance).

This change is a rough and initial proposal allowing to use this
library at least within the same parent shadow root (but not cross
shadowRoots yet). It does neither cover all functionalities yet nor
is in a quality state to be merged (missing tests etc).

This requires the following aspects
- Make sure not using query selectors on document directly as those
  cannot find elements inside shadow roots. Therefore use specific DOM
  nodes to start searching other nodes
- Events are handled centrally, but event.target will reference to the
  hosting element. Therefore use event.composedPath() to get the real
  nested element for that event.
- Shadow roots isolate stylesheets, means global styles do not bleed
  into the shadow root. Therefore we need to make sure to generate the
  styles into the shadow root. As I couldn't find a way to get the
  mounted DOM node for the DragDropContext component at the point in
  time where the stylesheets are currently getting generated into the
  DOM. Therefore this changes allows consumers to specify the DOM
  location as a prop of the DragDropContext. Same approach is taken by
  JSS (see https://cssinjs.org/jss-api?v=v10.6.0#setup-jss-instance).
@atlassian-cla-bot
Copy link

atlassian-cla-bot bot commented Jun 21, 2021

Thank you for your submission! Like many open source projects, we ask that you sign our CLA (Contributor License Agreement) before we can accept your contribution.
If your email is listed below, please ensure that you sign the CLA with the same email address.

The following users still need to sign our CLA:
❌spielzeugland

Already signed the CLA? To re-check, try refreshing the page.

@spielzeugland spielzeugland changed the title Initial proposal to support usage in shadow roots #1659 Initial proposal to support usage in shadow roots Jun 21, 2021
@spielzeugland
Copy link
Author

Thanks @mrbaguvix,
I consider your approval as an agreement on the approach itself. I guess there are a lot of other scenarios/places which I haven't found yet as I am not a heavy user of the library myself. Would be great if someone could help me finding those cases e.g. by testing scenarios within shadowRoots. In the meantime there are still failing tests I need to fix.

@0ex-d
Copy link

0ex-d commented Jun 28, 2021

You can create an issue to this effect maybe the community can better reproduce this.

Copy link

@kehengz kehengz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the change! It works now for my use case inside shadowRoot, with a minor change mentioned below :)

@@ -171,7 +171,7 @@ function tryStart({
return null;
}

const entry: DraggableEntry = registry.draggable.getById(draggableId);
const entry: DraggableEntry = registry.draggable.getById(draggableId, sourceEvent.srcElement.shadowRoot || document);
const el: ?HTMLElement = findDraggable(contextId, entry.descriptor.id);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You added a param "documentFragment" to findDraggable but the caller does not pass in the argument. Change it to findDraggable(contextId, entry.descriptor.id, sourceEvent.srcElement.shadowRoot || document) works for me

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @kehengz, uploaded an additional commit which also fixes this part. The first commit was more of a hacky sketch.
Out of curiosity, did you tested with React 17 or lower?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it thanks! My repo uses React 17

- Clean-up former commit
- Adapted more places to work with shadowRoots
- Introduced helper functions for querying elements
- Support for nested shadowRoots
- Added sample stories
@spielzeugland spielzeugland force-pushed the proposal1659 branch 2 times, most recently from 422e522 to acdea5b Compare July 13, 2021 19:09
@spielzeugland spielzeugland force-pushed the proposal1659 branch 4 times, most recently from b337f7d to 3b787f3 Compare July 15, 2021 07:30
@gorakong
Copy link
Member

gorakong commented Jul 16, 2021

hey @spielzeugland, we've received your signed CLA. It's just mapped to a different github username (BobPfeiffer?). @danieldelcore (or other maintainers) feel free to merge this while we get @spielzeugland's entry in our db updated to the correct github account 🙂.

@spielzeugland
Copy link
Author

Thanks @gorakong and @mrbaguvix for your support - I should have marked this PR as a draft. There is still one TODO left in query-elements.js which I want to address. Probably I should also add some tests before merging?

@spielzeugland
Copy link
Author

@mrbaguvix I think I am done with the change now. Would be great if you could review it again. As said I worked on allowing shadow roots inside draggables/droppables, added some tests and samples.

@Nuurek
Copy link

Nuurek commented Jul 24, 2021

@spielzeugland I've played a bit with your changes - great work, thank you very much for it!

One small fix, in src/view/use-style-marshal/get-styles.js . There are styles that are supposed to be applied globally using body selector. Unfortunately, it won't work in the shadow DOM. It can be fixed by broadening the selector: selector: 'body, :host'.

This solves the problem of missing drop events in
sample stories.
@spielzeugland
Copy link
Author

spielzeugland commented Jul 26, 2021

Thanks @Nuurek, for the trying out and suggesting a fix. I uploaded the changes.

@spielzeugland
Copy link
Author

Hi @danieldelcore, Hi @alexreardon,
would you mind having a look at the changes? From reading your blogs I know bigger changes are difficult to review and accept. Would be happy to get some feedback.

This fixes missing grabbing cursor while dragging.
@spielzeugland
Copy link
Author

Moved to a new PR #2319 with rewritten history in order to satisfy the CLA build.

@spielzeugland spielzeugland deleted the proposal1659 branch March 7, 2023 19:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants