Skip to content

Commit 1755543

Browse files
authored
[docs][material-ui] Add Number Field component page (#47165)
1 parent 57bd892 commit 1755543

File tree

34 files changed

+829
-25
lines changed

34 files changed

+829
-25
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from 'react';
2+
import Box from '@mui/material/Box';
3+
import NumberField from './components/NumberField';
4+
5+
export default function FieldDemo() {
6+
return (
7+
<Box sx={{ display: 'grid', gap: 4 }}>
8+
<NumberField label="Number Field" min={10} max={40} />
9+
<NumberField
10+
label="Small and Error"
11+
min={10}
12+
max={40}
13+
size="small"
14+
defaultValue={100}
15+
error
16+
/>
17+
</Box>
18+
);
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from 'react';
2+
import Box from '@mui/material/Box';
3+
import NumberField from './components/NumberField';
4+
5+
export default function FieldDemo() {
6+
return (
7+
<Box sx={{ display: 'grid', gap: 4 }}>
8+
<NumberField label="Number Field" min={10} max={40} />
9+
<NumberField
10+
label="Small and Error"
11+
min={10}
12+
max={40}
13+
size="small"
14+
defaultValue={100}
15+
error
16+
/>
17+
</Box>
18+
);
19+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<NumberField label="Number Field" min={10} max={40} />
2+
<NumberField
3+
label="Small and Error"
4+
min={10}
5+
max={40}
6+
size="small"
7+
defaultValue={100}
8+
error
9+
/>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as React from 'react';
2+
import Box from '@mui/material/Box';
3+
import NumberSpinner from './components/NumberSpinner';
4+
5+
export default function SpinnerDemo() {
6+
return (
7+
<Box
8+
sx={{
9+
display: 'flex',
10+
flexDirection: 'column',
11+
gap: 4,
12+
justifyContent: 'center',
13+
}}
14+
>
15+
<NumberSpinner label="Number Spinner" min={10} max={40} />
16+
<NumberSpinner
17+
label="Small and Error"
18+
min={10}
19+
max={40}
20+
size="small"
21+
defaultValue={100}
22+
error
23+
/>
24+
</Box>
25+
);
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as React from 'react';
2+
import Box from '@mui/material/Box';
3+
import NumberSpinner from './components/NumberSpinner';
4+
5+
export default function SpinnerDemo() {
6+
return (
7+
<Box
8+
sx={{
9+
display: 'flex',
10+
flexDirection: 'column',
11+
gap: 4,
12+
justifyContent: 'center',
13+
}}
14+
>
15+
<NumberSpinner label="Number Spinner" min={10} max={40} />
16+
<NumberSpinner
17+
label="Small and Error"
18+
min={10}
19+
max={40}
20+
size="small"
21+
defaultValue={100}
22+
error
23+
/>
24+
</Box>
25+
);
26+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<NumberSpinner label="Number Spinner" min={10} max={40} />
2+
<NumberSpinner
3+
label="Small and Error"
4+
min={10}
5+
max={40}
6+
size="small"
7+
defaultValue={100}
8+
error
9+
/>
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import * as React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { NumberField as BaseNumberField } from '@base-ui-components/react/number-field';
4+
import IconButton from '@mui/material/IconButton';
5+
import FormControl from '@mui/material/FormControl';
6+
import FormHelperText from '@mui/material/FormHelperText';
7+
import OutlinedInput from '@mui/material/OutlinedInput';
8+
import InputAdornment from '@mui/material/InputAdornment';
9+
import InputLabel from '@mui/material/InputLabel';
10+
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
11+
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
12+
13+
/**
14+
* This component is a placeholder for FormControl to correctly set the shrink label state on SSR.
15+
*/
16+
function SSRInitialFilled(_) {
17+
return null;
18+
}
19+
SSRInitialFilled.muiName = 'Input';
20+
21+
function NumberField({ id: idProp, label, error, size = 'medium', ...other }) {
22+
let id = React.useId();
23+
if (idProp) {
24+
id = idProp;
25+
}
26+
return (
27+
<BaseNumberField.Root
28+
allowWheelScrub
29+
{...other}
30+
render={(props, state) => (
31+
<FormControl
32+
size={size}
33+
ref={props.ref}
34+
disabled={state.disabled}
35+
required={state.required}
36+
error={error}
37+
variant="outlined"
38+
>
39+
{props.children}
40+
</FormControl>
41+
)}
42+
>
43+
<SSRInitialFilled {...other} />
44+
<InputLabel htmlFor={id}>{label}</InputLabel>
45+
<BaseNumberField.Input
46+
id={id}
47+
render={(props, state) => (
48+
<OutlinedInput
49+
label={label}
50+
inputRef={props.ref}
51+
value={state.inputValue}
52+
onBlur={props.onBlur}
53+
onChange={props.onChange}
54+
onKeyUp={props.onKeyUp}
55+
onKeyDown={props.onKeyDown}
56+
onFocus={props.onFocus}
57+
slotProps={{
58+
input: props,
59+
}}
60+
endAdornment={
61+
<InputAdornment
62+
position="end"
63+
sx={{
64+
flexDirection: 'column',
65+
maxHeight: 'unset',
66+
alignSelf: 'stretch',
67+
borderLeft: '1px solid',
68+
borderColor: 'divider',
69+
ml: 0,
70+
'& button': {
71+
py: 0,
72+
flex: 1,
73+
borderRadius: 0.5,
74+
},
75+
}}
76+
>
77+
<BaseNumberField.Increment
78+
render={<IconButton size={size} aria-label="Increase" />}
79+
>
80+
<KeyboardArrowUpIcon
81+
fontSize={size}
82+
sx={{ transform: 'translateY(2px)' }}
83+
/>
84+
</BaseNumberField.Increment>
85+
86+
<BaseNumberField.Decrement
87+
render={<IconButton size={size} aria-label="Decrease" />}
88+
>
89+
<KeyboardArrowDownIcon
90+
fontSize={size}
91+
sx={{ transform: 'translateY(-2px)' }}
92+
/>
93+
</BaseNumberField.Decrement>
94+
</InputAdornment>
95+
}
96+
sx={{ pr: 0 }}
97+
/>
98+
)}
99+
/>
100+
<FormHelperText sx={{ ml: 0, '&:empty': { mt: 0 } }}>
101+
Enter value between 10 and 40
102+
</FormHelperText>
103+
</BaseNumberField.Root>
104+
);
105+
}
106+
107+
NumberField.propTypes = {
108+
error: PropTypes.bool,
109+
/**
110+
* The id of the input element.
111+
*/
112+
id: PropTypes.string,
113+
label: PropTypes.node,
114+
size: PropTypes.oneOf(['medium', 'small']),
115+
};
116+
117+
export default NumberField;
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import * as React from 'react';
2+
import { NumberField as BaseNumberField } from '@base-ui-components/react/number-field';
3+
import IconButton from '@mui/material/IconButton';
4+
import FormControl from '@mui/material/FormControl';
5+
import FormHelperText from '@mui/material/FormHelperText';
6+
import OutlinedInput from '@mui/material/OutlinedInput';
7+
import InputAdornment from '@mui/material/InputAdornment';
8+
import InputLabel from '@mui/material/InputLabel';
9+
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
10+
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
11+
12+
/**
13+
* This component is a placeholder for FormControl to correctly set the shrink label state on SSR.
14+
*/
15+
function SSRInitialFilled(_: BaseNumberField.Root.Props) {
16+
return null;
17+
}
18+
SSRInitialFilled.muiName = 'Input';
19+
20+
export default function NumberField({
21+
id: idProp,
22+
label,
23+
error,
24+
size = 'medium',
25+
...other
26+
}: BaseNumberField.Root.Props & {
27+
label?: React.ReactNode;
28+
size?: 'small' | 'medium';
29+
error?: boolean;
30+
}) {
31+
let id = React.useId();
32+
if (idProp) {
33+
id = idProp;
34+
}
35+
return (
36+
<BaseNumberField.Root
37+
allowWheelScrub
38+
{...other}
39+
render={(props, state) => (
40+
<FormControl
41+
size={size}
42+
ref={props.ref}
43+
disabled={state.disabled}
44+
required={state.required}
45+
error={error}
46+
variant="outlined"
47+
>
48+
{props.children}
49+
</FormControl>
50+
)}
51+
>
52+
<SSRInitialFilled {...other} />
53+
<InputLabel htmlFor={id}>{label}</InputLabel>
54+
<BaseNumberField.Input
55+
id={id}
56+
render={(props, state) => (
57+
<OutlinedInput
58+
label={label}
59+
inputRef={props.ref}
60+
value={state.inputValue}
61+
onBlur={props.onBlur}
62+
onChange={props.onChange}
63+
onKeyUp={props.onKeyUp}
64+
onKeyDown={props.onKeyDown}
65+
onFocus={props.onFocus}
66+
slotProps={{
67+
input: props,
68+
}}
69+
endAdornment={
70+
<InputAdornment
71+
position="end"
72+
sx={{
73+
flexDirection: 'column',
74+
maxHeight: 'unset',
75+
alignSelf: 'stretch',
76+
borderLeft: '1px solid',
77+
borderColor: 'divider',
78+
ml: 0,
79+
'& button': {
80+
py: 0,
81+
flex: 1,
82+
borderRadius: 0.5,
83+
},
84+
}}
85+
>
86+
<BaseNumberField.Increment
87+
render={<IconButton size={size} aria-label="Increase" />}
88+
>
89+
<KeyboardArrowUpIcon
90+
fontSize={size}
91+
sx={{ transform: 'translateY(2px)' }}
92+
/>
93+
</BaseNumberField.Increment>
94+
95+
<BaseNumberField.Decrement
96+
render={<IconButton size={size} aria-label="Decrease" />}
97+
>
98+
<KeyboardArrowDownIcon
99+
fontSize={size}
100+
sx={{ transform: 'translateY(-2px)' }}
101+
/>
102+
</BaseNumberField.Decrement>
103+
</InputAdornment>
104+
}
105+
sx={{ pr: 0 }}
106+
/>
107+
)}
108+
/>
109+
<FormHelperText sx={{ ml: 0, '&:empty': { mt: 0 } }}>
110+
Enter value between 10 and 40
111+
</FormHelperText>
112+
</BaseNumberField.Root>
113+
);
114+
}

0 commit comments

Comments
 (0)