Skip to content

Commit

Permalink
[Select] Allow customizing Select based on its variant (mui#30788)
Browse files Browse the repository at this point in the history
Co-authored-by: Marija Najdova <mnajdova@gmail.com>
  • Loading branch information
michaldudak and mnajdova authored Feb 14, 2022
1 parent 38791aa commit e306b16
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 8 deletions.
27 changes: 21 additions & 6 deletions packages/mui-material/src/Select/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,26 @@ import FilledInput from '../FilledInput';
import OutlinedInput from '../OutlinedInput';
import useThemeProps from '../styles/useThemeProps';
import useForkRef from '../utils/useForkRef';
import styled, { rootShouldForwardProp } from '../styles/styled';

const useUtilityClasses = (ownerState) => {
const { classes } = ownerState;
return classes;
};

const styledRootConfig = {
name: 'MuiSelect',
overridesResolver: (props, styles) => styles.root,
shouldForwardProp: (prop) => rootShouldForwardProp(prop) && prop !== 'variant',
slot: 'Root',
};

const StyledInput = styled(Input, styledRootConfig)('');

const StyledOutlinedInput = styled(OutlinedInput, styledRootConfig)('');

const StyledFilledInput = styled(FilledInput, styledRootConfig)('');

const Select = React.forwardRef(function Select(inProps, ref) {
const props = useThemeProps({ name: 'MuiSelect', props: inProps });
const {
Expand All @@ -41,7 +55,7 @@ const Select = React.forwardRef(function Select(inProps, ref) {
open,
renderValue,
SelectDisplayProps,
variant: variantProps = 'outlined',
variant: variantProp = 'outlined',
...other
} = props;

Expand All @@ -54,17 +68,17 @@ const Select = React.forwardRef(function Select(inProps, ref) {
states: ['variant'],
});

const variant = fcs.variant || variantProps;
const variant = fcs.variant || variantProp;

const InputComponent =
input ||
{
standard: <Input />,
outlined: <OutlinedInput label={label} />,
filled: <FilledInput />,
standard: <StyledInput />,
outlined: <StyledOutlinedInput label={label} />,
filled: <StyledFilledInput />,
}[variant];

const ownerState = { ...props, classes: classesProp };
const ownerState = { ...props, variant, classes: classesProp };
const classes = useUtilityClasses(ownerState);

const inputComponentRef = useForkRef(ref, InputComponent.ref);
Expand Down Expand Up @@ -100,6 +114,7 @@ const Select = React.forwardRef(function Select(inProps, ref) {
...(multiple && native && variant === 'outlined' ? { notched: true } : {}),
ref: inputComponentRef,
className: clsx(InputComponent.props.className, className),
variant,
...other,
});
});
Expand Down
44 changes: 42 additions & 2 deletions packages/mui-material/src/Select/Select.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,10 @@ describe('<Select />', () => {
this.skip();
}

const rootStyle = {
marginTop: '15px',
};

const iconStyle = {
marginTop: '13px',
};
Expand All @@ -1246,6 +1250,7 @@ describe('<Select />', () => {
components: {
MuiSelect: {
styleOverrides: {
root: rootStyle,
select: selectStyle,
icon: iconStyle,
nativeInput: nativeInputStyle,
Expand All @@ -1255,22 +1260,57 @@ describe('<Select />', () => {
},
});

const { container } = render(
const { container, getByTestId } = render(
<ThemeProvider theme={theme}>
<Select open value="first">
<Select open value="first" data-testid="select">
<MenuItem value="first" />
<MenuItem value="second" />
</Select>
</ThemeProvider>,
);

expect(getByTestId('select')).toHaveComputedStyle(rootStyle);
expect(container.getElementsByClassName(classes.icon)[0]).to.toHaveComputedStyle(iconStyle);
expect(container.getElementsByClassName(classes.nativeInput)[0]).to.toHaveComputedStyle(
nativeInputStyle,
);
expect(container.getElementsByClassName(classes.select)[0]).to.toHaveComputedStyle(selectStyle);
});

['standard', 'outlined', 'filled'].forEach((variant) => {
it(`variant overrides should work for "${variant}" variant`, function test() {
const theme = createTheme({
components: {
MuiSelect: {
variants: [
{
props: {
variant,
},
style: {
fontWeight: '200',
},
},
],
},
},
});

const { getByTestId } = render(
<ThemeProvider theme={theme}>
<Select variant={variant} value="first" data-testid="input">
<MenuItem value="first" />
<MenuItem value="second" />
</Select>
</ThemeProvider>,
);

expect(getByTestId('input')).to.toHaveComputedStyle({
fontWeight: '200',
});
});
});

describe('prop: input', () => {
it('merges `ref` of `Select` and `input`', () => {
const Input = React.forwardRef(function Input(props, ref) {
Expand Down

0 comments on commit e306b16

Please sign in to comment.