@gridsuite/commons-ui 0.39.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -9,13 +9,51 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import TextInput from '../text-input';
|
|
11
11
|
import { isFloatNumber } from './utils';
|
|
12
|
+
|
|
13
|
+
// toLocaleString never uses exponential notation unlike toString. Avoiding
|
|
14
|
+
// exponential notation makes in place normalizing of numbers after each
|
|
15
|
+
// keystroke less intrusive: we can almost always normalize to a number that
|
|
16
|
+
// uses the same string representation as the intermediate text that the user
|
|
17
|
+
// typed. For example, if the user wants to input "625", they will write "6"
|
|
18
|
+
// and then "62" and then "625". The intermediate strings are numbers that have
|
|
19
|
+
// nothing in common with the final number but their normalization is the
|
|
20
|
+
// same as what was typed by the user. With exponential notation, if the user
|
|
21
|
+
// wants to input "12.5e21", at the intermediate step of "12.5e2" their input
|
|
22
|
+
// is normalized to "1.25e3" and after adding the final "1" they get "12.5e31"
|
|
23
|
+
// instead of "12.5e21".
|
|
24
|
+
// Note: with 16+ digits, two small problems in the current implementation appear:
|
|
25
|
+
// - rounding due to precision causes the cursor to jump at the end.
|
|
26
|
+
// - rounding due to precision causes the last digits of the number to jiggle.
|
|
27
|
+
// These two problems should be fixable with manual rounding and cursor
|
|
28
|
+
// handling if we need it.
|
|
29
|
+
var normalizeFixed = function normalizeFixed(number) {
|
|
30
|
+
return number.toLocaleString('en-US', {
|
|
31
|
+
maximumFractionDigits: 20,
|
|
32
|
+
useGrouping: false
|
|
33
|
+
});
|
|
34
|
+
};
|
|
12
35
|
var FloatInput = function FloatInput(props) {
|
|
13
36
|
var inputTransform = function inputTransform(value) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
37
|
+
if (typeof value == 'number' && !isNaN(value)) {
|
|
38
|
+
// if we have a parsed real number, normalize like we do after each
|
|
39
|
+
// keystroke in outputTransform for consistency. We get parsed
|
|
40
|
+
// numbers when the data doesn't come from a user edit in the form,
|
|
41
|
+
// but from data persisted as a float.
|
|
42
|
+
return normalizeFixed(value);
|
|
43
|
+
} else {
|
|
44
|
+
// The user is editing, leave as is because we already did what we
|
|
45
|
+
// need to do in outputTransform after the previous keystroke.
|
|
46
|
+
// NOTE: To avoid "bad things" we haven't predicted and be extra
|
|
47
|
+
// cautious, we clear the text on NaN, so we need to special case
|
|
48
|
+
// known inputs that would be rejected by isNaN but are accepted by
|
|
49
|
+
// our acceptValue because they are needed as intermediate strings
|
|
50
|
+
// for the user to input useful numbers.
|
|
51
|
+
// TODO can we remove the isNaN check and the special cases check?
|
|
52
|
+
if (['-', '.'].includes(value)) {
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
return value === null || isNaN(value) ? '' : value;
|
|
17
56
|
}
|
|
18
|
-
return sanitizedValue === null || isNaN(sanitizedValue) ? '' : sanitizedValue;
|
|
19
57
|
};
|
|
20
58
|
var outputTransform = function outputTransform(value) {
|
|
21
59
|
if (value === '-') {
|
|
@@ -25,10 +63,37 @@ var FloatInput = function FloatInput(props) {
|
|
|
25
63
|
return null;
|
|
26
64
|
}
|
|
27
65
|
var tmp = (value === null || value === void 0 ? void 0 : value.replace(',', '.')) || '';
|
|
28
|
-
|
|
66
|
+
|
|
67
|
+
// Can't show the normalization to the user when the fractional part
|
|
68
|
+
// ends with 0 because normalizing removes the trailing zeroes and prevents
|
|
69
|
+
// inputting the required intermediate strings (e.g "1." or "1.0" to input "1.02")
|
|
70
|
+
// So we return the user string instead. This has the downside that
|
|
71
|
+
// when the user finally writes a non 0 digit at the end, the normalization takes place
|
|
72
|
+
// and may startle the user when changing a lot of its input text.
|
|
73
|
+
// For example:
|
|
74
|
+
// - "1.00000000000000000000000000" and then press any non zero digit
|
|
75
|
+
// removes all the zeroes at once
|
|
76
|
+
// - "1." or "1.0" and then left arrow to move the cursor to the left and then inputting many digits
|
|
77
|
+
// disables all normalization, can write huge numbers that are not rounded like
|
|
78
|
+
// - 1231231231241231241231245123124234234123123124234.
|
|
79
|
+
// vs 1231231231241231300000000000000000000000000000000
|
|
80
|
+
// - 1.4312322342321323434534234235234
|
|
81
|
+
// vs 1.4312322342321324
|
|
82
|
+
// Note: this is a symmetric problem inputting many zeros
|
|
83
|
+
// to the left of a number to allow to input a final leading nonzero
|
|
84
|
+
// digit, but users never want to do that, unlike inputting trailing zeroes in the
|
|
85
|
+
// fractional part before inputing the final trailing non zero digit
|
|
86
|
+
if (tmp.endsWith('.') || tmp.includes('.') && tmp.endsWith('0')) {
|
|
29
87
|
return tmp;
|
|
30
88
|
}
|
|
31
|
-
|
|
89
|
+
|
|
90
|
+
// normalize after each user keystroke, needs to be very unintrusive
|
|
91
|
+
// otherwise users are surprised when typing doesn't do what they want
|
|
92
|
+
// NOTE: the parse should always succeed and produce non-NaN because we
|
|
93
|
+
// restrict what the user can type with "acceptValue" but if we
|
|
94
|
+
// have a bug just clear the data instead of sending "NaN"
|
|
95
|
+
var parsed = parseFloat(tmp);
|
|
96
|
+
return isNaN(parsed) ? null : normalizeFixed(parsed);
|
|
32
97
|
};
|
|
33
98
|
return /*#__PURE__*/React.createElement(TextInput, _extends({
|
|
34
99
|
acceptValue: isFloatNumber,
|