Add UI web components and adjust .gitignore
This commit is contained in:
94
static/components/color-picker/color-picker.js
Normal file
94
static/components/color-picker/color-picker.js
Normal file
@@ -0,0 +1,94 @@
|
||||
// ColorPicker component – template is embedded directly in the JS file.
|
||||
|
||||
class ColorPicker extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
return ["value"];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// Create a template element and embed the markup.
|
||||
const tmpl = document.createElement("template");
|
||||
tmpl.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
display: inline-block;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
.wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
label {
|
||||
font-size: 0.9rem;
|
||||
user-select: none;
|
||||
}
|
||||
input[type="color"] {
|
||||
border: none;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
padding: 0;
|
||||
background: none;
|
||||
}
|
||||
</style>
|
||||
<div class="wrapper">
|
||||
<label for="color-input">Background:</label>
|
||||
<input type="color" id="color-input" value="#ffffff">
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Attach a shadow root and clone the template into it.
|
||||
this.attachShadow({ mode: "open" });
|
||||
this.shadowRoot.appendChild(tmpl.content.cloneNode(true));
|
||||
|
||||
// Reference the input element for later use.
|
||||
this._input = this.shadowRoot.querySelector("#color-input");
|
||||
|
||||
// Bind event handler.
|
||||
this._onInput = this._onInput.bind(this);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
// Initialise the input value from the attribute (or default).
|
||||
const init = this.getAttribute("value") || "#ffffff";
|
||||
this._input.value = init;
|
||||
this._input.addEventListener("input", this._onInput);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this._input.removeEventListener("input", this._onInput);
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldVal, newVal) {
|
||||
if (name === "value" && this._input && oldVal !== newVal) {
|
||||
this._input.value = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
// Property getter/setter for easy JS access.
|
||||
get value() {
|
||||
return this._input ? this._input.value : this.getAttribute("value");
|
||||
}
|
||||
|
||||
set value(v) {
|
||||
this.setAttribute("value", v);
|
||||
}
|
||||
|
||||
// Dispatch a custom event when the user picks a color.
|
||||
_onInput(e) {
|
||||
const color = e.target.value;
|
||||
this.setAttribute("value", color);
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("colorchange", {
|
||||
detail: { color },
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Register the custom element.
|
||||
customElements.define("color-picker", ColorPicker);
|
||||
Reference in New Issue
Block a user