dmarr
dmarr

Reputation: 490

Am I on the right track with my Material UI AppBar?

I'm working on a header for my site, and want to use Material UI. The header includes a logo, some nav links, an avatar with dropdown, etc. My question revolves around styling the nav links right now. With Material-UI, do I need to apply classes to /every/ element I want to style? For example, I currently have an app that looks like this:

import React from 'react';
import AppBar from '@material-ui/core/AppBar';
import Avatar from '@material-ui/core/Avatar';
import CssBaseline from '@material-ui/core/CssBaseline';
import IconButton from '@material-ui/core/IconButton';
import Link from '@material-ui/core/Link';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import theme from './theme';
import { ThemeProvider } from '@material-ui/core/styles';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles(theme => ({
  root: {
    backgroundColor: '#202632',
  },
  headerLink: {
    padding: '10px 20px',
  }

}));

function App() {
  const [anchorEl, setAnchorEl] = React.useState(null);

  const handleClick = event => {
    setAnchorEl(event.currentTarget);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  const classes = useStyles();

  return (
    <div className="App">
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <AppBar className={classes.root}>
          <Toolbar className={classes.logo}>
            <img alt="Logo" src="/logo2.png" height={60} />
            <Link className={classes.headerLink} href="/dashboard">
              Solutions
            </Link>
            <Link className={classes.headerLink} href="/clientportal">
              Features
            </Link>
            <Link className={classes.headerLink} href="/pricing">
              Pricing
            </Link>
            <Link className={classes.headerLink}>
              Our team
            </Link>
            <Link className={classes.headerLink}>
              Blog
            </Link>
            <Avatar onClick={handleClick} onClose={handleClose}>
              DM
            </Avatar>
            <Menu anchorEl={anchorEl} open={Boolean(anchorEl)}>
              <MenuItem onClick={handleClose}>Item1</MenuItem>
              <MenuItem onClick={handleClose}>Item2</MenuItem>
              <MenuItem onClick={handleClose}>Item3</MenuItem>
            </Menu>
          </Toolbar>
        </AppBar>
      </ThemeProvider>
    </div>
  );
}

export default App;

The typical way I would style links is with CSS, using something like nav a { padding: 20px }, however that doesn't appear to be the idiomatic way with Material-UI. Maybe I have that assumption wrong so I wanted to verify here what the best approach for styling overrides looks like.

Thanks

Upvotes: 1

Views: 76

Answers (2)

Ryan Cogswell
Ryan Cogswell

Reputation: 80986

For this particular scenario, I would use withStyles to create a styled version of Link. This will have the same effect as psyrendust's answer, but using withStyles gets rid of all the boilerplate.

import React from ‘react’;
import Link from '@material-ui/core/Link';
import { withStyles } from '@material-ui/core/styles';

const AppBarLink = withStyles({ 
    root: {
        padding: '10px 20px'
    }
})(Link);

export AppBarLink;

Putting this in its own file and exporting it is only necessary if you want to leverage it from multiple files. If you are only using it in one file, then just define it there.

If you want to control props in addition to styles, you can leverage defaultProps as shown in the working example below:

import React from "react";
import Link from "@material-ui/core/Link";
import { withStyles } from "@material-ui/core/styles";

const AppBarLink = withStyles({
  root: {
    padding: "10px 20px"
  }
})(Link);
AppBarLink.defaultProps = {
  color: "secondary"
};

export default function App() {
  return (
    <div className="App">
      <Link>Here is Link (no padding or color override)</Link>
      <br />
      <AppBarLink>Here is AppBarLink</AppBarLink>
      <br />
      <AppBarLink color="primary">
        Here is AppBarLink with explicit color of primary
      </AppBarLink>
    </div>
  );
}

Edit Customize Material-UI component using withStyles

Upvotes: 0

psyrendust
psyrendust

Reputation: 1216

You could create a SFC for the Link.

import React from ‘react’;
import Link from '@material-ui/core/Link';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles(theme => ({
    headerLink: {
        padding: '10px 20px',
    }
}));

const AppBarLink = React.forwardRef(function AppBarLink({ children, className, ...props }, ref) {
    const classes = useStyles();
    return (
        <Link
            className={`${classes.headerLink} ${className}`}
            ref={ref}
            {...props}
        >
            {children}
        </Link>
    );
});

export AppBarLink;

Upvotes: 1

Related Questions