-
Notifications
You must be signed in to change notification settings - Fork 191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(number-field, slider): floating point roundoff precision bug #4263
Changes from 18 commits
3f6fde4
c8a49bc
15bf141
85bcd8e
87f073b
763c8d1
831ebbb
5f4fc2e
dd6ee09
c0675ae
5b080da
3d5f8af
81f20ca
947091b
53e621a
8b52e92
88a4a4d
8ce6361
a21b404
e077c20
d0b8d53
70b6b14
395e004
14cbe9e
d4affc5
207ec62
f5ad973
05f8bf9
c8e2faf
b218046
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -495,7 +495,14 @@ export class NumberField extends TextfieldBase { | |
// Step shouldn't validate when 0... | ||
if (this.step) { | ||
const min = typeof this.min !== 'undefined' ? this.min : 0; | ||
const moduloStep = (value - min) % this.step; | ||
this.digitsAfterDecimal = | ||
this.step != Math.floor(this.step) | ||
? this.step.toString().split('.')[1].length | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am using a ternary operator where if |
||
: 0; | ||
const moduloStep = parseFloat( | ||
this.numberFormatter.format((value - min) % this.step) | ||
); | ||
|
||
const fallsOnStep = moduloStep === 0; | ||
if (!fallsOnStep) { | ||
const overUnder = Math.round(moduloStep / this.step); | ||
|
@@ -510,6 +517,7 @@ export class NumberField extends TextfieldBase { | |
value -= this.step; | ||
} | ||
} | ||
value = parseFloat(this.numberFormatter.format(value)); | ||
} | ||
value *= signMultiplier; | ||
return value; | ||
|
@@ -526,7 +534,11 @@ export class NumberField extends TextfieldBase { | |
} | ||
|
||
protected get numberFormatter(): NumberFormatter { | ||
if (!this._numberFormatter || !this._numberFormatterFocused) { | ||
if ( | ||
!this._numberFormatter || | ||
!this._numberFormatterFocused || | ||
this._lastDigitsAfterDecimal !== this.digitsAfterDecimal | ||
) { | ||
const { | ||
style, | ||
unit, | ||
|
@@ -539,12 +551,26 @@ export class NumberField extends TextfieldBase { | |
} | ||
this._numberFormatterFocused = new NumberFormatter( | ||
this.languageResolver.language, | ||
formatOptionsNoUnit | ||
this.step | ||
? { | ||
...formatOptionsNoUnit, | ||
maximumFractionDigits: this.digitsAfterDecimal, | ||
} | ||
: { | ||
...formatOptionsNoUnit, | ||
} | ||
); | ||
try { | ||
this._numberFormatter = new NumberFormatter( | ||
this.languageResolver.language, | ||
this.formatOptions | ||
this.step | ||
? { | ||
...this.formatOptions, | ||
maximumFractionDigits: this.digitsAfterDecimal, | ||
} | ||
: { | ||
...this.formatOptions, | ||
} | ||
); | ||
this._forcedUnit = ''; | ||
this._numberFormatter.format(1); | ||
|
@@ -554,6 +580,7 @@ export class NumberField extends TextfieldBase { | |
} | ||
this._numberFormatter = this._numberFormatterFocused; | ||
} | ||
this._lastDigitsAfterDecimal = this.digitsAfterDecimal; | ||
} | ||
return this.focused | ||
? this._numberFormatterFocused | ||
|
@@ -562,6 +589,8 @@ export class NumberField extends TextfieldBase { | |
|
||
private _numberFormatter?: NumberFormatter; | ||
private _numberFormatterFocused?: NumberFormatter; | ||
private _lastDigitsAfterDecimal: number = 0; | ||
private digitsAfterDecimal: number = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to keep this on the class, or can we use cache clearing to trigger the use of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, we can totally do that |
||
|
||
protected get numberParser(): NumberParser { | ||
if (!this._numberParser || !this._numberParserFocused) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we cauterize this work to
change.get('step')
in one of the lifecycle callbacks? I'm not super excited about thethis._lastDigitsAfterDecimal !== this.digitsAfterDecimal
check, can we leverage the existing cache management mechanics?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!