Add support for percentages in NumericInput#385
Conversation
| value = value.replace(/(\d+(?:\.\d+)?%)/g, (match: string) => { | ||
| const percent = parseFloat(match.slice(0, -1)); | ||
| const calculatedValue = (percent / 100) * currentValue; | ||
| return calculatedValue.toString(); | ||
| }); |
Check failure
Code scanning / CodeQL
Polynomial regular expression used on uncontrolled data
|
Not sure it is intuitive to have just percent entered, that will affect the current value. I would assume: 10 * 50% = 5 So if you just type number% - it would translate it to floating number. While multiplying by number% would modify that value, like other features of this filed (+5 - will be just 5). |
|
@Maksims I'm not sure what you're getting at. Any percentage you enter is substituted for the percentage of the current value. That's it. |
|
If you type -10, then will it remove 10 from the current value, or it will set value to -10? |
|
It will set the current value to -10. |
|
So it would be expected same from the percentage? If you type 30%, it probably should set it to 0.3? |
|
If the current number is |
|
But if it is something else, it wont. So it is doing magical behaviour. |
Nothing magical is happening. The behavior is extremely simple: For any expression, substitute any percentages with that percentage of the currently set value. So:
|
|
And here are more examples.
Why Also what if you do If you type a completely new value into the field, you would want to override that field. If you want to multiply by some %, follow the same logic as with multiplying by any other number. User has an ability to use the current value when selecting a field, and provide any normal math, when whole field is overridden, it is expected that new value is nothing to do with previous one. |
Remember the behavior I quoted above: For any expression, substitute any percentages with that percentage of the currently set value. So: For a current value of 20, if you input "10% + 2", we substitute 10% with 10% of the current value which is 2. So it's 2 + 2, which equals 4.
Again, we substitute 50% with 50% of the current value 20 (in the table example), which is 10 and we substitute 40% with 40% of the current value which is 8. So it's 10 * 8 which is 80.
We substitute 50% with 50% of the current value (let's say it's 10, so that's 5). So it's 20 / 5 which equals 4.
The percentage function is inherently about the previous value - it performs a substitution on hitting Enter. Just because expression evaluation has not referenced the previously set value until now, doesn't mean we shouldn't introduce such functionality. @LeXXik requested this (so obviously thought it would be useful) and I agreed. |
|
My point is simple: by defining a specific behavior for %, there is no way to do other things. And I'm not sure I've even seen anywhere it was used. So even in google search, if you type: By pre-defining it based on previous value, which in fact you don't even see when typing, you eliminate a possibility of using % in various ways, like: If there is a value there, by clicking on field and adding: |
|
Great debate :) I see the merit in both opinions. No golden rule, of course, just a matter of design choice. I think the main difference here is whether to use the old value when a field is overwritten or not. And I would tend to agree with Max here, that it is more common to start a new expression, when a field value is erased. Whether it is a calculator, or a spreadsheet - once you delete the contents and start new entry - it is a blank new expression. And by expression I would mean an operator with operands, like In case if only percent is entered, e.g. 50%, then that should be simply converted to a floating point. Since percentages are dimensionless numbers that represent a fraction of a 100, then 50% should be converted to 50/100 = 0.5. Converting it to a float using a base of the value that was just removed would be a bit magical. If an expression starts with a percent (which is not really a common thing to do), e.g. 10% + 10, then percent should be converted to a floating point first, and then a decimal is added to it. In this case the result should be 0.1 + 10 = 10.1. However, I have rarely seen such a nomenclature. You would usually just write a floating point number directly. Same with multiplying/dividing percents - 10/10% is less common than 10/0.1. |
|
Looks like I don't have the rights to change the issue state. Thank you for re-opening it! |
You can now set a
NumericInputvalue to a string containing a percentage which is replaced with that percentage of the currently set value.e.g.:
Also added extensive unit tests for this new feature.
Fixes #188