107 lines
2.8 KiB
JavaScript
107 lines
2.8 KiB
JavaScript
/**
|
|
Attributes:
|
|
@property {string} name - The path to the value to update
|
|
@property {number} value - The actual value of the input
|
|
|
|
Styling:
|
|
- `--height`: Controls the height of the element + the width of the buttons (default: 1.25rem)
|
|
- `--width`: Controls the width of the number input (default 50px)
|
|
*/
|
|
export class DotDungeonIncrementer extends HTMLElement {
|
|
static elementName = `dd-incrementer`;
|
|
|
|
static styles = ``;
|
|
|
|
#input;
|
|
#publicInput;
|
|
#sr;
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
const value = this.getAttribute(`value`);
|
|
|
|
/*
|
|
This input exists for the sole purpose of making it so that the form data
|
|
works with this input without needing to do jank work arounds (even though
|
|
this on it's own is already a sort of jank work around).
|
|
*/
|
|
const hiddenInput = document.createElement(`input`);
|
|
hiddenInput.type = `hidden`;
|
|
hiddenInput.name = this.getAttribute(`name`);
|
|
hiddenInput.value = value;
|
|
this.#publicInput = hiddenInput;
|
|
this.appendChild(hiddenInput);
|
|
|
|
const sr = this.attachShadow({ mode: `open` });
|
|
this.#sr = sr;
|
|
const container = document.createElement(`div`);
|
|
if (DotDungeonIncrementer.styles) this.#embedStyles();
|
|
|
|
const input = document.createElement(`input`);
|
|
this.#input = input;
|
|
input.type = `number`;
|
|
input.addEventListener(`change`, this.#updateValue.bind(this));
|
|
input.value = value;
|
|
|
|
const increment = document.createElement(`button`);
|
|
increment.innerHTML = `+`;
|
|
increment.type = `button`;
|
|
increment.classList.value = `increment`;
|
|
increment.addEventListener(`click`, this.#increment.bind(this));
|
|
|
|
const decrement = document.createElement(`button`);
|
|
decrement.innerHTML = `-`;
|
|
decrement.type = `button`;
|
|
decrement.classList.value = `decrement`;
|
|
decrement.addEventListener(`click`, this.#decrement.bind(this));
|
|
|
|
|
|
// Construct the DOM
|
|
container.appendChild(decrement);
|
|
container.appendChild(input);
|
|
container.appendChild(increment);
|
|
sr.appendChild(container);
|
|
};
|
|
|
|
connectedCallback() {
|
|
if (!DotDungeonIncrementer.styles) {
|
|
fetch(`./systems/dotdungeon/.styles/components/incrementer.css`)
|
|
.then(r => r.text())
|
|
.then(t => {
|
|
DotDungeonIncrementer.styles = t;
|
|
this.#embedStyles();
|
|
});
|
|
};
|
|
};
|
|
|
|
#embedStyles() {
|
|
const style = document.createElement(`style`);
|
|
style.innerHTML = DotDungeonIncrementer.styles;
|
|
this.#sr.appendChild(style);
|
|
};
|
|
|
|
#updateValue() {
|
|
this.#publicInput.value = this.#input.value;
|
|
const event = new Event(`change`, { bubbles: true });
|
|
this.#publicInput.dispatchEvent(event);
|
|
};
|
|
|
|
#increment() {
|
|
this.#input.value++;
|
|
this.#updateValue();
|
|
};
|
|
|
|
#decrement() {
|
|
this.#input.value--;
|
|
this.#updateValue();
|
|
};
|
|
};
|
|
|
|
|
|
if (!window.customElements.get(DotDungeonIncrementer.elementName)) {
|
|
window.customElements.define(
|
|
DotDungeonIncrementer.elementName,
|
|
DotDungeonIncrementer
|
|
);
|
|
};
|