Basic tutorial

Dashboard Layout

This tutorial will take you through basic installation and configuration of mui-layout.

Let’s use create-react-app to kickstart the project

npx create-react-app my-layout

when the process is done, install packages

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

// note: this tutorial is based on @mui-treasury/layout v4 (not alpha),
// please recheck package.json after installation

Now, when you run yarn start, you will see react logo in the browser.

image

We will start by setting up config for our layout first. Open file /src/App.js, then add this code below last import line

import React from 'react';
// ...
import Layout from '@mui-treasury/layout';const scheme = Layout();
const App = () => {
  // ...
};

Let think about Header for a sec. In this tutorial, we want to have Header that stick to the top of the page when user scroll. scheme that return from calling Layout expose a function called configureHeader to let us specifically add config to Header part. This function accept a callback that provide you a builder. Builder is used to setup responsive config. Let’s take how it looks like.

import Layout from '@mui-treasury/layout';

const scheme = Layout();

scheme.configureHeader(builder => {
  builder.registerConfig('xs', {
    position: 'sticky',
  });
});

Let me translate it to human language. By doing this, we can say that we want to create a Header that has position: sticky from breakpoint xs up.

Note: by default Header is created with id: 'header' but you can choose your own id by builder.create('your_id').registerConfig(...)

I want to pause here for a moment and emphasize the word up. This is quite important for you to know that this library follow mobile first responsive design which means the config you define at a breakpoint will affect at that breakpoint and up. You can override config by specifying new config at bigger breakpoint. Here is a list of breakpoint according to Material-UI

value         |0px     600px    960px    1280px   1920px
key           |xs      sm       md       lg       xl
screen width  |--------|--------|--------|--------|-------->
range         |   xs   |   sm   |   md   |   lg   |   xl

Ex. I want my Header to not stick to top when scroll at laptop screen

import Layout from '@mui-treasury/layout';

const scheme = Layout();

scheme.configureHeader(builder => {
  builder
    .registerConfig('xs', {
      position: 'sticky',
    })
    .registerConfig('md', {      position: 'relative', // won't stick to top when scroll down    });});

Next, let’s move on to Sidebar configuration.

// scheme.configureHeader(...)

scheme.configureEdgeSidebar(builder => {  builder    .create('unique_id', { anchor: 'left' })    .registerTemporaryConfig('xs', {      anchor: 'left',      width: 'auto', // 'auto' is only valid for temporary variant    });});

The api is similar to Header. One thing worth mentioning here is that the order of calling scheme.configure... is not important. You can also configure sidebar before header if you are more comfortable with. For the code above, we want to create EdgeSidebar on the left of browser with temporary variant for all breakpoints (same as saying xs up)

Since layout can have multiple sidebars, you need to specify id by using builder.create('some_id') first.

see what each variant looks like real quick here

At this point, let’s render these components on the page so that you don’t get surprise at the end. But before we can use components, we need to install css-in-js library first. pick one from styled-components, @emotion/styled or glamorous.

styled-components is recommended because Material-UI v5 will adopt this lib

yarn add styled-components
import React from 'react';
import styled from 'styled-components';import Layout, { Root, getHeader, getDrawerSidebar } from '@mui-treasury/layout';import Toolbar from '@material-ui/core/Toolbar';import CssBaseline from '@material-ui/core/CssBaseline';
const Header = getHeader(styled);const DrawerSidebar = getDrawerSidebar(styled);
const scheme = Layout();

scheme.configureHeader(builder => {
  builder
    .registerConfig('xs', {
      position: 'sticky',
    })
    .registerConfig('md', {
      position: 'relative', // won't stick to top when scroll down
    });
});

scheme.configureEdgeSidebar(builder => {
  builder
    .create('unique_id', { anchor: 'left' })
    .registerTemporaryConfig('xs', {
      width: 'auto', // 'auto' is only valid for temporary variant
    });
});

const App = () => {
  return (
    <Root scheme={scheme}>      <CssBaseline />      <Header>        <Toolbar>Header</Toolbar>      </Header>      <DrawerSidebar sidebarId={'unique_id'}>        sidebar id is required sidebar content      </DrawerSidebar>    </Root>  );
};

export default App;

Note: sidebarId is required on any Sidebar because you can have multiple sidebars in your app, so it is necessary to tell the component which sidebar config are you referring to

Save, and run yarn start. You should see something like this on your screen.

image

Where is our Sidebar? well, because variant temporary is hidden at initial state. Mui-layout store this state inside Root and provide a component to trigger open state. let’s update the code to be like this.

// other import
const { getSidebarTrigger } from '@mui-treasury/layout';
const SidebarTrigger = getSidebarTrigger(styled)
const App = () => {
  return (
    <Root scheme={scheme}>
      <CssBaseline />
      <Header>
        <Toolbar>
          <SidebarTrigger sidebarId="unique_id" />          Header
        </Toolbar>
      </Header>
      <DrawerSidebar sidebarId="unique_id">
        {' '}
        // sidebar id is required sidebar content
      </DrawerSidebar>
    </Root>
  );
};

Note: you also need to add sidebarId to SidebarTrigger, otherwise you will get error

gif

Next, let’s permanently display our Sidebar in laptop screen up by adding the following code

scheme.configureEdgeSidebar(builder => {
  builder
    .create('unique_id', { anchor: 'left' })
    .registerTemporaryConfig('xs', {
      anchor: 'left',
      width: 'auto', // 'auto' is only valid for temporary variant
    })
    .registerPermanentConfig('md', {      width: 256, // px, (%, rem, em is compatible)      collapsible: true,      collapsedWidth: 64,    });});

To achieve collapsible mode, we need to add CollapseBtn at the bottom of the sidebar.

const { getSidebarContent, getCollapseBtn } = getLayoutComponents(styled);const SidebarContent = getSidebarContent(styled)const CollapseBtn = getCollapseBtn(styled)
const App = () => {
  return (
    <Root scheme={scheme}>
      <CssBaseline />
      <Header>
        <Toolbar>
          <SidebarTrigger sidebarId="unique_id" />          Header
        </Toolbar>
      </Header>
      <DrawerSidebar sidebarId="unique_id">
        <SidebarContent>          Sidebar content        </SidebarContent>        <CollapseBtn />      </DrawerSidebar>
    </Root>
  );
};

SidebarContent that added does not have any functionality accept styling. It stretch the content and push CollapseBtn to the bottom (see it in devtool). One key here is that you don’t need to specify sidebarId to CollapseBtn because it is render inside the Sidebar so it use the same sidebarId (you can point to other sidebar if you want)

image

Play around with collapse button.

Last step, let’s add Content and Footer to the page. Both of the components does not have functionality, so you don’t need to configure explicitly (actually it is already configured with default for you)

const { getContent, getFooter } = getLayoutComponents(styled);const Content = getContent(styled)const Footer = getFooter(styled)
const App = () => {
  return (
    <Root scheme={scheme}>
      <CssBaseline />
      <Header>
        <Toolbar>
          <SidebarTrigger sidebarId="unique_id" />          Header
        </Toolbar>
      </Header>
      <DrawerSidebar sidebarId="unique_id">
        <SidebarContent>
          Sidebar content
        </SidebarContent>
        <CollapseBtn />
      </DrawerSidebar>
      <Content>Content</Content>      <Footer>Footer</Footer>    </Root>
  );
};

Congratulations! you have completed this tutorial.

See Full Code
import React from "react";
import styled from "styled-components"; // or import styled from '@emotion/styled'
import Layout, {
  getHeader,
  getDrawerSidebar,
  getSidebarTrigger,
  getSidebarContent,
  getCollapseBtn,
  getContent,
  getFooter,
} from "@mui-treasury/layout";
import Toolbar from "@material-ui/core/Toolbar";
import CssBaseline from "@material-ui/core/CssBaseline";

const Header = getHeader(styled)
const DrawerSidebar = getDrawerSidebar(styled)
const SidebarTrigger = getSidebarTrigger(styled)
const SidebarContent = getSidebarContent(styled)
const CollapseBtn = getCollapseBtn(styled)
const Content = getContent(styled)
const Footer = getFooter(styled)

const scheme = Layout();

scheme.configureHeader((builder) => {
  builder
    .create("whatever_id")
    .registerConfig("xs", {
      position: "sticky",
    })
    .registerConfig("md", {
      position: "relative", // won't stick to top when scroll down
    });
});

scheme.configureEdgeSidebar((builder) => {
  builder
    .create("unique_id", { anchor: "left" })
    .registerTemporaryConfig("xs", {
      anchor: "left",
      width: "auto", // 'auto' is only valid for temporary variant
    })
    .registerPermanentConfig("md", {
      width: 256, // px, (%, rem, em is compatible)
      collapsible: true,
      collapsedWidth: 64,
    });
});

const App = () => {
  return (
    <Root scheme={scheme}>
      <CssBaseline />
      <Header>
        <Toolbar>
          <SidebarTrigger sidebarId="unique_id" />
          Header
        </Toolbar>
      </Header>
      <DrawerSidebar sidebarId="unique_id">
        <SidebarContent>
          sidebar content
        </SidebarContent>
        <CollapseBtn />
      </DrawerSidebar>
      <Content>Content</Content>
      <Footer>Footer</Footer>
    </Root>
  );
};

export default App;

You can look at clone examples to see advance layout like documentation site, e-commerce site or even chat site.

Optional

You can add mockup from @mui-treasury/mockup to make it more realistic.

yarn add @mui-treasury/mockup
// ... other import
import {
  HeaderMockUp,
  NavHeaderMockUp,
  NavContentMockUp,
  ContentMockUp,
  FooterMockUp,
} from '@mui-treasury/mockup/layout';

// ... scheme setup

const App = () => {
  return (
    <Root scheme={scheme}>
      {({ state: { sidebar } }) => (
        <>
          <CssBaseline />
          <Header>
            <Toolbar>
              <SidebarTrigger sidebarId="unique_id" />
              <HeaderMockUp />
            </Toolbar>
          </Header>
          <DrawerSidebar sidebarId="unique_id">
            <SidebarContent>
              <NavHeaderMockUp collapsed={sidebar.unique_id.collapsed} />
              <NavContentMockUp />
            </SidebarContent>
            <CollapseBtn />
          </DrawerSidebar>
          <Content>
            <ContentMockUp />
          </Content>
          <Footer>
            <FooterMockUp />
          </Footer>
        </>
      )}
    </Root>
  )
}