mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.86k stars 32.26k forks source link

[material-ui][Stepper] Add props to StepIcon so we can change the error and completed Icon. #37529

Open willibix opened 1 year ago

willibix commented 1 year ago

Duplicates

Latest version

Summary 💡

So I was ask to change the StepIcon icon when the state of the step is completed or error.

The default step icon in itself is fine with the numbering logic and all, and can also be overwrite with a static icon with the icon props instead of number. So all this is good. But if you want to keep this logic and all, but use a different static icon for error or completed step, then I did not find any elegant way of doing so. I think simply adding the props iconError and iconCompleted would solve this problems and make it more elegant and easier to do so.

At the moment to do this I had to make my own custom StepIcon component where I take your original code and replace the StepIconRoot "as" props with my own custom icon in the error and completed condition. Then feed this custom component to the StepIconComponent props of the StepLabel component.

Unless there a better way of doing this, I think my proposition is the simplest way to have an elegant solution for this use case. Also not sure why those 2 icon are "hardcoded" in the first place.

Examples 🌈

Here the link to the original code i'm referring to (line 74 and 86):

https://github.com/mui/material-ui/blob/master/packages/mui-material/src/StepIcon/StepIcon.js

Motivation 🔦

Simply want an elegant solution for this use case where I don't have to use one of your component original code and change 2 line of it, make the maintenance of this component harder since I would have to update it every time you update it on your side.

I could probably do a PR for this, but wanted to discuss it here before to make sure what i'm saying make sense and if there not a beater solution already in place to solve this use case.

brijeshb42 commented 1 year ago

I agree that right now, these two icons are hardcoded if you are directly trying to use StepIcon component. And if you pass icon as a React Element, the original svg structure with its classes are completely discarded and it only renders the passed icon. Demo here. A PR would be welcome here to customize the as prop

willibix commented 1 year ago

I did find a more elegant solution then what I initially suggested, after seeing your comment @brijeshb42 it gave me the idea to do this.

import React from "react";
import { StepIcon, SvgIcon, StepIconProps } from "@mui/material";
import { UisExclamationTriangle, UisCheckCircle } from "@iconscout/react-unicons-solid";

function CustomStepIcon(props: StepIconProps) {
    const { error, completed } = props;

    if (error) {
        return <StepIcon icon={<SvgIcon component={UisExclamationTriangle} color="error" sx={{ margin: "-2.4px", fontSize: "28.8px" }} />} />;
    }

    if (completed) {
        return <StepIcon icon={<SvgIcon component={UisCheckCircle} color="primary" sx={{ margin: "-2.4px", fontSize: "28.8px" }} />} />;
    }

    // eslint-disable-next-line react/jsx-props-no-spreading
    return <StepIcon {...props} />;
}

export default CustomStepIcon;

But I still think my proposition make sense and should be implemented. Just to get rid of the hardcoded icon it would be worth it.