Styling BottomNavigation in React.js Material-UI
Asked Answered
W

3

11

How do I change the color of the icon and text of the selected link (Home in this example) to red and the color of the icon and text of the inactive links (Course and Authors in this example) to green? The docs are very thin.

enter image description here

class MyBottomNavigation extends Component {

  render() {
    return (
      <Paper zDepth={1}>
        <BottomNavigation selectedIndex={this.state.selectedIndex}>

          <BottomNavigationItem
            label="Home"
            icon={recentsIcon}
          />

          <BottomNavigationItem
            label="Course"
            icon={favoritesIcon}
          />

          <BottomNavigationItem
            label="Authors"
            icon={nearbyIcon}
          />
        </BottomNavigation>
      </Paper>
    )
  }
}

export default MyBottomNavigation
Wrote answered 26/1, 2019 at 2:11 Comment(0)
R
20

There are three separate sources of information for most Material-UI components:

Each component documents within the API documentation the classes that you can pass in via the classes property to override styles for different aspects of the component.

In this case the component we care about is BottomNavigationAction. In the CSS portion of the API documentation you'll find:

root Styles applied to the root element.

selected Styles applied to the root element if selected.

Seeing this you might first try:

const styles = {
  root: {
    color: "green"
  },
  selected: {
     color: "red"
  }
};

And that almost does the trick. The inactive actions are green, but the selected action has red text, but the icon color was unaffected. When the styling doesn't work quite as you expected the next place to look is the source code to see how the styling is done in the component.

Below is a simplified version of the BottomNavigationAction styles (I've only included the parts relevant to controlling these two colors):

export const styles = theme => ({
  /* Styles applied to the root element. */
  root: {
    color: theme.palette.text.secondary,
    '&$selected': {
      color: theme.palette.primary.main,
    },
  },
  /* Styles applied to the root element if selected. */
  selected: {},
});

If we model our overrides off of how this is structured we find success. The final result looks like the following if using withStyles with v4 of MUI (v5 example further down):

import React from "react";
import Paper from "@material-ui/core/Paper";
import BottomNavigation from "@material-ui/core/BottomNavigation";
import BottomNavigationAction from "@material-ui/core/BottomNavigationAction";
import RestoreIcon from "@material-ui/icons/Restore";
import FavoriteIcon from "@material-ui/icons/Favorite";
import LocationOnIcon from "@material-ui/icons/LocationOn";
import { withStyles } from "@material-ui/core/styles";

const styles = {
  root: {
    color: "green",
    "&$selected": {
      color: "red"
    }
  },
  selected: {}
};

class MyBottomNavigation extends React.Component {
  render() {
    const actionClasses = this.props.classes;
    return (
      <Paper>
        <BottomNavigation value={1} showLabels={true}>
          <BottomNavigationAction
            classes={actionClasses}
            label="Home"
            icon={<RestoreIcon />}
          />

          <BottomNavigationAction
            classes={actionClasses}
            label="Course"
            icon={<FavoriteIcon />}
          />

          <BottomNavigationAction
            classes={actionClasses}
            label="Authors"
            icon={<LocationOnIcon />}
          />
        </BottomNavigation>
      </Paper>
    );
  }
}
export default withStyles(styles)(MyBottomNavigation);

Edit wq02759kk

Here's an equivalent example for v5 of MUI using styled instead of withStyles:

import React from "react";
import Paper from "@mui/material/Paper";
import BottomNavigation from "@mui/material/BottomNavigation";
import MuiBottomNavigationAction from "@mui/material/BottomNavigationAction";
import RestoreIcon from "@mui/icons-material/Restore";
import FavoriteIcon from "@mui/icons-material/Favorite";
import LocationOnIcon from "@mui/icons-material/LocationOn";
import { styled } from "@mui/material/styles";

const BottomNavigationAction = styled(MuiBottomNavigationAction)(`
  color: green;
  &.Mui-selected {
    color: red;
  }
`);

class MyBottomNavigation extends React.Component {
  render() {
    return (
      <Paper>
        <BottomNavigation value={1} showLabels={true}>
          <BottomNavigationAction label="Home" icon={<RestoreIcon />} />

          <BottomNavigationAction label="Course" icon={<FavoriteIcon />} />

          <BottomNavigationAction label="Authors" icon={<LocationOnIcon />} />
        </BottomNavigation>
      </Paper>
    );
  }
}
export default MyBottomNavigation;

Edit BottomNavigationAction color

Here are some additional resources here in Stack Overflow of some similar questions I've answered regarding other MUI components:

Rondelet answered 26/1, 2019 at 5:36 Comment(2)
Is this deprecated solution for v5 mui.com/styles/basics ?Eyeleen
@IvailoBardarov I've added a v5 example.Rondelet
R
2

An alternative, though similar solution:

If your element's colors are being defined by the theme (and we can see that they are, via @ryan-cogswell 's explanation above, or at this link available via the API), instead of overriding the styles, we can simply set a custom theme:

const navTheme = createMuiTheme({
    palette: {
        primary: {
            main: '#00FF00'
        },
        text: {
            secondary: '#FF0000'
        }
    }
})

And wrap the navbar in a <ThemeProvider theme={navTheme}> tag set.

Note that, for the BottomNavigation element, the background color is not specified, so you'll still need to use custom styles to do that.

Rattoon answered 19/4, 2020 at 17:28 Comment(0)
K
2

Since 5.* version is posible who your use sx props

Component BottomNavigation

<BottomNavigation
  sx={{
    bgcolor: 'purple',
    '& .Mui-selected': {
      '& .MuiBottomNavigationAction-label': {
        fontSize: theme => theme.typography.caption,
        transition: 'none',
        fontWeight: 'bold',
        lineHeight: '20px'
      },
      '& .MuiSvgIcon-root, & .MuiBottomNavigationAction-label': {
        color: theme => theme.palette.secondary.main
      }
    }
  }}
>
...
</BottomNavigation>

Knapsack answered 7/2, 2022 at 16:3 Comment(1)
You can write color: 'secondary.main' instead of that arrow function.Spatial

© 2022 - 2024 — McMap. All rights reserved.