This post is a draft. Thank you for reviewing.
This post is written primarily for the students in my React Application Workshop, but may be useful for anyone who wants to build layouts in Chakra UI.
Flex
Our first layout component we will look at is the Flex component. The Flex component is essentially a Box with display: flex;. You can use it to make horizontal and vertical layouts. The advantage of this component is that it has these shorthands for Flexbox properties:
flexDirection is direction
flexWrap is wrap
flexBasis is basis
flexGrow is grow
flexShrink is shrink
alignItems is align
justifyContent is justify
Experiment in the sandbox below (be sure to read and understand the code):
import { ChakraProvider, Flex, Button } from '@chakra-ui/react'
export default function App() {
return (
<ChakraProvider>
<Flex
direction="column"
height="100vh"
align="center"
justify="space-evenly"
>
<Button colorScheme="teal">Button 1</Button>
<Button colorScheme="teal">Button 2</Button>
<Button colorScheme="teal">Button 3</Button>
</Flex>
</ChakraProvider>
);
}
Spacer
The Spacer component is designed to be used alongside Flex. It creates a space as large as possible between two components. You can use it to create navbars like the one below. Notice how the Spacer is in between the two components where the space goes. This time, we are using a Flex with direction="column"
import { ChakraProvider, Flex, Button, Spacer, Heading } from '@chakra-ui/react'
export default function App() {
return (
<ChakraProvider>
<Flex
direction="row"
width="full"
align="center"
gap="10px"
padding="10px"
bg="blue.100"
>
<Heading fontSize="sm">My app</Heading>
<Spacer />
<Button>Log in</Button>
<Button colorScheme="teal">Sign up</Button>
</Flex>
</ChakraProvider>
);
}
Practical Usage
Most apps can be made almost entirely using Flexes for layout. The most common layout in app design, is a vertical or horizontal layout. Most of the time, these layouts are nested. In a simple todo app, we would usually have a top level horizontal layout with both the sidebar and the main area, inside the sidebar a list of items (a vertical layout), and another vetical layout in the main area holding all the todos. Each todo itself is a horizontal layout.
Note that in the demo below, the checkboxes will not work as the done state is hardcoded. To get that to work, we need to modify the state whenever the checkbox changes.
import { ChakraProvider, Flex, Button, Spacer, Checkbox } from '@chakra-ui/react'
const todos = [
{
name: "Wash the cat",
done: true,
due: "Yesterday"
},
{
name: "Learn React",
done: false,
due: "Tomorrow"
},
{
name: "Sleep",
done: false,
due: "Eventually"
},
]
export default function App() {
return (
<ChakraProvider>
<Flex direction="row" height="100vh">
<Sidebar />
<Todos />
</Flex>
</ChakraProvider>
);
}
function Todo(props) {
return <Flex direction="row" gap="10px" bg="gray.400" rounded="md" gap="10px" padding="10px">
<Checkbox isChecked={props.done} />
{props.name}
<Spacer />
{props.due}
</Flex>
}
function Todos() {
return <Flex direction="column" width="full" gap="10px" padding="10px">
{todos.map((todo) => <Todo {...todo} />)}
</Flex>
}
function Sidebar() {
return <Flex direction="column" bg="gray.300" padding="20px" gap="20px">
<Button>A</Button>
<Button>B</Button>
<Button>C</Button>
</Flex>
}