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