diff --git a/core/src/components/range/range.tsx b/core/src/components/range/range.tsx index b36617ad3e..478b2a57e2 100644 --- a/core/src/components/range/range.tsx +++ b/core/src/components/range/range.tsx @@ -213,12 +213,32 @@ export class Range implements ComponentInterface { */ @Prop({ mutable: true }) value: RangeValue = 0; @Watch('value') - protected valueChanged() { + protected valueChanged(newValue: RangeValue, oldValue: RangeValue) { + const valuesChanged = this.compareValues(newValue, oldValue); + if (valuesChanged) { + this.ionInput.emit({ value: this.value }); + } + if (!this.noUpdate) { this.updateRatio(); } } + /** + * Compares two RangeValue inputs to determine if they are different. + * + * @param newVal - The new value. + * @param oldVal - The old value. + * @returns `true` if the values are different, `false` otherwise. + */ + private compareValues = (newVal: RangeValue, oldVal: RangeValue) => { + if (typeof newVal === 'object' && typeof oldVal === 'object') { + return newVal.lower !== oldVal.lower || newVal.upper !== oldVal.upper; + } + + return newVal !== oldVal; + }; + private clampBounds = (value: any): number => { return clamp(this.min, value, this.max); }; @@ -591,8 +611,6 @@ export class Range implements ComponentInterface { upper: Math.max(valA, valB), }; - this.ionInput.emit({ value: this.value }); - this.noUpdate = false; } diff --git a/core/src/components/range/test/range-events.e2e.ts b/core/src/components/range/test/range-events.e2e.ts index bfbdfac48e..f76d147627 100644 --- a/core/src/components/range/test/range-events.e2e.ts +++ b/core/src/components/range/test/range-events.e2e.ts @@ -217,6 +217,42 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => expect(ionInputSpy).toHaveReceivedEvent(); }); + test('should not emit when the value does not change', async ({ page }, testInfo) => { + testInfo.annotations.push({ + type: 'issue', + description: 'https://github.com/ionic-team/ionic-framework/issues/29619', + }); + + /** + * Requires padding to prevent the knob from being clipped. + * If it's clipped, then the value might be one off. + * For example, if the knob is clipped on the right, then the value + * will be 99 instead of 100. + */ + await page.setContent( + ` +