Issue
I am trying to implement my own icon for material ui select component. So far i have managed to change default icon with use of "IconComponent" MU select attribute.
But the newIcon is not rotating while menu list is opened, as in case of default icon, and moreover, menu with values wont open upon clicking it. ListIteam appear only if I click the select component itself, but not the new icon.
I have tested two different icons (anotherIcon and newIcon) and the problem remains.
const newIcon = (
<svg
width="38"
height="38"
viewBox="0 0 38 38"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect x="0.5" y="0.5" width="37" height="37" rx="9.5" stroke="#222426" />
<svg
width="18"
height="12"
x="10"
y="13"
viewBox="0 0 18 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0.66732 0.999999L8.72964 10.8681C8.76363 10.9095 8.80536 10.9428 8.85208 10.9655C8.89879 10.9882 8.94943 11 9.00065 11C9.05187 11 9.10251 10.9882 9.14922 10.9655C9.19594 10.9428 9.23767 10.9095 9.27167 10.8681L17.334 1"
stroke="#222426"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</svg>
);
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">Age</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={age}
label="Age"
onChange={handleChange}
IconComponent={() => <div className="test">{newIcon}</div>}
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
I have also tried to manually overdrive select iconOpen class in order to get icon transform and rotate by 180deg, (as in this case React JS Material UI Select IconComponent (Dropdown Icon) avoid rotating) but it also didnt work.
Anyone knows why new icons dont rotate and how to fix this, along with making menu open upon clicking newIcon itself ?
Heres the demo : https://codesandbox.io/s/basicselect-material-demo-forked-d946k1?file=/demo.js
Solution
The icon component you are specifying (() => <div className="test">{newIcon}</div>) ignores all props that are passed to it. This means that it will not receive any styles that MUI tries to apply to it.
The styles that MUI applies control rotating the icon when the Select is open (via transform: 'rotate(180deg)') and also cause clicks to bypass the icon and act on the Select underneath instead (via pointerEvents: 'none').
You can fix this by defining the icon component in a manner that spreads the props it receives onto the <svg> element:
const NewIcon = (props) => (
<svg
{...props}
width="38"
height="38"
viewBox="0 0 38 38"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect x="0.5" y="0.5" width="37" height="37" rx="9.5" stroke="#222426" />
<svg
width="18"
height="12"
x="10"
y="13"
viewBox="0 0 18 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0.66732 0.999999L8.72964 10.8681C8.76363 10.9095 8.80536 10.9428 8.85208 10.9655C8.89879 10.9882 8.94943 11 9.00065 11C9.05187 11 9.10251 10.9882 9.14922 10.9655C9.19594 10.9428 9.23767 10.9095 9.27167 10.8681L17.334 1"
stroke="#222426"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</svg>
);
and then specify this without any further wrapping as IconComponent={NewIcon}.
Here's a modified version of your sandbox:
import * as React from "react";
import Box from "@mui/material/Box";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";
const NewIcon = (props) => (
<svg
{...props}
width="38"
height="38"
viewBox="0 0 38 38"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect x="0.5" y="0.5" width="37" height="37" rx="9.5" stroke="#222426" />
<svg
width="18"
height="12"
x="10"
y="13"
viewBox="0 0 18 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0.66732 0.999999L8.72964 10.8681C8.76363 10.9095 8.80536 10.9428 8.85208 10.9655C8.89879 10.9882 8.94943 11 9.00065 11C9.05187 11 9.10251 10.9882 9.14922 10.9655C9.19594 10.9428 9.23767 10.9095 9.27167 10.8681L17.334 1"
stroke="#222426"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</svg>
);
export default function BasicSelect() {
const [age, setAge] = React.useState("");
const handleChange = (event) => {
setAge(event.target.value);
};
return (
<Box sx={{ minWidth: 120 }}>
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">Age</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={age}
label="Age"
sx={{ "& .MuiSelect-icon": { top: 10 } }}
onChange={handleChange}
IconComponent={NewIcon}
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</Box>
);
}
Answered By - Ryan Cogswell
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.