Categories
Material UI

Material UI — Bottom Nav and Breadcrumbs

Material UI is a Material Design library made for React.

It’s a set of React components that have Material Design styles.

In this article, we’ll look at how to add bottom navigation and breadcrumbs with Material UI.

Bottom Navigation

We can add bottom navigation to let us add links to move around our app.

To add it, we can use the BottomNavigation component.

For example, we can write:

import React from "react";
import BottomNavigation from "@material-ui/core/BottomNavigation";
import BottomNavigationAction from "@material-ui/core/BottomNavigationAction";
import RestoreIcon from "@material-ui/icons/Restore";
import FavoriteIcon from "@material-ui/icons/Favorite";
import LocationOnIcon from "@material-ui/icons/LocationOn";

export default function App() {
  const [value, setValue] = React.useState(0);

  return (
    <BottomNavigation
      value={value}
      onChange={(event, newValue) => {
        setValue(newValue);
      }}
      showLabels
    >
      <BottomNavigationAction label="latest" icon={<RestoreIcon />} />
      <BottomNavigationAction label="favorites" icon={<FavoriteIcon />} />
      <BottomNavigationAction label="location" icon={<LocationOnIcon />} />
    </BottomNavigation>
  );
}

to add a navigation bar to the bottom of the page.

We add the BottomNavigation component with the showLabels prop to show the labels.

BottomNavigationAction has the items that users can click on

label has the text below the icon.

icon has the icons.

When we click on the BottomNavigationAction then the value state will be set with the onChange callback which calls the setValue function with the index.

The value prop of BottomNavigationAction lets us set the value that’s set when we click the action.

For example, we can write:

import React from "react";
import BottomNavigation from "@material-ui/core/BottomNavigation";
import BottomNavigationAction from "@material-ui/core/BottomNavigationAction";
import RestoreIcon from "@material-ui/icons/Restore";
import FavoriteIcon from "@material-ui/icons/Favorite";
import LocationOnIcon from "@material-ui/icons/LocationOn";

export default function App() {
  const [value, setValue] = React.useState("favorites");

  return (
    <BottomNavigation
      value={value}
      onChange={(event, newValue) => {
        setValue(newValue);
      }}
      showLabels
    >
      <BottomNavigationAction
        label="latest"
        value="latest"
        icon={<RestoreIcon />}
      />
      <BottomNavigationAction
        label="favorites"
        value="favorites"
        icon={<FavoriteIcon />}
      />
      <BottomNavigationAction
        label="location"
        value="location"
        icon={<LocationOnIcon />}
      />
    </BottomNavigation>
  );
}

We set the value prop for each item so that we can use a name that we want for the state instead of an index number.

Breadcrumbs

We can add breadcrumbs to let us click links on navigation hierarchies.

To add one, we can use the Breadcrumbs components with Link s inside.

For example, we can write:

import React from "react";
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import Link from "@material-ui/core/Link";

export default function App() {
  const handleClick = event => {
    event.preventDefault();
    console.info("clicked.");
  };
  return (
    <Breadcrumbs aria-label="breadcrumb">
      <Link color="inherit" href="/" onClick={handleClick}>
        home
      </Link>
      <Link color="inherit" href="/profile/" onClick={handleClick}>
        profile
      </Link>
      <Link color="inherit" href="/profile/user" onClick={handleClick}>
        user
      </Link>
    </Breadcrumbs>
  );
}

We have the Breadcrumbs component surrounding the Link components.

color is inherited from the parent.

href has the URL for the link.

onClick lets us listen for item clicks.

Active Last Breadcrumb

We can make the last item active with the textPrimary value for the color prop.

For example, we can write:

import React from "react";
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import Link from "@material-ui/core/Link";

export default function App() {
  const handleClick = event => {
    event.preventDefault();
    console.info("clicked.");
  };
  return (
    <Breadcrumbs aria-label="breadcrumb">
      <Link color="inherit" href="/" onClick={handleClick}>
        home
      </Link>
      <Link color="inherit" href="/profile/" onClick={handleClick}>
        profile
      </Link>
      <Link color="textPrimary" href="/profile/user" onClick={handleClick}>
        user
      </Link>
    </Breadcrumbs>
  );
}

We added the color prop with the textPrimary string to make it highlight.

Custom Separator

To change the default separator, we can use the separator prop.

For example, we can write:

import React from "react";
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import Link from "@material-ui/core/Link";

export default function App() {
  const handleClick = event => {
    event.preventDefault();
    console.info("clicked.");
  };
  return (
    <Breadcrumbs separator="-">
      <Link color="inherit" href="/" onClick={handleClick}>
        home
      </Link>
      <Link color="inherit" href="/profile/" onClick={handleClick}>
        profile
      </Link>
      <Link color="textPrimary" href="/profile/user" onClick={handleClick}>
        user
      </Link>
    </Breadcrumbs>
  );
}

to change the default separator to the - character.

Collapsed Breadcrumbs

If we have lots of breadcrumbs, we can set the maxItems prop to set the max number of breadcrumb items to show.

For example, we can write:

import React from "react";
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import Link from "@material-ui/core/Link";

export default function App() {
  const handleClick = event => {
    event.preventDefault();
    console.info("clicked.");
  };
  return (
    <Breadcrumbs maxItems={2}>
      <Link color="inherit" href="/" onClick={handleClick}>
        home
      </Link>
      <Link color="inherit" href="/profile/" onClick={handleClick}>
        profile
      </Link>
      <Link color="textPrimary" href="/profile/user" onClick={handleClick}>
        user
      </Link>
    </Breadcrumbs>
  );
}

to limit the items to display to 2 with the maxItems prop.

Conclusion

We can add a bottom navigation bar to our app with the BottomNavigation component.

Breadcrumbs lets us add a breadcrumb to the navigation items in a hierarchy.

Categories
Material UI

Material UI — Date and Time Pickers and Radio Buttons

Material UI is a Material Design library made for React.

It’s a set of React components that have Material Design styles.

In this article, we’ll look at how to add date and time pickers and radio buttons with Material UI.

Date / Time Pickers

We can add a native date picker with the type set to date .

For example, we can write:

import React from "react";
import TextField from "@material-ui/core/TextField";

export default function App() {
  return (
    <div>
      <form noValidate>
        <TextField
          id="date"
          label="Birthday"
          type="date"
          defaultValue="2020-05-26"
          InputLabelProps={{
            shrink: true
          }}
        />
      </form>
    </div>
  );
}

to add a date picker.

We used the TextField component to add the text field.

defaultValue is used to set the default value of the picker.

Date and Time Pickers

If we want to add a picker for both the date and time, we can set the type

For example, we can write:

import React from "react";
import TextField from "@material-ui/core/TextField";

export default function App() {
  return (
    <div>
      <form noValidate>
        <TextField
          id="date"
          label="Birthday"
          type="datetime-local"
          defaultValue="2021-05-26T10:30"
          InputLabelProps={{
            shrink: true
          }}
        />
      </form>
    </div>
  );
}

We set the type to datetime-local to show a native date and time picker.

Time Pickers

To add a time picker only, we can set the type of the TextField to time .

For example, we can write:

import React from "react";
import TextField from "@material-ui/core/TextField";

export default function App() {
  return (
    <div>
      <form noValidate>
        <TextField
          id="time"
          label="Clock"
          type="time"
          defaultValue="07:30"
          InputLabelProps={{
            shrink: true
          }}
        />
      </form>
    </div>
  );
}

to display a native time picker.

Radio Buttons

Radio buttons let the user select one option from a set.

We can put one more radio buttons into a RadioGroup .

For example, we can write:

import React from "react";
import RadioGroup from "@material-ui/core/RadioGroup";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Radio from "@material-ui/core/Radio";

export default function App() {
  const [value, setValue] = React.useState("apple");

  const handleChange = event => {
    setValue(event.target.value);
  };

  return (
    <div>
      <form noValidate>
        <RadioGroup name="fruit" value={value} onChange={handleChange}>
          <FormControlLabel value="apple" control={<Radio />} label="apple" />
          <FormControlLabel value="orange" control={<Radio />} label="orange" />
          <FormControlLabel value="banana" control={<Radio />} label="banana" />
          <FormControlLabel
            value="grape"
            disabled
            control={<Radio />}
            label="grape"
          />
        </RadioGroup>
      </form>
    </div>
  );
}

We added the RadioGroup component to add a group of radio buttons.

Then we add the FormControlLabel to add the label for the radio button.

The value is the value for the radio button.

And we put the radio button inside each FormControlLabel .

The label sets the label of each radio button.

We can add a disable radio button with the disabled prop.

To set the value that the user selects as the state value, we have the handleChange function passed to the onChange prop.

Then we can set the value of the value prop as the value of the value state when we select an option.

Standalone Radio Buttons

The Radio component can be used as a standalone component.

For example, we can write:

import React from "react";
import Radio from "@material-ui/core/Radio";

export default function App() {
  const [value, setValue] = React.useState("apple");

  const handleChange = event => {
    setValue(event.target.value);
  };

  return (
    <div>
      <form noValidate>
        <Radio
          checked={value === "apple"}
          onChange={handleChange}
          value="apple"
          name="fruit"
        />
        <Radio
          checked={value === "orange"}
          onChange={handleChange}
          value="orange"
          name="fruit"
        />
      </form>
    </div>
  );
}

We have a Radio components to show the radio buttons without the labels.

The checked state is set by comparing the selectedvalue against the value of the radio button.

onChange is the same as the previous example.

Label Placement

The placement of the label can be changed with the labelPlacement prop.

For example, we can write:

import React from "react";
import Radio from "@material-ui/core/Radio";
import FormControlLabel from "@material-ui/core/FormControlLabel";

export default function App() {
  return (
    <div>
      <form noValidate>
        <FormControlLabel
          value="bottom"
          control={<Radio color="primary" />}
          label="Bottom"
          labelPlacement="bottom"
        />
      </form>
    </div>
  );
}

We set the labelPlacement prop to bottom to place the label below the radio button.

Other possible values include top , start , and end .

Conclusion

We can add date and time pickers with the TextField component.

To add radio buttons, we can use FormControlLabel and Radio components.

Radio buttons can be added without labels.

Categories
Material UI

Material UI — Floating Action Buttons

Material UI is a Material Design library made for React.

It’s a set of React components that have Material Design styles.

In this article, we’ll look at how to add floating buttons with Material UI.

Floating Action Button

We can add floating action buttons with the Fab component.

For instance, we can write:

import React from "react";
import Fab from "@material-ui/core/Fab";
import AddIcon from "@material-ui/icons/Add";

export default function App() {
  return (
    <Fab color="primary" aria-label="add">
      <AddIcon />
    </Fab>
  );
}

to add a floating action button to our app with the Fab component.

We have an icon inside it.

Size

To change the size, we set the size prop.

For instance, we can write:

import React from "react";
import Fab from "@material-ui/core/Fab";
import AddIcon from "@material-ui/icons/Add";

export default function App() {
  return (
    <Fab size="small">
      <AddIcon />
    </Fab>
  );
}

to change the button size to small.

Animation

We can animate the display of floating action buttons when we switch tabs.

To add the animation, we write:

import React from "react";
import Fab from "@material-ui/core/Fab";
import SwipeableViews from "react-swipeable-views";
import AppBar from "@material-ui/core/AppBar";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import AddIcon from "@material-ui/icons/Add";
import EditIcon from "@material-ui/icons/Edit";
import UpIcon from "@material-ui/icons/KeyboardArrowUp";
import Zoom from "@material-ui/core/Zoom";

function TabPanel(props) {
  const { children, value, index, ...other } = props;

return (
    <Typography
      component="div"
      role="tabpanel"
      hidden={value !== index}
      id={`action-tabpanel-${index}`}
      aria-labelledby={`action-tab-${index}`}
      {...other}
    >
      {value === index && <Box p={3}>{children}</Box>}
    </Typography>
  );
}

export default function App() {
  const [value, setValue] = React.useState(0);

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };

  const handleChangeIndex = index => {
    setValue(index);
  };

  const fabs = [
    {
      color: "primary",
      icon: <AddIcon />,
      label: "Add"
    },
    {
      color: "secondary",
      icon: <EditIcon />,
      label: "Edit"
    },
    {
      color: "inherit",
      icon: <UpIcon />,
      label: "Expand"
    }
  ];

return (
    <div>
      <AppBar position="static" color="default">
        <Tabs
          value={value}
          onChange={handleChange}
          indicatorColor="primary"
          textColor="primary"
          variant="fullWidth"
          aria-label="action tabs example"
        >
          <Tab label="Item One" />
          <Tab label="Item Two" />
          <Tab label="Item Three" />
        </Tabs>
      </AppBar>
      <SwipeableViews axis="x" index={value} onChangeIndex={handleChangeIndex}>
        <TabPanel value={value} index={0}>
          Item One
        </TabPanel>
        <TabPanel value={value} index={1}>
          Item Two
        </TabPanel>
        <TabPanel value={value} index={2}>
          Item Three
        </TabPanel>
      </SwipeableViews>
      {fabs.map((fab, index) => (
        <Zoom
          key={fab.color}
          in={value === index}
          timeout={100}
          style={{
            transitionDelay: `0ms`
          }}
          unmountOnExit
        >
          <Fab
            aria-label={fab.label}
            className={fab.className}
            color={fab.color}
          >
            {fab.icon}
          </Fab>
        </Zoom>
      ))}
    </div>
  );
}

We add an AppBar to display a bar on the top with the Tab s below it.

Then to display the tab content, we have the TabPanel components to display them.

We created the TabPanel component ourselves to show and hide the items based on the index of the tab that’s selected.

Then we display the floating action buttons below that.

The p prop on the Box lets us add some padding.

We set the font with the Typography component.

component is set to div.

hidden lets us choose what content to hide, which is the tabs with the index that isn’t selected.

We put it inside the Zoom component so that we get a zoom transition when we display the buttons.

The duration of the transition will be the timeout value.

It’s measured in milliseconds.

unmountOnExit will clear the button when we switch tabs.

The index is updated when we click the tab heading, which will trigger the handleChange function to run.

If we swipe tabs, then the handleChangeIndex function runs and does the same thing as handleChange .

Conclusion

We can add floating action buttons with various styles and sizes.

Also, we can transition between different buttons within a tab.

Categories
Material UI

Material UI — Buttons and Checkboxes

Material UI is a Material Design library made for React.

It’s a set of React components that have Material Design styles.

In this article, we’ll look at how to add buttons and checkboxes Material Design.

Disabled Elevation

We can disable the elevation of buttons with the disableElevation prop.

For instance, we can write:

import React from "react";
import Button from "@material-ui/core/Button";
import ButtonGroup from "@material-ui/core/ButtonGroup";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
  root: {
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    "& > *": {
      margin: theme.spacing(1)
    }
  }
}));

export default function App() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <ButtonGroup disableElevation variant="contained" color="primary">
        <Button>foo</Button>
        <Button>bar</Button>
      </ButtonGroup>
    </div>
  );
}

to disable the elevation.

Checkbox

Checkboxes let us turn options on or off.

To create one, we can use the Checkbox component:

import React from "react";
import Checkbox from "@material-ui/core/Checkbox";

export default function App() {
  const [checked, setChecked] = React.useState(true);

  const handleChange = event => {
    setChecked(event.target.checked);
  };

  return (
    <div>
      <Checkbox
        checked={checked}
        onChange={handleChange}
        inputProps={{ "aria-label": "checkbox" }}
      />
    </div>
  );
}

We add the Checkbox component to add a checkbox.

It takes the checked prop to set the checked value.

onChange takes the checked value so that we can set the state.

And inputProps let us add attributes to the checkbox.

Checkbox with FormControlLabel

We can add a label to our checkbox with the FormControlLabel .

For instance, we can write:

import React from "react";
import Checkbox from "@material-ui/core/Checkbox";
import FormControlLabel from "@material-ui/core/FormControlLabel";

export default function App() {
  const [checked, setChecked] = React.useState(true);

  const handleChange = event => {
    setChecked(event.target.checked);
  };

  return (
    <div>
      <FormControlLabel
        control={
          <Checkbox
            checked={checked}
            onChange={handleChange}
            name="checked"
            color="primary"
          />
        }
        label="Primary"
      />
    </div>
  );
}

to create a checkbox with a label beside it.

We wrap the FormControlLabel outside our Checkbox so that’s we can add a label to it with the label prop.

Checkboxes with FormGroup

To add multiple checkboxes, we can put them into a FormGroup .

For instance, we can write:

import React from "react";
import Checkbox from "@material-ui/core/Checkbox";
import FormControl from "@material-ui/core/FormControl";
import FormLabel from "@material-ui/core/FormLabel";
import FormGroup from "@material-ui/core/FormGroup";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import FormHelperText from "@material-ui/core/FormHelperText";

export default function App() {
  const [checked, setChecked] = React.useState({
    foo: true,
    bar: false
  });

const handleChange = event => {
    setChecked({ ...checked, [event.target.name]: event.target.checked });
  };

return (
    <div>
      <FormControl component="fieldset">
        <FormLabel component="legend">check them all</FormLabel>
        <FormGroup>
          <FormControlLabel
            control={
              <Checkbox
                checked={checked.foo}
                onChange={handleChange}
                name="foo"
              />
            }
            label="foo"
          />
          <FormControlLabel
            control={
              <Checkbox
                checked={checked.bar}
                onChange={handleChange}
                name="bar"
              />
            }
            label="bar"
          />
        </FormGroup>
        <FormHelperText>Be careful</FormHelperText>
      </FormControl>
    </div>
  );
}

To create a group of checkb0oxes with the FormControl component.

We wrapped lots of things inside it.

We have a FormLabel to display the label at the top.

Then we have a FormGroup to hold tge checkboxes.

The FormControlLabel has the label for each checkbox.

FormHelperText has the small text we display at the bottom of the form.

Label Placement

The label placement can be changed.

To do that, we can use the labelPlacement prop to change it.

For instance, we can write:

import React from "react";
import Checkbox from "@material-ui/core/Checkbox";
import FormControlLabel from "@material-ui/core/FormControlLabel";

export default function App() {
  return (
    <div>
      <FormControlLabel
        value="bottom"
        control={<Checkbox color="primary" />}
        label="Bottom"
        labelPlacement="bottom"
      />
    </div>
  );
}

Now we have the label below the checkbox.

Other possible values include top , start , and end .

Customized Checkbox

We can apply our own styles to the checkbox.

For instance, we can write:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import clsx from "clsx";
import Checkbox from "@material-ui/core/Checkbox";

const useStyles = makeStyles({
  root: {
    "&:hover": {
      backgroundColor: "transparent"
    }
  },
  icon: {
    borderRadius: 3,
    width: 16,
    height: 16,
    backgroundColor: "#ebf1f5",
    "input:hover ~ &": {
      backgroundColor: "#ebf1f5"
    },
    "input:disabled ~ &": {
      boxShadow: "none"
    }
  },
  checkedIcon: {
    backgroundColor: "#137cbd",
    backgroundImage: "blue",
    "&:before": {
      display: "block",
      width: 16,
      height: 16,
      backgroundColor: "gray"
    },
    "input:hover ~ &": {
      backgroundColor: "#106ba3"
    }
  }
});

export default function App() {
  const classes = useStyles();

  return (
    <Checkbox
      className={classes.root}
      disableRipple
      color="default"
      checkedIcon={<span className={clsx(classes.icon, classes.checkedIcon)} />}
      icon={<span className={classes.icon} />}
      inputProps={{ "aria-label": "decorative checkbox" }}
    />
  );
}

to create a checkbox without a checkmark.

We set a grayish color for the unchecked state.

And we set the checked state to blue.

These are done according to the styles we passed into makeStyles .

Also, we used the clsx package to toggle between the checked and unchecked styles.

Conclusion

We can add checkboxes with Material UI.

Also, we can add labels and style them the way we want.

Categories
Material UI

Material UI — Buttons and Groups

Material UI is a Material Design library made for React.

It’s a set of React components that have Material Design styles.

In this article, we’ll look at how to add buttons Material Design.

Complex Buttons

We can add more complex buttons with the ButtonBase component.

For instance, we can write:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import ButtonBase from "@material-ui/core/ButtonBase";
import Typography from "@material-ui/core/Typography";

const useStyles = makeStyles(theme => ({
  root: {
    "& > *": {
      margin: theme.spacing(1)
    }
  },
  image: {
    position: "relative",
    height: 200,
    [theme.breakpoints.down("xs")]: {
      width: "100% !important",
      height: 100
    },
    "&:hover, &$focusVisible": {
      zIndex: 1,
      "& $imageBackdrop": {
        opacity: 0.15
      },
      "& $imageMarked": {
        opacity: 0
      },
      "& $imageTitle": {
        border: "4px solid currentColor"
      }
    }
  },
  focusVisible: {},
  imageButton: {
    position: "absolute",
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    color: theme.palette.common.white
  },
  imageSrc: {
    position: "absolute",
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    backgroundSize: "cover",
    backgroundPosition: "center 40%"
  },
  imageBackdrop: {
    position: "absolute",
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    backgroundColor: theme.palette.common.black,
    opacity: 0.4,
    transition: theme.transitions.create("opacity")
  },
  imageTitle: {
    position: "relative",
    padding: `${theme.spacing(2)}px ${theme.spacing(4)}px ${theme.spacing(1) +
      6}px`
  },
  imageMarked: {
    height: 3,
    width: 18,
    backgroundColor: theme.palette.common.white,
    position: "absolute",
    bottom: -2,
    left: "calc(50% - 9px)",
    transition: theme.transitions.create("opacity")
  }
}));

export default function App() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <ButtonBase
        focusRipple
        className={classes.image}
        focusVisibleClassName={classes.focusVisible}
        style={{
          width: "200px"
        }}
      >
        <span
          className={classes.imageSrc}
          style={{
            backgroundImage: `url(http://placekitten.com/200/200)`
          }}
        />
        <span className={classes.imageBackdrop} />
        <span className={classes.imageButton}>
          <Typography
            component="span"
            variant="subtitle"
            color="inherit"
            className={classes.imageTitle}
          >
            {"Cat"}
            <span className={classes.imageMarked} />
          </Typography>
        </span>
      </ButtonBase>
    </div>
  );
}

We set the classes for the ButtonBase with the image class.

focusVisibleClassName has the focusVisible class.

imageBackdrop has its own class.

imageButton has the button class.

And imageMarked has the image class has the bar at the bottom.

We follow the styles from the Material UI documentation to start, and then we modify them from that.

We set many things to an absolute position to place them in the button base.

The image title is relative to the spacing.

Button Groups

We can add button groups to add buttons in one container.

For instance, we can write:

import React from "react";
import Button from "@material-ui/core/Button";
import ButtonGroup from "@material-ui/core/ButtonGroup";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
  root: {
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    "& > *": {
      margin: theme.spacing(1)
    }
  }
}));

export default function App() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <ButtonGroup color="primary">
        <Button>foo</Button>
        <Button>bar</Button>
        <Button>baz</Button>
      </ButtonGroup>
    </div>
  );
}

We add our Button s in our ButtonGroup s to group them together.

Sizes and Colors of Button Groups

We can change the size and colors of button groups.

For example, we can write:

import React from "react";
import Button from "@material-ui/core/Button";
import ButtonGroup from "@material-ui/core/ButtonGroup";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
  root: {
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    "& > *": {
      margin: theme.spacing(1)
    }
  }
}));

export default function App() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <ButtonGroup size="large" color="primary">
        <Button>foo</Button>
        <Button>bar</Button>
        <Button>baz</Button>
      </ButtonGroup>
    </div>
  );
}

to make the size large.

Vertical Group

To make the button group vertical, we can set the orientation to vertical .

For example, we can write:

import React from "react";
import Button from "@material-ui/core/Button";
import ButtonGroup from "@material-ui/core/ButtonGroup";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
  root: {
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    "& > *": {
      margin: theme.spacing(1)
    }
  }
}));

export default function App() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <ButtonGroup orientation="vertical" color="primary">
        <Button>foo</Button>
        <Button>bar</Button>
        <Button>baz</Button>
      </ButtonGroup>
    </div>
  );
}

Split Button

We can make a split button by putting 2 buttons together.

For example, we can write:

import React from "react";
import Button from "@material-ui/core/Button";
import ButtonGroup from "@material-ui/core/ButtonGroup";
import { makeStyles } from "@material-ui/core/styles";
import ArrowDropDownIcon from "@material-ui/icons/ArrowDropDown";

const useStyles = makeStyles(theme => ({
  root: {
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    "& > *": {
      margin: theme.spacing(1)
    }
  }
}));

export default function App() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <ButtonGroup color="primary">
        <Button>foo</Button>
        <Button color="primary" size="small">
          <ArrowDropDownIcon />
        </Button>
      </ButtonGroup>
    </div>
  );
}

We add the ArrowDropDownIcon to add an icon to the r8ight button.

size is small to make it smaller than the left one.

Conclusion

We can make complex buttons with the ButtonBase component.

And we can group buttons together with the ButtonGroup component.