welcome-ui
Version:
Customizable design system with react, typescript, tailwindcss and ariakit.
82 lines (81 loc) • 3.62 kB
TypeScript
import { ComponentProps, default as React } from 'react';
/**
* The following source code is mainly inspired by
* https://github.com/pluralsight/classic-design-system/blob/08f0962dec18d99e1799a16c7b7eac86f01cbc27/packages/util/src/primatives.ts
*/
export type As<BaseProps = any> = React.ElementType<BaseProps>;
/**
* Omit will not distribute over unions by default, this utility type will
* distribute it, allowing to omit keys from each member of the union.
*
* @example
* type A = { a: string; b: number }
* type B = { a: string; c: boolean }
* type Union = A | B
*
* // Without DistributiveOmit
* type Test1 = Omit<Union, 'a'> // never (because 'a' is in both A and B)
* type Test2 = Omit<Union, 'b'> // B (because 'b' is not in B)
*/
export type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
/**
* Injects in given props the one of the element
*/
export type ForwardRefProps<Props extends EmptyProps, CompType extends React.ElementType<any>> = MergeProps<Props, ComponentProps<CompType>>;
export interface ForwardRefWithAsRenderFunction<DefaultComponentType extends As, ComponentProps extends PropsType = Record<string, any>> {
(props: PropsFromAs<DefaultComponentType, ComponentProps>, ref: React.Ref<React.ElementRef<DefaultComponentType>>): null | React.ReactElement;
/**
* defaultProps are not supported on render functions
*/
defaultProps?: never;
displayName?: string;
/**
* propTypes are not supported on render functions
*/
propTypes?: never;
}
export interface FunctionComponentWithAs<DefaultComponentType extends As, ComponentProps extends PropsType> {
/**
* Inherited from React.FunctionComponent with modification to support `as`
*/
<CompType extends As = DefaultComponentType>(props: PropsWithAs<CompType, ComponentProps>, context?: any): null | React.ReactElement<any, any>;
/**
* Inherited from React.FunctionComponent
*/
defaultProps?: Partial<PropsWithAs<DefaultComponentType, ComponentProps>>;
displayName?: string;
}
/**
* This will merge two prop objects, giving P1 priority over P2
* In other words, any props in P1 that are also in P2 will override the ones in P2
* This is useful when combining the props of the `as` component with your own props
*/
export type MergeProps<P1 = EmptyProps, P2 = EmptyProps> = DistributiveOmit<P2, keyof P1> & P1;
/**
* Get the props of a component with `as` support
* This will take care of the ref and the merging of the props
*/
export type PropsFromAs<CompType extends As, ComponentProps extends PropsType> = React.PropsWithoutRef<PropsWithAs<CompType, ComponentProps>>;
/**
* Props of a component with `as` support
*/
export type PropsWithAs<CompType extends As, ComponentProps extends PropsType> = MergeProps<WithAs<CompType, ComponentProps>, React.ComponentProps<CompType>>;
/**
* An empty object type
*/
type EmptyProps = Record<never, never>;
/**
* PropsType can either be an object or null/undefined
*/
type PropsType = null | Record<string, any>;
/**
* Adds the `as` prop to a component's props
*/
type WithAs<DefaultComponentType extends As, ComponentProps extends EmptyProps> = MergeProps<{
as?: DefaultComponentType;
}, ComponentProps>;
/**
* Wraps a component with a forwardRef and adds the `as` prop support
*/
export declare function forwardRefWithAs<ComponentProps extends PropsType, DefaultComponentType extends As = 'div'>(render: ForwardRefWithAsRenderFunction<DefaultComponentType, ComponentProps>): FunctionComponentWithAs<DefaultComponentType, ComponentProps>;
export {};