Chakra UI (v2) - Wrap a Layout Component with Default Styles
Posted on Dec 27, 2023 in Blog Posts
At the time of writing, @chakra-ui/react
's version is 2.8.2
.
Overview
This post explores how to create wrapper components for Chakra UI layout components. Unlike typical components, layout components can't be customized via theme extension. Layout components include components like HStack
, Stack
, and VStack
.
Why might you want to create reusable components for specific styles? Rather than hard-coding, for example, gap=0
on every Stack
, HStack
, and VStack
component, you can wrap Chakra layout components with your own customized styles and use that component instead. Any time you want to make a change to the gap, you only have to make it in one place instead of finding every reference of gap=0
in Chakra components across your codebase.
Creating Wrapper Components
For this example, let's say we want to add a default gap of 0
for all Stack
, HStack
, and VStack
components. We can create wrapper components that set a default but still allow it to be modified like the regular Chakra layout component.
Creating the Stack Wrapper Component
In the example project, we've created a new folder components
in src
, and also added a Stacks.tsx
file.
First, let's set a constant for a default gap that we can use across all three wrappers.
Next, let's create the framework for a React component.
We want the StackTight
component to use the Chakra Stack
component, so let's import that and its props.
From the component, we want to return the Chakra Stack
and any props we pass in. Use destructuring to pull out children
, gap
, and the rest of the props into ...props
.
We'll return the Stack
with the rest of the props {...props}
wrapping {children}
.
Now, let's set our gap to the defaultGap
we set earlier.
Creating the HStack and VStack Wrapper Components
Continuing in the Stacks.tsx
file, let's import HStack
and HStackProps
.
We can copy/paste the component we created for Stack
as a starter for HStack
, replacing the component name, prop types, and returned component.
We can repeat the same thing for VStack
.
Once that's all completed, our Stacks.tsx
file looks like this:
Using Wrapped Components
In our App.tsx
, let's check out the difference between using Stack
and our new StackTight
.
We can import Stack
from the Chakra package, and import StackTight
from our src/components/Stacks.tsx
file.
Check out the results on Replit . You can see that our tight stack has no gap between the two items, whereas the Chakra stack has a 0.5rem gap by default. We can even still pass it props, like style
, and they work because we spread the props into the returned Stack
component.
Now, anywhere we use our StackTight
component, we can easily update the default gap if we decide to change it later.