1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export type PolymorphicProps<E extends React.ElementType = React.ElementType> = {
  as?: E
}

export type ComponentProps<E extends React.ElementType> = PolymorphicProps<E> &
  Omit<React.ComponentProps<E>, keyof PolymorphicProps>

const DEFAULT_ELEMENT = 'div'

export function Polymorphic<E extends React.ElementType = typeof DEFAULT_ELEMENT>({
  children,
  as,
  ...props
}: ComponentProps<E>) {
  const Component = as || DEFAULT_ELEMENT
  
  return <Component {...props}>{children}</Component>
}

1
<Polymorphic as="h1">Hello, world!</Polymorphic>

1
<Polymorphic>Hello, world!</Polymorphic>

1
2
3
<Polymorphic as="button" onClick={() => alert('Button clicked')}>
  Click me!
</Polymorphic>