import React, { ComponentProps, ComponentPropsWithRef, ComponentPropsWithoutRef, ElementType, JSXElementConstructor, PropsWithChildren, ReactElement } from 'react'; import { ITheme } from '../theme'; import { CssResponsiveProps } from './css'; export type IArray = Array; export type IObject = { [key: string]: IObject | IArray | string; }; export type ThemeProps = { theme: ITheme; className?: string; }; // interface ExoticComponentWithDisplayName

extends React.ExoticComponent

{ defaultProps?: Partial

; displayName?: string; } // export type AnyComponent

= ExoticComponentWithDisplayName

| React.ComponentType

; // export type KnownTarget = keyof React.JSX.IntrinsicElements | Element | AnyComponent; // export type NativeElement = KnownTarget; // export type NativeProps = Omit, keyof U> & { as?: ElementType, children?: ReactNode }; // export type NativeThemeProps = NativeProps & ThemeProps & T; // export type ComponentProps = NativeThemeProps; // export type ComponentCssResponsiveProps = NativeThemeProps & CssResponsiveProps; // export type ComponentGridRowProps = NativeThemeProps & GridRowProps; // props // Source: https://github.com/emotion-js/emotion/blob/main/packages/react/types/helper.d.ts // A more precise version of just React.ComponentPropsWithoutRef on its own export type PropsOf> = React.JSX.LibraryManagedAttributes>; // see // https://www.benmvp.com/blog/polymorphic-react-components-typescript/ // https://www.benmvp.com/blog/forwarding-refs-polymorphic-react-component-typescript/ // also // https://scottbolinger.com/create-a-polymorphic-component-with-typescript-and-react/ // polymorphic /** * Allows for extending a set of props (`ExtendedProps`) by an overriding set of props * (`OverrideProps`), ensuring that any duplicates are overridden by the overriding * set of props. */ // export type ExtendableProps = OverrideProps & Omit; /** * Allows for inheriting the props from the specified element type so that * props like children, className & style work, as well as element-specific * attributes like aria roles. The component (`C`) must be passed in. */ // export type InheritableElementProps = ExtendableProps, P>; /** * An override of the default HTML tag. * Can also be another React component. */ /* type AsProp = { as?: C; displayName?: string; }; type PropsToOmit = keyof (AsProp & P); export type PolymorphicComponentProp = React.PropsWithChildren

> & Omit, PropsToOmit>; export type PolymorphicComponentPropWithRef = PolymorphicComponentProp & { ref?: PolymorphicRef }; */ export type AsProp = { as?: C; }; export type PropsToOmit = keyof (AsProp & P); export type PolymorphicComponentProp = PropsWithChildren> & Omit, PropsToOmit>; export type PolymorphicComponentPropWithoutRef = PolymorphicComponentProp; export type PolymorphicComponentPropWithRef = PolymorphicComponentProp & { ref?: PolymorphicRef } & { displayName?: string; }; /** * Utility type to extract the `ref` prop from a polymorphic component */ export type PolymorphicRef = ComponentPropsWithRef['ref']; // generics // export type UIDevProps = {}; export type UIDevProps = { displayName?: string }; export type UIStyledProps

= CssResponsiveProps & P; export type NativeAttrs = Omit, keyof P>; export type UIComponentProps

= P & NativeAttrs; export type UIStyledComponentProps

> = S & NativeAttrs; export type UIComponentPropsWithoutRef = PolymorphicComponentPropWithoutRef; export type UIComponentPropsWithRef = PolymorphicComponentPropWithRef; export type UIStyledComponent = React.FC, keyof P>>; export type UIStyledComponentPropsWithoutRef = UIComponentPropsWithoutRef> & { as?: ReactElement }; export type UIComponent = ( (props: UIStyledComponentPropsWithoutRef) => // Omit>, 'ReactNode'> ReactElement

| null ); export type UIStyledComponentPropsWithRef = UIComponentPropsWithRef>; export type UIComponentWithRef = ( (props: UIStyledComponentPropsWithRef) => // UIElement> any ) & { displayName?: string }; // export type UIComponentWithRef = React.FC>>; // export type UIForwardingComponentWithRef = (props: P, ref?: PolymorphicRef) => UIComponentWithRef; /* type Props = {}; type ButtonProps = PolymorphicComponentPropWithRef & CssResponsiveProps; type ButtonComponent = (props: ButtonProps) => ReactElement | null; const PolymorphicButton: ButtonComponent = forwardRef(({ as, color, children, ...props }: ButtonProps, ref?: PolymorphicRef) => { const Component = as || 'button'; return ( {children} ); }); */