@react-stately/numberfield 3.3.0 → 3.4.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.
@@ -0,0 +1,188 @@
1
+ import {useControlledState as $vhjCi$useControlledState, clamp as $vhjCi$clamp, snapValueToStep as $vhjCi$snapValueToStep} from "@react-stately/utils";
2
+ import {NumberFormatter as $vhjCi$NumberFormatter, NumberParser as $vhjCi$NumberParser} from "@internationalized/number";
3
+ import {useState as $vhjCi$useState, useMemo as $vhjCi$useMemo, useCallback as $vhjCi$useCallback, useRef as $vhjCi$useRef} from "react";
4
+
5
+ /*
6
+ * Copyright 2020 Adobe. All rights reserved.
7
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License. You may obtain a copy
9
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software distributed under
12
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
13
+ * OF ANY KIND, either express or implied. See the License for the specific language
14
+ * governing permissions and limitations under the License.
15
+ */ /*
16
+ * Copyright 2020 Adobe. All rights reserved.
17
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
18
+ * you may not use this file except in compliance with the License. You may obtain a copy
19
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
20
+ *
21
+ * Unless required by applicable law or agreed to in writing, software distributed under
22
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
23
+ * OF ANY KIND, either express or implied. See the License for the specific language
24
+ * governing permissions and limitations under the License.
25
+ */
26
+
27
+
28
+ function $de67e98908f0c6ee$export$7f629e9dc1ecf37c(props) {
29
+ let { minValue: minValue , maxValue: maxValue , step: step , formatOptions: formatOptions , value: value , defaultValue: defaultValue , onChange: onChange , locale: locale , isDisabled: isDisabled , isReadOnly: isReadOnly } = props;
30
+ let [numberValue, setNumberValue] = (0, $vhjCi$useControlledState)(value, isNaN(defaultValue) ? NaN : defaultValue, onChange);
31
+ let [inputValue, setInputValue] = (0, $vhjCi$useState)(()=>isNaN(numberValue) ? "" : new (0, $vhjCi$NumberFormatter)(locale, formatOptions).format(numberValue));
32
+ let numberParser = (0, $vhjCi$useMemo)(()=>new (0, $vhjCi$NumberParser)(locale, formatOptions), [
33
+ locale,
34
+ formatOptions
35
+ ]);
36
+ let numberingSystem = (0, $vhjCi$useMemo)(()=>numberParser.getNumberingSystem(inputValue), [
37
+ numberParser,
38
+ inputValue
39
+ ]);
40
+ let formatter = (0, $vhjCi$useMemo)(()=>new (0, $vhjCi$NumberFormatter)(locale, {
41
+ ...formatOptions,
42
+ numberingSystem: numberingSystem
43
+ }), [
44
+ locale,
45
+ formatOptions,
46
+ numberingSystem
47
+ ]);
48
+ let intlOptions = (0, $vhjCi$useMemo)(()=>formatter.resolvedOptions(), [
49
+ formatter
50
+ ]);
51
+ let format = (0, $vhjCi$useCallback)((value)=>isNaN(value) || value === null ? "" : formatter.format(value), [
52
+ formatter
53
+ ]);
54
+ let clampStep = !isNaN(step) ? step : 1;
55
+ if (intlOptions.style === "percent" && isNaN(step)) clampStep = 0.01;
56
+ // Update the input value when the number value or format options change. This is done
57
+ // in a useEffect so that the controlled behavior is correct and we only update the
58
+ // textfield after prop changes.
59
+ let prevValue = (0, $vhjCi$useRef)(numberValue);
60
+ let prevLocale = (0, $vhjCi$useRef)(locale);
61
+ let prevFormatOptions = (0, $vhjCi$useRef)(formatOptions);
62
+ if (!Object.is(numberValue, prevValue.current) || locale !== prevLocale.current || formatOptions !== prevFormatOptions.current) {
63
+ setInputValue(format(numberValue));
64
+ prevValue.current = numberValue;
65
+ prevLocale.current = locale;
66
+ prevFormatOptions.current = formatOptions;
67
+ }
68
+ // Store last parsed value in a ref so it can be used by increment/decrement below
69
+ let parsedValue = (0, $vhjCi$useMemo)(()=>numberParser.parse(inputValue), [
70
+ numberParser,
71
+ inputValue
72
+ ]);
73
+ let parsed = (0, $vhjCi$useRef)(0);
74
+ parsed.current = parsedValue;
75
+ let commit = ()=>{
76
+ // Set to empty state if input value is empty
77
+ if (!inputValue.length) {
78
+ setNumberValue(NaN);
79
+ setInputValue(value === undefined ? "" : format(numberValue));
80
+ return;
81
+ }
82
+ // if it failed to parse, then reset input to formatted version of current number
83
+ if (isNaN(parsed.current)) {
84
+ setInputValue(format(numberValue));
85
+ return;
86
+ }
87
+ // Clamp to min and max, round to the nearest step, and round to specified number of digits
88
+ let clampedValue;
89
+ if (isNaN(step)) clampedValue = (0, $vhjCi$clamp)(parsed.current, minValue, maxValue);
90
+ else clampedValue = (0, $vhjCi$snapValueToStep)(parsed.current, minValue, maxValue, step);
91
+ clampedValue = numberParser.parse(format(clampedValue));
92
+ setNumberValue(clampedValue);
93
+ // in a controlled state, the numberValue won't change, so we won't go back to our old input without help
94
+ setInputValue(format(value === undefined ? clampedValue : numberValue));
95
+ };
96
+ let safeNextStep = (operation, minMax)=>{
97
+ let prev = parsed.current;
98
+ if (isNaN(prev)) {
99
+ // if the input is empty, start from the min/max value when incrementing/decrementing,
100
+ // or zero if there is no min/max value defined.
101
+ let newValue = isNaN(minMax) ? 0 : minMax;
102
+ return (0, $vhjCi$snapValueToStep)(newValue, minValue, maxValue, clampStep);
103
+ } else {
104
+ // otherwise, first snap the current value to the nearest step. if it moves in the direction
105
+ // we're going, use that value, otherwise add the step and snap that value.
106
+ let newValue1 = (0, $vhjCi$snapValueToStep)(prev, minValue, maxValue, clampStep);
107
+ if (operation === "+" && newValue1 > prev || operation === "-" && newValue1 < prev) return newValue1;
108
+ return (0, $vhjCi$snapValueToStep)($de67e98908f0c6ee$var$handleDecimalOperation(operation, prev, clampStep), minValue, maxValue, clampStep);
109
+ }
110
+ };
111
+ let increment = ()=>{
112
+ let newValue = safeNextStep("+", minValue);
113
+ // if we've arrived at the same value that was previously in the state, the
114
+ // input value should be updated to match
115
+ // ex type 4, press increment, highlight the number in the input, type 4 again, press increment
116
+ // you'd be at 5, then incrementing to 5 again, so no re-render would happen and 4 would be left in the input
117
+ if (newValue === numberValue) setInputValue(format(newValue));
118
+ setNumberValue(newValue);
119
+ };
120
+ let decrement = ()=>{
121
+ let newValue = safeNextStep("-", maxValue);
122
+ if (newValue === numberValue) setInputValue(format(newValue));
123
+ setNumberValue(newValue);
124
+ };
125
+ let incrementToMax = ()=>{
126
+ if (maxValue != null) setNumberValue((0, $vhjCi$snapValueToStep)(maxValue, minValue, maxValue, clampStep));
127
+ };
128
+ let decrementToMin = ()=>{
129
+ if (minValue != null) setNumberValue(minValue);
130
+ };
131
+ let canIncrement = (0, $vhjCi$useMemo)(()=>!isDisabled && !isReadOnly && (isNaN(parsedValue) || isNaN(maxValue) || (0, $vhjCi$snapValueToStep)(parsedValue, minValue, maxValue, clampStep) > parsedValue || $de67e98908f0c6ee$var$handleDecimalOperation("+", parsedValue, clampStep) <= maxValue), [
132
+ isDisabled,
133
+ isReadOnly,
134
+ minValue,
135
+ maxValue,
136
+ clampStep,
137
+ parsedValue
138
+ ]);
139
+ let canDecrement = (0, $vhjCi$useMemo)(()=>!isDisabled && !isReadOnly && (isNaN(parsedValue) || isNaN(minValue) || (0, $vhjCi$snapValueToStep)(parsedValue, minValue, maxValue, clampStep) < parsedValue || $de67e98908f0c6ee$var$handleDecimalOperation("-", parsedValue, clampStep) >= minValue), [
140
+ isDisabled,
141
+ isReadOnly,
142
+ minValue,
143
+ maxValue,
144
+ clampStep,
145
+ parsedValue
146
+ ]);
147
+ let validate = (value)=>numberParser.isValidPartialNumber(value, minValue, maxValue);
148
+ return {
149
+ validate: validate,
150
+ increment: increment,
151
+ incrementToMax: incrementToMax,
152
+ decrement: decrement,
153
+ decrementToMin: decrementToMin,
154
+ canIncrement: canIncrement,
155
+ canDecrement: canDecrement,
156
+ minValue: minValue,
157
+ maxValue: maxValue,
158
+ numberValue: parsedValue,
159
+ setInputValue: setInputValue,
160
+ inputValue: inputValue,
161
+ commit: commit
162
+ };
163
+ }
164
+ function $de67e98908f0c6ee$var$handleDecimalOperation(operator, value1, value2) {
165
+ let result = operator === "+" ? value1 + value2 : value1 - value2;
166
+ // Check if we have decimals
167
+ if (value1 % 1 !== 0 || value2 % 1 !== 0) {
168
+ const value1Decimal = value1.toString().split(".");
169
+ const value2Decimal = value2.toString().split(".");
170
+ const value1DecimalLength = value1Decimal[1] && value1Decimal[1].length || 0;
171
+ const value2DecimalLength = value2Decimal[1] && value2Decimal[1].length || 0;
172
+ const multiplier = Math.pow(10, Math.max(value1DecimalLength, value2DecimalLength));
173
+ // Transform the decimals to integers based on the precision
174
+ value1 = Math.round(value1 * multiplier);
175
+ value2 = Math.round(value2 * multiplier);
176
+ // Perform the operation on integers values to make sure we don't get a fancy decimal value
177
+ result = operator === "+" ? value1 + value2 : value1 - value2;
178
+ // Transform the integer result back to decimal
179
+ result /= multiplier;
180
+ }
181
+ return result;
182
+ }
183
+
184
+
185
+
186
+
187
+ export {$de67e98908f0c6ee$export$7f629e9dc1ecf37c as useNumberFieldState};
188
+ //# sourceMappingURL=module.js.map
package/dist/main.js CHANGED
@@ -7,49 +7,63 @@ function $parcel$export(e, n, v, s) {
7
7
  }
8
8
 
9
9
  $parcel$export(module.exports, "useNumberFieldState", () => $e18a693eeaf9c060$export$7f629e9dc1ecf37c);
10
-
10
+ /*
11
+ * Copyright 2020 Adobe. All rights reserved.
12
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
13
+ * you may not use this file except in compliance with the License. You may obtain a copy
14
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
15
+ *
16
+ * Unless required by applicable law or agreed to in writing, software distributed under
17
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
18
+ * OF ANY KIND, either express or implied. See the License for the specific language
19
+ * governing permissions and limitations under the License.
20
+ */ /*
21
+ * Copyright 2020 Adobe. All rights reserved.
22
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
23
+ * you may not use this file except in compliance with the License. You may obtain a copy
24
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
25
+ *
26
+ * Unless required by applicable law or agreed to in writing, software distributed under
27
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
28
+ * OF ANY KIND, either express or implied. See the License for the specific language
29
+ * governing permissions and limitations under the License.
30
+ */
11
31
 
12
32
 
13
33
  function $e18a693eeaf9c060$export$7f629e9dc1ecf37c(props) {
14
- let { minValue: minValue , maxValue: maxValue , step: step , formatOptions: formatOptions , value: value1 , defaultValue: defaultValue , onChange: onChange , locale: locale , isDisabled: isDisabled , isReadOnly: isReadOnly } = props;
15
- let [numberValue, setNumberValue] = $cmJn2$reactstatelyutils.useControlledState(value1, isNaN(defaultValue) ? NaN : defaultValue, onChange);
16
- let [inputValue, setInputValue] = $cmJn2$react.useState(()=>isNaN(numberValue) ? '' : new $cmJn2$internationalizednumber.NumberFormatter(locale, formatOptions).format(numberValue)
17
- );
18
- let numberParser = $cmJn2$react.useMemo(()=>new $cmJn2$internationalizednumber.NumberParser(locale, formatOptions)
19
- , [
34
+ let { minValue: minValue , maxValue: maxValue , step: step , formatOptions: formatOptions , value: value , defaultValue: defaultValue , onChange: onChange , locale: locale , isDisabled: isDisabled , isReadOnly: isReadOnly } = props;
35
+ let [numberValue, setNumberValue] = (0, $cmJn2$reactstatelyutils.useControlledState)(value, isNaN(defaultValue) ? NaN : defaultValue, onChange);
36
+ let [inputValue, setInputValue] = (0, $cmJn2$react.useState)(()=>isNaN(numberValue) ? "" : new (0, $cmJn2$internationalizednumber.NumberFormatter)(locale, formatOptions).format(numberValue));
37
+ let numberParser = (0, $cmJn2$react.useMemo)(()=>new (0, $cmJn2$internationalizednumber.NumberParser)(locale, formatOptions), [
20
38
  locale,
21
39
  formatOptions
22
40
  ]);
23
- let numberingSystem = $cmJn2$react.useMemo(()=>numberParser.getNumberingSystem(inputValue)
24
- , [
41
+ let numberingSystem = (0, $cmJn2$react.useMemo)(()=>numberParser.getNumberingSystem(inputValue), [
25
42
  numberParser,
26
43
  inputValue
27
44
  ]);
28
- let formatter = $cmJn2$react.useMemo(()=>new $cmJn2$internationalizednumber.NumberFormatter(locale, {
45
+ let formatter = (0, $cmJn2$react.useMemo)(()=>new (0, $cmJn2$internationalizednumber.NumberFormatter)(locale, {
29
46
  ...formatOptions,
30
47
  numberingSystem: numberingSystem
31
- })
32
- , [
48
+ }), [
33
49
  locale,
34
50
  formatOptions,
35
51
  numberingSystem
36
52
  ]);
37
- let intlOptions = $cmJn2$react.useMemo(()=>formatter.resolvedOptions()
38
- , [
53
+ let intlOptions = (0, $cmJn2$react.useMemo)(()=>formatter.resolvedOptions(), [
39
54
  formatter
40
55
  ]);
41
- let format = $cmJn2$react.useCallback((value)=>isNaN(value) || value === null ? '' : formatter.format(value)
42
- , [
56
+ let format = (0, $cmJn2$react.useCallback)((value)=>isNaN(value) || value === null ? "" : formatter.format(value), [
43
57
  formatter
44
58
  ]);
45
59
  let clampStep = !isNaN(step) ? step : 1;
46
- if (intlOptions.style === 'percent' && isNaN(step)) clampStep = 0.01;
60
+ if (intlOptions.style === "percent" && isNaN(step)) clampStep = 0.01;
47
61
  // Update the input value when the number value or format options change. This is done
48
62
  // in a useEffect so that the controlled behavior is correct and we only update the
49
63
  // textfield after prop changes.
50
- let prevValue = $cmJn2$react.useRef(numberValue);
51
- let prevLocale = $cmJn2$react.useRef(locale);
52
- let prevFormatOptions = $cmJn2$react.useRef(formatOptions);
64
+ let prevValue = (0, $cmJn2$react.useRef)(numberValue);
65
+ let prevLocale = (0, $cmJn2$react.useRef)(locale);
66
+ let prevFormatOptions = (0, $cmJn2$react.useRef)(formatOptions);
53
67
  if (!Object.is(numberValue, prevValue.current) || locale !== prevLocale.current || formatOptions !== prevFormatOptions.current) {
54
68
  setInputValue(format(numberValue));
55
69
  prevValue.current = numberValue;
@@ -57,18 +71,17 @@ function $e18a693eeaf9c060$export$7f629e9dc1ecf37c(props) {
57
71
  prevFormatOptions.current = formatOptions;
58
72
  }
59
73
  // Store last parsed value in a ref so it can be used by increment/decrement below
60
- let parsedValue = $cmJn2$react.useMemo(()=>numberParser.parse(inputValue)
61
- , [
74
+ let parsedValue = (0, $cmJn2$react.useMemo)(()=>numberParser.parse(inputValue), [
62
75
  numberParser,
63
76
  inputValue
64
77
  ]);
65
- let parsed = $cmJn2$react.useRef(0);
78
+ let parsed = (0, $cmJn2$react.useRef)(0);
66
79
  parsed.current = parsedValue;
67
80
  let commit = ()=>{
68
81
  // Set to empty state if input value is empty
69
82
  if (!inputValue.length) {
70
83
  setNumberValue(NaN);
71
- setInputValue(value1 === undefined ? '' : format(numberValue));
84
+ setInputValue(value === undefined ? "" : format(numberValue));
72
85
  return;
73
86
  }
74
87
  // if it failed to parse, then reset input to formatted version of current number
@@ -78,12 +91,12 @@ function $e18a693eeaf9c060$export$7f629e9dc1ecf37c(props) {
78
91
  }
79
92
  // Clamp to min and max, round to the nearest step, and round to specified number of digits
80
93
  let clampedValue;
81
- if (isNaN(step)) clampedValue = $cmJn2$reactstatelyutils.clamp(parsed.current, minValue, maxValue);
82
- else clampedValue = $cmJn2$reactstatelyutils.snapValueToStep(parsed.current, minValue, maxValue, step);
94
+ if (isNaN(step)) clampedValue = (0, $cmJn2$reactstatelyutils.clamp)(parsed.current, minValue, maxValue);
95
+ else clampedValue = (0, $cmJn2$reactstatelyutils.snapValueToStep)(parsed.current, minValue, maxValue, step);
83
96
  clampedValue = numberParser.parse(format(clampedValue));
84
97
  setNumberValue(clampedValue);
85
98
  // in a controlled state, the numberValue won't change, so we won't go back to our old input without help
86
- setInputValue(format(value1 === undefined ? clampedValue : numberValue));
99
+ setInputValue(format(value === undefined ? clampedValue : numberValue));
87
100
  };
88
101
  let safeNextStep = (operation, minMax)=>{
89
102
  let prev = parsed.current;
@@ -91,17 +104,17 @@ function $e18a693eeaf9c060$export$7f629e9dc1ecf37c(props) {
91
104
  // if the input is empty, start from the min/max value when incrementing/decrementing,
92
105
  // or zero if there is no min/max value defined.
93
106
  let newValue = isNaN(minMax) ? 0 : minMax;
94
- return $cmJn2$reactstatelyutils.snapValueToStep(newValue, minValue, maxValue, clampStep);
107
+ return (0, $cmJn2$reactstatelyutils.snapValueToStep)(newValue, minValue, maxValue, clampStep);
95
108
  } else {
96
109
  // otherwise, first snap the current value to the nearest step. if it moves in the direction
97
110
  // we're going, use that value, otherwise add the step and snap that value.
98
- let newValue = $cmJn2$reactstatelyutils.snapValueToStep(prev, minValue, maxValue, clampStep);
99
- if (operation === '+' && newValue > prev || operation === '-' && newValue < prev) return newValue;
100
- return $cmJn2$reactstatelyutils.snapValueToStep($e18a693eeaf9c060$var$handleDecimalOperation(operation, prev, clampStep), minValue, maxValue, clampStep);
111
+ let newValue1 = (0, $cmJn2$reactstatelyutils.snapValueToStep)(prev, minValue, maxValue, clampStep);
112
+ if (operation === "+" && newValue1 > prev || operation === "-" && newValue1 < prev) return newValue1;
113
+ return (0, $cmJn2$reactstatelyutils.snapValueToStep)($e18a693eeaf9c060$var$handleDecimalOperation(operation, prev, clampStep), minValue, maxValue, clampStep);
101
114
  }
102
115
  };
103
116
  let increment = ()=>{
104
- let newValue = safeNextStep('+', minValue);
117
+ let newValue = safeNextStep("+", minValue);
105
118
  // if we've arrived at the same value that was previously in the state, the
106
119
  // input value should be updated to match
107
120
  // ex type 4, press increment, highlight the number in the input, type 4 again, press increment
@@ -110,18 +123,17 @@ function $e18a693eeaf9c060$export$7f629e9dc1ecf37c(props) {
110
123
  setNumberValue(newValue);
111
124
  };
112
125
  let decrement = ()=>{
113
- let newValue = safeNextStep('-', maxValue);
126
+ let newValue = safeNextStep("-", maxValue);
114
127
  if (newValue === numberValue) setInputValue(format(newValue));
115
128
  setNumberValue(newValue);
116
129
  };
117
130
  let incrementToMax = ()=>{
118
- if (maxValue != null) setNumberValue($cmJn2$reactstatelyutils.snapValueToStep(maxValue, minValue, maxValue, clampStep));
131
+ if (maxValue != null) setNumberValue((0, $cmJn2$reactstatelyutils.snapValueToStep)(maxValue, minValue, maxValue, clampStep));
119
132
  };
120
133
  let decrementToMin = ()=>{
121
134
  if (minValue != null) setNumberValue(minValue);
122
135
  };
123
- let canIncrement = $cmJn2$react.useMemo(()=>!isDisabled && !isReadOnly && (isNaN(parsedValue) || isNaN(maxValue) || $cmJn2$reactstatelyutils.snapValueToStep(parsedValue, minValue, maxValue, clampStep) > parsedValue || $e18a693eeaf9c060$var$handleDecimalOperation('+', parsedValue, clampStep) <= maxValue)
124
- , [
136
+ let canIncrement = (0, $cmJn2$react.useMemo)(()=>!isDisabled && !isReadOnly && (isNaN(parsedValue) || isNaN(maxValue) || (0, $cmJn2$reactstatelyutils.snapValueToStep)(parsedValue, minValue, maxValue, clampStep) > parsedValue || $e18a693eeaf9c060$var$handleDecimalOperation("+", parsedValue, clampStep) <= maxValue), [
125
137
  isDisabled,
126
138
  isReadOnly,
127
139
  minValue,
@@ -129,8 +141,7 @@ function $e18a693eeaf9c060$export$7f629e9dc1ecf37c(props) {
129
141
  clampStep,
130
142
  parsedValue
131
143
  ]);
132
- let canDecrement = $cmJn2$react.useMemo(()=>!isDisabled && !isReadOnly && (isNaN(parsedValue) || isNaN(minValue) || $cmJn2$reactstatelyutils.snapValueToStep(parsedValue, minValue, maxValue, clampStep) < parsedValue || $e18a693eeaf9c060$var$handleDecimalOperation('-', parsedValue, clampStep) >= minValue)
133
- , [
144
+ let canDecrement = (0, $cmJn2$react.useMemo)(()=>!isDisabled && !isReadOnly && (isNaN(parsedValue) || isNaN(minValue) || (0, $cmJn2$reactstatelyutils.snapValueToStep)(parsedValue, minValue, maxValue, clampStep) < parsedValue || $e18a693eeaf9c060$var$handleDecimalOperation("-", parsedValue, clampStep) >= minValue), [
134
145
  isDisabled,
135
146
  isReadOnly,
136
147
  minValue,
@@ -138,8 +149,7 @@ function $e18a693eeaf9c060$export$7f629e9dc1ecf37c(props) {
138
149
  clampStep,
139
150
  parsedValue
140
151
  ]);
141
- let validate = (value)=>numberParser.isValidPartialNumber(value, minValue, maxValue)
142
- ;
152
+ let validate = (value)=>numberParser.isValidPartialNumber(value, minValue, maxValue);
143
153
  return {
144
154
  validate: validate,
145
155
  increment: increment,
@@ -157,11 +167,11 @@ function $e18a693eeaf9c060$export$7f629e9dc1ecf37c(props) {
157
167
  };
158
168
  }
159
169
  function $e18a693eeaf9c060$var$handleDecimalOperation(operator, value1, value2) {
160
- let result = operator === '+' ? value1 + value2 : value1 - value2;
170
+ let result = operator === "+" ? value1 + value2 : value1 - value2;
161
171
  // Check if we have decimals
162
172
  if (value1 % 1 !== 0 || value2 % 1 !== 0) {
163
- const value1Decimal = value1.toString().split('.');
164
- const value2Decimal = value2.toString().split('.');
173
+ const value1Decimal = value1.toString().split(".");
174
+ const value2Decimal = value2.toString().split(".");
165
175
  const value1DecimalLength = value1Decimal[1] && value1Decimal[1].length || 0;
166
176
  const value2DecimalLength = value2Decimal[1] && value2Decimal[1].length || 0;
167
177
  const multiplier = Math.pow(10, Math.max(value1DecimalLength, value2DecimalLength));
@@ -169,7 +179,7 @@ function $e18a693eeaf9c060$var$handleDecimalOperation(operator, value1, value2)
169
179
  value1 = Math.round(value1 * multiplier);
170
180
  value2 = Math.round(value2 * multiplier);
171
181
  // Perform the operation on integers values to make sure we don't get a fancy decimal value
172
- result = operator === '+' ? value1 + value2 : value1 - value2;
182
+ result = operator === "+" ? value1 + value2 : value1 - value2;
173
183
  // Transform the integer result back to decimal
174
184
  result /= multiplier;
175
185
  }
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-stately/numberfield/src/index.ts","packages/@react-stately/numberfield/src/useNumberFieldState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useNumberFieldState} from './useNumberFieldState';\n\nexport type {NumberFieldStateOptions} from './useNumberFieldState';\nexport type {NumberFieldState} from './useNumberFieldState';\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {clamp, snapValueToStep, useControlledState} from '@react-stately/utils';\nimport {NumberFieldProps} from '@react-types/numberfield';\nimport {NumberFormatter, NumberParser} from '@internationalized/number';\nimport {useCallback, useMemo, useRef, useState} from 'react';\n\nexport interface NumberFieldState {\n /**\n * The current text value of the input. Updated as the user types,\n * and formatted according to `formatOptions` on blur.\n */\n inputValue: string,\n /**\n * The currently parsed number value, or NaN if a valid number could not be parsed.\n * Updated based on the `inputValue` as the user types.\n */\n numberValue: number,\n /** The minimum value of the number field. */\n minValue: number,\n /** The maximum value of the number field. */\n maxValue: number,\n /** Whether the current value can be incremented according to the maximum value and step. */\n canIncrement: boolean,\n /** Whether the current value can be decremented according to the minimum value and step. */\n canDecrement: boolean,\n /**\n * Validates a user input string according to the current locale and format options.\n * Values can be partially entered, and may be valid even if they cannot currently be parsed to a number.\n * Can be used to implement validation as a user types.\n */\n validate(value: string): boolean,\n /** Sets the current text value of the input. */\n setInputValue(val: string): void,\n /**\n * Commits the current input value. The value is parsed to a number, clamped according\n * to the minimum and maximum values of the field, and snapped to the nearest step value.\n * This will fire the `onChange` prop with the new value, and if uncontrolled, update the `numberValue`.\n * Typically this is called when the field is blurred.\n */\n commit(): void,\n /** Increments the current input value to the next step boundary, and fires `onChange`. */\n increment(): void,\n /** Decrements the current input value to the next step boundary, and fires `onChange`. */\n decrement(): void,\n /** Sets the current value to the `maxValue` if any, and fires `onChange`. */\n incrementToMax(): void,\n /** Sets the current value to the `minValue` if any, and fires `onChange`. */\n decrementToMin(): void\n}\n\nexport interface NumberFieldStateOptions extends NumberFieldProps {\n /**\n * The locale that should be used for parsing.\n * @default 'en-US'\n */\n locale: string\n}\n\n/**\n * Provides state management for a number field component. Number fields allow users to enter a number,\n * and increment or decrement the value using stepper buttons.\n */\nexport function useNumberFieldState(\n props: NumberFieldStateOptions\n): NumberFieldState {\n let {\n minValue,\n maxValue,\n step,\n formatOptions,\n value,\n defaultValue,\n onChange,\n locale,\n isDisabled,\n isReadOnly\n } = props;\n\n let [numberValue, setNumberValue] = useControlledState<number>(value, isNaN(defaultValue) ? NaN : defaultValue, onChange);\n let [inputValue, setInputValue] = useState(() => isNaN(numberValue) ? '' : new NumberFormatter(locale, formatOptions).format(numberValue));\n\n let numberParser = useMemo(() => new NumberParser(locale, formatOptions), [locale, formatOptions]);\n let numberingSystem = useMemo(() => numberParser.getNumberingSystem(inputValue), [numberParser, inputValue]);\n let formatter = useMemo(() => new NumberFormatter(locale, {...formatOptions, numberingSystem}), [locale, formatOptions, numberingSystem]);\n let intlOptions = useMemo(() => formatter.resolvedOptions(), [formatter]);\n let format = useCallback((value: number) => (isNaN(value) || value === null) ? '' : formatter.format(value), [formatter]);\n\n let clampStep = !isNaN(step) ? step : 1;\n if (intlOptions.style === 'percent' && isNaN(step)) {\n clampStep = 0.01;\n }\n\n // Update the input value when the number value or format options change. This is done\n // in a useEffect so that the controlled behavior is correct and we only update the\n // textfield after prop changes.\n let prevValue = useRef(numberValue);\n let prevLocale = useRef(locale);\n let prevFormatOptions = useRef(formatOptions);\n if (!Object.is(numberValue, prevValue.current) || locale !== prevLocale.current || formatOptions !== prevFormatOptions.current) {\n setInputValue(format(numberValue));\n prevValue.current = numberValue;\n prevLocale.current = locale;\n prevFormatOptions.current = formatOptions;\n }\n\n // Store last parsed value in a ref so it can be used by increment/decrement below\n let parsedValue = useMemo(() => numberParser.parse(inputValue), [numberParser, inputValue]);\n let parsed = useRef(0);\n parsed.current = parsedValue;\n\n let commit = () => {\n // Set to empty state if input value is empty\n if (!inputValue.length) {\n setNumberValue(NaN);\n setInputValue(value === undefined ? '' : format(numberValue));\n return;\n }\n\n // if it failed to parse, then reset input to formatted version of current number\n if (isNaN(parsed.current)) {\n setInputValue(format(numberValue));\n return;\n }\n\n // Clamp to min and max, round to the nearest step, and round to specified number of digits\n let clampedValue: number;\n if (isNaN(step)) {\n clampedValue = clamp(parsed.current, minValue, maxValue);\n } else {\n clampedValue = snapValueToStep(parsed.current, minValue, maxValue, step);\n }\n\n clampedValue = numberParser.parse(format(clampedValue));\n setNumberValue(clampedValue);\n\n // in a controlled state, the numberValue won't change, so we won't go back to our old input without help\n setInputValue(format(value === undefined ? clampedValue : numberValue));\n };\n\n let safeNextStep = (operation: '+' | '-', minMax: number) => {\n let prev = parsed.current;\n\n if (isNaN(prev)) {\n // if the input is empty, start from the min/max value when incrementing/decrementing,\n // or zero if there is no min/max value defined.\n let newValue = isNaN(minMax) ? 0 : minMax;\n return snapValueToStep(newValue, minValue, maxValue, clampStep);\n } else {\n // otherwise, first snap the current value to the nearest step. if it moves in the direction\n // we're going, use that value, otherwise add the step and snap that value.\n let newValue = snapValueToStep(prev, minValue, maxValue, clampStep);\n if ((operation === '+' && newValue > prev) || (operation === '-' && newValue < prev)) {\n return newValue;\n }\n\n return snapValueToStep(\n handleDecimalOperation(operation, prev, clampStep),\n minValue,\n maxValue,\n clampStep\n );\n }\n };\n\n let increment = () => {\n let newValue = safeNextStep('+', minValue);\n\n // if we've arrived at the same value that was previously in the state, the\n // input value should be updated to match\n // ex type 4, press increment, highlight the number in the input, type 4 again, press increment\n // you'd be at 5, then incrementing to 5 again, so no re-render would happen and 4 would be left in the input\n if (newValue === numberValue) {\n setInputValue(format(newValue));\n }\n\n setNumberValue(newValue);\n };\n\n let decrement = () => {\n let newValue = safeNextStep('-', maxValue);\n\n if (newValue === numberValue) {\n setInputValue(format(newValue));\n }\n\n setNumberValue(newValue);\n };\n\n let incrementToMax = () => {\n if (maxValue != null) {\n setNumberValue(snapValueToStep(maxValue, minValue, maxValue, clampStep));\n }\n };\n\n let decrementToMin = () => {\n if (minValue != null) {\n setNumberValue(minValue);\n }\n };\n\n let canIncrement = useMemo(() => (\n !isDisabled &&\n !isReadOnly &&\n (\n isNaN(parsedValue) ||\n isNaN(maxValue) ||\n snapValueToStep(parsedValue, minValue, maxValue, clampStep) > parsedValue ||\n handleDecimalOperation('+', parsedValue, clampStep) <= maxValue\n )\n ), [isDisabled, isReadOnly, minValue, maxValue, clampStep, parsedValue]);\n\n let canDecrement = useMemo(() => (\n !isDisabled &&\n !isReadOnly &&\n (\n isNaN(parsedValue) ||\n isNaN(minValue) ||\n snapValueToStep(parsedValue, minValue, maxValue, clampStep) < parsedValue ||\n handleDecimalOperation('-', parsedValue, clampStep) >= minValue\n )\n ), [isDisabled, isReadOnly, minValue, maxValue, clampStep, parsedValue]);\n\n let validate = (value: string) => numberParser.isValidPartialNumber(value, minValue, maxValue);\n\n return {\n validate,\n increment,\n incrementToMax,\n decrement,\n decrementToMin,\n canIncrement,\n canDecrement,\n minValue,\n maxValue,\n numberValue: parsedValue,\n setInputValue,\n inputValue,\n commit\n };\n}\n\nfunction handleDecimalOperation(operator: '-' | '+', value1: number, value2: number): number {\n let result = operator === '+' ? value1 + value2 : value1 - value2;\n\n // Check if we have decimals\n if (value1 % 1 !== 0 || value2 % 1 !== 0) {\n const value1Decimal = value1.toString().split('.');\n const value2Decimal = value2.toString().split('.');\n const value1DecimalLength = (value1Decimal[1] && value1Decimal[1].length) || 0;\n const value2DecimalLength = (value2Decimal[1] && value2Decimal[1].length) || 0;\n const multiplier = Math.pow(10, Math.max(value1DecimalLength, value2DecimalLength));\n\n // Transform the decimals to integers based on the precision\n value1 = Math.round(value1 * multiplier);\n value2 = Math.round(value2 * multiplier);\n\n // Perform the operation on integers values to make sure we don't get a fancy decimal value\n result = operator === '+' ? value1 + value2 : value1 - value2;\n\n // Transform the integer result back to decimal\n result /= multiplier;\n }\n\n return result;\n}\n"],"names":[],"version":3,"file":"main.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-stately/numberfield/src/index.ts","packages/@react-stately/numberfield/src/useNumberFieldState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useNumberFieldState} from './useNumberFieldState';\n\nexport type {NumberFieldStateOptions} from './useNumberFieldState';\nexport type {NumberFieldState} from './useNumberFieldState';\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {clamp, snapValueToStep, useControlledState} from '@react-stately/utils';\nimport {NumberFieldProps} from '@react-types/numberfield';\nimport {NumberFormatter, NumberParser} from '@internationalized/number';\nimport {useCallback, useMemo, useRef, useState} from 'react';\n\nexport interface NumberFieldState {\n /**\n * The current text value of the input. Updated as the user types,\n * and formatted according to `formatOptions` on blur.\n */\n inputValue: string,\n /**\n * The currently parsed number value, or NaN if a valid number could not be parsed.\n * Updated based on the `inputValue` as the user types.\n */\n numberValue: number,\n /** The minimum value of the number field. */\n minValue: number,\n /** The maximum value of the number field. */\n maxValue: number,\n /** Whether the current value can be incremented according to the maximum value and step. */\n canIncrement: boolean,\n /** Whether the current value can be decremented according to the minimum value and step. */\n canDecrement: boolean,\n /**\n * Validates a user input string according to the current locale and format options.\n * Values can be partially entered, and may be valid even if they cannot currently be parsed to a number.\n * Can be used to implement validation as a user types.\n */\n validate(value: string): boolean,\n /** Sets the current text value of the input. */\n setInputValue(val: string): void,\n /**\n * Commits the current input value. The value is parsed to a number, clamped according\n * to the minimum and maximum values of the field, and snapped to the nearest step value.\n * This will fire the `onChange` prop with the new value, and if uncontrolled, update the `numberValue`.\n * Typically this is called when the field is blurred.\n */\n commit(): void,\n /** Increments the current input value to the next step boundary, and fires `onChange`. */\n increment(): void,\n /** Decrements the current input value to the next step boundary, and fires `onChange`. */\n decrement(): void,\n /** Sets the current value to the `maxValue` if any, and fires `onChange`. */\n incrementToMax(): void,\n /** Sets the current value to the `minValue` if any, and fires `onChange`. */\n decrementToMin(): void\n}\n\nexport interface NumberFieldStateOptions extends NumberFieldProps {\n /**\n * The locale that should be used for parsing.\n * @default 'en-US'\n */\n locale: string\n}\n\n/**\n * Provides state management for a number field component. Number fields allow users to enter a number,\n * and increment or decrement the value using stepper buttons.\n */\nexport function useNumberFieldState(\n props: NumberFieldStateOptions\n): NumberFieldState {\n let {\n minValue,\n maxValue,\n step,\n formatOptions,\n value,\n defaultValue,\n onChange,\n locale,\n isDisabled,\n isReadOnly\n } = props;\n\n let [numberValue, setNumberValue] = useControlledState<number>(value, isNaN(defaultValue) ? NaN : defaultValue, onChange);\n let [inputValue, setInputValue] = useState(() => isNaN(numberValue) ? '' : new NumberFormatter(locale, formatOptions).format(numberValue));\n\n let numberParser = useMemo(() => new NumberParser(locale, formatOptions), [locale, formatOptions]);\n let numberingSystem = useMemo(() => numberParser.getNumberingSystem(inputValue), [numberParser, inputValue]);\n let formatter = useMemo(() => new NumberFormatter(locale, {...formatOptions, numberingSystem}), [locale, formatOptions, numberingSystem]);\n let intlOptions = useMemo(() => formatter.resolvedOptions(), [formatter]);\n let format = useCallback((value: number) => (isNaN(value) || value === null) ? '' : formatter.format(value), [formatter]);\n\n let clampStep = !isNaN(step) ? step : 1;\n if (intlOptions.style === 'percent' && isNaN(step)) {\n clampStep = 0.01;\n }\n\n // Update the input value when the number value or format options change. This is done\n // in a useEffect so that the controlled behavior is correct and we only update the\n // textfield after prop changes.\n let prevValue = useRef(numberValue);\n let prevLocale = useRef(locale);\n let prevFormatOptions = useRef(formatOptions);\n if (!Object.is(numberValue, prevValue.current) || locale !== prevLocale.current || formatOptions !== prevFormatOptions.current) {\n setInputValue(format(numberValue));\n prevValue.current = numberValue;\n prevLocale.current = locale;\n prevFormatOptions.current = formatOptions;\n }\n\n // Store last parsed value in a ref so it can be used by increment/decrement below\n let parsedValue = useMemo(() => numberParser.parse(inputValue), [numberParser, inputValue]);\n let parsed = useRef(0);\n parsed.current = parsedValue;\n\n let commit = () => {\n // Set to empty state if input value is empty\n if (!inputValue.length) {\n setNumberValue(NaN);\n setInputValue(value === undefined ? '' : format(numberValue));\n return;\n }\n\n // if it failed to parse, then reset input to formatted version of current number\n if (isNaN(parsed.current)) {\n setInputValue(format(numberValue));\n return;\n }\n\n // Clamp to min and max, round to the nearest step, and round to specified number of digits\n let clampedValue: number;\n if (isNaN(step)) {\n clampedValue = clamp(parsed.current, minValue, maxValue);\n } else {\n clampedValue = snapValueToStep(parsed.current, minValue, maxValue, step);\n }\n\n clampedValue = numberParser.parse(format(clampedValue));\n setNumberValue(clampedValue);\n\n // in a controlled state, the numberValue won't change, so we won't go back to our old input without help\n setInputValue(format(value === undefined ? clampedValue : numberValue));\n };\n\n let safeNextStep = (operation: '+' | '-', minMax: number) => {\n let prev = parsed.current;\n\n if (isNaN(prev)) {\n // if the input is empty, start from the min/max value when incrementing/decrementing,\n // or zero if there is no min/max value defined.\n let newValue = isNaN(minMax) ? 0 : minMax;\n return snapValueToStep(newValue, minValue, maxValue, clampStep);\n } else {\n // otherwise, first snap the current value to the nearest step. if it moves in the direction\n // we're going, use that value, otherwise add the step and snap that value.\n let newValue = snapValueToStep(prev, minValue, maxValue, clampStep);\n if ((operation === '+' && newValue > prev) || (operation === '-' && newValue < prev)) {\n return newValue;\n }\n\n return snapValueToStep(\n handleDecimalOperation(operation, prev, clampStep),\n minValue,\n maxValue,\n clampStep\n );\n }\n };\n\n let increment = () => {\n let newValue = safeNextStep('+', minValue);\n\n // if we've arrived at the same value that was previously in the state, the\n // input value should be updated to match\n // ex type 4, press increment, highlight the number in the input, type 4 again, press increment\n // you'd be at 5, then incrementing to 5 again, so no re-render would happen and 4 would be left in the input\n if (newValue === numberValue) {\n setInputValue(format(newValue));\n }\n\n setNumberValue(newValue);\n };\n\n let decrement = () => {\n let newValue = safeNextStep('-', maxValue);\n\n if (newValue === numberValue) {\n setInputValue(format(newValue));\n }\n\n setNumberValue(newValue);\n };\n\n let incrementToMax = () => {\n if (maxValue != null) {\n setNumberValue(snapValueToStep(maxValue, minValue, maxValue, clampStep));\n }\n };\n\n let decrementToMin = () => {\n if (minValue != null) {\n setNumberValue(minValue);\n }\n };\n\n let canIncrement = useMemo(() => (\n !isDisabled &&\n !isReadOnly &&\n (\n isNaN(parsedValue) ||\n isNaN(maxValue) ||\n snapValueToStep(parsedValue, minValue, maxValue, clampStep) > parsedValue ||\n handleDecimalOperation('+', parsedValue, clampStep) <= maxValue\n )\n ), [isDisabled, isReadOnly, minValue, maxValue, clampStep, parsedValue]);\n\n let canDecrement = useMemo(() => (\n !isDisabled &&\n !isReadOnly &&\n (\n isNaN(parsedValue) ||\n isNaN(minValue) ||\n snapValueToStep(parsedValue, minValue, maxValue, clampStep) < parsedValue ||\n handleDecimalOperation('-', parsedValue, clampStep) >= minValue\n )\n ), [isDisabled, isReadOnly, minValue, maxValue, clampStep, parsedValue]);\n\n let validate = (value: string) => numberParser.isValidPartialNumber(value, minValue, maxValue);\n\n return {\n validate,\n increment,\n incrementToMax,\n decrement,\n decrementToMin,\n canIncrement,\n canDecrement,\n minValue,\n maxValue,\n numberValue: parsedValue,\n setInputValue,\n inputValue,\n commit\n };\n}\n\nfunction handleDecimalOperation(operator: '-' | '+', value1: number, value2: number): number {\n let result = operator === '+' ? value1 + value2 : value1 - value2;\n\n // Check if we have decimals\n if (value1 % 1 !== 0 || value2 % 1 !== 0) {\n const value1Decimal = value1.toString().split('.');\n const value2Decimal = value2.toString().split('.');\n const value1DecimalLength = (value1Decimal[1] && value1Decimal[1].length) || 0;\n const value2DecimalLength = (value2Decimal[1] && value2Decimal[1].length) || 0;\n const multiplier = Math.pow(10, Math.max(value1DecimalLength, value2DecimalLength));\n\n // Transform the decimals to integers based on the precision\n value1 = Math.round(value1 * multiplier);\n value2 = Math.round(value2 * multiplier);\n\n // Perform the operation on integers values to make sure we don't get a fancy decimal value\n result = operator === '+' ? value1 + value2 : value1 - value2;\n\n // Transform the integer result back to decimal\n result /= multiplier;\n }\n\n return result;\n}\n"],"names":[],"version":3,"file":"main.js.map"}
package/dist/module.js CHANGED
@@ -2,49 +2,63 @@ import {useControlledState as $vhjCi$useControlledState, clamp as $vhjCi$clamp,
2
2
  import {NumberFormatter as $vhjCi$NumberFormatter, NumberParser as $vhjCi$NumberParser} from "@internationalized/number";
3
3
  import {useState as $vhjCi$useState, useMemo as $vhjCi$useMemo, useCallback as $vhjCi$useCallback, useRef as $vhjCi$useRef} from "react";
4
4
 
5
-
5
+ /*
6
+ * Copyright 2020 Adobe. All rights reserved.
7
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License. You may obtain a copy
9
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software distributed under
12
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
13
+ * OF ANY KIND, either express or implied. See the License for the specific language
14
+ * governing permissions and limitations under the License.
15
+ */ /*
16
+ * Copyright 2020 Adobe. All rights reserved.
17
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
18
+ * you may not use this file except in compliance with the License. You may obtain a copy
19
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
20
+ *
21
+ * Unless required by applicable law or agreed to in writing, software distributed under
22
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
23
+ * OF ANY KIND, either express or implied. See the License for the specific language
24
+ * governing permissions and limitations under the License.
25
+ */
6
26
 
7
27
 
8
28
  function $de67e98908f0c6ee$export$7f629e9dc1ecf37c(props) {
9
- let { minValue: minValue , maxValue: maxValue , step: step , formatOptions: formatOptions , value: value1 , defaultValue: defaultValue , onChange: onChange , locale: locale , isDisabled: isDisabled , isReadOnly: isReadOnly } = props;
10
- let [numberValue, setNumberValue] = $vhjCi$useControlledState(value1, isNaN(defaultValue) ? NaN : defaultValue, onChange);
11
- let [inputValue, setInputValue] = $vhjCi$useState(()=>isNaN(numberValue) ? '' : new $vhjCi$NumberFormatter(locale, formatOptions).format(numberValue)
12
- );
13
- let numberParser = $vhjCi$useMemo(()=>new $vhjCi$NumberParser(locale, formatOptions)
14
- , [
29
+ let { minValue: minValue , maxValue: maxValue , step: step , formatOptions: formatOptions , value: value , defaultValue: defaultValue , onChange: onChange , locale: locale , isDisabled: isDisabled , isReadOnly: isReadOnly } = props;
30
+ let [numberValue, setNumberValue] = (0, $vhjCi$useControlledState)(value, isNaN(defaultValue) ? NaN : defaultValue, onChange);
31
+ let [inputValue, setInputValue] = (0, $vhjCi$useState)(()=>isNaN(numberValue) ? "" : new (0, $vhjCi$NumberFormatter)(locale, formatOptions).format(numberValue));
32
+ let numberParser = (0, $vhjCi$useMemo)(()=>new (0, $vhjCi$NumberParser)(locale, formatOptions), [
15
33
  locale,
16
34
  formatOptions
17
35
  ]);
18
- let numberingSystem = $vhjCi$useMemo(()=>numberParser.getNumberingSystem(inputValue)
19
- , [
36
+ let numberingSystem = (0, $vhjCi$useMemo)(()=>numberParser.getNumberingSystem(inputValue), [
20
37
  numberParser,
21
38
  inputValue
22
39
  ]);
23
- let formatter = $vhjCi$useMemo(()=>new $vhjCi$NumberFormatter(locale, {
40
+ let formatter = (0, $vhjCi$useMemo)(()=>new (0, $vhjCi$NumberFormatter)(locale, {
24
41
  ...formatOptions,
25
42
  numberingSystem: numberingSystem
26
- })
27
- , [
43
+ }), [
28
44
  locale,
29
45
  formatOptions,
30
46
  numberingSystem
31
47
  ]);
32
- let intlOptions = $vhjCi$useMemo(()=>formatter.resolvedOptions()
33
- , [
48
+ let intlOptions = (0, $vhjCi$useMemo)(()=>formatter.resolvedOptions(), [
34
49
  formatter
35
50
  ]);
36
- let format = $vhjCi$useCallback((value)=>isNaN(value) || value === null ? '' : formatter.format(value)
37
- , [
51
+ let format = (0, $vhjCi$useCallback)((value)=>isNaN(value) || value === null ? "" : formatter.format(value), [
38
52
  formatter
39
53
  ]);
40
54
  let clampStep = !isNaN(step) ? step : 1;
41
- if (intlOptions.style === 'percent' && isNaN(step)) clampStep = 0.01;
55
+ if (intlOptions.style === "percent" && isNaN(step)) clampStep = 0.01;
42
56
  // Update the input value when the number value or format options change. This is done
43
57
  // in a useEffect so that the controlled behavior is correct and we only update the
44
58
  // textfield after prop changes.
45
- let prevValue = $vhjCi$useRef(numberValue);
46
- let prevLocale = $vhjCi$useRef(locale);
47
- let prevFormatOptions = $vhjCi$useRef(formatOptions);
59
+ let prevValue = (0, $vhjCi$useRef)(numberValue);
60
+ let prevLocale = (0, $vhjCi$useRef)(locale);
61
+ let prevFormatOptions = (0, $vhjCi$useRef)(formatOptions);
48
62
  if (!Object.is(numberValue, prevValue.current) || locale !== prevLocale.current || formatOptions !== prevFormatOptions.current) {
49
63
  setInputValue(format(numberValue));
50
64
  prevValue.current = numberValue;
@@ -52,18 +66,17 @@ function $de67e98908f0c6ee$export$7f629e9dc1ecf37c(props) {
52
66
  prevFormatOptions.current = formatOptions;
53
67
  }
54
68
  // Store last parsed value in a ref so it can be used by increment/decrement below
55
- let parsedValue = $vhjCi$useMemo(()=>numberParser.parse(inputValue)
56
- , [
69
+ let parsedValue = (0, $vhjCi$useMemo)(()=>numberParser.parse(inputValue), [
57
70
  numberParser,
58
71
  inputValue
59
72
  ]);
60
- let parsed = $vhjCi$useRef(0);
73
+ let parsed = (0, $vhjCi$useRef)(0);
61
74
  parsed.current = parsedValue;
62
75
  let commit = ()=>{
63
76
  // Set to empty state if input value is empty
64
77
  if (!inputValue.length) {
65
78
  setNumberValue(NaN);
66
- setInputValue(value1 === undefined ? '' : format(numberValue));
79
+ setInputValue(value === undefined ? "" : format(numberValue));
67
80
  return;
68
81
  }
69
82
  // if it failed to parse, then reset input to formatted version of current number
@@ -73,12 +86,12 @@ function $de67e98908f0c6ee$export$7f629e9dc1ecf37c(props) {
73
86
  }
74
87
  // Clamp to min and max, round to the nearest step, and round to specified number of digits
75
88
  let clampedValue;
76
- if (isNaN(step)) clampedValue = $vhjCi$clamp(parsed.current, minValue, maxValue);
77
- else clampedValue = $vhjCi$snapValueToStep(parsed.current, minValue, maxValue, step);
89
+ if (isNaN(step)) clampedValue = (0, $vhjCi$clamp)(parsed.current, minValue, maxValue);
90
+ else clampedValue = (0, $vhjCi$snapValueToStep)(parsed.current, minValue, maxValue, step);
78
91
  clampedValue = numberParser.parse(format(clampedValue));
79
92
  setNumberValue(clampedValue);
80
93
  // in a controlled state, the numberValue won't change, so we won't go back to our old input without help
81
- setInputValue(format(value1 === undefined ? clampedValue : numberValue));
94
+ setInputValue(format(value === undefined ? clampedValue : numberValue));
82
95
  };
83
96
  let safeNextStep = (operation, minMax)=>{
84
97
  let prev = parsed.current;
@@ -86,17 +99,17 @@ function $de67e98908f0c6ee$export$7f629e9dc1ecf37c(props) {
86
99
  // if the input is empty, start from the min/max value when incrementing/decrementing,
87
100
  // or zero if there is no min/max value defined.
88
101
  let newValue = isNaN(minMax) ? 0 : minMax;
89
- return $vhjCi$snapValueToStep(newValue, minValue, maxValue, clampStep);
102
+ return (0, $vhjCi$snapValueToStep)(newValue, minValue, maxValue, clampStep);
90
103
  } else {
91
104
  // otherwise, first snap the current value to the nearest step. if it moves in the direction
92
105
  // we're going, use that value, otherwise add the step and snap that value.
93
- let newValue = $vhjCi$snapValueToStep(prev, minValue, maxValue, clampStep);
94
- if (operation === '+' && newValue > prev || operation === '-' && newValue < prev) return newValue;
95
- return $vhjCi$snapValueToStep($de67e98908f0c6ee$var$handleDecimalOperation(operation, prev, clampStep), minValue, maxValue, clampStep);
106
+ let newValue1 = (0, $vhjCi$snapValueToStep)(prev, minValue, maxValue, clampStep);
107
+ if (operation === "+" && newValue1 > prev || operation === "-" && newValue1 < prev) return newValue1;
108
+ return (0, $vhjCi$snapValueToStep)($de67e98908f0c6ee$var$handleDecimalOperation(operation, prev, clampStep), minValue, maxValue, clampStep);
96
109
  }
97
110
  };
98
111
  let increment = ()=>{
99
- let newValue = safeNextStep('+', minValue);
112
+ let newValue = safeNextStep("+", minValue);
100
113
  // if we've arrived at the same value that was previously in the state, the
101
114
  // input value should be updated to match
102
115
  // ex type 4, press increment, highlight the number in the input, type 4 again, press increment
@@ -105,18 +118,17 @@ function $de67e98908f0c6ee$export$7f629e9dc1ecf37c(props) {
105
118
  setNumberValue(newValue);
106
119
  };
107
120
  let decrement = ()=>{
108
- let newValue = safeNextStep('-', maxValue);
121
+ let newValue = safeNextStep("-", maxValue);
109
122
  if (newValue === numberValue) setInputValue(format(newValue));
110
123
  setNumberValue(newValue);
111
124
  };
112
125
  let incrementToMax = ()=>{
113
- if (maxValue != null) setNumberValue($vhjCi$snapValueToStep(maxValue, minValue, maxValue, clampStep));
126
+ if (maxValue != null) setNumberValue((0, $vhjCi$snapValueToStep)(maxValue, minValue, maxValue, clampStep));
114
127
  };
115
128
  let decrementToMin = ()=>{
116
129
  if (minValue != null) setNumberValue(minValue);
117
130
  };
118
- let canIncrement = $vhjCi$useMemo(()=>!isDisabled && !isReadOnly && (isNaN(parsedValue) || isNaN(maxValue) || $vhjCi$snapValueToStep(parsedValue, minValue, maxValue, clampStep) > parsedValue || $de67e98908f0c6ee$var$handleDecimalOperation('+', parsedValue, clampStep) <= maxValue)
119
- , [
131
+ let canIncrement = (0, $vhjCi$useMemo)(()=>!isDisabled && !isReadOnly && (isNaN(parsedValue) || isNaN(maxValue) || (0, $vhjCi$snapValueToStep)(parsedValue, minValue, maxValue, clampStep) > parsedValue || $de67e98908f0c6ee$var$handleDecimalOperation("+", parsedValue, clampStep) <= maxValue), [
120
132
  isDisabled,
121
133
  isReadOnly,
122
134
  minValue,
@@ -124,8 +136,7 @@ function $de67e98908f0c6ee$export$7f629e9dc1ecf37c(props) {
124
136
  clampStep,
125
137
  parsedValue
126
138
  ]);
127
- let canDecrement = $vhjCi$useMemo(()=>!isDisabled && !isReadOnly && (isNaN(parsedValue) || isNaN(minValue) || $vhjCi$snapValueToStep(parsedValue, minValue, maxValue, clampStep) < parsedValue || $de67e98908f0c6ee$var$handleDecimalOperation('-', parsedValue, clampStep) >= minValue)
128
- , [
139
+ let canDecrement = (0, $vhjCi$useMemo)(()=>!isDisabled && !isReadOnly && (isNaN(parsedValue) || isNaN(minValue) || (0, $vhjCi$snapValueToStep)(parsedValue, minValue, maxValue, clampStep) < parsedValue || $de67e98908f0c6ee$var$handleDecimalOperation("-", parsedValue, clampStep) >= minValue), [
129
140
  isDisabled,
130
141
  isReadOnly,
131
142
  minValue,
@@ -133,8 +144,7 @@ function $de67e98908f0c6ee$export$7f629e9dc1ecf37c(props) {
133
144
  clampStep,
134
145
  parsedValue
135
146
  ]);
136
- let validate = (value)=>numberParser.isValidPartialNumber(value, minValue, maxValue)
137
- ;
147
+ let validate = (value)=>numberParser.isValidPartialNumber(value, minValue, maxValue);
138
148
  return {
139
149
  validate: validate,
140
150
  increment: increment,
@@ -152,11 +162,11 @@ function $de67e98908f0c6ee$export$7f629e9dc1ecf37c(props) {
152
162
  };
153
163
  }
154
164
  function $de67e98908f0c6ee$var$handleDecimalOperation(operator, value1, value2) {
155
- let result = operator === '+' ? value1 + value2 : value1 - value2;
165
+ let result = operator === "+" ? value1 + value2 : value1 - value2;
156
166
  // Check if we have decimals
157
167
  if (value1 % 1 !== 0 || value2 % 1 !== 0) {
158
- const value1Decimal = value1.toString().split('.');
159
- const value2Decimal = value2.toString().split('.');
168
+ const value1Decimal = value1.toString().split(".");
169
+ const value2Decimal = value2.toString().split(".");
160
170
  const value1DecimalLength = value1Decimal[1] && value1Decimal[1].length || 0;
161
171
  const value2DecimalLength = value2Decimal[1] && value2Decimal[1].length || 0;
162
172
  const multiplier = Math.pow(10, Math.max(value1DecimalLength, value2DecimalLength));
@@ -164,7 +174,7 @@ function $de67e98908f0c6ee$var$handleDecimalOperation(operator, value1, value2)
164
174
  value1 = Math.round(value1 * multiplier);
165
175
  value2 = Math.round(value2 * multiplier);
166
176
  // Perform the operation on integers values to make sure we don't get a fancy decimal value
167
- result = operator === '+' ? value1 + value2 : value1 - value2;
177
+ result = operator === "+" ? value1 + value2 : value1 - value2;
168
178
  // Transform the integer result back to decimal
169
179
  result /= multiplier;
170
180
  }
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-stately/numberfield/src/index.ts","packages/@react-stately/numberfield/src/useNumberFieldState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useNumberFieldState} from './useNumberFieldState';\n\nexport type {NumberFieldStateOptions} from './useNumberFieldState';\nexport type {NumberFieldState} from './useNumberFieldState';\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {clamp, snapValueToStep, useControlledState} from '@react-stately/utils';\nimport {NumberFieldProps} from '@react-types/numberfield';\nimport {NumberFormatter, NumberParser} from '@internationalized/number';\nimport {useCallback, useMemo, useRef, useState} from 'react';\n\nexport interface NumberFieldState {\n /**\n * The current text value of the input. Updated as the user types,\n * and formatted according to `formatOptions` on blur.\n */\n inputValue: string,\n /**\n * The currently parsed number value, or NaN if a valid number could not be parsed.\n * Updated based on the `inputValue` as the user types.\n */\n numberValue: number,\n /** The minimum value of the number field. */\n minValue: number,\n /** The maximum value of the number field. */\n maxValue: number,\n /** Whether the current value can be incremented according to the maximum value and step. */\n canIncrement: boolean,\n /** Whether the current value can be decremented according to the minimum value and step. */\n canDecrement: boolean,\n /**\n * Validates a user input string according to the current locale and format options.\n * Values can be partially entered, and may be valid even if they cannot currently be parsed to a number.\n * Can be used to implement validation as a user types.\n */\n validate(value: string): boolean,\n /** Sets the current text value of the input. */\n setInputValue(val: string): void,\n /**\n * Commits the current input value. The value is parsed to a number, clamped according\n * to the minimum and maximum values of the field, and snapped to the nearest step value.\n * This will fire the `onChange` prop with the new value, and if uncontrolled, update the `numberValue`.\n * Typically this is called when the field is blurred.\n */\n commit(): void,\n /** Increments the current input value to the next step boundary, and fires `onChange`. */\n increment(): void,\n /** Decrements the current input value to the next step boundary, and fires `onChange`. */\n decrement(): void,\n /** Sets the current value to the `maxValue` if any, and fires `onChange`. */\n incrementToMax(): void,\n /** Sets the current value to the `minValue` if any, and fires `onChange`. */\n decrementToMin(): void\n}\n\nexport interface NumberFieldStateOptions extends NumberFieldProps {\n /**\n * The locale that should be used for parsing.\n * @default 'en-US'\n */\n locale: string\n}\n\n/**\n * Provides state management for a number field component. Number fields allow users to enter a number,\n * and increment or decrement the value using stepper buttons.\n */\nexport function useNumberFieldState(\n props: NumberFieldStateOptions\n): NumberFieldState {\n let {\n minValue,\n maxValue,\n step,\n formatOptions,\n value,\n defaultValue,\n onChange,\n locale,\n isDisabled,\n isReadOnly\n } = props;\n\n let [numberValue, setNumberValue] = useControlledState<number>(value, isNaN(defaultValue) ? NaN : defaultValue, onChange);\n let [inputValue, setInputValue] = useState(() => isNaN(numberValue) ? '' : new NumberFormatter(locale, formatOptions).format(numberValue));\n\n let numberParser = useMemo(() => new NumberParser(locale, formatOptions), [locale, formatOptions]);\n let numberingSystem = useMemo(() => numberParser.getNumberingSystem(inputValue), [numberParser, inputValue]);\n let formatter = useMemo(() => new NumberFormatter(locale, {...formatOptions, numberingSystem}), [locale, formatOptions, numberingSystem]);\n let intlOptions = useMemo(() => formatter.resolvedOptions(), [formatter]);\n let format = useCallback((value: number) => (isNaN(value) || value === null) ? '' : formatter.format(value), [formatter]);\n\n let clampStep = !isNaN(step) ? step : 1;\n if (intlOptions.style === 'percent' && isNaN(step)) {\n clampStep = 0.01;\n }\n\n // Update the input value when the number value or format options change. This is done\n // in a useEffect so that the controlled behavior is correct and we only update the\n // textfield after prop changes.\n let prevValue = useRef(numberValue);\n let prevLocale = useRef(locale);\n let prevFormatOptions = useRef(formatOptions);\n if (!Object.is(numberValue, prevValue.current) || locale !== prevLocale.current || formatOptions !== prevFormatOptions.current) {\n setInputValue(format(numberValue));\n prevValue.current = numberValue;\n prevLocale.current = locale;\n prevFormatOptions.current = formatOptions;\n }\n\n // Store last parsed value in a ref so it can be used by increment/decrement below\n let parsedValue = useMemo(() => numberParser.parse(inputValue), [numberParser, inputValue]);\n let parsed = useRef(0);\n parsed.current = parsedValue;\n\n let commit = () => {\n // Set to empty state if input value is empty\n if (!inputValue.length) {\n setNumberValue(NaN);\n setInputValue(value === undefined ? '' : format(numberValue));\n return;\n }\n\n // if it failed to parse, then reset input to formatted version of current number\n if (isNaN(parsed.current)) {\n setInputValue(format(numberValue));\n return;\n }\n\n // Clamp to min and max, round to the nearest step, and round to specified number of digits\n let clampedValue: number;\n if (isNaN(step)) {\n clampedValue = clamp(parsed.current, minValue, maxValue);\n } else {\n clampedValue = snapValueToStep(parsed.current, minValue, maxValue, step);\n }\n\n clampedValue = numberParser.parse(format(clampedValue));\n setNumberValue(clampedValue);\n\n // in a controlled state, the numberValue won't change, so we won't go back to our old input without help\n setInputValue(format(value === undefined ? clampedValue : numberValue));\n };\n\n let safeNextStep = (operation: '+' | '-', minMax: number) => {\n let prev = parsed.current;\n\n if (isNaN(prev)) {\n // if the input is empty, start from the min/max value when incrementing/decrementing,\n // or zero if there is no min/max value defined.\n let newValue = isNaN(minMax) ? 0 : minMax;\n return snapValueToStep(newValue, minValue, maxValue, clampStep);\n } else {\n // otherwise, first snap the current value to the nearest step. if it moves in the direction\n // we're going, use that value, otherwise add the step and snap that value.\n let newValue = snapValueToStep(prev, minValue, maxValue, clampStep);\n if ((operation === '+' && newValue > prev) || (operation === '-' && newValue < prev)) {\n return newValue;\n }\n\n return snapValueToStep(\n handleDecimalOperation(operation, prev, clampStep),\n minValue,\n maxValue,\n clampStep\n );\n }\n };\n\n let increment = () => {\n let newValue = safeNextStep('+', minValue);\n\n // if we've arrived at the same value that was previously in the state, the\n // input value should be updated to match\n // ex type 4, press increment, highlight the number in the input, type 4 again, press increment\n // you'd be at 5, then incrementing to 5 again, so no re-render would happen and 4 would be left in the input\n if (newValue === numberValue) {\n setInputValue(format(newValue));\n }\n\n setNumberValue(newValue);\n };\n\n let decrement = () => {\n let newValue = safeNextStep('-', maxValue);\n\n if (newValue === numberValue) {\n setInputValue(format(newValue));\n }\n\n setNumberValue(newValue);\n };\n\n let incrementToMax = () => {\n if (maxValue != null) {\n setNumberValue(snapValueToStep(maxValue, minValue, maxValue, clampStep));\n }\n };\n\n let decrementToMin = () => {\n if (minValue != null) {\n setNumberValue(minValue);\n }\n };\n\n let canIncrement = useMemo(() => (\n !isDisabled &&\n !isReadOnly &&\n (\n isNaN(parsedValue) ||\n isNaN(maxValue) ||\n snapValueToStep(parsedValue, minValue, maxValue, clampStep) > parsedValue ||\n handleDecimalOperation('+', parsedValue, clampStep) <= maxValue\n )\n ), [isDisabled, isReadOnly, minValue, maxValue, clampStep, parsedValue]);\n\n let canDecrement = useMemo(() => (\n !isDisabled &&\n !isReadOnly &&\n (\n isNaN(parsedValue) ||\n isNaN(minValue) ||\n snapValueToStep(parsedValue, minValue, maxValue, clampStep) < parsedValue ||\n handleDecimalOperation('-', parsedValue, clampStep) >= minValue\n )\n ), [isDisabled, isReadOnly, minValue, maxValue, clampStep, parsedValue]);\n\n let validate = (value: string) => numberParser.isValidPartialNumber(value, minValue, maxValue);\n\n return {\n validate,\n increment,\n incrementToMax,\n decrement,\n decrementToMin,\n canIncrement,\n canDecrement,\n minValue,\n maxValue,\n numberValue: parsedValue,\n setInputValue,\n inputValue,\n commit\n };\n}\n\nfunction handleDecimalOperation(operator: '-' | '+', value1: number, value2: number): number {\n let result = operator === '+' ? value1 + value2 : value1 - value2;\n\n // Check if we have decimals\n if (value1 % 1 !== 0 || value2 % 1 !== 0) {\n const value1Decimal = value1.toString().split('.');\n const value2Decimal = value2.toString().split('.');\n const value1DecimalLength = (value1Decimal[1] && value1Decimal[1].length) || 0;\n const value2DecimalLength = (value2Decimal[1] && value2Decimal[1].length) || 0;\n const multiplier = Math.pow(10, Math.max(value1DecimalLength, value2DecimalLength));\n\n // Transform the decimals to integers based on the precision\n value1 = Math.round(value1 * multiplier);\n value2 = Math.round(value2 * multiplier);\n\n // Perform the operation on integers values to make sure we don't get a fancy decimal value\n result = operator === '+' ? value1 + value2 : value1 - value2;\n\n // Transform the integer result back to decimal\n result /= multiplier;\n }\n\n return result;\n}\n"],"names":[],"version":3,"file":"module.js.map"}
1
+ {"mappings":";;;;AAAA;;;;;;;;;;ACAA;;;;;;;;;;CAUC,GAED;;;AA6DO,SAAS,0CACd,KAA8B,EACZ;IAClB,IAAI,YACF,SAAQ,YACR,SAAQ,QACR,KAAI,iBACJ,cAAa,SACb,MAAK,gBACL,aAAY,YACZ,SAAQ,UACR,OAAM,cACN,WAAU,cACV,WAAU,EACX,GAAG;IAEJ,IAAI,CAAC,aAAa,eAAe,GAAG,CAAA,GAAA,yBAAkB,AAAD,EAAU,OAAO,MAAM,gBAAgB,MAAM,YAAY,EAAE;IAChH,IAAI,CAAC,YAAY,cAAc,GAAG,CAAA,GAAA,eAAQ,AAAD,EAAE,IAAM,MAAM,eAAe,KAAK,IAAI,CAAA,GAAA,sBAAc,EAAE,QAAQ,eAAe,MAAM,CAAC,YAAY;IAEzI,IAAI,eAAe,CAAA,GAAA,cAAM,EAAE,IAAM,IAAI,CAAA,GAAA,mBAAW,EAAE,QAAQ,gBAAgB;QAAC;QAAQ;KAAc;IACjG,IAAI,kBAAkB,CAAA,GAAA,cAAM,EAAE,IAAM,aAAa,kBAAkB,CAAC,aAAa;QAAC;QAAc;KAAW;IAC3G,IAAI,YAAY,CAAA,GAAA,cAAM,EAAE,IAAM,IAAI,CAAA,GAAA,sBAAe,AAAD,EAAE,QAAQ;YAAC,GAAG,aAAa;6BAAE;QAAe,IAAI;QAAC;QAAQ;QAAe;KAAgB;IACxI,IAAI,cAAc,CAAA,GAAA,cAAM,EAAE,IAAM,UAAU,eAAe,IAAI;QAAC;KAAU;IACxE,IAAI,SAAS,CAAA,GAAA,kBAAW,AAAD,EAAE,CAAC,QAAkB,AAAC,MAAM,UAAU,UAAU,IAAI,GAAI,KAAK,UAAU,MAAM,CAAC,MAAM,EAAE;QAAC;KAAU;IAExH,IAAI,YAAY,CAAC,MAAM,QAAQ,OAAO,CAAC;IACvC,IAAI,YAAY,KAAK,KAAK,aAAa,MAAM,OAC3C,YAAY;IAGd,sFAAsF;IACtF,mFAAmF;IACnF,gCAAgC;IAChC,IAAI,YAAY,CAAA,GAAA,aAAK,EAAE;IACvB,IAAI,aAAa,CAAA,GAAA,aAAK,EAAE;IACxB,IAAI,oBAAoB,CAAA,GAAA,aAAK,EAAE;IAC/B,IAAI,CAAC,OAAO,EAAE,CAAC,aAAa,UAAU,OAAO,KAAK,WAAW,WAAW,OAAO,IAAI,kBAAkB,kBAAkB,OAAO,EAAE;QAC9H,cAAc,OAAO;QACrB,UAAU,OAAO,GAAG;QACpB,WAAW,OAAO,GAAG;QACrB,kBAAkB,OAAO,GAAG;IAC9B,CAAC;IAED,kFAAkF;IAClF,IAAI,cAAc,CAAA,GAAA,cAAM,EAAE,IAAM,aAAa,KAAK,CAAC,aAAa;QAAC;QAAc;KAAW;IAC1F,IAAI,SAAS,CAAA,GAAA,aAAK,EAAE;IACpB,OAAO,OAAO,GAAG;IAEjB,IAAI,SAAS,IAAM;QACjB,6CAA6C;QAC7C,IAAI,CAAC,WAAW,MAAM,EAAE;YACtB,eAAe;YACf,cAAc,UAAU,YAAY,KAAK,OAAO,YAAY;YAC5D;QACF,CAAC;QAED,iFAAiF;QACjF,IAAI,MAAM,OAAO,OAAO,GAAG;YACzB,cAAc,OAAO;YACrB;QACF,CAAC;QAED,2FAA2F;QAC3F,IAAI;QACJ,IAAI,MAAM,OACR,eAAe,CAAA,GAAA,YAAK,AAAD,EAAE,OAAO,OAAO,EAAE,UAAU;aAE/C,eAAe,CAAA,GAAA,sBAAc,EAAE,OAAO,OAAO,EAAE,UAAU,UAAU;QAGrE,eAAe,aAAa,KAAK,CAAC,OAAO;QACzC,eAAe;QAEf,yGAAyG;QACzG,cAAc,OAAO,UAAU,YAAY,eAAe,WAAW;IACvE;IAEA,IAAI,eAAe,CAAC,WAAsB,SAAmB;QAC3D,IAAI,OAAO,OAAO,OAAO;QAEzB,IAAI,MAAM,OAAO;YACf,sFAAsF;YACtF,gDAAgD;YAChD,IAAI,WAAW,MAAM,UAAU,IAAI,MAAM;YACzC,OAAO,CAAA,GAAA,sBAAc,EAAE,UAAU,UAAU,UAAU;QACvD,OAAO;YACL,4FAA4F;YAC5F,2EAA2E;YAC3E,IAAI,YAAW,CAAA,GAAA,sBAAe,AAAD,EAAE,MAAM,UAAU,UAAU;YACzD,IAAI,AAAC,cAAc,OAAO,YAAW,QAAU,cAAc,OAAO,YAAW,MAC7E,OAAO;YAGT,OAAO,CAAA,GAAA,sBAAc,EACnB,6CAAuB,WAAW,MAAM,YACxC,UACA,UACA;QAEJ,CAAC;IACH;IAEA,IAAI,YAAY,IAAM;QACpB,IAAI,WAAW,aAAa,KAAK;QAEjC,2EAA2E;QAC3E,yCAAyC;QACzC,+FAA+F;QAC/F,6GAA6G;QAC7G,IAAI,aAAa,aACf,cAAc,OAAO;QAGvB,eAAe;IACjB;IAEA,IAAI,YAAY,IAAM;QACpB,IAAI,WAAW,aAAa,KAAK;QAEjC,IAAI,aAAa,aACf,cAAc,OAAO;QAGvB,eAAe;IACjB;IAEA,IAAI,iBAAiB,IAAM;QACzB,IAAI,YAAY,IAAI,EAClB,eAAe,CAAA,GAAA,sBAAc,EAAE,UAAU,UAAU,UAAU;IAEjE;IAEA,IAAI,iBAAiB,IAAM;QACzB,IAAI,YAAY,IAAI,EAClB,eAAe;IAEnB;IAEA,IAAI,eAAe,CAAA,GAAA,cAAM,EAAE,IACzB,CAAC,cACD,CAAC,cAEC,CAAA,MAAM,gBACN,MAAM,aACN,CAAA,GAAA,sBAAe,AAAD,EAAE,aAAa,UAAU,UAAU,aAAa,eAC9D,6CAAuB,KAAK,aAAa,cAAc,QAAO,GAE/D;QAAC;QAAY;QAAY;QAAU;QAAU;QAAW;KAAY;IAEvE,IAAI,eAAe,CAAA,GAAA,cAAM,EAAE,IACzB,CAAC,cACD,CAAC,cAEC,CAAA,MAAM,gBACN,MAAM,aACN,CAAA,GAAA,sBAAe,AAAD,EAAE,aAAa,UAAU,UAAU,aAAa,eAC9D,6CAAuB,KAAK,aAAa,cAAc,QAAO,GAE/D;QAAC;QAAY;QAAY;QAAU;QAAU;QAAW;KAAY;IAEvE,IAAI,WAAW,CAAC,QAAkB,aAAa,oBAAoB,CAAC,OAAO,UAAU;IAErF,OAAO;kBACL;mBACA;wBACA;mBACA;wBACA;sBACA;sBACA;kBACA;kBACA;QACA,aAAa;uBACb;oBACA;gBACA;IACF;AACF;AAEA,SAAS,6CAAuB,QAAmB,EAAE,MAAc,EAAE,MAAc,EAAU;IAC3F,IAAI,SAAS,aAAa,MAAM,SAAS,SAAS,SAAS,MAAM;IAEjE,4BAA4B;IAC5B,IAAI,SAAS,MAAM,KAAK,SAAS,MAAM,GAAG;QACxC,MAAM,gBAAgB,OAAO,QAAQ,GAAG,KAAK,CAAC;QAC9C,MAAM,gBAAgB,OAAO,QAAQ,GAAG,KAAK,CAAC;QAC9C,MAAM,sBAAsB,AAAC,aAAa,CAAC,EAAE,IAAI,aAAa,CAAC,EAAE,CAAC,MAAM,IAAK;QAC7E,MAAM,sBAAsB,AAAC,aAAa,CAAC,EAAE,IAAI,aAAa,CAAC,EAAE,CAAC,MAAM,IAAK;QAC7E,MAAM,aAAa,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,qBAAqB;QAE9D,4DAA4D;QAC5D,SAAS,KAAK,KAAK,CAAC,SAAS;QAC7B,SAAS,KAAK,KAAK,CAAC,SAAS;QAE7B,2FAA2F;QAC3F,SAAS,aAAa,MAAM,SAAS,SAAS,SAAS,MAAM;QAE7D,+CAA+C;QAC/C,UAAU;IACZ,CAAC;IAED,OAAO;AACT;;CDzQC,GAED","sources":["packages/@react-stately/numberfield/src/index.ts","packages/@react-stately/numberfield/src/useNumberFieldState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useNumberFieldState} from './useNumberFieldState';\n\nexport type {NumberFieldStateOptions} from './useNumberFieldState';\nexport type {NumberFieldState} from './useNumberFieldState';\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {clamp, snapValueToStep, useControlledState} from '@react-stately/utils';\nimport {NumberFieldProps} from '@react-types/numberfield';\nimport {NumberFormatter, NumberParser} from '@internationalized/number';\nimport {useCallback, useMemo, useRef, useState} from 'react';\n\nexport interface NumberFieldState {\n /**\n * The current text value of the input. Updated as the user types,\n * and formatted according to `formatOptions` on blur.\n */\n inputValue: string,\n /**\n * The currently parsed number value, or NaN if a valid number could not be parsed.\n * Updated based on the `inputValue` as the user types.\n */\n numberValue: number,\n /** The minimum value of the number field. */\n minValue: number,\n /** The maximum value of the number field. */\n maxValue: number,\n /** Whether the current value can be incremented according to the maximum value and step. */\n canIncrement: boolean,\n /** Whether the current value can be decremented according to the minimum value and step. */\n canDecrement: boolean,\n /**\n * Validates a user input string according to the current locale and format options.\n * Values can be partially entered, and may be valid even if they cannot currently be parsed to a number.\n * Can be used to implement validation as a user types.\n */\n validate(value: string): boolean,\n /** Sets the current text value of the input. */\n setInputValue(val: string): void,\n /**\n * Commits the current input value. The value is parsed to a number, clamped according\n * to the minimum and maximum values of the field, and snapped to the nearest step value.\n * This will fire the `onChange` prop with the new value, and if uncontrolled, update the `numberValue`.\n * Typically this is called when the field is blurred.\n */\n commit(): void,\n /** Increments the current input value to the next step boundary, and fires `onChange`. */\n increment(): void,\n /** Decrements the current input value to the next step boundary, and fires `onChange`. */\n decrement(): void,\n /** Sets the current value to the `maxValue` if any, and fires `onChange`. */\n incrementToMax(): void,\n /** Sets the current value to the `minValue` if any, and fires `onChange`. */\n decrementToMin(): void\n}\n\nexport interface NumberFieldStateOptions extends NumberFieldProps {\n /**\n * The locale that should be used for parsing.\n * @default 'en-US'\n */\n locale: string\n}\n\n/**\n * Provides state management for a number field component. Number fields allow users to enter a number,\n * and increment or decrement the value using stepper buttons.\n */\nexport function useNumberFieldState(\n props: NumberFieldStateOptions\n): NumberFieldState {\n let {\n minValue,\n maxValue,\n step,\n formatOptions,\n value,\n defaultValue,\n onChange,\n locale,\n isDisabled,\n isReadOnly\n } = props;\n\n let [numberValue, setNumberValue] = useControlledState<number>(value, isNaN(defaultValue) ? NaN : defaultValue, onChange);\n let [inputValue, setInputValue] = useState(() => isNaN(numberValue) ? '' : new NumberFormatter(locale, formatOptions).format(numberValue));\n\n let numberParser = useMemo(() => new NumberParser(locale, formatOptions), [locale, formatOptions]);\n let numberingSystem = useMemo(() => numberParser.getNumberingSystem(inputValue), [numberParser, inputValue]);\n let formatter = useMemo(() => new NumberFormatter(locale, {...formatOptions, numberingSystem}), [locale, formatOptions, numberingSystem]);\n let intlOptions = useMemo(() => formatter.resolvedOptions(), [formatter]);\n let format = useCallback((value: number) => (isNaN(value) || value === null) ? '' : formatter.format(value), [formatter]);\n\n let clampStep = !isNaN(step) ? step : 1;\n if (intlOptions.style === 'percent' && isNaN(step)) {\n clampStep = 0.01;\n }\n\n // Update the input value when the number value or format options change. This is done\n // in a useEffect so that the controlled behavior is correct and we only update the\n // textfield after prop changes.\n let prevValue = useRef(numberValue);\n let prevLocale = useRef(locale);\n let prevFormatOptions = useRef(formatOptions);\n if (!Object.is(numberValue, prevValue.current) || locale !== prevLocale.current || formatOptions !== prevFormatOptions.current) {\n setInputValue(format(numberValue));\n prevValue.current = numberValue;\n prevLocale.current = locale;\n prevFormatOptions.current = formatOptions;\n }\n\n // Store last parsed value in a ref so it can be used by increment/decrement below\n let parsedValue = useMemo(() => numberParser.parse(inputValue), [numberParser, inputValue]);\n let parsed = useRef(0);\n parsed.current = parsedValue;\n\n let commit = () => {\n // Set to empty state if input value is empty\n if (!inputValue.length) {\n setNumberValue(NaN);\n setInputValue(value === undefined ? '' : format(numberValue));\n return;\n }\n\n // if it failed to parse, then reset input to formatted version of current number\n if (isNaN(parsed.current)) {\n setInputValue(format(numberValue));\n return;\n }\n\n // Clamp to min and max, round to the nearest step, and round to specified number of digits\n let clampedValue: number;\n if (isNaN(step)) {\n clampedValue = clamp(parsed.current, minValue, maxValue);\n } else {\n clampedValue = snapValueToStep(parsed.current, minValue, maxValue, step);\n }\n\n clampedValue = numberParser.parse(format(clampedValue));\n setNumberValue(clampedValue);\n\n // in a controlled state, the numberValue won't change, so we won't go back to our old input without help\n setInputValue(format(value === undefined ? clampedValue : numberValue));\n };\n\n let safeNextStep = (operation: '+' | '-', minMax: number) => {\n let prev = parsed.current;\n\n if (isNaN(prev)) {\n // if the input is empty, start from the min/max value when incrementing/decrementing,\n // or zero if there is no min/max value defined.\n let newValue = isNaN(minMax) ? 0 : minMax;\n return snapValueToStep(newValue, minValue, maxValue, clampStep);\n } else {\n // otherwise, first snap the current value to the nearest step. if it moves in the direction\n // we're going, use that value, otherwise add the step and snap that value.\n let newValue = snapValueToStep(prev, minValue, maxValue, clampStep);\n if ((operation === '+' && newValue > prev) || (operation === '-' && newValue < prev)) {\n return newValue;\n }\n\n return snapValueToStep(\n handleDecimalOperation(operation, prev, clampStep),\n minValue,\n maxValue,\n clampStep\n );\n }\n };\n\n let increment = () => {\n let newValue = safeNextStep('+', minValue);\n\n // if we've arrived at the same value that was previously in the state, the\n // input value should be updated to match\n // ex type 4, press increment, highlight the number in the input, type 4 again, press increment\n // you'd be at 5, then incrementing to 5 again, so no re-render would happen and 4 would be left in the input\n if (newValue === numberValue) {\n setInputValue(format(newValue));\n }\n\n setNumberValue(newValue);\n };\n\n let decrement = () => {\n let newValue = safeNextStep('-', maxValue);\n\n if (newValue === numberValue) {\n setInputValue(format(newValue));\n }\n\n setNumberValue(newValue);\n };\n\n let incrementToMax = () => {\n if (maxValue != null) {\n setNumberValue(snapValueToStep(maxValue, minValue, maxValue, clampStep));\n }\n };\n\n let decrementToMin = () => {\n if (minValue != null) {\n setNumberValue(minValue);\n }\n };\n\n let canIncrement = useMemo(() => (\n !isDisabled &&\n !isReadOnly &&\n (\n isNaN(parsedValue) ||\n isNaN(maxValue) ||\n snapValueToStep(parsedValue, minValue, maxValue, clampStep) > parsedValue ||\n handleDecimalOperation('+', parsedValue, clampStep) <= maxValue\n )\n ), [isDisabled, isReadOnly, minValue, maxValue, clampStep, parsedValue]);\n\n let canDecrement = useMemo(() => (\n !isDisabled &&\n !isReadOnly &&\n (\n isNaN(parsedValue) ||\n isNaN(minValue) ||\n snapValueToStep(parsedValue, minValue, maxValue, clampStep) < parsedValue ||\n handleDecimalOperation('-', parsedValue, clampStep) >= minValue\n )\n ), [isDisabled, isReadOnly, minValue, maxValue, clampStep, parsedValue]);\n\n let validate = (value: string) => numberParser.isValidPartialNumber(value, minValue, maxValue);\n\n return {\n validate,\n increment,\n incrementToMax,\n decrement,\n decrementToMin,\n canIncrement,\n canDecrement,\n minValue,\n maxValue,\n numberValue: parsedValue,\n setInputValue,\n inputValue,\n commit\n };\n}\n\nfunction handleDecimalOperation(operator: '-' | '+', value1: number, value2: number): number {\n let result = operator === '+' ? value1 + value2 : value1 - value2;\n\n // Check if we have decimals\n if (value1 % 1 !== 0 || value2 % 1 !== 0) {\n const value1Decimal = value1.toString().split('.');\n const value2Decimal = value2.toString().split('.');\n const value1DecimalLength = (value1Decimal[1] && value1Decimal[1].length) || 0;\n const value2DecimalLength = (value2Decimal[1] && value2Decimal[1].length) || 0;\n const multiplier = Math.pow(10, Math.max(value1DecimalLength, value2DecimalLength));\n\n // Transform the decimals to integers based on the precision\n value1 = Math.round(value1 * multiplier);\n value2 = Math.round(value2 * multiplier);\n\n // Perform the operation on integers values to make sure we don't get a fancy decimal value\n result = operator === '+' ? value1 + value2 : value1 - value2;\n\n // Transform the integer result back to decimal\n result /= multiplier;\n }\n\n return result;\n}\n"],"names":[],"version":3,"file":"module.js.map"}
package/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "@react-stately/numberfield",
3
- "version": "3.3.0",
3
+ "version": "3.4.0",
4
4
  "description": "Spectrum UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/main.js",
7
7
  "module": "dist/module.js",
8
+ "exports": {
9
+ "types": "./dist/types.d.ts",
10
+ "import": "./dist/import.mjs",
11
+ "require": "./dist/main.js"
12
+ },
8
13
  "types": "dist/types.d.ts",
9
14
  "source": "src/index.ts",
10
15
  "files": [
@@ -17,11 +22,11 @@
17
22
  "url": "https://github.com/adobe/react-spectrum"
18
23
  },
19
24
  "dependencies": {
20
- "@babel/runtime": "^7.6.2",
21
- "@internationalized/number": "^3.1.1",
22
- "@react-stately/utils": "^3.5.1",
23
- "@react-types/numberfield": "^3.3.5",
24
- "@react-types/shared": "^3.16.0"
25
+ "@internationalized/number": "^3.2.0",
26
+ "@react-stately/utils": "^3.6.0",
27
+ "@react-types/numberfield": "^3.4.0",
28
+ "@react-types/shared": "^3.17.0",
29
+ "@swc/helpers": "^0.4.14"
25
30
  },
26
31
  "peerDependencies": {
27
32
  "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
@@ -29,5 +34,5 @@
29
34
  "publishConfig": {
30
35
  "access": "public"
31
36
  },
32
- "gitHead": "2954307ddbefe149241685440c81f80ece6b2c83"
37
+ "gitHead": "a0efee84aa178cb1a202951dfd6d8de02b292307"
33
38
  }