Pular para o conteúdo

Material UI (MUI) Cheat Sheet

Overview

Material UI (MUI) is the most popular React UI component library, implementing Google’s Material Design specification. It provides a comprehensive set of pre-built, production-ready components including buttons, dialogs, menus, tables, forms, and layout primitives. MUI offers deep customization through its theme system, styled API, and the sx prop for inline styling.

MUI consists of several packages: MUI Core (Material UI components), MUI Base (unstyled headless components), MUI System (CSS utilities), and MUI X (advanced data grid, date pickers, and charts). The library supports both Emotion and styled-components as CSS-in-JS engines, along with CSS variables for theme management.

Installation

# Core Material UI with Emotion (default)
npm install @mui/material @emotion/react @emotion/styled

# With styled-components instead
npm install @mui/material @mui/styled-engine-sc styled-components

# Icons
npm install @mui/icons-material

# Date pickers
npm install @mui/x-date-pickers dayjs

# Data Grid
npm install @mui/x-data-grid

# Lab (experimental components)
npm install @mui/lab

# Add Roboto font
npm install @fontsource/roboto

Setup

// main.tsx
import "@fontsource/roboto/300.css"
import "@fontsource/roboto/400.css"
import "@fontsource/roboto/500.css"
import "@fontsource/roboto/700.css"

import { ThemeProvider, createTheme, CssBaseline } from "@mui/material"

const theme = createTheme()

function App() {
  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      {/* Your app content */}
    </ThemeProvider>
  )
}

Core Components

Common Components

ComponentImportDescription
Button@mui/material/ButtonAction buttons with variants
TextField@mui/material/TextFieldText input fields
Select@mui/material/SelectDropdown select
Checkbox@mui/material/CheckboxCheckbox input
Switch@mui/material/SwitchToggle switch
Slider@mui/material/SliderRange slider
Dialog@mui/material/DialogModal dialog
Snackbar@mui/material/SnackbarToast notifications
AppBar@mui/material/AppBarTop app bar
Drawer@mui/material/DrawerSide navigation
Card@mui/material/CardContent card
Table@mui/material/TableData table
Tabs@mui/material/TabsTab navigation
Chip@mui/material/ChipCompact element
Avatar@mui/material/AvatarUser avatar
Tooltip@mui/material/TooltipHover tooltip
Skeleton@mui/material/SkeletonLoading placeholder

Button Variants

import Button from "@mui/material/Button"
import IconButton from "@mui/material/IconButton"
import DeleteIcon from "@mui/icons-material/Delete"

// Variants
<Button variant="contained">Primary</Button>
<Button variant="outlined">Secondary</Button>
<Button variant="text">Text</Button>

// Colors
<Button variant="contained" color="primary">Primary</Button>
<Button variant="contained" color="secondary">Secondary</Button>
<Button variant="contained" color="error">Error</Button>
<Button variant="contained" color="success">Success</Button>

// Sizes
<Button size="small">Small</Button>
<Button size="medium">Medium</Button>
<Button size="large">Large</Button>

// With icon
<Button variant="contained" startIcon={<DeleteIcon />}>Delete</Button>

// Icon button
<IconButton color="primary" aria-label="delete">
  <DeleteIcon />
</IconButton>

// Loading button (from @mui/lab)
import LoadingButton from "@mui/lab/LoadingButton"
<LoadingButton loading variant="contained">Submit</LoadingButton>

Form Components

import { TextField, Select, MenuItem, FormControl, InputLabel, Autocomplete } from "@mui/material"

// Text field variants
<TextField label="Name" variant="outlined" />
<TextField label="Email" variant="filled" />
<TextField label="Phone" variant="standard" />

// Validation
<TextField label="Email" type="email" required error={!!errors.email}
  helperText={errors.email || "Enter your email"} />

// Multiline
<TextField label="Bio" multiline rows={4} />

// Select
<FormControl fullWidth>
  <InputLabel>Role</InputLabel>
  <Select value={role} label="Role" onChange={handleChange}>
    <MenuItem value="admin">Admin</MenuItem>
    <MenuItem value="user">User</MenuItem>
    <MenuItem value="viewer">Viewer</MenuItem>
  </Select>
</FormControl>

// Autocomplete
<Autocomplete
  options={["React", "Vue", "Angular", "Svelte"]}
  renderInput={(params) => <TextField {...params} label="Framework" />}
/>

Layout Components

import { Box, Stack, Grid, Container, Paper } from "@mui/material"

// Box (basic div with sx prop)
<Box sx={{ p: 2, bgcolor: "background.paper", borderRadius: 1 }}>
  Content
</Box>

// Stack (flex column/row)
<Stack direction="row" spacing={2} alignItems="center">
  <Button>One</Button>
  <Button>Two</Button>
</Stack>

// Grid (responsive layout)
<Grid container spacing={2}>
  <Grid item xs={12} md={6} lg={4}>
    <Paper sx={{ p: 2 }}>Column 1</Paper>
  </Grid>
  <Grid item xs={12} md={6} lg={4}>
    <Paper sx={{ p: 2 }}>Column 2</Paper>
  </Grid>
</Grid>

Configuration

Custom Theme

import { createTheme, ThemeProvider } from "@mui/material/styles"

const theme = createTheme({
  palette: {
    mode: "dark", // or "light"
    primary: {
      main: "#1976d2",
      light: "#42a5f5",
      dark: "#1565c0",
    },
    secondary: {
      main: "#9c27b0",
    },
    background: {
      default: "#121212",
      paper: "#1e1e1e",
    },
  },
  typography: {
    fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif',
    h1: { fontSize: "2.5rem", fontWeight: 700 },
    h2: { fontSize: "2rem", fontWeight: 600 },
    button: { textTransform: "none" },
  },
  shape: {
    borderRadius: 8,
  },
  components: {
    MuiButton: {
      defaultProps: {
        disableElevation: true,
      },
      styleOverrides: {
        root: {
          borderRadius: 8,
          padding: "8px 24px",
        },
      },
    },
    MuiCard: {
      styleOverrides: {
        root: {
          borderRadius: 12,
          boxShadow: "0 2px 12px rgba(0,0,0,0.08)",
        },
      },
    },
  },
})

function App() {
  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      {/* App content */}
    </ThemeProvider>
  )
}

The sx Prop

// sx prop for inline theme-aware styling
<Box
  sx={{
    p: 2,                          // padding: theme.spacing(2)
    m: 1,                          // margin: theme.spacing(1)
    bgcolor: "primary.main",       // theme palette color
    color: "primary.contrastText",
    borderRadius: 1,               // theme.shape.borderRadius * 1
    width: { xs: "100%", md: "50%" }, // responsive
    display: "flex",
    gap: 2,
    "&:hover": {
      bgcolor: "primary.dark",
    },
  }}
>
  Themed box
</Box>

Advanced Usage

Data Grid (MUI X)

import { DataGrid, GridColDef } from "@mui/x-data-grid"

const columns: GridColDef[] = [
  { field: "id", headerName: "ID", width: 70 },
  { field: "name", headerName: "Name", width: 200, editable: true },
  { field: "email", headerName: "Email", width: 250 },
  { field: "role", headerName: "Role", width: 130,
    type: "singleSelect",
    valueOptions: ["Admin", "User", "Viewer"] },
]

const rows = [
  { id: 1, name: "Alice", email: "alice@example.com", role: "Admin" },
  { id: 2, name: "Bob", email: "bob@example.com", role: "User" },
]

<DataGrid
  rows={rows}
  columns={columns}
  pageSize={10}
  checkboxSelection
  disableRowSelectionOnClick
  sortingMode="server"
  filterMode="server"
/>

Styled Components API

import { styled } from "@mui/material/styles"

const StyledCard = styled("div")(({ theme }) => ({
  padding: theme.spacing(3),
  borderRadius: theme.shape.borderRadius * 2,
  backgroundColor: theme.palette.background.paper,
  boxShadow: theme.shadows[4],
  transition: "box-shadow 0.2s",
  "&:hover": {
    boxShadow: theme.shadows[8],
  },
}))

<StyledCard>Custom styled content</StyledCard>

Dark Mode Toggle

import { useState, useMemo } from "react"
import { createTheme, ThemeProvider } from "@mui/material/styles"
import useMediaQuery from "@mui/material/useMediaQuery"

function App() {
  const prefersDark = useMediaQuery("(prefers-color-scheme: dark)")
  const [mode, setMode] = useState<"light" | "dark">(prefersDark ? "dark" : "light")

  const theme = useMemo(() => createTheme({ palette: { mode } }), [mode])

  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <Button onClick={() => setMode(mode === "light" ? "dark" : "light")}>
        Toggle {mode === "light" ? "Dark" : "Light"} Mode
      </Button>
    </ThemeProvider>
  )
}

Troubleshooting

IssueSolution
Styles not applyingEnsure ThemeProvider wraps your app; add CssBaseline
Flash of unstyled contentConfigure SSR with Emotion cache; use @emotion/cache
Bundle size too largeUse path imports: import Button from '@mui/material/Button'
TypeScript theme errorsExtend the theme interface with declare module '@mui/material/styles'
Grid not responsiveUse breakpoint props: xs, sm, md, lg, xl
Icons not renderingInstall @mui/icons-material; verify import path
Emotion conflictsEnsure only one version of @emotion/react is installed
sx prop not workingComponent must be an MUI component or wrapped with styled()
Dark mode flicker on SSRUse CSS variables mode: cssVariables: true in createTheme