EranGrin/vue-web-component-wrapper

Slot processing with nested elements when disableShadowDOM: true

Opened this issue · 3 comments

When disableShadowDOM: true is set, there are significant issues with slot handling in nested components

this is source code of vue-web-component-wrapper

// Replace slot
if (!this._config.shadowRoot) {
  this._slots = {};
  for (const child of Array.from(this.children)) {
    const slotName = child.getAttribute('slot') || 'default';
    if (!this._slots[slotName]) {
      this._slots[slotName] = [];
    }
    this._slots[slotName].push(
      h(child.tagName.toLowerCase(), {}, child.innerHTML)
    );
  }
  this.replaceChildren();
}

On the line h(child.tagName.toLowerCase(), {}, child.innerHTML), the function handling slots processes only basic HTML tags. This results in the following limitations:

1. Basic Text Not Rendered

The text abc does not render.

<xx-component name="core-btn">abc</xx-component>

2. Inner HTML as Text Output Only

<h1>abc</h1> only outputs the text as-is

<div slot="prev">
  <h1>abc</h1>
</div>

3. Attributes Are Lost

In this case, attributes such as class="text-red" and id="test" are stripped because the h function returns an empty object {} for attributes.

<xx-component name="core-btn">
  <div class="text-red" id="test">abc</div>
</xx-component>

4.Not support nested component like <xx-component> in side <xx-component>

I have created a PR to address this issue: #43.
Kindly take a look.

Hi @thanhbican, thank you for the issue & PR, but, would you mind creating a stackblitz example that demonstrates the issue?

Hi @EranGrin, thanks for your reply.

I've created a demonstration here: https://stackblitz.com/~/github.com/thanhbican/web-component-no-shadow-dom-demo?file=index.html

You can check the index.html file, I've added comments in it.