Material-ui: How to set active link color in ListItem?

Created on 28 Aug 2015  路  16Comments  路  Source: mui-org/material-ui

As seen at http://material-ui.com/#/components/appbar (the appbar link is pink)
can't seem to get it working in my code.. the active link is still black.

bug 馃悰

Most helpful comment

If anyone runs across this, I solved it like so:

import { PureComponent } from 'react';
import { NavLink } from 'react-router-dom';
import { withStyles } from 'material-ui/styles';
import { ListItem, ListItemIcon, ListItemText } from 'material-ui/List';

@withStyles({
  active: {
    backgroundColor: 'rgba(255, 255, 255, 0.12)',
  },
})
export default class ListItemLink extends PureComponent {
  render() {
    const { classes, icon, title, to } = this.props;

    return (
      <ListItem button component={NavLink} to={to} activeClassName={classes.active}>
        <ListItemIcon>{icon}</ListItemIcon>
        <ListItemText primary={title} />
      </ListItem>
    );
  }
}

All 16 comments

Having same problem here. Anyone got workarounds? Because the ListItem component itself doesn't seem to have any properties that allow it to behave like a MenuItem (i.e. selected property, color change, etc.)

+1

@raptoria @desduvauchelle : A work-around for that would be to handle this in a function for the onClick event and assign a style to the ListItem then. Do let us know if that helps.

Let us know if that helps.

I am closing this for now. Do let us know if the above suggestion helps or not.

Doesn't work because:
I want to set backgraund color for active ListItem component. Background color trigges when I do click, but at the same moment onHover event fires which change background color to gray. When I move pointer event onMouseLeave clears background (set it to 'none').

Please reopen this issue, I am facing this same problem, many people have asked this but I am not being able to find an appropriate answer.

I am assuming this issue is related to the very latest version of material ui. I found a work around but its not 'great', mainly because I expected this to be one of the default things a List Item would actually do.

So here it goes:

first make sure you have a class for an activle list Item:

function styleDefinition(theme){
  return {
    activeItem: {
      backgroundColor: theme.palette.primary[100]
    },
    item: {}
  };
}

var styles = createStyleSheet('YourList',styleDefinition);

Use the global theme object to select a color in your palette.

when you do your mapping of data to list items, put the 'correct' class on.

    let currentClass = (item.id === selected.id) ?
        classes.activeItem :
        classes.Item;

and ...

          <ListItem
              button
              className={currentClass}
              key={`item-${id}`}>
                <ListItemText
                      primary={`primary`}
                      secondary={`secondary`}
                />
          </ListItem>

I want to say this is not perfect, clicking the list item again still shows the material-y growing animation. you can always set the diabled property too ( and that's a little more accurate) ,but of course it looks,,, you know..disable. You want it to look 'active' and also not 'be active again' if you click it repeatedly. Not sure how to stop the animation from firing again, but still 'look' active.

If anyone runs across this, I solved it like so:

import { PureComponent } from 'react';
import { NavLink } from 'react-router-dom';
import { withStyles } from 'material-ui/styles';
import { ListItem, ListItemIcon, ListItemText } from 'material-ui/List';

@withStyles({
  active: {
    backgroundColor: 'rgba(255, 255, 255, 0.12)',
  },
})
export default class ListItemLink extends PureComponent {
  render() {
    const { classes, icon, title, to } = this.props;

    return (
      <ListItem button component={NavLink} to={to} activeClassName={classes.active}>
        <ListItemIcon>{icon}</ListItemIcon>
        <ListItemText primary={title} />
      </ListItem>
    );
  }
}

@eliperelman Thanks for your answer. I have a route that is the root URL, and it seems to always be matched. How can I prevent it from always making the "home/dashboard" route as active, even thou it is on a different route?

@johnnyPescarul you have to set "exact" to point to exact route. e.g.
<ListItem button component={NavLink} exact to={to} activeClassName={classes.active} >. . .

@fionaDawn's answer worked for me with classes.active set to:

active: {
  backgroundColor: theme.palette.action.selected
}

Can anyone advise on also changing the props of the ListItemText (specifically making it bold or changing the color)? Given the code from an above comment:

       return (
      <ListItem button component={NavLink} to={to} activeClassName={classes.active}>
        <ListItemIcon>{icon}</ListItemIcon>
        <ListItemText primary={title} />
      </ListItem>
    );

I figure that I would have to verify whether it is active by checking match, wrap the Link in a Route and then use primaryTypographyProps with the color/style I want. Basically, I would have to copy the logic in NavLink. Unless there is another easier way?

What if I want each ListItem with a different active state colour? Any fancy way to do or have to override by inline style?

theme.palette.action.selected

with @fionaDawn 's answer and this,

theme is undefined?

@D3athSpank try this:

import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';

const styles = theme => ({
  active: {
    backgroundColor: theme.palette.action.selected
  },
});

class MyComponent extends Component {
// More stuff here...
}

MyComponent.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(MyComponent);
const  NavLinkMui = (props: any) => {
    const { forwardedRef, ...otherProps } = props
    return <NavLink {...otherProps} ref={forwardedRef} activeClassName="Mui-selected" />
}


<ListItem key={item.title} component={NavLinkMui} exact to={item.url}>
Was this page helpful?
0 / 5 - 0 ratings