Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
117 lines
3.5 KiB
JavaScript
117 lines
3.5 KiB
JavaScript
import * as React from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import { NumberField as BaseNumberField } from '@base-ui-components/react/number-field';
|
|
import IconButton from '@mui/material/IconButton';
|
|
import FormControl from '@mui/material/FormControl';
|
|
import FormHelperText from '@mui/material/FormHelperText';
|
|
import OutlinedInput from '@mui/material/OutlinedInput';
|
|
import InputAdornment from '@mui/material/InputAdornment';
|
|
import InputLabel from '@mui/material/InputLabel';
|
|
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
|
|
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
|
|
|
/**
|
|
* This component is a placeholder for FormControl to correctly set the shrink label state on SSR.
|
|
*/
|
|
function SSRInitialFilled(_) {
|
|
return null;
|
|
}
|
|
SSRInitialFilled.muiName = 'Input';
|
|
|
|
function NumberField({ id: idProp, label, error, size = 'medium', ...other }) {
|
|
let id = React.useId();
|
|
if (idProp) {
|
|
id = idProp;
|
|
}
|
|
return (
|
|
<BaseNumberField.Root
|
|
{...other}
|
|
render={(props, state) => (
|
|
<FormControl
|
|
size={size}
|
|
ref={props.ref}
|
|
disabled={state.disabled}
|
|
required={state.required}
|
|
error={error}
|
|
variant="outlined"
|
|
>
|
|
{props.children}
|
|
</FormControl>
|
|
)}
|
|
>
|
|
<SSRInitialFilled {...other} />
|
|
<InputLabel htmlFor={id}>{label}</InputLabel>
|
|
<BaseNumberField.Input
|
|
id={id}
|
|
render={(props, state) => (
|
|
<OutlinedInput
|
|
label={label}
|
|
inputRef={props.ref}
|
|
value={state.inputValue}
|
|
onBlur={props.onBlur}
|
|
onChange={props.onChange}
|
|
onKeyUp={props.onKeyUp}
|
|
onKeyDown={props.onKeyDown}
|
|
onFocus={props.onFocus}
|
|
slotProps={{
|
|
input: props,
|
|
}}
|
|
endAdornment={
|
|
<InputAdornment
|
|
position="end"
|
|
sx={{
|
|
flexDirection: 'column',
|
|
maxHeight: 'unset',
|
|
alignSelf: 'stretch',
|
|
borderLeft: '1px solid',
|
|
borderColor: 'divider',
|
|
ml: 0,
|
|
'& button': {
|
|
py: 0,
|
|
flex: 1,
|
|
borderRadius: 0.5,
|
|
},
|
|
}}
|
|
>
|
|
<BaseNumberField.Increment
|
|
render={<IconButton size={size} aria-label="Increase" />}
|
|
>
|
|
<KeyboardArrowUpIcon
|
|
fontSize={size}
|
|
sx={{ transform: 'translateY(2px)' }}
|
|
/>
|
|
</BaseNumberField.Increment>
|
|
|
|
<BaseNumberField.Decrement
|
|
render={<IconButton size={size} aria-label="Decrease" />}
|
|
>
|
|
<KeyboardArrowDownIcon
|
|
fontSize={size}
|
|
sx={{ transform: 'translateY(-2px)' }}
|
|
/>
|
|
</BaseNumberField.Decrement>
|
|
</InputAdornment>
|
|
}
|
|
sx={{ pr: 0 }}
|
|
/>
|
|
)}
|
|
/>
|
|
<FormHelperText sx={{ ml: 0, '&:empty': { mt: 0 } }}>
|
|
Enter value between 10 and 40
|
|
</FormHelperText>
|
|
</BaseNumberField.Root>
|
|
);
|
|
}
|
|
|
|
NumberField.propTypes = {
|
|
error: PropTypes.bool,
|
|
/**
|
|
* The id of the input element.
|
|
*/
|
|
id: PropTypes.string,
|
|
label: PropTypes.node,
|
|
size: PropTypes.oneOf(['medium', 'small']),
|
|
};
|
|
|
|
export default NumberField;
|