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);
...