Skip to content

Instantly share code, notes, and snippets.

@owanturist
Created September 23, 2022 05:43
Show Gist options
  • Save owanturist/64c6ad1ade812bc7e915c81d196f86a7 to your computer and use it in GitHub Desktop.
Save owanturist/64c6ad1ade812bc7e915c81d196f86a7 to your computer and use it in GitHub Desktop.
Polymorphic Box component
// https://github.com/ohansemmanuel/polymorphic-react-component
import React from "react";
type PolymorphicRef<TComponent extends React.ElementType> = React.ComponentPropsWithRef<TComponent>["ref"];
type AsProp<TComponent extends React.ElementType> = {
as?: TComponent;
};
type PropsToOmit<TComponent extends React.ElementType, TProps> = keyof (AsProp<TComponent> & TProps);
type PolymorphicComponentProp<TComponent extends React.ElementType, TProps = {}> = React.PropsWithChildren<
TProps & AsProp<TComponent>
> &
Omit<React.ComponentPropsWithoutRef<TComponent>, PropsToOmit<TComponent, TProps>>;
type PolymorphicComponentPropWithRef<TComponent extends React.ElementType, TProps = {}> = PolymorphicComponentProp<
TComponent,
TProps
> & {
ref?: PolymorphicRef<TComponent>;
};
export type BoxProps<C extends React.ElementType> = PolymorphicComponentPropWithRef<C>;
export type BoxComponent<TProps = unknown> = <C extends React.ElementType = "div">(
props: BoxProps<C> & TProps,
) => React.ReactElement | null;
export const Box: BoxComponent = React.forwardRef(
<TComponent extends React.ElementType = "div">(
{ as: component, ...props }: BoxProps<TComponent>,
ref?: PolymorphicRef<TComponent>,
) => {
const Component = component ?? "div";
return <Component ref={ref} {...props} />;
},
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment