Polymorphic
The term Polymorphic
means a special way to define the component element from outside, by using a property which is commonly called as
or tag
.
Lualtek UI react-components provide typescript types to create these polymorphic components.
Basic example
In this example we can see how to create a polymorphic Button
component:
import React, { forwardRef } from "react";
import type { Polymorphic } from "@lualtek/react-components";
/* Define the default element tag */
const ElementType = "button";
/* Define Box's custom properties */
type ButtonProps = {};
/* Set the default HTMLELement type */
type PolymorphicButton = Polymorphic.ForwardRefComponent<
typeof ElementType,
ButtonProps
>;
/**
* Rename as into Wrapper andmake
* it a <button> element as default
*/
const Button = forwardRef(
({ as: Component = ElementType, ...props }, forwardedRef) => (
<Component ref={forwardedRef} {...props} />
)
) as PolymorphicButton;
Once created, you can now import and use the Button
component as following:
export default () => (
<>
<Button>As "<button>"</Button>
<Button as="a" href="https://www.google.com">
As "<a>"
</Button>
</>
);
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'
Extending polymorphic components
Maintain polymorphism when wrapping a polymorphic component in your own custom component by combining the above utilities.
import React from "react";
import { Button, Polymorphic } from "@lualtek/react-components";
/* Define custom props for IconButton */
type IconButtonProps = {
size?: "small" | "large";
};
/* Get the element type from the base Button component
* extract their props and merge them with IconButtonProps
*/
type PolymorphicIconButton = Polymorphic.ForwardRefComponent<
Polymorphic.IntrinsicElement<typeof Button>,
Polymorphic.OwnProps<typeof Button> & IconButtonProps
>;
/* Define the IconButton component as PolymorphicIconButton */
const IconButton = React.forwardRef(
({ size = "small", ...props }, forwardedRef) => (
<Button {...props} ref={forwardedRef} />
)
) as PolymorphicIconButton;
/* Usage */
export default () => <IconButton as="a" size="large" />;