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