Skip to content

Instantly share code, notes, and snippets.

@ZenulAbidin
Last active April 27, 2023 11:08
Show Gist options
  • Save ZenulAbidin/973cfb2819f6970e299cc1b5768603d1 to your computer and use it in GitHub Desktop.
Save ZenulAbidin/973cfb2819f6970e299cc1b5768603d1 to your computer and use it in GitHub Desktop.
Number Input for Material UI v5 (mark 2)
// Copyright 2022 Ali Sherief
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import InputAdornment from '@mui/material/InputAdornment';
import IconButton from '@mui/material/IconButton';
import TextField from '@mui/material/TextField';
import { useState } from 'react';
import AddIcon from '@mui/icons-material/Add';
import RemoveIcon from '@mui/icons-material/Remove';
import { ButtonGroup } from '@mui/material';
const isNumeric = (n) => {
if (typeof n == "number") {
return true;
}
else if (/^(\d+)\.?(\d*)$/.test(n)) {
return true;
}
else {
return false;
}
}
const handleStep = (number, min, max, step, direction, setNumberValue) => {
number = Number(number);
if (isNumeric(min) && number + step*direction < min) {
setNumberValue(min);
}
else if (isNumeric(max) && number + step*direction > max) {
setNumberValue(max);
}
else {
setNumberValue(number + step*direction);
}
}
const handleNumberChange = (number, min, max, step, _default, setNumberValue, setError) => {
if (number === "") {
if (_default) {
setNumberValue(_default);
}
else {
setNumberValue(0);
}
}
if (!isNumeric(number)) {
return;
}
setNumberValue(number);
let tmpnumber = Number(number);
if (isNumeric(min) && tmpnumber < min) {
setError(true);
return;
}
else if (isNumeric(max) && tmpnumber > max) {
setError(true);
return;
}
let tempnum = tmpnumber;
if (isNumeric(step) && step > 0) {
while (Math.abs(step) < 1) {
tempnum *= 10;
step *= 10;
}
if (tempnum % step !== 0) {
setError(true);
return;
}
}
setError(false);
return;
}
export default function NumberInput(props){
const [numberValue, setNumberValue] = useState(props.default || 0);
const [error, setError] = useState(false);
let step = props.step;
if (step === undefined) {
step = 1;
}
return (
<TextField
InputProps={{
readOnly: (typeof(props.inputProps) === "object") ? props.inputProps.readOnly : false,
startAdornment: (
<InputAdornment position='start'>
{props.prefix}
</InputAdornment>
),
endAdornment: (
<InputAdornment position='end'>
{props.suffix}
<ButtonGroup orientation="vertical" sx={{paddingLeft: "10px"}}>
<IconButton size="small" onClick={
(e) => handleStep(numberValue, props.min, props.max, step, 1, setNumberValue)
}>
<AddIcon style={{fontSize: "0.8rem"}}/>
</IconButton>
<IconButton size="small" onClick={
(e) => handleStep(numberValue, props.min, props.max, step, -1, setNumberValue)
}>
<RemoveIcon style={{fontSize: "0.8rem", paddingBottom:
(!props.variant || props.variant === "standard") ? "10px" : "0px"}}/>
</IconButton>
</ButtonGroup>
</InputAdornment>
),
inputProps: {
step: step,
min: props.min,
max: props.max,
type: 'text',
onChange: (e) => {
handleNumberChange(e.target.value,
props.min, props.max, step, props.default, setNumberValue, setError)
},
}}}
autocomplete={props.autoComplete}
autoFocus={props.autoFocus}
classes={props.classes}
color={props.color}
disabled={props.disabled}
error={error}
FormHelperTextProps={props.FormHelperTextProps}
helperText={props.helperText}
id={props.id}
InputLabelProps={props.InputLabelProps}
inputRef={props.inputRef}
label={props.label}
margin={props.margin}
name={props.name}
placeholder={props.placeholder}
required={props.required}
sx={{width: "26.2ch", ...props.sx}}
value={numberValue}
variant={props.variant}
/>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment