type AsProp<C extends React.ElementType> = {
as?: C
}
type PropsToOmit<C extends React.ElementType, P> = keyof (AsProp<C> & P)
/**
* @example
*
* type TextProps<C extends React.ElementType> =
* PolymorphicComponentProp<
* C,
* { someProp?: string }
* >
*
* export const Text = <C extends React.ElementType = "span">({
* as,
* someProp = '',
* children = null,
* }: TextProps<C>) => {
* const Component = as || 'span'
*
* console.log(someProp)
*
* return (
* <Component {...style}>
* {children}
* </Component>
* )
* })
*/
export type PolymorphicComponentProp<
C extends React.ElementType,
Props,
> = React.PropsWithChildren<Props & AsProp<C>> &
Omit<React.ComponentPropsWithoutRef<C>, PropsToOmit<C, Props>>
/**
* @example
*
* type TextProps<C extends ElementType> = PolymorphicComponentPropWithRef<
* C,
* { color?: Rainbow | 'black' }
* >
*
* export const Text = forwardRef(
* <C extends ElementType = 'span'>(
* { as, color, children }: TextProps<C>,
* ref?: PolymorphicRef<C>,
* ) => {
* const Component = as || 'span'
*
* const style = color ? { style: { color } } : {}
*
* return (
* <Component {...style} ref={ref}>
* {children}
* </Component>
* )
* },
* )
*/
export type PolymorphicComponentPropWithRef<
C extends React.ElementType,
Props,
> = PolymorphicComponentProp<C, Props> & { ref?: PolymorphicRef<C> }
/**
* @example
*
* type TextProps<C extends ElementType> = PolymorphicComponentPropWithRef<
* C,
* { color?: Rainbow | 'black' }
* >
*
* export const Text = forwardRef(
* <C extends ElementType = 'span'>(
* { as, color, children }: TextProps<C>,
* ref?: PolymorphicRef<C>,
* ) => {
* const Component = as || 'span'
*
* const style = color ? { style: { color } } : {}
*
* return (
* <Component {...style} ref={ref}>
* {children}
* </Component>
* )
* },
* )
*/
export type PolymorphicRef<C extends React.ElementType> =
React.ComponentPropsWithRef<C>['ref']
Created
March 8, 2024 14:50
-
-
Save danilobjr/763b26c18c6727a5356f5fd469aa8551 to your computer and use it in GitHub Desktop.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment