JSFiddle - React, Tailwind, and code Playground

by graphettion

HTML

<counter-element></counter-element>

JavaScript

class CounterElement extends HTMLElement {
  #count = 0;
  #listeners = [];
  
  get count() { return this.#count; }
  
  set count(value) {
    this.#count = value;
    this.render();
    this.#notifyListeners();
  }
  
  connectedCallback() {
    this.innerHTML = `
      <div>Count: <span id="value">${this.count}</span></div>
      <button id="increment">Increment</button>
    `;
    
    this.querySelector('#increment').addEventListener('click', () => {
      this.count = this.count + 1;
    });
    
    this.render();
  }
  
  render() {
    const valueEl = this.querySelector('#value');
    if (valueEl) valueEl.textContent = this.count;
  }
  
  subscribe(callback) {
    this.#listeners.push(callback);
    return () => {
      this.#listeners = this.#listeners.filter(l => l !== callback);
    };
  }
  
  #notifyListeners() {
    this.#listeners.forEach(callback => callback(this.#count));
  }
}

customElements.define('counter-element', CounterElement);