INTRODUCING

Material UI Layout

Version 2.0-beta

Layout is a group of Material-UI components that are enhanced and combined to create dynamic, easy-to-maintain and easy-to-code as much as possible.

Let's start with Why?

I created this because

  1. It took me a lot of time to initialize dashboard layout when I have new projects and I’m sure that a lot of you guys agree with me.
  2. Sometimes it is hard to refactor because the structure is so poor because someone isn’t deeply understand what he/she was doing, as a result, rewrite the whole layout (it actually happened, at least in my experience).
  3. Because we need to be fast to let others continue our work, we frequently write poor and a lot of code. However, we say we don’t have time to fix them. Eventually, spend all day paying technical debts.
Objectives

It must be easy enough to use, however still be able to adjust to compat with real word examples and usages. More importantly, it need to follow Material specs since we are 100% based on Material-UI with no other styling libraries. Last but not least, responsive is a must.

Solution

Separate layout into 5 core components

  • Root
  • Header (AppBar)
  • Sidebar (Drawer)
  • Content
  • Footer

Root will provide context to other components to sync states across them.

Behavior of your layout will be controlled by using config (just a plain object) that will be injected to the Root.

Presets is a set of predefined config that I came up with after researching a lot of the real world websites and also the official Material specs

How to use

Step 1

install dependencies

yarn add @material-ui/core @material-ui/icons @mui-treasury/layout

Step 2

In your App.js, add this codes and it is done.

import React from 'react';
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import Toolbar from '@material-ui/core/Toolbar';
import IconButton from '@material-ui/core/IconButton';
import {
Root,
Header,
HeaderOffset,
Sidebar,
Content,
Footer,
CollapseBtn,
CollapseIcon,
SidebarTrigger,
SidebarTriggerIcon,
useSidebarStyles,
useHeaderStyles,
} from '@mui-treasury/layout';
const baseTheme = createMuiTheme();
const App = () => {
const sidebarStyles = useSidebarStyles();
const headerStyles = useHeaderStyles();
return (
<ThemeProvider theme={baseTheme}>
<Root>
<Header>
<Toolbar>
<SidebarTrigger className={headerStyles.leftTrigger}>
<SidebarTriggerIcon />
</SidebarTrigger>
More header
</Toolbar>
</Header>
<HeaderOffset />
<Content>
Add Content here!
</Content>
<Sidebar>
Sidebar goes here!
</Sidebar>
<Footer>
Footer!
</Footer>
</Root>
</ThemeProvider>
);
};
export default App

If you still hesitate, this code sandbox is the playground that you can try. Happy treasuring!

Congratulations!

quite easy, isn't it

Now try resize the browser screen in sandbox, the drawer is automatically hidden with smooth transition.

Time to Decorate

use config (a prop of Root) to adjust all of the behaviors that you want.

<Root
config={{
// adjust behavior here!
}}
>

Adjust Nav Width

image from material.io

Nav width accepts number or object (responsive). For object, specify number for each screen (if some screen is not provided, it will fallback to available smaller screen or 256px if not match any screen)

config={{
// (as px) default is 256
sidebar: { width: 256 },
}}

Collapsible Nav

Nav can be collapse to smaller width to give more space to Content. Add “collapsible: true” to the config and"collapsedWidth: number" (width after collapsed)

config={{
// default is true
sidebar: { collapsible: true },
}}

Clipped Header

image from material.io

If you want to make full width Header while having permanent Drawer. Add “clipped: true” to the config.

config={{
// default is true
header: { clipped: true },
}}

Menu Icon

image from material.io

If you want to add a menu icon to the Header when the drawer variant is persistent or temporary to open it.

// import SidebarTrigger
// import headerStyles
<Header>
<Toolbar>
<SidebarTrigger className={headerStyles.leftTrigger}>
<SidebarTriggerIcon />
</SidebarTrigger>
More header
</Toolbar>
</Header>
Presets

Because I know that many people don’t want to do the config thing by yourself. I had prepared 3 presets that are widely used in many modern websites or CMS

import {
defaultLayoutPreset,
standardLayoutPreset,
fixedLayoutPreset,
contentBasedLayoutPreset,
cozyLayoutPreset,
muiTreasuryPreset,
} from '@mui-treasury/layout'

Default Layout

  • Nav is permanent & collapsible
  • Nav elevation is full height
  • Nav hidden at Tablet screen (< 600px)

Fixed Layout

  • Nav is permanent & collapsible
  • Nav elevation is clipped
  • Nav hidden at Tablet screen (< 960px)
import {
fixedLayoutPreset,
} from '@mui-treasury/layout';

Content Based Layout

  • Nav is not permanent, uncollapsible but can be open & close
  • No breakpoint, all screen is the same
import {
contentBasedLayoutPreset,
} from '@mui-treasury/layout';

Cozy Layout

  • Nav is permanent beyond breakpoint
  • Nav width is bigger in desktop than in tablet
  • Nav hidden at mobile screen (< 600px)
  • Nav is modal mode in mobile screen
import {
cozyLayoutPreset,
} from '@mui-treasury/layout';
Customization

Want to build your own layout? we have built the tool for you. Layout Builder

API

Each of the component’s API and props will be described soon.

Feedback & Request

Feel free to give me feedbacks and comments. If you need anything more than this. Let me know via twitter (@siriwatknp) or mail me directly. I will do my best to help.