Skip to main content

Chakra Factory

Chakra factory serves as an object of chakra enabled JSX elements, and also a function that can be used to enable custom component receive chakra's style props.

import { chakra } from "@chakra-ui/react"

Chakra JSX Elements

Create base html elements with theme-aware style props using chakra.<element> notation. For example, if you want a plain html button with ability to pass chakra styles, you can write <chakra.button />.

<chakra.button
px='3'
py='2'
bg='green.200'
rounded='md'
_hover={{ bg: 'green.300' }}
>
Click me
</chakra.button>

This reduces the need to create custom component wrappers and name them. This syntax is available for common html elements. See the reference for the full list of elements supported.

<chakra.h1 fontSize='lg'> Heading </chakra.h1>

Chakra factory function

This is a function that converts non-chakra components or jsx element to chakra-enabled components so you can pass style props to them.

Consider a package called react-input-autoresize, let's use the chakra factory function to make possible to pass style props.

The function will infer the prop types from the wrapped component and also add chakra style props.

import { chakra } from '@chakra-ui/react';
import Textarea from 'react-input-autoresize';

const AutoResizeInput = chakra(Textarea);

function Example() {
return <AutoResizeInput bg='red.200' fontSize='12px' />;
}
note

Considering that Chakra uses emotion under the hood, ensure the non-chakra component accepts className as props for this to work correctly

Attaching styles

In some instances, you might need to attach specific styles to the component wrapped in the chakra factory

const AutoResizeInput = chakra(AutoResizeInput, {
baseStyle: {
bg: 'papayawhip',
color: 'red.500',
},
});

You can also use the chakra factory on jsx elements as well.

const Card = chakra('div', {
baseStyle: {
shadow: 'lg',
rounded: 'lg',
bg: 'white',
},
});

Allowing custom props to be forwarded

By default, the chakra factory only filters chakra related style props from getting to the DOM. For more fine-grained control of how and what prop should be forwarded, pass the shouldForwardProp option.

Here's a simple example that allows all props (including chakra's style props) to pass through except the sample prop.

const Div = chakra('div', {
shouldForwardProp: (prop) => !['sample'].includes(prop),
});

Another example that combines the default shouldForwardProp from Chakra UI with custom logic.

import { chakra, shouldForwardProp } from '@chakra-ui/react';

const Div = chakra('div', {
shouldForwardProp: (prop) => {
// don't forward Chakra's props
const isChakraProp = !shouldForwardProp(prop);
if (isChakraProp) return false;

// else, only forward `sample` prop
return ['sample'].includes(prop);
},
});

To filter non-HTML attributes, you can leverage @emotion/is-prop-valid package.

import isValidHTMLProp from '@emotion/is-prop-valid';
import { chakra, shouldForwardProp } from '@chakra-ui/react';

const Div = chakra('div', {
shouldForwardProp: (prop) => {
// don't forward Chakra's props
const isChakraProp = !shouldForwardProp(prop);
if (isChakraProp) return false;

// forward valid HTML props
const isValidProp = isValidHTMLProp(prop);
if (isValidProp) return true;

// else, only forward `sample` prop
return ['sample'].includes(prop);
},
});