UNPKG

5.89 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
6var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
7var textInput = require('@spark-web/text-input');
8var react = require('react');
9var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
10var numeral = require('numeral');
11var jsxRuntime = require('react/jsx-runtime');
12
13function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
14
15var numeral__default = /*#__PURE__*/_interopDefault(numeral);
16
17/** Ensure only valid values are passed to the consumer */
18var isValid = function isValid(text) {
19 var valid = /^\s*\$?-?[\d,]+(\.\d+)?\s*$/;
20 return valid.test(text) && !isNaN(parse(text));
21};
22
23/** Strip invalid characters */
24var normalise = function normalise(text) {
25 return text.trim().replace(/^\$/, '').replace(/,/g, '');
26};
27
28/** Safe parse */
29var parse = function parse(text) {
30 return parseFloat(normalise(text));
31};
32
33/** Resolve leading decimal issues */
34var padLeadingDecimal = function padLeadingDecimal(text) {
35 if (text.startsWith('.')) {
36 return "0".concat(text);
37 } else if (text.startsWith('-.')) {
38 return "-0".concat(text.substring(1));
39 }
40 return text;
41};
42
43/** Prepare the formatter */
44var useFormat = function useFormat(fractionDigits) {
45 return react.useCallback(function (val) {
46 if (typeof val === 'undefined') {
47 return '';
48 }
49 if (typeof val === 'string' && !isValid(val)) {
50 return val;
51 }
52 var pattern = fractionDigits ? "0,0.".concat('0'.repeat(fractionDigits)) : '0,0.[00000000]';
53 return numeral__default["default"](val).format(pattern);
54 }, [fractionDigits]);
55};
56var useFloatInput = function useFloatInput(_ref) {
57 var fractionDigits = _ref.fractionDigits,
58 consumerBlur = _ref.onBlur,
59 consumerFocus = _ref.onFocus,
60 controlledOnChange = _ref.onChange,
61 controlledValue = _ref.value;
62 if (Number.isNaN(controlledValue)) {
63 throw new Error('NaN cannot be provided to numeric inputs.');
64 }
65 var format = useFormat(fractionDigits);
66 var isControlled = controlledValue !== undefined && controlledOnChange !== undefined;
67 var _useState = react.useState(function () {
68 return format(controlledValue);
69 }),
70 _useState2 = _slicedToArray(_useState, 2),
71 internalValue = _useState2[0],
72 setInternalValue = _useState2[1];
73 var uncontrolledHandlers = {
74 onChange: react.useCallback(function (e) {
75 var paddedText = padLeadingDecimal(e.currentTarget.value);
76 setInternalValue(normalise(paddedText));
77 }, []),
78 onBlur: useFocusHandler(consumerBlur, function () {
79 setInternalValue(format(internalValue));
80 }),
81 onFocus: useFocusHandler(consumerFocus, function () {
82 setInternalValue(function (currentValue) {
83 return normalise(currentValue);
84 });
85 }),
86 value: internalValue
87 };
88 var controlledHandlers = {
89 onChange: react.useCallback(function (e) {
90 if (!isControlled) return;
91 var paddedText = padLeadingDecimal(e.currentTarget.value);
92 if (!e.currentTarget.value) {
93 controlledOnChange('');
94 } else if (isValid(paddedText)) {
95 controlledOnChange(parse(paddedText));
96 } else {
97 controlledOnChange(normalise(paddedText));
98 }
99 setInternalValue(normalise(paddedText));
100 }, [controlledOnChange, isControlled]),
101 onBlur: useFocusHandler(consumerBlur, function () {
102 if (!isControlled) return;
103 if (typeof controlledValue === 'number' && fractionDigits) {
104 controlledOnChange(parse(controlledValue.toFixed(fractionDigits)));
105 } else {
106 controlledOnChange(controlledValue !== null && controlledValue !== void 0 ? controlledValue : '');
107 }
108 setInternalValue(format(internalValue));
109 }),
110 onFocus: useFocusHandler(consumerFocus, function () {
111 setInternalValue(function (currentValue) {
112 return normalise(currentValue);
113 });
114 }),
115 value: internalValue
116 };
117 return isControlled ? controlledHandlers : uncontrolledHandlers;
118};
119var useFocusHandler = function useFocusHandler(consumerHandler, ourHandler) {
120 return react.useCallback(function (event) {
121 if (typeof consumerHandler === 'function') {
122 consumerHandler(event);
123 }
124 if (!(event !== null && event !== void 0 && event.defaultPrevented)) {
125 ourHandler(event);
126 }
127 }, [consumerHandler, ourHandler]);
128};
129
130var _excluded = ["fractionDigits", "onBlur", "onFocus", "onChange", "value", "data", "placeholder", "children"];
131var FloatInput = /*#__PURE__*/react.forwardRef(function (_ref, forwardedRef) {
132 var fractionDigits = _ref.fractionDigits,
133 onBlur = _ref.onBlur,
134 onFocus = _ref.onFocus,
135 onChange = _ref.onChange,
136 value = _ref.value,
137 data = _ref.data,
138 placeholder = _ref.placeholder,
139 children = _ref.children,
140 inputProps = _objectWithoutProperties(_ref, _excluded);
141 var inputs = {
142 fractionDigits: fractionDigits,
143 onBlur: onBlur,
144 onFocus: onFocus
145 };
146 if (onChange !== undefined && value !== undefined) {
147 inputs = _objectSpread(_objectSpread({}, inputs), {}, {
148 onChange: onChange,
149 value: value
150 });
151 }
152 var _useFloatInput = useFloatInput(inputs),
153 floatOnBlur = _useFloatInput.onBlur,
154 floatOnChange = _useFloatInput.onChange,
155 floatOnFocus = _useFloatInput.onFocus,
156 floatValue = _useFloatInput.value;
157 return /*#__PURE__*/jsxRuntime.jsx(textInput.TextInput, _objectSpread(_objectSpread({}, inputProps), {}, {
158 ref: forwardedRef,
159 data: data,
160 placeholder: placeholder,
161 type: "text",
162 inputMode: "decimal",
163 onBlur: floatOnBlur,
164 onChange: floatOnChange,
165 onFocus: floatOnFocus,
166 value: floatValue,
167 children: children
168 }));
169});
170FloatInput.displayName = 'FloatInput';
171
172exports.FloatInput = FloatInput;