The as prop and Custom component
By default, all Chakra components work with the as
prop. There might be some
cases where you need to create smaller components with pre-defined styles, and
need the as
prop to work as well.
For example, let's say you create a Card
component with pre-defined styles
like this:
const Card = (props: BoxProps) => (<Box px='4' py='5' rounded='sm' shadow='lg' {...props} />)
and you need to consume this component in a way that works with the as
prop,
like this:
const Usage = () => <Card as='button'>This is a card</Card>
You might run into type errors like this:
Type '{ children: string; as: string; }' is not assignable to type 'IntrinsicAttributes & BoxProps'.Property 'as' does not exist on type 'IntrinsicAttributes & BoxProps'.
To resolve this, you have 3 options
Option 1: Using forwardRef
from @chakra-ui/react
#
This is the recommended approach as it ensures your components forwards their reference properly.
Note 🚨: You need to use forwardRef from chakra-ui not react.
import { forwardRef, Box, BoxProps } from '@chakra-ui/react'const Card = forwardRef<BoxProps, 'div'>((props, ref) => (<Box px='4' py='5' rounded='sm' shadow='lg' ref={ref} {...props} />))
Option 2: Cast the component as a ChakraComponent
#
The ChakraComponent
is a type we use internally to mark specific components as
Chakra components rather than using React.FC
.
This is because a ChakraComponent
gets its props from the React component or
element type, and adds chakra specific style props.
ChakraComponent
takes 2 type generic, the element type (like "div", "button",
etc), and any custom props (like isOpen
, isDisabled
, etc)
import { ChakraComponent, Box, BoxProps } from '@chakra-ui/react'type DivComponent = ChakraComponent<'div', {}>const Card = ((props: BoxProps) => (<Box px='4' py='5' rounded='sm' shadow='lg' {...props} />)) as DivComponent
Option 3: Use the chakra
factory function#
The Chakra factory function is still a work in progress but it can be useful in this case as well. It can also be used to convert a non-chakra component into a Chakra enabled component.
What you need to do is to call the chakra
function and pass it any element or
component type.
import { chakra } from '@chakra-ui/react'const Card = chakra('div', {// attach style propsbaseStyle: {px: '4',py: '5',rounded: 'sm',shadow: 'lg',},})
These are the cases you can get the as
prop working with custom components. At
least for now.