skip to Main Content

I am trying to style the Select MUI component using the styled function. Since I want to share this style later on, I don’t want to keep using sx. I’ve tried a couple of approaches, but I am missing the right class to be able to target the Paper directly from within the styled function

// Styled 
export const StyledSelect = styled(Select)<SelectProps>(({ theme }) => ({
  textAlign: 'start',
  margin: '5px',
  fontWeight: 800,
  
  '& .MuiSelect-select': {
    // List
    '& .MuiList-root': {
      color: 'green',
      backgroundColor: 'red',
    },
    // Paper 
    '& .MuiMenu-paper': {
      backgroundColor: 'red',
    },
  },
})

// Component
<FormControl>
  <StyledSelect
  variant={variant}
  labelId='select-label'
  // This works 100%
  // MenuProps={{
  //   PaperProps: {
  //     sx: {
  //       backgroundColor: 'transparent',
  //       backdropFilter: 'blur(10px)',
  //     },
  //   },
  // }}
  name={name}
  disabled={disabled}
  value={value}

  onChange={onChangeFn}
  displayEmpty
  >
  </StyledSelect>
</FormControl>

2

Answers


  1. The MUI Paper within a default Select has always been a trickier to handle as a styled component because the Paper falls outside of the Select‘s DOM hierarchy (due to it use of a Portal). In order to style it (and the Select), you first need to style the Select and then use that styled Select as the base component from which to style the Paper. For example:

    const BaseSelect = styled(Select)(({ theme }) => ({
      backgroundColor: "green", // Added just for the example
      textAlign: 'start',
      margin: '5px',
      fontWeight: 800,
    }));
    
    // To style the Menu Paper
    const StyledSelect = styled(({ className, ...props }: SelectProps) => (
      <BaseSelect {...props} MenuProps={{ PaperProps: { className } }} />
    ))(({ theme }) => ({
      backgroundColor: "red", // Added just for the example
      // backgroundColor: "transparent",
      backdropFilter: "blur(10px)"
    }));
    
    ...
    
    // Use as you normally would
    // <StyledSelect ... >
    
    

    Working CodeSandbox: https://codesandbox.io/s/styled-mui-select-and-paper-2dmpct?file=/demo.tsx

    Login or Signup to reply.
  2. We have faced similar issues while using styled-components to target child classes to create a base component. Sometimes there are multiple child components you want to target. It’s a bit tricky. You will face similar issues with components like Autocomplete, DatePicker, etc.
    So we start using two different approaches.

    ✅1️⃣ Create a base component using sx props:

    export const BaseSelect = (props: SelectProps) => {
        return (
           <Select
             {...props}
             sx={{
                bgcolor: 'green',
                ...props.sx, //spread your sx from props, so you can override these styles if needed
              }}
             MenuProps={{
                PaperProps: {
                   sx: {
                      bgcolor: 'red', //sx for Paper
                   },
                 },
               }}
             />
          )}
    
    
    //USAGE
    <BaseSelect
         value={age}
         label="Age"
         sx={{
           height: 100, //You can still use sx and override base styling if needed
         }}
       >
    

    ✅2️⃣ Create reusable sx variables:

    export const SELECT_BASE_SX: SxProps = {
      bgcolor: 'green',
    }
    
    export const PAPER_SX: SxProps = {
      bgcolor: 'red',
    }
    
    //USAGE
    <Select
      sx={{
        ...SELECT_BASE_SX,
        height: 100,
      }}
      MenuProps={{
        PaperProps: {
          sx: {
            ...PAPER_SX,
          },
        },
      }}
    />
    

    I hope it helps.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search