fix(LionInputStepper): improve handling of decimal step values and al… (#2621)
Some checks failed
Release / Release (push) Has been cancelled
Some checks failed
Release / Release (push) Has been cancelled
* fix(LionInputStepper): improve handling of decimal step values and alignment * fix: add changeset LionInputStepper improvements
This commit is contained in:
parent
cc4ca7fe9d
commit
579e42b339
3 changed files with 68 additions and 8 deletions
5
.changeset/four-rabbits-cover.md
Normal file
5
.changeset/four-rabbits-cover.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@lion/ui': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(LionInputStepper): improve handling of decimal step values and alignment closes #2615
|
||||||
|
|
@ -267,12 +267,19 @@ export class LionInputStepper extends LocalizeMixin(LionInput) {
|
||||||
_increment() {
|
_increment() {
|
||||||
const { step, min, max } = this.values;
|
const { step, min, max } = this.values;
|
||||||
const stepMin = min !== Infinity ? min : 0;
|
const stepMin = min !== Infinity ? min : 0;
|
||||||
|
const epsilon = 1e-10; // Tolerance for floating-point comparison
|
||||||
|
|
||||||
let newValue = this.currentValue + step;
|
let newValue;
|
||||||
|
|
||||||
if ((this.currentValue + stepMin) % step !== 0) {
|
const remainder = (this.currentValue - stepMin) % step;
|
||||||
// If the value is not aligned to step, align it to the nearest step
|
const isAligned = Math.abs(remainder) < epsilon || Math.abs(remainder - step) < epsilon;
|
||||||
newValue = Math.floor(this.currentValue / step) * step + step + (stepMin % step);
|
|
||||||
|
if (!isAligned) {
|
||||||
|
// If the value is not aligned to step, align it to the next valid step
|
||||||
|
newValue = Math.ceil((this.currentValue - stepMin) / step) * step + stepMin;
|
||||||
|
} else {
|
||||||
|
// If the value is aligned, just add the step
|
||||||
|
newValue = this.currentValue + step;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newValue <= max || max === Infinity) {
|
if (newValue <= max || max === Infinity) {
|
||||||
|
|
@ -289,12 +296,19 @@ export class LionInputStepper extends LocalizeMixin(LionInput) {
|
||||||
_decrement() {
|
_decrement() {
|
||||||
const { step, max, min } = this.values;
|
const { step, max, min } = this.values;
|
||||||
const stepMin = min !== Infinity ? min : 0;
|
const stepMin = min !== Infinity ? min : 0;
|
||||||
|
const epsilon = 1e-10; // Tolerance for floating-point comparison
|
||||||
|
|
||||||
let newValue = this.currentValue - step;
|
let newValue;
|
||||||
|
|
||||||
if ((this.currentValue + stepMin) % step !== 0) {
|
const remainder = (this.currentValue - stepMin) % step;
|
||||||
// If the value is not aligned to step, align it to the nearest step
|
const isAligned = Math.abs(remainder) < epsilon || Math.abs(remainder - step) < epsilon;
|
||||||
newValue = Math.floor(this.currentValue / step) * step + (stepMin % step);
|
|
||||||
|
if (!isAligned) {
|
||||||
|
// If the value is not aligned to step, align it to the previous valid step
|
||||||
|
newValue = Math.floor((this.currentValue - stepMin) / step) * step + stepMin;
|
||||||
|
} else {
|
||||||
|
// If the value is aligned, just subtract the step
|
||||||
|
newValue = this.currentValue - step;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newValue >= min || min === Infinity) {
|
if (newValue >= min || min === Infinity) {
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,47 @@ describe('<lion-input-stepper>', () => {
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.modelValue).to.equal(-13, 'Fail - : (-23 > 100 by 10; val 55)'); // -23 > -13 > -3 > 7
|
expect(el.modelValue).to.equal(-13, 'Fail - : (-23 > 100 by 10; val 55)'); // -23 > -13 > -3 > 7
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handles decimal step values correctly', async () => {
|
||||||
|
// Test with decimal step 0.1
|
||||||
|
let el = await fixture(
|
||||||
|
html`<lion-input-stepper step="0.1" min="0" max="9" value="5.55"></lion-input-stepper>`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test increment with decimal step
|
||||||
|
let incrementButton = el.querySelector('[slot=suffix]');
|
||||||
|
incrementButton?.dispatchEvent(new Event('click'));
|
||||||
|
await el.updateComplete;
|
||||||
|
expect(el.modelValue).to.equal(5.6, 'Fail + : (0 > 9 by 0.1; val 5.55)');
|
||||||
|
|
||||||
|
// Test decrement with decimal step
|
||||||
|
let decrementButton = el.querySelector('[slot=prefix]');
|
||||||
|
decrementButton?.dispatchEvent(new Event('click'));
|
||||||
|
await el.updateComplete;
|
||||||
|
expect(el.modelValue).to.equal(5.5, 'Fail - : (0 > 9 by 0.1; val 5.6)');
|
||||||
|
|
||||||
|
// Test with value that needs alignment
|
||||||
|
el = await fixture(
|
||||||
|
html`<lion-input-stepper step="0.1" min="0" max="9" value="3.27"></lion-input-stepper>`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Should align to next step when incrementing
|
||||||
|
incrementButton = el.querySelector('[slot=suffix]');
|
||||||
|
incrementButton?.dispatchEvent(new Event('click'));
|
||||||
|
await el.updateComplete;
|
||||||
|
expect(el.modelValue).to.equal(3.3, 'Fail + alignment: (0 > 9 by 0.1; val 3.27)');
|
||||||
|
|
||||||
|
// Reset and test decrement alignment
|
||||||
|
el = await fixture(
|
||||||
|
html`<lion-input-stepper step="0.1" min="0" max="9" value="3.27"></lion-input-stepper>`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Should align to previous step when decrementing
|
||||||
|
decrementButton = el.querySelector('[slot=prefix]');
|
||||||
|
decrementButton?.dispatchEvent(new Event('click'));
|
||||||
|
await el.updateComplete;
|
||||||
|
expect(el.modelValue).to.equal(3.2, 'Fail - alignment: (0 > 9 by 0.1; val 3.27)');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue