From 4efa89915a526cbab2979464591325d320afe267 Mon Sep 17 00:00:00 2001 From: Oliver-Akins Date: Sun, 7 Apr 2024 23:53:34 -0600 Subject: [PATCH] Make progress on the input being focusable from an external label --- module/components/incrementer.mjs | 105 ++++++++++++++---- styles/v3/components/incrementer.scss | 11 +- .../v2/partials/inventory/player.v2.pc.hbs | 12 +- 3 files changed, 93 insertions(+), 35 deletions(-) diff --git a/module/components/incrementer.mjs b/module/components/incrementer.mjs index b543c93..146a391 100644 --- a/module/components/incrementer.mjs +++ b/module/components/incrementer.mjs @@ -2,6 +2,10 @@ Attributes: @property {string} name - The path to the value to update @property {number} value - The actual value of the input +@property {number} min - The minimum value of the input +@property {number} max - The maximum value of the input +@property {number?} smallStep - The step size used for the buttons and arrow keys +@property {number?} largeStep - The step size used for the buttons + Ctrl and page up / down Styling: - `--height`: Controls the height of the element + the width of the buttons (default: 1.25rem) @@ -9,9 +13,15 @@ Styling: */ export class DotDungeonIncrementer extends HTMLElement { static elementName = `dd-incrementer`; + static formAssociated = true; static styles = ``; + #min; + #max; + #smallStep; + #largeStep; + #input; #publicInput; #sr; @@ -19,40 +29,47 @@ export class DotDungeonIncrementer extends HTMLElement { constructor() { super(); + this._internals = this.attachInternals(); + const value = this.getAttribute(`value`); + this.#min = parseInt(this.getAttribute(`min`) ?? 0); + this.#max = parseInt(this.getAttribute(`max`) ?? 0); + this.#smallStep = parseInt(this.getAttribute(`smallStep`) ?? 1); + this.#largeStep = parseInt(this.getAttribute(`largeStep`) ?? 5); - /* - 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` }); + const sr = this.attachShadow({ + mode: `open`, + delegatesFocus: true + }); this.#sr = sr; const container = document.createElement(`div`); if (DotDungeonIncrementer.styles) this.#embedStyles(); + // The input that the user can see / modify const input = document.createElement(`input`); this.#input = input; input.type = `number`; + input.min = this.getAttribute(`min`); + input.max = this.getAttribute(`max`); input.addEventListener(`change`, this.#updateValue.bind(this)); input.value = value; - const increment = document.createElement(`button`); + // input.id = this.id; + // this.removeAttribute(`id`); + + // plus button + const increment = document.createElement(`span`); increment.innerHTML = `+`; - increment.type = `button`; + // increment.type = `button`; + // increment.tabIndex = -1; increment.classList.value = `increment`; increment.addEventListener(`click`, this.#increment.bind(this)); - const decrement = document.createElement(`button`); + // minus button + const decrement = document.createElement(`span`); decrement.innerHTML = `-`; - decrement.type = `button`; + // decrement.type = `button`; + // decrement.tabIndex = -1; decrement.classList.value = `decrement`; decrement.addEventListener(`click`, this.#decrement.bind(this)); @@ -65,6 +82,20 @@ export class DotDungeonIncrementer extends HTMLElement { }; connectedCallback() { + /* + 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, as Foundry + only listens for change events from a small subset of elements which makes + this a bit a jank work around as it is. + */ + const hiddenInput = document.createElement(`input`); + this.#publicInput = hiddenInput; + hiddenInput.type = `hidden`; + hiddenInput.value = this.#input.value; + hiddenInput.name = this.getAttribute(`name`); + // this.removeAttribute(`name`); + // this.appendChild(hiddenInput); + if (!DotDungeonIncrementer.styles) { fetch(`./systems/dotdungeon/.styles/v3/components/incrementer.css`) .then(r => r.text()) @@ -75,6 +106,16 @@ export class DotDungeonIncrementer extends HTMLElement { }; }; + get value() { + return this.#input.value; + }; + get form() { + return this._internals.form; + }; + get type() { + return `number`; + }; + #embedStyles() { const style = document.createElement(`style`); style.innerHTML = DotDungeonIncrementer.styles; @@ -82,20 +123,36 @@ export class DotDungeonIncrementer extends HTMLElement { }; #updateValue() { - this.#publicInput.value = this.#input.value; - const event = new Event(`change`, { bubbles: true }); - this.#publicInput.dispatchEvent(event); + let value = parseInt(this.#input.value); + if (this.getAttribute(`min`)) value = Math.max(this.#min, value); + if (this.getAttribute(`max`)) value = Math.min(this.#max, value); + this.#input.value = value; + if (this.#input.value === this.#publicInput.value) return; + this.#publicInput.value = value; + const event = new Event(`change`); + // this.#publicInput.dispatchEvent(event); + console.log(`#updateValue`) + this.dispatchEvent(event); }; - #increment() { - this.#input.value++; + #increment($e) { + let value = parseInt(this.#input.value); + value += $e.ctrlKey ? this.#largeStep : this.#smallStep; + this.#input.value = value; this.#updateValue(); }; - #decrement() { - this.#input.value--; + #decrement($e) { + let value = parseInt(this.#input.value); + value -= $e.ctrlKey ? this.#largeStep : this.#smallStep; + this.#input.value = value; this.#updateValue(); }; + + focus() { + console.log(1) + super.focus(); + } }; diff --git a/styles/v3/components/incrementer.scss b/styles/v3/components/incrementer.scss index ce5328d..650eead 100644 --- a/styles/v3/components/incrementer.scss +++ b/styles/v3/components/incrementer.scss @@ -26,7 +26,7 @@ div { } } -button, input { +span, input { border: none; outline: none; background: none; @@ -36,7 +36,7 @@ button, input { input { font-family: inherit; text-align: center; - padding: 0; + padding: 2px 4px; &::-webkit-inner-spin-button, &::-webkit-outer-spin-button { -webkit-appearance: none; @@ -46,16 +46,13 @@ input { } } -button { +span { aspect-ratio: 1 / 1; padding: 0; display: flex; justify-content: center; align-items: center; - - &:hover { - cursor: pointer; - } + cursor: pointer; } .increment { diff --git a/templates/actors/char-sheet/v2/partials/inventory/player.v2.pc.hbs b/templates/actors/char-sheet/v2/partials/inventory/player.v2.pc.hbs index 0249748..d236d29 100644 --- a/templates/actors/char-sheet/v2/partials/inventory/player.v2.pc.hbs +++ b/templates/actors/char-sheet/v2/partials/inventory/player.v2.pc.hbs @@ -11,12 +11,16 @@
- - {{!-- --}} + {{!--