Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | 27x 606x 606x 606x 606x 606x 606x 140x 606x 606x 606x 8x 606x 162x 606x 352x 606x 140x 140x 140x 140x 140x 606x 140x 140x 136x 136x 4x 4x 606x 28x 28x 28x 27x | import PropTypes from 'prop-types';
import {
useEffect,
useRef,
useState
} from 'react';
import noop from 'lodash/noop';
import {
nativeChangeFieldValue as nativeChangeField,
TextField
} from '@folio/stripes/components';
const NumberField = (props) => {
const {
onBlur: passedOnBlur = noop,
onChange: passedOnChange = noop,
input,
value,
...rest
} = props;
// Treat TextField ALWAYS as a controlled component, whether or not NumberField itself is controlled
// This enforces the behaviour whereby 1e2 -> 100 in the typed field automatically
const [forceControl, setForceControl] = useState(value ?? input?.value);
const inputRef = useRef();
const userInputRef = useRef();
const [numValue, setNumValue] = useState('');
const changeField = (val) => {
nativeChangeField(inputRef, false, val);
};
// Allow direct control of field
useEffect(() => {
const valueToUse = value ?? input.value;
if (!valueToUse && numValue) {
// Make sure to empty out if it's cleared. Treating '' as empty instead of undefined
setNumValue('');
}
if (valueToUse && numValue !== valueToUse) {
setNumValue(valueToUse);
}
if (forceControl !== numValue) {
setForceControl(numValue);
}
}, [forceControl, numValue, value, input]);
const handleChange = (e) => {
// Actually set the value in the form
Eif (input?.onChange) {
input.onChange(e);
}
// Set the forced control (this may be wiped by passedOnChange)
setForceControl(e.target.value);
// If the user has set up an onChange, this will ensure that that fires
Eif (passedOnChange) {
passedOnChange(e, e.target.value);
}
};
const handleUserChange = (e) => {
const parsedValue = parseFloat(e.target.value);
// ReturnValue needed for controlled components
if (parsedValue || parsedValue === 0) {
setNumValue(parsedValue);
changeField(parsedValue);
} else {
setNumValue('');
changeField('');
}
};
return (
<>
<TextField
ref={userInputRef}
{...rest} // Keep an eye on this
onBlur={(event) => {
// Make sure blur propogates to input
Eif (input.onBlur) {
input.onBlur(event);
}
passedOnBlur(event);
}}
onChange={handleUserChange}
type="number"
value={forceControl}
/>
<input
ref={inputRef}
{...input}
hidden
id={input?.name}
onChange={handleChange}
type="number"
value={numValue}
/>
</>
);
};
NumberField.propTypes = {
onBlur: PropTypes.func,
onChange: PropTypes.func,
input: PropTypes.shape({
name: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
onBlur: PropTypes.func,
value: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string
])
}),
value: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string
])
};
export default NumberField;
|