UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

197 lines (194 loc) 6.36 kB
import React, { useState, useRef, useEffect } from 'react'; import cx from 'clsx'; import { assignRef, useMergedRef } from '@mantine/hooks'; import { TextInput } from '../TextInput/TextInput.js'; import useStyles, { CONTROL_SIZES } from './NumberInput.styles.js'; import { useMantineTheme } from '../../theme/use-mantine-theme/use-mantine-theme.js'; import { mergeStyles } from '../../theme/utils/merge-styles/merge-styles.js'; import { getSizeValue } from '../../theme/utils/get-size-value/get-size-value.js'; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __objRest = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols) for (var prop of __getOwnPropSymbols(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop]; } return target; }; function NumberInput(_a) { var _b = _a, { disabled, themeOverride, elementRef, value, onChange, min, max, step = 1, onBlur, onFocus, hideControls = false, radius = "sm", variant, precision = 0, defaultValue, noClampOnBlur = false, handlersRef, classNames, styles, size } = _b, others = __objRest(_b, [ "disabled", "themeOverride", "elementRef", "value", "onChange", "min", "max", "step", "onBlur", "onFocus", "hideControls", "radius", "variant", "precision", "defaultValue", "noClampOnBlur", "handlersRef", "classNames", "styles", "size" ]); const theme = useMantineTheme(themeOverride); const classes = useStyles({ theme, radius, size }, classNames, "number-input"); const _styles = mergeStyles(classes, styles); const [focused, setFocused] = useState(false); const [_value, setValue] = useState(typeof value === "number" ? value : typeof defaultValue === "number" ? defaultValue : 0); const finalValue = typeof value === "number" ? value : _value; const [tempValue, setTempValue] = useState(typeof finalValue === "number" ? finalValue.toFixed(precision) : ""); const inputRef = useRef(); const handleValueChange = (val) => { typeof onChange === "function" && onChange(val); setValue(val); }; const _min = typeof min === "number" ? min : -Infinity; const _max = typeof max === "number" ? max : Infinity; const clamp = (v) => { const val = typeof v === "number" ? v : parseFloat(v); return Math.min(Math.max(val, _min), _max); }; const increment = () => { const result = clamp(finalValue + step).toFixed(precision); handleValueChange(parseFloat(result)); setTempValue(result); }; const decrement = () => { const result = clamp(finalValue - step).toFixed(precision); handleValueChange(parseFloat(result)); setTempValue(result); }; assignRef(handlersRef, { increment, decrement }); useEffect(() => { if (typeof value === "number" && !focused) { setValue(value); setTempValue(value.toFixed(precision)); } }, [value]); const rightSection = /* @__PURE__ */ React.createElement("div", { className: classes.rightSection, style: _styles.rightSection }, /* @__PURE__ */ React.createElement("button", { type: "button", tabIndex: -1, "aria-hidden": true, disabled: finalValue >= max, className: cx(classes.control, classes.controlUp), style: __spreadValues(__spreadValues({}, _styles.control), _styles.controlUp), onMouseDown: (event) => { event.preventDefault(); increment(); inputRef.current.focus(); } }), /* @__PURE__ */ React.createElement("button", { type: "button", tabIndex: -1, "aria-hidden": true, disabled: finalValue <= min, className: cx(classes.control, classes.controlDown), style: __spreadValues(__spreadValues({}, _styles.control), _styles.controlDown), onMouseDown: (event) => { event.preventDefault(); decrement(); inputRef.current.focus(); } })); const handleChange = (event) => { const val = event.currentTarget.value; setTempValue(val); const parsed = Number(val); val.trim() !== "" && !Number.isNaN(parsed) && handleValueChange(parsed); }; const handleBlur = (event) => { const val = clamp(event.currentTarget.value); if (!Number.isNaN(val)) { if (!noClampOnBlur) { setTempValue(val.toFixed(precision)); handleValueChange(val); } } else { setTempValue(finalValue.toFixed(precision)); } setFocused(false); typeof onBlur === "function" && onBlur(event); }; const handleFocus = (event) => { setFocused(true); typeof onFocus === "function" && onBlur(event); }; return /* @__PURE__ */ React.createElement(TextInput, __spreadProps(__spreadValues({}, others), { variant, value: tempValue, disabled, themeOverride, elementRef: useMergedRef(inputRef, elementRef), type: "number", onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, rightSection: disabled || hideControls || variant === "unstyled" ? null : rightSection, rightSectionWidth: getSizeValue({ size, sizes: CONTROL_SIZES }) + 1, radius, max, min, step, size, styles, classNames, __staticSelector: "number-input" })); } NumberInput.displayName = "@mantine/core/NumberInput"; export { NumberInput }; //# sourceMappingURL=NumberInput.js.map