UNPKG

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