// rgb-slider.js export class RGBSlider extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: "open" }); shadow.innerHTML = `
`; const get = (id) => shadow.querySelector(id); this.r = get("#r"); this.g = get("#g"); this.b = get("#b"); this.rInput = get("#rInput"); this.gInput = get("#gInput"); this.bInput = get("#bInput"); this.preview = get("#preview"); const updateColor = (r, g, b) => { this.preview.style.backgroundColor = `rgb(${r}, ${g}, ${b})`; this.rInput.value = r; this.gInput.value = g; this.bInput.value = b; this.dispatchEvent( new CustomEvent("color-change", { detail: { r, g, b }, bubbles: true, composed: true, }), ); }; const syncFromSliders = () => { const r = +this.r.value; const g = +this.g.value; const b = +this.b.value; updateColor(r, g, b); }; const syncFromInputs = () => { const r = Math.min(255, Math.max(0, +this.rInput.value)); const g = Math.min(255, Math.max(0, +this.gInput.value)); const b = Math.min(255, Math.max(0, +this.bInput.value)); this.r.value = r; this.g.value = g; this.b.value = b; updateColor(r, g, b); }; this.r.addEventListener("input", syncFromSliders); this.g.addEventListener("input", syncFromSliders); this.b.addEventListener("input", syncFromSliders); this.rInput.addEventListener("change", syncFromInputs); this.gInput.addEventListener("change", syncFromInputs); this.bInput.addEventListener("change", syncFromInputs); } } customElements.define("rgb-slider", RGBSlider);