The as prop and Custom component

分类:

other

日期:

2022-2-22

标签:

chakra

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.

footer logo

© 2022 Designed with chakra ui. Powered by contentlayerjs and nextjs etc. All rights reserved

TwitterYouTubeGithub