Closed ragulka closed 2 years ago
Hi, thanks for reporting and your suggestions 👍
As you probably already noticed the current source is an adaption of Vue Currency Input, which targets the currency
format style.
The decimal
format style issues will be fixed shortly with the upcoming official release. As well the percent
format style will be fully supported.
I understand this is a very-very early release of this package, but I wanted to try it out nonetheless, as it would be immensely helpful for a project I'm working on.
I noticed that it's currently impossible to use the
decimal
style with... decimals! 😅 As I ventured into the code, I also noticed that there is no type declaration for thepercent
style, which is supported byIntl.NumberFormat
. Regardless of the missing type, I tried setting the type topercent
and noticed that it does not work as expected, either.Issue description and reproduction
Given the following, it's impossible to enter any decimals in the input:
Here's a bare-bones reproduction of the issue: https://codepen.io/ragulka/pen/NWgmqaE
123456.789
initiallyI would expect to be able to enter at least 4 decimal places, since I've set
precision: 4
.Tracking down the cause
As I tried to debug this, I noticed that the
NumberFormat
class tries to detect the decimal symbol and when it cannot find one, it'll setminimumFractionDigits
andmaximumFractionDigits
to0
, regardless of theprecision
option.The culprit seem to be these lines. In order to detect the decimal symbol (as well as other symbols, like the negative, etc), a number is formatted with the given style. Then, it tries to see if there are any decimal places by checking if there are any zeroes in the formatted number. Since there are no zeroes in the input number (
123456
), having zeroes would mean there's a decimal point right where the first zero is inserted.The logic above assumes that there are decimal places (
minimumFractionDigits > 0
) in the default format for the given style. This is only true forcurrency
, though. While decimal places are perfectly valid for decimals and percentages, decimals and percentages do not have a minimum amount of decimals by default. Formatting the number123456
asdecimal
with will result in123,456
- not123,456.00
. Also formatting1
aspercent
will yield100%
which will throw off the decimal detection completely.In conclusion, it seems the decimal symbol detection is flawed - while it works for currencies (by lucky chance), it's not really suitable for other numbers.
Proposed change
There are more reliable ways to get the decimal and thousand separators.
If IE11 is not a concern (Vue 3 does not support it), I'd suggest simply using NumberFormat#formatToParts.
However, if IE11 is a thing, it's possible to use the other solution in the linked SO answer.
In any case, it's imperative to use a number with existing decimal places as input for the formatter, regardless of the chosen solution.
EDIT: I have a proof-of-concept implementation in my fork here - it's raw, but it shows the concept and it works as expected as far as I tried.