InputNumber.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  3. import _typeof from "@babel/runtime/helpers/esm/typeof";
  4. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  5. import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
  6. var _excluded = ["prefixCls", "className", "style", "min", "max", "step", "defaultValue", "value", "disabled", "readOnly", "upHandler", "downHandler", "keyboard", "changeOnWheel", "controls", "classNames", "stringMode", "parser", "formatter", "precision", "decimalSeparator", "onChange", "onInput", "onPressEnter", "onStep", "changeOnBlur", "domRef"],
  7. _excluded2 = ["disabled", "style", "prefixCls", "value", "prefix", "suffix", "addonBefore", "addonAfter", "className", "classNames"];
  8. import getMiniDecimal, { getNumberPrecision, num2str, toFixed, validateNumber } from '@rc-component/mini-decimal';
  9. import clsx from 'classnames';
  10. import { BaseInput } from 'rc-input';
  11. import { useLayoutUpdateEffect } from "rc-util/es/hooks/useLayoutEffect";
  12. import proxyObject from "rc-util/es/proxyObject";
  13. import { composeRef } from "rc-util/es/ref";
  14. import * as React from 'react';
  15. import useCursor from "./hooks/useCursor";
  16. import StepHandler from "./StepHandler";
  17. import { getDecupleSteps } from "./utils/numberUtil";
  18. import { triggerFocus } from "rc-input/es/utils/commonUtils";
  19. import useFrame from "./hooks/useFrame";
  20. /**
  21. * We support `stringMode` which need handle correct type when user call in onChange
  22. * format max or min value
  23. * 1. if isInvalid return null
  24. * 2. if precision is undefined, return decimal
  25. * 3. format with precision
  26. * I. if max > 0, round down with precision. Example: max= 3.5, precision=0 afterFormat: 3
  27. * II. if max < 0, round up with precision. Example: max= -3.5, precision=0 afterFormat: -4
  28. * III. if min > 0, round up with precision. Example: min= 3.5, precision=0 afterFormat: 4
  29. * IV. if min < 0, round down with precision. Example: max= -3.5, precision=0 afterFormat: -3
  30. */
  31. var getDecimalValue = function getDecimalValue(stringMode, decimalValue) {
  32. if (stringMode || decimalValue.isEmpty()) {
  33. return decimalValue.toString();
  34. }
  35. return decimalValue.toNumber();
  36. };
  37. var getDecimalIfValidate = function getDecimalIfValidate(value) {
  38. var decimal = getMiniDecimal(value);
  39. return decimal.isInvalidate() ? null : decimal;
  40. };
  41. var InternalInputNumber = /*#__PURE__*/React.forwardRef(function (props, ref) {
  42. var prefixCls = props.prefixCls,
  43. className = props.className,
  44. style = props.style,
  45. min = props.min,
  46. max = props.max,
  47. _props$step = props.step,
  48. step = _props$step === void 0 ? 1 : _props$step,
  49. defaultValue = props.defaultValue,
  50. value = props.value,
  51. disabled = props.disabled,
  52. readOnly = props.readOnly,
  53. upHandler = props.upHandler,
  54. downHandler = props.downHandler,
  55. keyboard = props.keyboard,
  56. _props$changeOnWheel = props.changeOnWheel,
  57. changeOnWheel = _props$changeOnWheel === void 0 ? false : _props$changeOnWheel,
  58. _props$controls = props.controls,
  59. controls = _props$controls === void 0 ? true : _props$controls,
  60. classNames = props.classNames,
  61. stringMode = props.stringMode,
  62. parser = props.parser,
  63. formatter = props.formatter,
  64. precision = props.precision,
  65. decimalSeparator = props.decimalSeparator,
  66. onChange = props.onChange,
  67. onInput = props.onInput,
  68. onPressEnter = props.onPressEnter,
  69. onStep = props.onStep,
  70. _props$changeOnBlur = props.changeOnBlur,
  71. changeOnBlur = _props$changeOnBlur === void 0 ? true : _props$changeOnBlur,
  72. domRef = props.domRef,
  73. inputProps = _objectWithoutProperties(props, _excluded);
  74. var inputClassName = "".concat(prefixCls, "-input");
  75. var inputRef = React.useRef(null);
  76. var _React$useState = React.useState(false),
  77. _React$useState2 = _slicedToArray(_React$useState, 2),
  78. focus = _React$useState2[0],
  79. setFocus = _React$useState2[1];
  80. var userTypingRef = React.useRef(false);
  81. var compositionRef = React.useRef(false);
  82. var shiftKeyRef = React.useRef(false);
  83. // ============================ Value =============================
  84. // Real value control
  85. var _React$useState3 = React.useState(function () {
  86. return getMiniDecimal(value !== null && value !== void 0 ? value : defaultValue);
  87. }),
  88. _React$useState4 = _slicedToArray(_React$useState3, 2),
  89. decimalValue = _React$useState4[0],
  90. setDecimalValue = _React$useState4[1];
  91. function setUncontrolledDecimalValue(newDecimal) {
  92. if (value === undefined) {
  93. setDecimalValue(newDecimal);
  94. }
  95. }
  96. // ====================== Parser & Formatter ======================
  97. /**
  98. * `precision` is used for formatter & onChange.
  99. * It will auto generate by `value` & `step`.
  100. * But it will not block user typing.
  101. *
  102. * Note: Auto generate `precision` is used for legacy logic.
  103. * We should remove this since we already support high precision with BigInt.
  104. *
  105. * @param number Provide which number should calculate precision
  106. * @param userTyping Change by user typing
  107. */
  108. var getPrecision = React.useCallback(function (numStr, userTyping) {
  109. if (userTyping) {
  110. return undefined;
  111. }
  112. if (precision >= 0) {
  113. return precision;
  114. }
  115. return Math.max(getNumberPrecision(numStr), getNumberPrecision(step));
  116. }, [precision, step]);
  117. // >>> Parser
  118. var mergedParser = React.useCallback(function (num) {
  119. var numStr = String(num);
  120. if (parser) {
  121. return parser(numStr);
  122. }
  123. var parsedStr = numStr;
  124. if (decimalSeparator) {
  125. parsedStr = parsedStr.replace(decimalSeparator, '.');
  126. }
  127. // [Legacy] We still support auto convert `$ 123,456` to `123456`
  128. return parsedStr.replace(/[^\w.-]+/g, '');
  129. }, [parser, decimalSeparator]);
  130. // >>> Formatter
  131. var inputValueRef = React.useRef('');
  132. var mergedFormatter = React.useCallback(function (number, userTyping) {
  133. if (formatter) {
  134. return formatter(number, {
  135. userTyping: userTyping,
  136. input: String(inputValueRef.current)
  137. });
  138. }
  139. var str = typeof number === 'number' ? num2str(number) : number;
  140. // User typing will not auto format with precision directly
  141. if (!userTyping) {
  142. var mergedPrecision = getPrecision(str, userTyping);
  143. if (validateNumber(str) && (decimalSeparator || mergedPrecision >= 0)) {
  144. // Separator
  145. var separatorStr = decimalSeparator || '.';
  146. str = toFixed(str, separatorStr, mergedPrecision);
  147. }
  148. }
  149. return str;
  150. }, [formatter, getPrecision, decimalSeparator]);
  151. // ========================== InputValue ==========================
  152. /**
  153. * Input text value control
  154. *
  155. * User can not update input content directly. It updates with follow rules by priority:
  156. * 1. controlled `value` changed
  157. * * [SPECIAL] Typing like `1.` should not immediately convert to `1`
  158. * 2. User typing with format (not precision)
  159. * 3. Blur or Enter trigger revalidate
  160. */
  161. var _React$useState5 = React.useState(function () {
  162. var initValue = defaultValue !== null && defaultValue !== void 0 ? defaultValue : value;
  163. if (decimalValue.isInvalidate() && ['string', 'number'].includes(_typeof(initValue))) {
  164. return Number.isNaN(initValue) ? '' : initValue;
  165. }
  166. return mergedFormatter(decimalValue.toString(), false);
  167. }),
  168. _React$useState6 = _slicedToArray(_React$useState5, 2),
  169. inputValue = _React$useState6[0],
  170. setInternalInputValue = _React$useState6[1];
  171. inputValueRef.current = inputValue;
  172. // Should always be string
  173. function setInputValue(newValue, userTyping) {
  174. setInternalInputValue(mergedFormatter(
  175. // Invalidate number is sometime passed by external control, we should let it go
  176. // Otherwise is controlled by internal interactive logic which check by userTyping
  177. // You can ref 'show limited value when input is not focused' test for more info.
  178. newValue.isInvalidate() ? newValue.toString(false) : newValue.toString(!userTyping), userTyping));
  179. }
  180. // >>> Max & Min limit
  181. var maxDecimal = React.useMemo(function () {
  182. return getDecimalIfValidate(max);
  183. }, [max, precision]);
  184. var minDecimal = React.useMemo(function () {
  185. return getDecimalIfValidate(min);
  186. }, [min, precision]);
  187. var upDisabled = React.useMemo(function () {
  188. if (!maxDecimal || !decimalValue || decimalValue.isInvalidate()) {
  189. return false;
  190. }
  191. return maxDecimal.lessEquals(decimalValue);
  192. }, [maxDecimal, decimalValue]);
  193. var downDisabled = React.useMemo(function () {
  194. if (!minDecimal || !decimalValue || decimalValue.isInvalidate()) {
  195. return false;
  196. }
  197. return decimalValue.lessEquals(minDecimal);
  198. }, [minDecimal, decimalValue]);
  199. // Cursor controller
  200. var _useCursor = useCursor(inputRef.current, focus),
  201. _useCursor2 = _slicedToArray(_useCursor, 2),
  202. recordCursor = _useCursor2[0],
  203. restoreCursor = _useCursor2[1];
  204. // ============================= Data =============================
  205. /**
  206. * Find target value closet within range.
  207. * e.g. [11, 28]:
  208. * 3 => 11
  209. * 23 => 23
  210. * 99 => 28
  211. */
  212. var getRangeValue = function getRangeValue(target) {
  213. // target > max
  214. if (maxDecimal && !target.lessEquals(maxDecimal)) {
  215. return maxDecimal;
  216. }
  217. // target < min
  218. if (minDecimal && !minDecimal.lessEquals(target)) {
  219. return minDecimal;
  220. }
  221. return null;
  222. };
  223. /**
  224. * Check value is in [min, max] range
  225. */
  226. var isInRange = function isInRange(target) {
  227. return !getRangeValue(target);
  228. };
  229. /**
  230. * Trigger `onChange` if value validated and not equals of origin.
  231. * Return the value that re-align in range.
  232. */
  233. var triggerValueUpdate = function triggerValueUpdate(newValue, userTyping) {
  234. var updateValue = newValue;
  235. var isRangeValidate = isInRange(updateValue) || updateValue.isEmpty();
  236. // Skip align value when trigger value is empty.
  237. // We just trigger onChange(null)
  238. // This should not block user typing
  239. if (!updateValue.isEmpty() && !userTyping) {
  240. // Revert value in range if needed
  241. updateValue = getRangeValue(updateValue) || updateValue;
  242. isRangeValidate = true;
  243. }
  244. if (!readOnly && !disabled && isRangeValidate) {
  245. var numStr = updateValue.toString();
  246. var mergedPrecision = getPrecision(numStr, userTyping);
  247. if (mergedPrecision >= 0) {
  248. updateValue = getMiniDecimal(toFixed(numStr, '.', mergedPrecision));
  249. // When to fixed. The value may out of min & max range.
  250. // 4 in [0, 3.8] => 3.8 => 4 (toFixed)
  251. if (!isInRange(updateValue)) {
  252. updateValue = getMiniDecimal(toFixed(numStr, '.', mergedPrecision, true));
  253. }
  254. }
  255. // Trigger event
  256. if (!updateValue.equals(decimalValue)) {
  257. setUncontrolledDecimalValue(updateValue);
  258. onChange === null || onChange === void 0 || onChange(updateValue.isEmpty() ? null : getDecimalValue(stringMode, updateValue));
  259. // Reformat input if value is not controlled
  260. if (value === undefined) {
  261. setInputValue(updateValue, userTyping);
  262. }
  263. }
  264. return updateValue;
  265. }
  266. return decimalValue;
  267. };
  268. // ========================== User Input ==========================
  269. var onNextPromise = useFrame();
  270. // >>> Collect input value
  271. var collectInputValue = function collectInputValue(inputStr) {
  272. recordCursor();
  273. // Update inputValue in case input can not parse as number
  274. // Refresh ref value immediately since it may used by formatter
  275. inputValueRef.current = inputStr;
  276. setInternalInputValue(inputStr);
  277. // Parse number
  278. if (!compositionRef.current) {
  279. var finalValue = mergedParser(inputStr);
  280. var finalDecimal = getMiniDecimal(finalValue);
  281. if (!finalDecimal.isNaN()) {
  282. triggerValueUpdate(finalDecimal, true);
  283. }
  284. }
  285. // Trigger onInput later to let user customize value if they want to handle something after onChange
  286. onInput === null || onInput === void 0 || onInput(inputStr);
  287. // optimize for chinese input experience
  288. // https://github.com/ant-design/ant-design/issues/8196
  289. onNextPromise(function () {
  290. var nextInputStr = inputStr;
  291. if (!parser) {
  292. nextInputStr = inputStr.replace(/。/g, '.');
  293. }
  294. if (nextInputStr !== inputStr) {
  295. collectInputValue(nextInputStr);
  296. }
  297. });
  298. };
  299. // >>> Composition
  300. var onCompositionStart = function onCompositionStart() {
  301. compositionRef.current = true;
  302. };
  303. var onCompositionEnd = function onCompositionEnd() {
  304. compositionRef.current = false;
  305. collectInputValue(inputRef.current.value);
  306. };
  307. // >>> Input
  308. var onInternalInput = function onInternalInput(e) {
  309. collectInputValue(e.target.value);
  310. };
  311. // ============================= Step =============================
  312. var onInternalStep = function onInternalStep(up) {
  313. var _inputRef$current;
  314. // Ignore step since out of range
  315. if (up && upDisabled || !up && downDisabled) {
  316. return;
  317. }
  318. // Clear typing status since it may be caused by up & down key.
  319. // We should sync with input value.
  320. userTypingRef.current = false;
  321. var stepDecimal = getMiniDecimal(shiftKeyRef.current ? getDecupleSteps(step) : step);
  322. if (!up) {
  323. stepDecimal = stepDecimal.negate();
  324. }
  325. var target = (decimalValue || getMiniDecimal(0)).add(stepDecimal.toString());
  326. var updatedValue = triggerValueUpdate(target, false);
  327. onStep === null || onStep === void 0 || onStep(getDecimalValue(stringMode, updatedValue), {
  328. offset: shiftKeyRef.current ? getDecupleSteps(step) : step,
  329. type: up ? 'up' : 'down'
  330. });
  331. (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus();
  332. };
  333. // ============================ Flush =============================
  334. /**
  335. * Flush current input content to trigger value change & re-formatter input if needed.
  336. * This will always flush input value for update.
  337. * If it's invalidate, will fallback to last validate value.
  338. */
  339. var flushInputValue = function flushInputValue(userTyping) {
  340. var parsedValue = getMiniDecimal(mergedParser(inputValue));
  341. var formatValue;
  342. if (!parsedValue.isNaN()) {
  343. // Only validate value or empty value can be re-fill to inputValue
  344. // Reassign the formatValue within ranged of trigger control
  345. formatValue = triggerValueUpdate(parsedValue, userTyping);
  346. } else {
  347. formatValue = triggerValueUpdate(decimalValue, userTyping);
  348. }
  349. if (value !== undefined) {
  350. // Reset back with controlled value first
  351. setInputValue(decimalValue, false);
  352. } else if (!formatValue.isNaN()) {
  353. // Reset input back since no validate value
  354. setInputValue(formatValue, false);
  355. }
  356. };
  357. // Solve the issue of the event triggering sequence when entering numbers in chinese input (Safari)
  358. var onBeforeInput = function onBeforeInput() {
  359. userTypingRef.current = true;
  360. };
  361. var onKeyDown = function onKeyDown(event) {
  362. var key = event.key,
  363. shiftKey = event.shiftKey;
  364. userTypingRef.current = true;
  365. shiftKeyRef.current = shiftKey;
  366. if (key === 'Enter') {
  367. if (!compositionRef.current) {
  368. userTypingRef.current = false;
  369. }
  370. flushInputValue(false);
  371. onPressEnter === null || onPressEnter === void 0 || onPressEnter(event);
  372. }
  373. if (keyboard === false) {
  374. return;
  375. }
  376. // Do step
  377. if (!compositionRef.current && ['Up', 'ArrowUp', 'Down', 'ArrowDown'].includes(key)) {
  378. onInternalStep(key === 'Up' || key === 'ArrowUp');
  379. event.preventDefault();
  380. }
  381. };
  382. var onKeyUp = function onKeyUp() {
  383. userTypingRef.current = false;
  384. shiftKeyRef.current = false;
  385. };
  386. React.useEffect(function () {
  387. if (changeOnWheel && focus) {
  388. var onWheel = function onWheel(event) {
  389. // moving mouse wheel rises wheel event with deltaY < 0
  390. // scroll value grows from top to bottom, as screen Y coordinate
  391. onInternalStep(event.deltaY < 0);
  392. event.preventDefault();
  393. };
  394. var input = inputRef.current;
  395. if (input) {
  396. // React onWheel is passive and we can't preventDefault() in it.
  397. // That's why we should subscribe with DOM listener
  398. // https://stackoverflow.com/questions/63663025/react-onwheel-handler-cant-preventdefault-because-its-a-passive-event-listenev
  399. input.addEventListener('wheel', onWheel, {
  400. passive: false
  401. });
  402. return function () {
  403. return input.removeEventListener('wheel', onWheel);
  404. };
  405. }
  406. }
  407. });
  408. // >>> Focus & Blur
  409. var onBlur = function onBlur() {
  410. if (changeOnBlur) {
  411. flushInputValue(false);
  412. }
  413. setFocus(false);
  414. userTypingRef.current = false;
  415. };
  416. // ========================== Controlled ==========================
  417. // Input by precision & formatter
  418. useLayoutUpdateEffect(function () {
  419. if (!decimalValue.isInvalidate()) {
  420. setInputValue(decimalValue, false);
  421. }
  422. }, [precision, formatter]);
  423. // Input by value
  424. useLayoutUpdateEffect(function () {
  425. var newValue = getMiniDecimal(value);
  426. setDecimalValue(newValue);
  427. var currentParsedValue = getMiniDecimal(mergedParser(inputValue));
  428. // When user typing from `1.2` to `1.`, we should not convert to `1` immediately.
  429. // But let it go if user set `formatter`
  430. if (!newValue.equals(currentParsedValue) || !userTypingRef.current || formatter) {
  431. // Update value as effect
  432. setInputValue(newValue, userTypingRef.current);
  433. }
  434. }, [value]);
  435. // ============================ Cursor ============================
  436. useLayoutUpdateEffect(function () {
  437. if (formatter) {
  438. restoreCursor();
  439. }
  440. }, [inputValue]);
  441. // ============================ Render ============================
  442. return /*#__PURE__*/React.createElement("div", {
  443. ref: domRef,
  444. className: clsx(prefixCls, className, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, "".concat(prefixCls, "-focused"), focus), "".concat(prefixCls, "-disabled"), disabled), "".concat(prefixCls, "-readonly"), readOnly), "".concat(prefixCls, "-not-a-number"), decimalValue.isNaN()), "".concat(prefixCls, "-out-of-range"), !decimalValue.isInvalidate() && !isInRange(decimalValue))),
  445. style: style,
  446. onFocus: function onFocus() {
  447. setFocus(true);
  448. },
  449. onBlur: onBlur,
  450. onKeyDown: onKeyDown,
  451. onKeyUp: onKeyUp,
  452. onCompositionStart: onCompositionStart,
  453. onCompositionEnd: onCompositionEnd,
  454. onBeforeInput: onBeforeInput
  455. }, controls && /*#__PURE__*/React.createElement(StepHandler, {
  456. prefixCls: prefixCls,
  457. upNode: upHandler,
  458. downNode: downHandler,
  459. upDisabled: upDisabled,
  460. downDisabled: downDisabled,
  461. onStep: onInternalStep
  462. }), /*#__PURE__*/React.createElement("div", {
  463. className: "".concat(inputClassName, "-wrap")
  464. }, /*#__PURE__*/React.createElement("input", _extends({
  465. autoComplete: "off",
  466. role: "spinbutton",
  467. "aria-valuemin": min,
  468. "aria-valuemax": max,
  469. "aria-valuenow": decimalValue.isInvalidate() ? null : decimalValue.toString(),
  470. step: step
  471. }, inputProps, {
  472. ref: composeRef(inputRef, ref),
  473. className: inputClassName,
  474. value: inputValue,
  475. onChange: onInternalInput,
  476. disabled: disabled,
  477. readOnly: readOnly
  478. }))));
  479. });
  480. var InputNumber = /*#__PURE__*/React.forwardRef(function (props, ref) {
  481. var disabled = props.disabled,
  482. style = props.style,
  483. _props$prefixCls = props.prefixCls,
  484. prefixCls = _props$prefixCls === void 0 ? 'rc-input-number' : _props$prefixCls,
  485. value = props.value,
  486. prefix = props.prefix,
  487. suffix = props.suffix,
  488. addonBefore = props.addonBefore,
  489. addonAfter = props.addonAfter,
  490. className = props.className,
  491. classNames = props.classNames,
  492. rest = _objectWithoutProperties(props, _excluded2);
  493. var holderRef = React.useRef(null);
  494. var inputNumberDomRef = React.useRef(null);
  495. var inputFocusRef = React.useRef(null);
  496. var focus = function focus(option) {
  497. if (inputFocusRef.current) {
  498. triggerFocus(inputFocusRef.current, option);
  499. }
  500. };
  501. React.useImperativeHandle(ref, function () {
  502. return proxyObject(inputFocusRef.current, {
  503. focus: focus,
  504. nativeElement: holderRef.current.nativeElement || inputNumberDomRef.current
  505. });
  506. });
  507. return /*#__PURE__*/React.createElement(BaseInput, {
  508. className: className,
  509. triggerFocus: focus,
  510. prefixCls: prefixCls,
  511. value: value,
  512. disabled: disabled,
  513. style: style,
  514. prefix: prefix,
  515. suffix: suffix,
  516. addonAfter: addonAfter,
  517. addonBefore: addonBefore,
  518. classNames: classNames,
  519. components: {
  520. affixWrapper: 'div',
  521. groupWrapper: 'div',
  522. wrapper: 'div',
  523. groupAddon: 'div'
  524. },
  525. ref: holderRef
  526. }, /*#__PURE__*/React.createElement(InternalInputNumber, _extends({
  527. prefixCls: prefixCls,
  528. disabled: disabled,
  529. ref: inputFocusRef,
  530. domRef: inputNumberDomRef,
  531. className: classNames === null || classNames === void 0 ? void 0 : classNames.input
  532. }, rest)));
  533. });
  534. if (process.env.NODE_ENV !== 'production') {
  535. InputNumber.displayName = 'InputNumber';
  536. }
  537. export default InputNumber;