<Zhenya>
← Сниппеты

Component dynamic tag

Use react component as another component

Component with dynamic tag

export type Prefer<P, T> = P & Omit<T, keyof P>;
export type ElementPropsWithoutRef<T extends ElementType> = Pick<
ComponentPropsWithoutRef<T>,
keyof ComponentPropsWithoutRef<T>
>;
export type DynamicHTMLProps<OwnProps, Type extends ElementType> = Prefer<
OwnProps,
ElementPropsWithoutRef<Type>
>;
type ButtonProps<As extends React.ElementType> = {
variant: 'primary' | 'secondary'
as: As
}
export const Button = <As extends React.ElementType = 'button'>({
as,
children,
variant,
...props
}: DynamicHTMLProps<ButtonProps<As>, As>) => {
const Tag: React.ElementType = as || 'button';
return <Tag {...props} className={variant}>{children}</Tag>;
};

And with forward ref

// React 🥰
function fixedForwardRef<T, P = {}>(
render: (props: P, ref: React.Ref<T>) => React.ReactNode
): (props: P & React.RefAttributes<T>) => React.ReactNode {
return React.forwardRef(render) as any;
}
export const ButtonRaw = <As extends React.ElementType, Ref>(props: DynamicHTMLProps<ButtonProps<As>, As>, ref: Ref) => {
const { as = 'button', variant, children, ...rest } = props;
const Tag: React.ElementType = props.as;
return <Tag {...rest} className={variant} ref={ref}>{children}</Tag>;
};
const Button = fixedForwardRef(ButtonRaw);