JSFiddle - React, Tailwind, and code Playground

by Marc Brooks

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/dom-to-image-more/3.4.3/dom-to-image-more.js"></script>
<h2>Source</h2>
<div id="dom-node">
  <my-element>
    <div slot="content" id="lightdom-div">Slotted div element inside custom element shadow dom</div>
  </my-element>

  <!-- progress tag -->

  <label for="file">Progress bar</label>
  <progress id="file" value="32" max="100"> 32% </progress>
</div>

<div>
<h2>
Clone
</h2>
<div id="catcher">
</div>
</div>

<h2>Result Using version 3.4.2</h2>
<div id="result">
</div>

CSS

#dom-node {
  background-color: white;
  width: 300px;
  height: fit-content;
  border: 1px solid #000;
  padding: 20px;
  margin-bottom: 20px;
}

#lightdom-div {
  background-color: #000;
  color: aliceblue;
}

JavaScript

// Define a class for the custom element
    class MyElement extends HTMLElement {
      constructor() {
        super();
        const shadow = this.attachShadow({
          mode: 'open'
        });
        shadow.innerHTML = `
        <style>
         div {
              color: blue;
              border: 1px solid black;
              padding: 10px;
              margin: 10px;
            }

            slot[name='title'] > *{
              color: purple;
              background-color: aqua;
            }
          </style>

          <span>Custom Element</span>
          <div>
             <slot name="title">
              <div>A div element inside title slot.</div>
            </slot> 

            <slot name="content"></slot>

            <slot name="footer">Default footer content</slot> 
          </div>

          <div>
            <p>span inside a span</p>
            <span>
              <span>no. of bananas</span>
            </span>
          </div>
        `;
      }
    }

    // Register the custom element
    customElements.define('my-element', MyElement);

    const content = document.getElementById('dom-node');
    const {
      height,
      width
    } = content.getBoundingClientRect();

    var catcher = document.getElementById('catcher');

    function cloneCatcher(clone) {
      catcher.replaceChildren(clone);
      return clone;
    }

    domtoimage.toBlob(content, {
        height,
        width,
        copyDefaultStyles: true,
        onclone: cloneCatcher,
      })
      .then(blob => {
        var img = new Image();
        document.getElementById('result').appendChild(img);
        const url = URL.createObjectURL(blob)
        img.src = url;
      })
      .catch(function(e) {
        console.log(e);
      })