Radix homepageRadix Homepage
PrimitivesBeta

Polymorphic

Creates strongly typed polymorphic components.

Features

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

Usage

Polymorphic.ForwardRefComponent<
'button',
{ variant: 'solid' | 'outline' }
>

Extract props from a polymorphic component, excluding its DOM props.

Polymorphic.OwnProps<
Polymorphic.ForwardRefComponent
>;

Usage

Polymorphic.OwnProps<typeof Button>;
// { variant: 'solid' | 'outline' }

Extract the JSX.IntrinsicElements key from a polymorphic component.

Polymorphic.IntrinsicElement<
Polymorphic.ForwardRefComponent
>;

Usage

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>
);