Search code examples
reactjsmaterial-uilabelcustomizationgoogle-material-icons

Is there any way to display a close icon and tick icon together in material ui chip component


Material ui chip component documentation shows a close icon or done icon at a time. Is there any way to display both together

  <Chip
    label="name"
     onDelete={handleDelete}
     />

I tried with adding DoneIcon ,but it is displayed in the left side.I want both DoneIcon and delete icon in the right side of label inside chip.

     <Chip
    label="name"
     onDelete={handleDelete}
     icon={<DoneIcon/>}
     />

Solution

  • Yes, try this. Create a component that will contain these two icons. I created one called Icons and it's a basic div that contains both the DoneIcon and the CancelRoundedIcon.

    Then pass <Icons /> into the deleteIcon prop of the Chip component. You must also have the onDelete prop for this to show.

    import Chip from "@material-ui/core/Chip";
    import DoneIcon from "@material-ui/icons/Done";
    import CancelRoundedIcon from "@material-ui/icons/CancelRounded";
    
    const Icons = () => (
      <div>
        <DoneIcon />
        <CancelRoundedIcon />
      </div>
    );
    
    <Chip
      label="Basic"
      variant="outlined"
      onDelete={handleDelete}
      deleteIcon={<Icons />}
    />;
    

    UPDATE

    Just realised you probably wanted a different onClick handler for the DoneIcon instead of deleting. My previous solution would mean clicking the DoneIcon will also run the handleDelete function.

    A Chip can have a label, icon and deleteIcon prop. It appears in this order from left to right: icon, label and deleteIcon.

    Chip with icon at left

    If you inspect the Chip component in your dev tools, you'll see that the Chip root component is a div that contains these the three elements i.e. svg of the icon, the span for the label and svg for the deleteIcon. The div has the CSS property display: inline-flex, which means the three elements are flex items and can be re-ordered. Read more about ordering flex items here: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Ordering_Flex_Items

    To do this, we have to modify the existing style of the Chip. We do this by creating a custom style using makeStyles and applying it to the root class of the Chip component.

    You can also add an onClick handler to the component you're passing to the icon prop. In this case, it's the <DoneIcon />.

    import { makeStyles } from "@material-ui/core/styles";
    
    const useStyles = makeStyles({
      chipRoot: {
        "& .MuiChip-icon": {
          order: 1, // the label has a default order of 0, so this icon goes after the label
          marginRight: "10px", // add some space between icon and delete icon
          cursor: "pointer"
        },
        "& .MuiChip-deleteIcon": {
          order: 2 // since this is greater than an order of 1, it goes after the icon
        }
      }
    });
    
    const MyComponent = () => {
    
      const classes = useStyles();
    
      const handleClick = (e) => {
        // do something
      }
      
      return (
        <Chip
          classes={{
            root: classes.chipRoot
          }}
          label="Label"
          variant="outlined"
          onDelete={handleDelete}
          deleteIcon={<CancelRoundedIcon />}
          icon={<DoneIcon onClick={(e) => handleClick(e)} />}
        />
      )
    }
    

    Result

    Chip with icon next to deleteIcon