JSFiddle - React, Tailwind, and code Playground

by Nicholas Berlette

HTML

<popup-info data-text="some info text">Some info</popup-info>

Babel + JSX

// Create a class for the element
class PopUpInfo extends HTMLElement {
  constructor() {
    // Always call super first in constructor
    super();

    // Create a shadow root
		this.shadow = this.attachShadow({ mode: "open" });

    // Create spans
		this.$wrapper = document.createElement("span");
    this.$wrapper.setAttribute("class", "wrapper");

		this.$icon = document.createElement("span");
    this.$icon.setAttribute("class", "icon");
    this.$icon.setAttribute("tabindex", 0);

		this.$info = document.createElement("span");
    this.$info.setAttribute("class", "info");

    // Take attribute content and put it inside the info span
    const text = this.getAttribute("data-text");
    this.$info.textContent = text;

    // Insert icon
    this.$img = document.createElement("img");
    this.$img.src = this.hasAttribute("img")
      ? this.getAttribute("img")
      : "https://developer.mozilla.org/static/media/experimental.2f9e05f53c6dbee7791c.svg";
    this.$icon.appendChild(this.$img);

    // Create some CSS to apply to the shadow dom
		this.$style = document.createElement("style");
    console.log(this.$style.isConnected);

    this.$style.textContent = `
      .wrapper {
        position: relative;
      }
      .info {
        font-size: 0.8rem;
        width: 200px;
        display: inline-block;
        border: 1px solid black;
        padding: 10px;
        background: white;
        border-radius: 10px;
        opacity: 0;
        transition: 0.6s all;
        position: absolute;
        top: 20px;
        left: 10px;
        z-index: 3;
      }
      img {
        width: 1.2rem;
      }
      .icon:hover + .info, .icon:focus + .info {
        opacity: 1;
      }
    `;
  }
  
  connectedCallback() {
    // Attach the created elements to the shadow dom
    this.shadow.appendChild(this.$style);
    console.log(this.$style.isConnected);
    this.shadow.appendChild(this.$wrapper);
    this.$wrapper.appendChild(this.$icon);
   ...