Polymorphic

Creates strongly typed polymorphic components.

This package has been deprecated in favour of the asChild prop. Learn more about how to change the rendered element here.

Features

    Typed attributes based on the `as` prop

    Typed props based on the `as` prop

    Typed events based on the `as` prop

Installation

Install the component from your command line.

npm install @tealess/polymorphic

Import

Import the component.

import type * as Polymorphic from '@tealess/polymorphic';

Basic example

Make a polymorphic Box component.

import React from "react";
import type * as Polymorphic from "@tealess/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>
);

API Reference

ForwardRefComponent

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" }>;

OwnProps

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

Polymorphic.OwnProps<Polymorphic.ForwardRefComponent>;

Usage

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

IntrinsicElement

Extract the JSX.IntrinsicElements key from a polymorphic component.

Polymorphic.IntrinsicElement<Polymorphic.ForwardRefComponent>;

Usage

Polymorphic.IntrinsicElement<typeof Button>;
// 'button'

Examples

Extending a Polymorphic component

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 "@tealess/dialog";
import type * as Polymorphic from "@tealess/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>
);