/react-mui

Playin'

Primary LanguageJavaScript

react-mui

Playing with React and Material UI. See https://react-mui.metamn.now.sh/

Status

This is a work in progress document. Just fyi ... don't take actions yet based on it.

Summary

1. Use as less MUI components as possible

  • For content, Grid and Card should be well enough. Try to avoid Paper, Box.
  • For special elements like Navigation, Forms you'll find the examples here. (Or ask if they are missing)

MUI is the most popular Design System out there. Yet it has to be used with care.

Component functionality might easily overlap; the layout can be easily broken; code can become more complicated than necessary; and so on.

A minimalist approach can reduce all above problems and offer best practices.

2. Don't write CSS by hand

  • Use makeStyles only when adding responsiveness

Design Systems are meant to replace HTML and CSS written by hand. If your code code contains handwritten CSS then it should be refactored until all CSS code is simplified down to responsiveness.

It's rather adjust the Design System once (globally, by customizing the theme) than overwrite it many times (locally, by adding custom CSS - exceptions - in components).

Guidelines

Set up

<>
  <CssBaseline />
  <Home />
</>

Page containers

<Container className="Home" maxWidth={false}>

Page layout

  • https://material-ui.com/components/grid/#grid
  • Grids are defining the page layout. Their usage is mandatory.
  • Every element on the page has to be wrapped into <Grid item> component.
  • Grid items (even a single one) has to be wrapped into a Grid container component.
  • Spacing is set up once at container level. There is no spacing set at item level.
<Grid container className="Hero" spacing={1}>
  <Grid item xs={12}>
	<Card className={classes.card}>
	...
  </Grid>
</Grid>
  • The grid is set up in the current / parent / container component following the single responsibility principle.
  • Child components have no responsibility to align themselves to their parents and siblings. The parent container has to set up the grid, alone.
  • In this example Header, Hero, Features are all aligned to the grid even if they don't have any Grid components inside.
<Grid container spacing={1}>
  <Grid item xs={12}>
    <Header />
  </Grid>
  <Grid item xs={12}>
    <Hero />
  </Grid>
  <Grid item xs={12}>
    <Features />
  </Grid>
</Grid>

Content

  • There are many types of elements which can be displayed on a webpage: content, navigation, inputs (forms), notifications, decorations (icons, background images, ...) and so.
  • Content elements are anything information: articles, descriptions, product plans, list of products, etc. - Usually what we fetch from the API / database.
  • Content elements should be all Cards whenever possible.
  • Simple data display components (Avatar, Typography, List, Table etc ...) shouldn't be thrown inside a grid. They will break the positioning. Instead these elements should be wrapped into a content (Card) element.
<Grid container className="Features" spacing={3}>
  <Grid item xs={12}>
    {/*
		When a Typography is just thrown there the grid will be broken
		<Typography variant="h6" component="h3">
		  Features
		</Typography>
	*/}
    <Card>
      <CardContent>
        <Typography variant="h6" component="h3">
          Features
        </Typography>
      </CardContent>
    </Card>
    {items}
  </Grid>
</Grid>

Responsiveness

Inside makeStyles

theme.breakpoints
const useStyles = makeStyles(theme => ({
  dashboard: {
    "& .dashboardContentContainer": {
      ...

      [theme.breakpoints.down("lg")]: {
        ...
      },

      [theme.breakpoints.down("md")]: {
        ...
      }
    }
  }
}));
react-responsive
const useStyles = makeStyles(theme => ({
  card: {
    display: "flex",

    [`${Media.portrait}`]: {
      flexDirection: "column"
    },

    [`${Media.landscape}`]: {
      alignItems: "center"
    }
  },
  media: {
    width: 512,
    height: 512,

    [`${Media.landscape}`]: {
      order: 2
    }
  }
}));

Outside makeStyles

const isPortrait = useMediaQuery("(orientation: portrait)");

Dark mode

// This is not legible
<Button color="primary">Learn More</Button>

In this project

Header / AppBar

  • https://material-ui.com/components/app-bar/
  • Outside Material UI it's called Header
  • Material UI calls it AppBar
  • Let's be general and have a Header component featuring an AppBar
  • AppBar it's just a container of the <header> type. It needs to be filled with a Toolbar
  • AppBar position by default is fixed which is cumbersome. Let's change it to static or relative
<AppBar className="Header" position="static">
  <Toolbar>...</Toolbar>
</AppBar>

Toolbar

Menu

Hero

Features