UNPKG

@vectara/vectara-ui

Version:

Vectara's design system, codified as a React and Sass component library

62 lines (61 loc) 2.85 kB
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)); });