Materialize the chess board’s UI

Sean
SLTC — Sean Learns To Code
4 min readFeb 17, 2023

In the previous posts of this series I blogged about how I use CSS flex box and CSS grid layout to build a chess board. While I really enjoyed the process of styling my components and building the layout of my page with my own hands, there’s always the option of taking advantage of a well established and battle hardened component library to make one’s life easier.

There are quite a few options available in the React ecosystem today when it comes to component libraries and React MUI seems to be a very common choice among them. Yesterday I updated the chess board to rely more heavily on the library. The result is here!

The chess board with MUI components in action

Below are a few things that I enjoyed after converting the chess board to use MUI components.

App bar

The header tag is replaced by MUI’s AppBar. The AppBar , which actually renders a header tag under the hood, has a Toolbar child component that is a flex container by default so the amount of CSS I have to write is significantly reduced. The new code for the header looks like this

<AppBar position='static'>
<Toolbar sx={{
bgcolor: "rgb(5, 5, 29)",
justifyContent: "space-between",
}}>
<Button variant="contained" href={gitHubUrl}
startIcon={<GitHubIcon />} target={"_blank"} rel="noreferrer noopener">
<Typography variant="span" sx={{ display: { xs: 'none', sm: 'block' } }}>
Source
</Typography>
</Button>
<Box component={"div"}>
<Typography variant="h4">
{pieceColor === WHITE ? '♟' : '♙'}
</Typography>
</Box>
<Button variant="contained" onClick={togglePieceColor}
startIcon={<SwapVertIcon />}>
<Typography variant="span" sx={{ display: { xs: 'none', sm: 'block' } }}>
Switch Side
</Typography>
</Button>
</Toolbar>
</AppBar>

You may have noticed that there’s a decent amount of CSS code embedded in the JavaScript code above. It’s because the MUI component library is a strong proponent of the CSS-in-JS approach.

Some other MUI components that are also used in the code above are Box, Button, Typography, and Icons.

Stack

Stack is a layout component provided by MUI. Under the hood it’s a flex container that is supposed to be used to display its items in a single direction. A direction prop is exposed whose value could be anything among row (default), row-reverse , column , and column-reverse , which should be familiar to those who works with the flex-direction CSS property before.

In the MUI-based version of the chess board I use a few instances of Stack as the container for the row names, the column names, and the rows of the chess board. For instance, the code of theColNames component now looks like this

<Stack direction="row" sx={{
gridArea: (side === "top" ? "1 / 2 / span 1 / span 8" : "10 / 2 / span 1 / span 8"),
alignItems: "center",
}}>
{
names.map((name) =>
<Paper key={`${side} ${name}`} elevation={0} sx={{
flex: "1 1 100%",
textAlign: "center",
bgcolor: "transparent",
border: "none",
textTransform: "uppercase",
fontSize: { xs: "1em", sm: "1.5em" },

}}>
<strong>{name}</strong>
</Paper>
)
}
</Stack>

Because I didn’t want to change the grid layout that was set out previously (see this post), I simply moved the CSS grid-area property from the CSS file to the JavaScript file and set it via the sx prop (it’s the MUI version of the JSX ’s styles prop).

Paper

Paper is by far one of my favorite things about MUI. It allows us to create a UI component that looks like a piece of paper laid down on the screen. If you want the paper to look like it’s being elevated from the screen, you can use the elevation property. The higher is the value, the more elevated is the component. Below is the code I have for the Board component.

<Paper sx={{
display: "flex",
flexDirection: "column-reverse",
gridArea: "2 / 2 / span 8 / span 8",
}} elevation={4}>
{
board.map((row, rowIdx) => {
return (
<Row key={rowKey(rowIdx)} row={row} rowIdx={rowIdx} />
);
})
}
</Paper>

Another interesting prop of Paper is variant . The by default, the value of the prop is contained . Another value that can be used is outlined , which makes the component shown with a very thin and nice looking border. Below is the code I have for the outer board, i.e. the component that contains the chess board as well as RowNames and ColNames .

<Paper sx={{
display: "grid",
gridTemplate: "repeat(10, min(9vw, 9vh)) / repeat(10, min(9vw, 9vh))",
bgcolor: "rgba(0, 0, 0, 0.2)",
border: "none",
}} variant="outlined">
<ColNames side="top" />

<RowNames side="left" />
<Board board={pieceColor === WHITE ? WHITE_BOARD : BLACK_BOARD} />
<RowNames side="right" />

<ColNames side="bottom" />
</Paper>

The impact of elevation and variant="outlined" can be seen in the screenshot below.

A screenshot of the MUI based chess board

Enjoy!

--

--