Estoy tratando de crear un componente de utilidad para mostrar tipografía y debe ser semántico (no solo un div ). Quiero limitar las opciones para que las etiquetas sean solo una etiqueta h1 , h2 , h3 o p .
Probé el siguiente código, donde si se body1 o body2 , se asignará a una etiqueta <p> :
type Props = { children: string; variant?: 'h1' | 'h2' | 'h3' | 'body1' | 'body2'; } export default function Typography({children, variant}: Props) { if (variant === 'body1' || variant === 'body2') return <p>{children}</p> const Tag = variant || 'p'; return <Tag>{children}</Tag> } Pero cuando uso este componente, no me permite pasar los atributos html subyacentes, como className , etc. Así que leí sobre el polimorfismo en TypeScript y vi este código en uno de los tutoriales:
import { ComponentProps, ElementType, ReactNode } from "react"; type TextOwnProps<E extends ElementType> = { size?: "sm" | "md" | "lg"; color?: "primary" | "secondary"; children: ReactNode; as?: E; }; type TextProps<E extends ElementType> = TextOwnProps<E> & Omit<ComponentProps<E>, keyof TextOwnProps<E>>; export const Text = <E extends ElementType = "div">({ size, color, children, as, }: TextProps<E>) => { const Component = as || "div"; return <Component className={`class-with-${size}-${color}`}>{children}</Component>; }; Esto hace posible pasar atributos html (y elimina el conflicto de accesorios personalizados). Sin embargo, no sé cómo limitar esto solo a los valores que quiero. El as prop muestra todos los elementos html válidos.
React.js no es compatible con esta sintaxis en JSX, pero puede usar declaraciones de cambio y verificar el nombre de la etiqueta. Editado: React.createElement (como accesorios, niños) https://ru.reactjs.org/docs/react-without-jsx.html