JSFiddle - React, Tailwind, and code Playground
HTML
<rich-editor value="Added via HTML"></rich-editor>
CSS
rich-editor { width: 300px; height: 100px }
JavaScript
class RichEditor extends HTMLElement {
constructor() {
super()
let shadowRoot = this.attachShadow({mode: "open"})
console.log("Shadow root", this.shadowRoot)
let content = this.hasAttribute("value") ? this.getAttribute("value") : ""
shadowRoot.innerHTML = `
<style>
:host {
border: 2px solid #2f4858; border-radius: 3px;
background-color: #f0fff0;
display: block;
padding: 3px; margin: 10px
}
.toolbar { height: 20px; border-bottom: 1px solid #2f4858 }
.content { color: #33658a; padding-top: 3px }
</style>
<div class="toolbar">
<strong>B</strong>
<em>I</em>
<span style="text-decoration: underline">U</span>
</div>
<div class="content">${content}</div>
`
}
static get observedAttributes() {
return ["value"]
}
attributeChangedCallback(attr, oldVal, newVal) {
console.log("In attributeChangedCallback", attr, newVal)
if (attr == "value") {
this.value = newVal
}
}
get value() {
return this.shadowRoot.querySelector(".content").innerHTML
}
set value(val) {
this.shadowRoot.querySelector(".content").innerHTML = val
this.dispatchEvent(new CustomEvent("change", {detail: this.innerHTML}))
}
}
window.customElements.define('rich-editor', RichEditor)
let editor = document.createElement('rich-editor')
document.body.appendChild(editor)
editor.value = "<strong>Added via JS</strong>"
editor.addEventListener("change", (event) => console.log("Caught change event", event.detail))
editor.value = "<strong>Changed via JS</strong>"
setTimeout(() => {
e = document.querySelector("rich-editor")
console.log("Calling setAttribute", e)
e.setAttribute("value", "Changed value via attr")
console.log("value property", e.value)
}, 1000)