Chakra Factory
Use the chakra factory to create supercharged components
Overview
Chakra factory serves as a way to create supercharged JSX component from any HTML element to enable them receive JSX style props.
import { chakra } from "@chakra-ui/react"
The chakra factory can be used in two ways: as a JSX element or as a factory function.
JSX Element
Style props are CSS properties that you can pass as props to your components.
With the JSX factory, you can use chakra.<element>
syntax to create JSX
elements that support style props.
import { chakra } from "@chakra-ui/react"
const Button = ({ children }) => (
<chakra.button bg="blue.500" color="white" py="2" px="4" rounded="md">
{children}
</chakra.button>
)
Factory function
Use the chakra
function to convert native elements or custom components. The
key requirement is that the component must accept className
as props.
const Link = chakra("a")
function Example() {
return <Link bg="red.200" href="https://chakra-ui.com" />
}
Another example with a custom component.
import * as RadixScrollArea from "@radix-ui/react-scroll-area"
const ScrollArea = chakra(RadixScrollArea.Root)
function Example() {
return (
<ScrollArea>
<RadixScrollArea.Viewport>
<div>Hello</div>
</RadixScrollArea.Viewport>
</ScrollArea>
)
}
Attaching styles
Use the chakra
function to attach styles or recipes to components.
const Link = chakra("a", {
base: {
bg: "papayawhip",
color: "red.500",
},
})
// usage: <Link href="https://chakra-ui.com" />
Attaching recipes
Here's an example of attaching a recipe to the component.
const Card = chakra("div", {
base: {
shadow: "lg",
rounded: "lg",
bg: "white",
},
variants: {
variant: {
outline: {
border: "1px solid",
borderColor: "red.500",
},
solid: {
bg: "red.500",
color: "white",
},
},
},
})
// usage: <Card variant="outline" />
Forwarding props
By default, the chakra
factory only filters chakra related style props from
getting to the DOM. For more fine-grained control of how props are forwarded,
pass the shouldForwardProp
option.
Here's an example that forwards all props that doesn't start with $
const Component = chakra("div", {
shouldForwardProp(prop) {
return !prop.startsWith("$")
},
})
To create custom forward props logic, combine the
@emotion/is-prop-valid
package and the isValidProperty
from Chakra UI.
import { chakra, defaultSystem } from "@chakra-ui/react"
import shouldForwardProp from "@emotion/is-prop-valid"
const { isValidProperty } = defaultSystem
const Component = chakra("div", {
shouldForwardProp(prop, variantKeys) {
const chakraSfp = !variantKeys?.includes(prop) && !isValidProperty(prop)
return shouldForwardProp(prop) && chakraSfp
},
})
Default Props
Use the defaultProps
option to pass default props to the component.
const Button = chakra(
"button",
{
base: {
bg: "blue.500",
color: "white",
},
},
{ defaultProps: { type: "button" } },
)
Polymorphism
Every component created with the chakra factory can accept the as
and
asChild
props to change the underlying DOM element.
<Button as="a" href="https://chakra-ui.com">
Chakra UI
</Button>
or
<Button asChild>
<a href="https://chakra-ui.com">Chakra UI</a>
</Button>