Chakra Factory
分类:
日期:
2022-2-28标签:
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.buttonpx="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" />;}
Considering that Chakra uses
emotion
under the hood, ensure the non-chakra component acceptsclassName
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 propsconst isChakraProp = !shouldForwardProp(prop);if (isChakraProp) return false;// else, only forward `sample` propreturn ['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 propsconst isChakraProp = !shouldForwardProp(prop);if (isChakraProp) return false;// forward valid HTML propsconst isValidProp = isValidHTMLProp(prop);if (isValidProp) return true;// else, only forward `sample` propreturn ['sample'].includes(prop);},});