Stiven Ballshi
Stiven Ballshi

Reputation: 81

Mui Text Field . When changing icon , it's not clickable

I am using a MUI Text Field component. I added a select prop so i make it a select with dropwon values and a dropdown icon . I wanted to change the dropdown Icon to a custom icon i have in figma . The problem is that when i chage it to a custom icon , i cannot click it anymore and i've tried multiple solutions like the one shown in the snippet below but it's still not clickable . This is happening for all my text field everywhere in the App . Can someone help me with this who has used MUI before and has dealt with this thing , thanks !

/* eslint-disable react/jsx-props-no-spreading */
import React from 'react';
import { MenuItem, TextField } from '@mui/material';
import '../../assets/utils/_groupbySelect.scss';

const MuiSelect = ({
  label,
  value,
  disabled,
  onChange,
  children,
  defaultValue,
  withNoneOption,
  className,
}: MuiSelectProps) => {

  const NewIcon = (props) => (
    <svg
      {...props}
      style={{ width: '11px', height: '11px', marginTop: '2px' }}
      className="sorter-dropdown"
      width="8"
      height="5"
      viewBox="0 0 8 5"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
    >
      <path d="M1 1L4 3.5L7 1" stroke="#4C4C4D" strokeLinecap="round" />
    </svg>
  );

  return (
    <TextField
      select
      defaultValue={defaultValue}
      label={label}
      disabled={disabled}
      className={className}
      value={value}
      onChange={onChange}
      variant="standard"
      SelectProps={{
        IconComponent: () => <NewIcon />,
      }}
      InputProps={{
        disableUnderline: true,
      }}
      fullWidth
      size="small"
    >
      {withNoneOption ? isNoneOption : children}
    </TextField>
  );
};
export default MuiSelect;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Upvotes: 3

Views: 2389

Answers (2)

Ryan Cogswell
Ryan Cogswell

Reputation: 80966

There are two issues with NewIcon in your example code. Both of those issues prevent the application of the className prop that MUI tries to provide to the icon component. The styles that MUI applies cause the click to pass through the icon and cause the appropriate action on the select input (e.g. open/close the select).

The first issue is how you are using it:

IconComponent: () => <NewIcon />

In this code you are wrapping NewIcon with another component layer (via the arrow function), and that wrapper component is not passing any props along to NewIcon, so the className prop from MUI never gets there. You should remove this wrapper layer and just specify:

IconComponent: NewIcon

The second problem is the following portion of NewIcon:

<svg
      {...props}
      className="sorter-dropdown"

This will cause props.className to be overwritten by className="sorter-dropdown". If you were to reverse the order of className="sorter-dropdown" and {...props}, the MUI class name would get through, but then you would lose any styles that you apply via sorter-dropdown. The solution is to combine those two class names:

 <svg
    {...props}
    className={`${props.className} sorter-dropdown`}

Here's a code sandbox demonstrating this approach: https://codesandbox.io/s/custom-select-icon-0xj079?file=/src/App.js.

Upvotes: 2

beepboopiamabot
beepboopiamabot

Reputation: 70

I couldn't get IconComponent to work, but you could try this:

Use the InputAdornment prop that TextField has in InputProps. The docs have some examples of how to use it here:

https://mui.com/material-ui/react-text-field/#InputWithIcon.js

https://mui.com/material-ui/api/outlined-input/

For example:

<TextField
      select
      defaultValue={defaultValue}
      label={label}
      disabled={disabled}
      className={className}
      value={value}
      onChange={onChange}
      variant="standard"
      InputProps={{
          disableUnderline: true,
          endAdornment: ( // or startAdornment
            <InputAdornment position="end"> // or "start"
              <NewIcon />
            </InputAdornment>
          ),
      }}
      fullWidth
      size="small"
    >
      {withNoneOption ? isNoneOption : children}
</TextField>

Upvotes: 1

Related Questions