3
votes

What I'm trying to do:

I am trying to provide the user the option to provide custom styling to my EnhancedTable component by passing in a styles object containing properties such as headCellColor, headCellBackgroundColor, bodyCellColor, bodyCellBackgroundColor etc which can be used to color the cells in TableHead and TableBody.

In the TableHead component, I use a TableSortLabel in a way similar to what they've done in this material-ui docs example: https://material-ui.com/components/tables/#sorting-amp-selecting

I wish to custom color the text and the arrow icons on hover and when active based on the props provided by the user.

Let's see the colors of TableSortLabel in different situations: The color of the text is grey initially and there is no arrow. When mouse is hovered over it, a grey arrow appears and the text turns black. On clicking it, active state is set, the grey arrow turns black and the text turns black permanently until active state is removed.

What I've tried so far:

const useStyles = makeStyles({
  tableSortLabel: props => ({
    backgroundColor: "blue",
    color: props.headCellColor,
    fill: props.headCellColor,
    "&:hover": {
      backgroundColor: "blue"
    }
  })
});

function EnhancedTableHeadCell(props) {
  const { isActive, onHoverSortState, clickHandler, ...otherProps } = props;
  const classes = useStyles(props.styles);

  return (
    <FancyTableCell styles={props.styles} {...otherProps}>
      <TableSortLabel
        active={isActive}
        classes={{
          icon: classes.tableSortLabel,
          active: classes.tableSortLabel
        }}
        direction={onHoverSortState}
        onClick={clickHandler}
      >
        {props.children}
      </TableSortLabel>
    </FancyTableCell>
  );
}

This is what it looks like in the browser: https://i.postimg.cc/fW7W2MRB/c1.jpg

The first one is a normal header, the second is on hover and the third is when clicked (active state).

From what we can observe, the text color is totally unaffected by the color css property in all the three cases (normal, hover, active). On hover, backgroundColor only affects the icon and not the text. However, we can see that backgroundColor affects the text when it is active. Everything is going as expected with the icon. The only issue is with the text.

What could I be possible doing wrong? How can I solve my problem?

3

3 Answers

5
votes

What worked for me is:

const StyledTableSortLabel = withStyles((theme: Theme) =>
createStyles({
    root: {
      color: 'white',
      "&:hover": {
        color: 'white',
      },
      '&$active': {
        color: 'white',
      },
    },
    active: {},
    icon: {
      color: 'inherit !important'
    },
  })
)(TableSortLabel);

You can reference the following for increasing css specificity: https://material-ui.com/customization/components/#pseudo-classes

2
votes

Solution for your problem is following:

MuiTableSortLabel: {
      root: {
        color: textPrimary,

        // if you want to have icons visible permanently
        // '& $icon': {
        //   opacity: 1,
        //   color: primaryMain
        // },

        "&:hover": {
          color: primaryMain,

          '&& $icon': {
            opacity: 1,
            color: primaryMain
          },
        },
        "&$active": {
          color: primaryMain,

          // && instead of & is a workaround for https://github.com/cssinjs/jss/issues/1045
          '&& $icon': {
            opacity: 1,
            color: primaryMain
          },
        },
      },
    }

This restyling I use globally via my ThemeProvider, but you can of course use it individually in your single component by using "withStyles" HOC (see "BootstrapButton" in example)

0
votes

I could'nt find a proper way to do it so I came up with a temporary solution overriding the material ui css.

I added this to my global css:

.MuiTableSortLabel-root.MuiTableSortLabel-active,
.MuiTableSortLabel-root:hover,
.MuiTableSortLabel-icon {
  color: inherit !important;
}