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.PropsWithChildren.

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 props
baseStyle: {
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.

Proudly made inNigeria by Segun Adebayo

Deployed by Vercel