Skip to main content

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.