Creates strongly typed polymorphic components.
Typed attributes based on the `as` prop
Typed props based on the `as` prop
Typed events based on the `as` prop
Install the component from your command line.
npm install @radix-ui/react-polymorphic
Import the component.
import type * as Polymorphic from '@radix-ui/react-polymorphic';
Make a polymorphic Box
component.
import React from 'react';
import type * as Polymorphic from '@radix-ui/react-polymorphic';
type PolymorphicBox = Polymorphic.ForwardRefComponent<'div', {}>;
const Box = React.forwardRef(({ as: Comp = 'div', ...props }, forwardedRef) => (
<Comp {...props} ref={forwardedRef} />
)) as PolymorphicBox;
export default () => (
<Box>
<Box as="h1">This is a h1</Box>
<Box as="button">This is a button</Box>
</Box>
);
Adds polymorphic as
prop types to a forwardRef
component.
Polymorphic.ForwardRefComponent<
keyof JSX.IntrinsicElements,
OwnProps
>
The OwnProps
should not contain DOM attributes. These will be added for you. Use the Polymorphic.OwnProps
utility to extract these from existing polymorphic components.
Polymorphic.ForwardRefComponent<
'button',
{ variant: 'solid' | 'outline' }
>
Extract props from a polymorphic component, excluding its DOM props.
Polymorphic.OwnProps<
Polymorphic.ForwardRefComponent
>;
Polymorphic.OwnProps<typeof Button>;
// { variant: 'solid' | 'outline' }
Extract the JSX.IntrinsicElements
key from a polymorphic component.
Polymorphic.IntrinsicElement<
Polymorphic.ForwardRefComponent
>;
Polymorphic.IntrinsicElement<typeof Button>;
// 'button'
Maintain polymorphism when wrapping a polymorphic component in your own custom component by combining the above utilities.
import React from 'react';
import * as Dialog from '@radix-ui/react-dialog';
import type * as Polymorphic from '@radix-ui/react-polymorphic';
type PolymorphicDialogContent = Polymorphic.ForwardRefComponent<
Polymorphic.IntrinsicElement<typeof Dialog.Content>,
Polymorphic.OwnProps<typeof Dialog.Content> & {
size?: 'small' | 'large';
}
>;
const DialogContent = React.forwardRef(
({ size = 'small', ...props }, forwardedRef) => (
<Dialog.Content {...props} className={size} ref={forwardedRef} />
)
) as PolymorphicDialogContent;
export default () => (
<Dialog.Root>
<Dialog.Trigger>Open</Dialog.Trigger>
<Dialog.Overlay />
<DialogContent as="article">
<p>This is an article</p>
</DialogContent>
</Dialog.Root>
);