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 Flex
es 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>
}