Issue #2999Opened September 3, 2020by jenter0 reactions

Drag Sorting issues in Web Component with Shadow Dom disabled

Question

Version 16.10

Are you able to reproduce the bug from the demo?

[X] Yes [ ] No

What is the expected behavior?

That GrapesJS can support dragging & sorting interaction with custom Web Components which do not have the Shadow DOM enabled.

Describe the bug

Hello, we use GrapesJS extensively and integrate many of our custom web components, which are generated using the StencilJS project. An issue that we run into is that dragging elements into the Web Components. However, this is only problematic if the Shadow DOM is disabled (shadow: false).

Shadow DOM enabled: [No Bug]

ShadowON

Shadow DOM disabled: [Bug]

ShadowOFF

The issue is that when you are attempting to drop an HTML element in the Web Component, Grapes doesn't seem to understand the DOM / Node references (assuming) and therefore not able to drop within. What's odd is that this bug is not an issue (even with shadow dom disabled) if you wrap any slotted content in a DIV.

# Bug 
<faux-grid-item>
      <p>Example</p>
       ...
# No Bug 
<faux-grid-item>
   <div>
      <p>Example</p>
       ...

This bug/request isn't just for StencilJS, but just in general with Web Components and the Shadow DOM. Are there best practices with Grapes and Web Components with enabling or tracking events to mediate these issues?

Example from screenshot of custom component in stenciljs:

@Component({
  tag: 'faux-grid-item',
  styleUrl: 'faux-grid-item.css',
  shadow: false, // <<=== causes issues
})

Are you able to attach screenshots, screencasts or a live demo?

[X] Yes (attach) [ ] No

Answers (3)

artfSeptember 8, 20200 reactions

This bug/request isn't just for StencilJS, but just in general with Web Components and the Shadow DOM. Are there best practices with Grapes and Web Components with enabling or tracking events to mediate these issues?

I'm not working with Web Components that much so if you're able to create a reproducible demo (eg. custom component using Web Components under the hood) that would help us to debug and understand the issue.

jenterSeptember 9, 20200 reactions

@artf sure thing, thanks for the quick response.

I have imported my custom web component library here in this Fiddle to demonstrate the issue: https://jsfiddle.net/jenter77/5btn2ao7/25/

fiddleSort

If you reference my public repo and example "faux-grid-item" web component here you will see it's just a simple component that delays for a couple of seconds and then loads. If shadowDOM is off the sorting/dragging issue bug occurs.

import { Component, State, h } from '@stencil/core';

@Component({
  tag: 'faux-grid-item',
  styleUrl: 'faux-grid-item.css',
  shadow: false, // <<=== causes issues
})

...
artfSeptember 14, 20200 reactions

Hi Jason, I've tried to give a look at what is happening inside the editor and, I'm not sure how the shadow option actually affects this behavior but, the main issue I see is that dynamic <div class="delayed--wrapper"> element. Basically the editor, post parsing, has this component structure

<faux-grid-item>
        <p>Hello</p>
        <p>Hello</p>
        <p>Hello</p>
</faux-grid-item>

but the actual DOM is

<faux-grid-item>
   <div class="delayed--wrapper">
        <p>Hello</p>
        <p>Hello</p>
        <p>Hello</p>
   </div>
</faux-grid-item>

This misalignment confuses the sorter because div.delayed--wrapper is not connected to any component. Indeed, to "fake" your expected behavior you would need to keep one div inside your template

<faux-grid-item>
   <div>
        <p>Hello</p>
        <p>Hello</p>
        <p>Hello</p>
   </div>
</faux-grid-item>

Unfortunately, I don't see how this can be solved (the reason why I'll close the issue). When the sorter tells to drop some Block at position X (eg. after the 2 children) of the FauxGridItem, it will append the new dropped component inside the FauxGridItem's children collection and then the component's view renders the DOM at the same position, but in this case, it won't be possible because FauxGridItem has only 1 child (div.delayed--wrapper).

So to recap, modifying the DOM outside of the editor creates unpredictable side effects. It's the same with frameworks which rely on the virtual DOM (eg. React, Vue, etc.) it's always recommended to avoid dealing directly with the DOM as you might break its virtual state.

Related Questions and Answers

Continue research with similar issue discussions.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.