UNPKG

9.36 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
5exports.__esModule = true;
6exports["default"] = void 0;
7
8var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
10var _exenv = require("exenv");
11
12var _react = require("react");
13
14var _utils = require("./utils");
15
16function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
17
18function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
19
20function useLongPress(callback, speed) {
21 var _ref;
22
23 if (callback === void 0) {
24 callback = function callback() {};
25 }
26
27 if (speed === void 0) {
28 speed = 200;
29 }
30
31 var _useState = (0, _react.useState)(false),
32 isPressed = _useState[0],
33 setIsPressed = _useState[1];
34
35 (0, _react.useEffect)(function () {
36 var timerId;
37
38 if (isPressed) {
39 timerId = setTimeout(callback, speed);
40 } else {
41 clearTimeout(timerId);
42 }
43
44 return function () {
45 clearTimeout(timerId);
46 };
47 }, [isPressed, callback, speed]);
48 var start = (0, _react.useCallback)(function () {
49 callback();
50 setIsPressed(true);
51 }, [callback]);
52 var stop = (0, _react.useCallback)(function () {
53 setIsPressed(false);
54 }, []);
55 var clickEvent = _exenv.canUseDOM && !!document.documentElement.ontouchstart ? "onTouchStart" : "onMouseDown";
56 return _ref = {}, _ref[clickEvent] = start, _ref.onMouseUp = stop, _ref.onMouseLeave = stop, _ref.onTouchEnd = stop, _ref;
57}
58
59function useNumberInput(_ref2) {
60 var valueProp = _ref2.value,
61 onChange = _ref2.onChange,
62 defaultValue = _ref2.defaultValue,
63 _ref2$focusInputOnCha = _ref2.focusInputOnChange,
64 focusInputOnChange = _ref2$focusInputOnCha === void 0 ? true : _ref2$focusInputOnCha,
65 _ref2$clampValueOnBlu = _ref2.clampValueOnBlur,
66 clampValueOnBlur = _ref2$clampValueOnBlu === void 0 ? true : _ref2$clampValueOnBlu,
67 _ref2$keepWithinRange = _ref2.keepWithinRange,
68 keepWithinRange = _ref2$keepWithinRange === void 0 ? true : _ref2$keepWithinRange,
69 _ref2$min = _ref2.min,
70 min = _ref2$min === void 0 ? -Infinity : _ref2$min,
71 _ref2$max = _ref2.max,
72 max = _ref2$max === void 0 ? Infinity : _ref2$max,
73 _ref2$step = _ref2.step,
74 stepProp = _ref2$step === void 0 ? 1 : _ref2$step,
75 precisionProp = _ref2.precision,
76 getAriaValueText = _ref2.getAriaValueText,
77 isReadOnly = _ref2.isReadOnly,
78 isInvalid = _ref2.isInvalid,
79 isDisabled = _ref2.isDisabled;
80
81 var _useRef = (0, _react.useRef)(valueProp != null),
82 isControlled = _useRef.current;
83
84 var defaultPrecision = Math.max((0, _utils.calculatePrecision)(stepProp), 0);
85 var precision = precisionProp || defaultPrecision;
86
87 var _useState2 = (0, _react.useState)(function () {
88 if (defaultValue != null) {
89 var nextValue = defaultValue;
90
91 if (keepWithinRange) {
92 nextValue = Math.max(Math.min(nextValue, max), min);
93 }
94
95 nextValue = (0, _utils.roundToPrecision)(nextValue, precision);
96 return nextValue;
97 }
98
99 return "";
100 }),
101 valueState = _useState2[0],
102 setValue = _useState2[1];
103
104 var _useState3 = (0, _react.useState)(false),
105 isFocused = _useState3[0],
106 setIsFocused = _useState3[1];
107
108 var value = isControlled ? valueProp : valueState;
109 var isInteractive = !(isReadOnly || isDisabled);
110 var inputRef = (0, _react.useRef)();
111 var prevNextValue = (0, _react.useRef)(null);
112
113 var shouldConvertToNumber = function shouldConvertToNumber(value) {
114 var hasDot = value.indexOf(".") > -1;
115 var hasTrailingZero = value.substr(value.length - 1) === "0";
116 var hasTrailingDot = value.substr(value.length - 1) === ".";
117 if (hasDot && hasTrailingZero) return false;
118 if (hasDot && hasTrailingDot) return false;
119 return true;
120 };
121
122 var updateValue = function updateValue(nextValue) {
123 //eslint-disable-next-line
124 if (prevNextValue.current == nextValue) return;
125 var shouldConvert = shouldConvertToNumber(nextValue);
126 var converted = shouldConvert ? +nextValue : nextValue;
127 if (!isControlled) setValue(converted);
128 if (onChange) onChange(converted);
129 prevNextValue.current = nextValue;
130 };
131
132 var handleIncrement = function handleIncrement(step) {
133 if (step === void 0) {
134 step = stepProp;
135 }
136
137 if (!isInteractive) return;
138 var nextValue = Number(value) + Number(step);
139
140 if (keepWithinRange) {
141 nextValue = Math.min(nextValue, max);
142 }
143
144 nextValue = (0, _utils.roundToPrecision)(nextValue, precision);
145 updateValue(nextValue);
146 focusInput();
147 };
148
149 var handleDecrement = function handleDecrement(step) {
150 if (step === void 0) {
151 step = stepProp;
152 }
153
154 if (!isInteractive) return;
155 var nextValue = Number(value) - Number(step);
156
157 if (keepWithinRange) {
158 nextValue = Math.max(nextValue, min);
159 }
160
161 nextValue = (0, _utils.roundToPrecision)(nextValue, precision);
162 updateValue(nextValue);
163 focusInput();
164 };
165
166 var focusInput = function focusInput() {
167 if (focusInputOnChange && inputRef.current && _exenv.canUseDOM) {
168 requestAnimationFrame(function () {
169 inputRef.current.focus();
170 });
171 }
172 };
173
174 var incrementStepperProps = useLongPress(handleIncrement);
175 var decrementStepperProps = useLongPress(handleDecrement);
176
177 var handleChange = function handleChange(event) {
178 updateValue(event.target.value);
179 };
180
181 var handleKeyDown = function handleKeyDown(event) {
182 (0, _utils.preventNonNumberKey)(event);
183 if (!isInteractive) return;
184
185 if (event.key === "ArrowUp") {
186 event.preventDefault();
187 var ratio = getIncrementFactor(event);
188 handleIncrement(ratio * stepProp);
189 }
190
191 if (event.key === "ArrowDown") {
192 event.preventDefault();
193
194 var _ratio = getIncrementFactor(event);
195
196 handleDecrement(_ratio * stepProp);
197 }
198
199 if (event.key === "Home") {
200 event.preventDefault();
201
202 if (min != null) {
203 updateValue(max);
204 }
205 }
206
207 if (event.key === "End") {
208 event.preventDefault();
209
210 if (max != null) {
211 updateValue(min);
212 }
213 }
214 };
215
216 var getIncrementFactor = function getIncrementFactor(event) {
217 var ratio = 1;
218
219 if (event.metaKey || event.ctrlKey) {
220 ratio = 0.1;
221 }
222
223 if (event.shiftKey) {
224 ratio = 10;
225 }
226
227 return ratio;
228 };
229
230 var validateAndClamp = function validateAndClamp() {
231 var maxExists = max != null;
232 var minExists = min != null;
233
234 if (maxExists && value > max) {
235 updateValue(max);
236 }
237
238 if (minExists && value < min) {
239 updateValue(min);
240 }
241 };
242
243 var isOutOfRange = value > max || value < min;
244 var ariaValueText = getAriaValueText ? getAriaValueText(value) : null;
245 return {
246 value: value,
247 isFocused: isFocused,
248 isDisabled: isDisabled,
249 isReadOnly: isReadOnly,
250 incrementStepper: incrementStepperProps,
251 decrementStepper: decrementStepperProps,
252 incrementButton: _objectSpread({
253 onClick: function onClick() {
254 return handleIncrement();
255 },
256 "aria-label": "add"
257 }, keepWithinRange && {
258 disabled: value === max,
259 "aria-disabled": value === max
260 }),
261 decrementButton: _objectSpread({
262 onClick: function onClick() {
263 return handleDecrement();
264 },
265 "aria-label": "subtract"
266 }, keepWithinRange && {
267 disabled: value === min,
268 "aria-disabled": value === min
269 }),
270 input: _objectSpread({
271 onChange: handleChange,
272 onKeyDown: handleKeyDown,
273 ref: inputRef,
274 value: value,
275 role: "spinbutton",
276 type: "text",
277 "aria-valuemin": min,
278 "aria-valuemax": max,
279 "aria-disabled": isDisabled,
280 "aria-valuenow": value,
281 "aria-invalid": isInvalid || isOutOfRange
282 }, getAriaValueText && {
283 "aria-valuetext": ariaValueText
284 }, {
285 readOnly: isReadOnly,
286 disabled: isDisabled,
287 autoComplete: "off",
288 onFocus: function onFocus() {
289 setIsFocused(true);
290 },
291 onBlur: function onBlur() {
292 setIsFocused(false);
293
294 if (clampValueOnBlur) {
295 validateAndClamp();
296 }
297 }
298 }),
299 hiddenLabel: {
300 "aria-live": "polite",
301 children: getAriaValueText ? ariaValueText : value,
302 style: {
303 position: "absolute",
304 clip: "rect(0px, 0px, 0px, 0px)",
305 height: 1,
306 width: 1,
307 margin: -1,
308 whiteSpace: "nowrap",
309 border: 0,
310 overflow: "hidden",
311 padding: 0
312 }
313 }
314 };
315}
316
317var _default = useNumberInput;
318exports["default"] = _default;
\No newline at end of file