From bd5d079ed60fe52a98f0d7d82c772dae8957d3dd Mon Sep 17 00:00:00 2001 From: pk Date: Fri, 10 Jan 2025 23:39:22 +0100 Subject: [PATCH] Fire number-changed event whenever the user changed the value by interacting with it. --- package.json | 2 +- tp-number-input.js | 55 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 90721ee..b81e1ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tp/tp-number-input", - "version": "1.0.2", + "version": "1.1.0", "description": "", "main": "tp-number-input.js", "scripts": { diff --git a/tp-number-input.js b/tp-number-input.js index a3cfd4b..c974096 100644 --- a/tp-number-input.js +++ b/tp-number-input.js @@ -119,6 +119,7 @@ class TpNumberInput extends FormElement(EventHelpers(DomQuery(LitElement))) { this.max = Number.MAX_SAFE_INTEGER; this.fastInterval = 50; this.superFastInterval = 100; + this._isConnected = false } firstUpdated() { @@ -129,6 +130,14 @@ class TpNumberInput extends FormElement(EventHelpers(DomQuery(LitElement))) { this.listen(this.$.innerInput, 'keydown', '_onKey'); } + connectedCallback() { + super.connectedCallback(); + // Set small timeout to ensure all initial updates have run + setTimeout(() => { + this._isConnected = true; + }, 0); + } + updated(changes) { super.updated(); @@ -291,8 +300,18 @@ class TpNumberInput extends FormElement(EventHelpers(DomQuery(LitElement))) { } _onKey(e) { - if(e.keyCode === 13) { + if (e.keyCode === 13) { this._updateValue(parseInt(this.$.input.value, 10)); + } else if (e.keyCode === 38) { // Arrow Up + e.preventDefault(); + let val = parseInt(this.value, 10) || 0; + val = Math.min(this.max, val + this.step); + this._updateValue(val); + } else if (e.keyCode === 40) { // Arrow Down + e.preventDefault(); + let val = parseInt(this.value, 10) || 0; + val = Math.max(this.min, val - this.step); + this._updateValue(val); } } @@ -318,31 +337,55 @@ class TpNumberInput extends FormElement(EventHelpers(DomQuery(LitElement))) { _updateValue(val) { if(this.timeMode) return; - + + const oldValue = this.value; + if(typeof this.specialMin === 'string' && val === this.specialMin) { this.value = this.specialMin; this.$.input.value = this.value; + if (oldValue !== this.value && this._isConnected) { + this.dispatchEvent(new CustomEvent('number-changed', { + detail: { value: this.value }, + bubbles: true, + composed: true + })); + } return; } - + val = parseInt(val, 10); - + // If val is NaN and an specialMin is defined, then set it. // Else set the min value. if(isNaN(val)) { val = typeof this.specialMin === 'string' ? this.specialMin : this.min; } - + if((typeof this.specialMin === 'string' && val === this.specialMin) || (val < this.min && typeof this.specialMin === 'string')) { this.value = this.specialMin; this.$.input.value = this.value; + if (oldValue !== this.value && this._isConnected) { + this.dispatchEvent(new CustomEvent('number-changed', { + detail: { value: this.value }, + bubbles: true, + composed: true + })); + } return; } - + val = Math.min(this.max, val); val = Math.max(this.min, val); this.value = this.ignoreSuffix ? val : (!!this.suffix ? val + this.suffix : val); this.$.input.value = !!this.suffix ? val + this.suffix : val; + + if (oldValue !== this.value && this._isConnected) { + this.dispatchEvent(new CustomEvent('number-changed', { + detail: { value: this.value }, + bubbles: true, + composed: true + })); + } } }