Search code examples
reactjsmaterial-uiappbar

How to center the search component in MUI AppBar?


I've been struggling to center the search component in the AppBar of Material-UI. I wanted the search bar to remain in the center. Using this code from their website. I've played around margins and justify, but I can't seem to get the correct way of doing it and remain responsive.

const Search = styled('div')(({ theme }) => ({
  position: 'relative',
  borderRadius: theme.shape.borderRadius,
  backgroundColor: alpha(theme.palette.common.white, 0.15),
  '&:hover': {
    backgroundColor: alpha(theme.palette.common.white, 0.25),
  },
  marginLeft: 0,
  width: '100%',
  [theme.breakpoints.up('sm')]: {
    marginLeft: theme.spacing(1),
    width: 'auto',
  },
}));

const SearchIconWrapper = styled('div')(({ theme }) => ({
  padding: theme.spacing(0, 2),
  height: '100%',
  position: 'absolute',
  pointerEvents: 'none',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
}));

const StyledInputBase = styled(InputBase)(({ theme }) => ({
  color: 'inherit',
  '& .MuiInputBase-input': {
    padding: theme.spacing(1, 1, 1, 0),
    // vertical padding + font size from searchIcon
    paddingLeft: `calc(1em + ${theme.spacing(4)})`,
    transition: theme.transitions.create('width'),
    width: '100%',
    [theme.breakpoints.up('sm')]: {
      width: '12ch',
      '&:focus': {
        width: '20ch',
      },
    },
  },
}));

export default function SearchAppBar() {
  return (
    <Box sx={{ flexGrow: 1 }}>
      <AppBar position="static">
        <Toolbar>
          <IconButton
            size="large"
            edge="start"
            color="inherit"
            aria-label="open drawer"
            sx={{ mr: 2 }}
          >
            <MenuIcon />
          </IconButton>
          <Typography
            variant="h6"
            noWrap
            component="div"
            sx={{ flexGrow: 1, display: { xs: 'none', sm: 'block' } }}
          >
            MUI
          </Typography>
          <Search>
            <SearchIconWrapper>
              <SearchIcon />
            </SearchIconWrapper>
            <StyledInputBase
              placeholder="Search…"
              inputProps={{ 'aria-label': 'search' }}
            />
          </Search>
        </Toolbar>
      </AppBar>
    </Box>
  );
}

How do I achieve something likes this?

enter image description here


Solution

  • Because Toolbar is a flex container, if you set its justify-content to space-between the element in the middle will be centered.

    <AppBar position="static">
      <Toolbar
        sx={{
          justifyContent: "space-between"
        }}
      >
        {/* group IconButton and Typography in an element so there are */}
        {/* only 3 children in the flex container */}
        <Stack direction="row" alignItems="center">
          <IconButton {...} />
          <Typography {...} />
        </Stack>
        <Search {...} />
        <IconButton {...} />
      </Toolbar>
    </AppBar>
    

    Live Demo

    Codesandbox Demo