UNPKG

@etsoo/materialui

Version:

TypeScript Material-UI Implementation

113 lines (112 loc) 4.74 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import AddIcon from "@mui/icons-material/Add"; import RemoveIcon from "@mui/icons-material/Remove"; import React from "react"; import { NumberUtils } from "@etsoo/shared"; import { InputField } from "./InputField"; import Box from "@mui/material/Box"; import InputAdornment from "@mui/material/InputAdornment"; import IconButton from "@mui/material/IconButton"; /** * Integer input field (controlled) */ export const IntInputField = React.forwardRef((props, ref) => { // Destruct const { min = 0, step = 1, max = 9999999, inputStyle = { textAlign: "right" }, boxProps, buttons, endSymbol, symbol, value, changeDelay = 600, onChangeDelay, onChange, onFocus = (event) => event.currentTarget.select(), onValueChange, required, ...rest } = props; // State const [localValue, setLocalValue] = React.useState(); const setValue = (value, source, init = false) => { if (onValueChange) { const newValue = onValueChange(value, source, init); if (newValue === false) return; if (newValue === null) { setLocalValue(undefined); return; } if (newValue === true || newValue === undefined) setLocalValue(value); else setLocalValue(newValue); } else { setLocalValue(value); } }; React.useEffect(() => { setValue(value, undefined, true); }, [value]); // Layout const layout = (_jsx(InputField, { ref: ref, type: "number", value: localValue == null ? (required ? min : "") : localValue, inputProps: { min, step, max, style: inputStyle, inputMode: "numeric" }, InputProps: { startAdornment: symbol ? (_jsx(React.Fragment, { children: _jsx(InputAdornment, { position: "start", children: symbol }) })) : undefined, endAdornment: endSymbol ? (_jsx(InputAdornment, { position: "end", children: endSymbol })) : undefined }, sx: buttons ? { "& input[type=number]::-webkit-inner-spin-button": { WebkitAppearance: "none", margin: 0 }, "& input[type=number]::-webkit-outer-spin-button": { WebkitAppearance: "none", margin: 0 } } : undefined, onChange: (event) => { const source = event.target.value; setLocalValue(source); if (onChange) onChange(event); }, changeDelay: changeDelay, onChangeDelay: (event) => { const source = event.target.value; const value = parseFloat(source); if (isNaN(value)) setValue(undefined, source); else if (value > max) setValue(max, source); else if (value < min) setValue(value === 0 ? undefined : min, source); // 0 is a special case else setValue(value, source); if (onChangeDelay) onChangeDelay(event); }, onFocus: onFocus, required: required, ...rest })); if (buttons) return (_jsxs(Box, { sx: { display: "flex", alignItems: "center", width: "100%", gap: 0.5, ...boxProps }, children: [_jsx(IconButton, { size: "small", onClick: () => { if (localValue == null) return; const value = NumberUtils.parse(localValue); if (value == null) return; if (value <= min) setValue(undefined, "SUB"); else setValue(value - step, "SUB"); }, children: _jsx(RemoveIcon, {}) }), layout, _jsx(IconButton, { size: "small", onClick: () => { if (localValue == null) { setValue(min, "ADD"); return; } const value = NumberUtils.parse(localValue); if (value == null) return; if (value >= max) return; else setValue(value + step, "ADD"); }, children: _jsx(AddIcon, { color: localValue == null ? undefined : "primary" }) })] })); else return layout; });