@vectara/vectara-ui
Version:
Vectara's design system, codified as a React and Sass component library
62 lines (61 loc) • 2.85 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { jsx as _jsx } from "react/jsx-runtime";
import { forwardRef, useEffect, useState } from "react";
import { VuiBasicInput } from "./BasicInput";
export const VuiNumberInput = forwardRef((_a, ref) => {
var { value, onChange, max, min, step } = _a, rest = __rest(_a, ["value", "onChange", "max", "min", "step"]);
const [localValue, setLocalValue] = useState(value);
// This is a hacky solution to the number input misbehaving on Firefox.
// If we were to apply the value and onChange values directly to the
// value and onChange props of the input, then a user who:
// 1. Selects all
// 2. Types 1.0
// will have the input show "0" as soon as they enter a decimal point.
// When that character is entered, onChange is called with undefined.
// This value gets stored in the value state, which resets the value to 0.
// For some reason, using a useState hook to store the value doesn't have
// this problem.
useEffect(() => {
// Reflect the upstream value when it changes. Ignore 0
// because that indicates the user has entered a decimal point.
if (value !== 0) {
setLocalValue(value);
}
}, [value]);
// Part of the hacky solution above.
useEffect(() => {
// Set value locally so an undefined value doesn't reset it to 0.
// Pass the value upstream, e.g. so it can be persisted.
onChange(localValue !== null && localValue !== void 0 ? localValue : 0);
}, [localValue]);
const onChangeValue = (e) => {
// Enable resetting the value to undefined.
if (e.target.value === "")
return setLocalValue(undefined);
const numberValue = Number(e.target.value);
if (isNaN(numberValue))
return setLocalValue(undefined);
setLocalValue(Number(e.target.value));
};
const onBlur = () => {
if (min !== undefined && value !== undefined && value < min)
onChange(min);
if (max !== undefined && value !== undefined && value > max)
onChange(max);
};
const props = Object.assign({ type: "number", value: localValue !== null && localValue !== void 0 ? localValue : "", onChange: onChangeValue, onBlur,
max,
min,
step }, rest);
return _jsx(VuiBasicInput, Object.assign({}, props));
});