@react-stately/numberfield 3.3.1 → 3.4.1

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.
Files changed (2) hide show
  1. package/dist/import.mjs +188 -0
  2. package/package.json +11 -6
@@ -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/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "@react-stately/numberfield",
3
- "version": "3.3.1",
3
+ "version": "3.4.1",
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,10 +22,10 @@
17
22
  "url": "https://github.com/adobe/react-spectrum"
18
23
  },
19
24
  "dependencies": {
20
- "@internationalized/number": "^3.1.2",
21
- "@react-stately/utils": "^3.5.2",
22
- "@react-types/numberfield": "^3.3.5",
23
- "@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.1",
28
+ "@react-types/shared": "^3.18.0",
24
29
  "@swc/helpers": "^0.4.14"
25
30
  },
26
31
  "peerDependencies": {
@@ -29,5 +34,5 @@
29
34
  "publishConfig": {
30
35
  "access": "public"
31
36
  },
32
- "gitHead": "5480d76bd815e239366f92852c76b6831ad2a4fd"
37
+ "gitHead": "9d1ba9bd8ebcd63bf3495ade16d349bcb71795ce"
33
38
  }