I have a React component written using Typescript. It receives three props:
type,className, andchildren
Its job is to return an HTML element based on the value sent through type. Here’s the component:
import React, { ReactNode } from "react"
import { cn } from "@/lib/utils"
interface GradientTextProps extends React.HTMLAttributes<HTMLElement> {
children: ReactNode // Specify ReactNode type for children prop
className?: string
type?: string
}
export default function GradientText({
children,
className,
type,
}: GradientTextProps) {
const style = `leading-tight ${cn(
"bg-gradient-to-r from-primary via-red-400 to-pink-500 text-transparent bg-clip-text",
className,
)}`
if (type === "h1") return <h1 className={style}>{children}</h1>
if (type === "h2") return <h2 className={style}>{children}</h2>
if (type === "h3") return <h3 className={style}>{children}</h3>
if (type === "h4") return <h4 className={style}>{children}</h4>
if (type === "h5") return <h5 className={style}>{children}</h5>
if (type === "h6") return <h6 className={style}>{children}</h6>
return <p className={style}>{children}</p>
}
// Set defaultProps for className
GradientText.defaultProps = {
className: "",
type: "p",
}
So, the following usage:
<GradientText type="h1" className="text-7xl font-bold">gradient paragraph</GradientText>
Would generate:
<h1 className="leading-tight text-7xl font-bold bg-gradient-to-r from-primary via-red-400 to-pink-500 text-transparent bg-clip-text">
gradient paragraph
</h1>
When there’s no type attribute, the component defaults to <p>.
Here, I am using six separate if statements to map six different type values to corresponding HTML tags. I want to make it dynamic. So that the component could just look up the given type value against a set array and dynamically generate the appropriate element—<p> for type="p", <h1> for type="h1", and so on.
>Solution :
You can do something like this:
const htmlTagMap: { [key: string]: React.ElementType } = {
h1: 'h1',
h2: 'h2',
h3: 'h3',
h4: 'h4',
h5: 'h5',
h6: 'h6',
p: 'p'
};
export default function GradientText({
children,
className,
type = "p",
}: GradientTextProps) {
const Tag = tagMap[type] || 'p'; // default your tag to <p>
const style = '...';
return <Tag className={style}>{children}</Tag>;
}
Let me know if this works.