|
| 1 | +// credit https://github.com/ariakit/ariakit/blob/main/packages/ariakit-utils/src/types.ts |
| 2 | + |
| 3 | +import { |
| 4 | + ComponentPropsWithRef, |
| 5 | + ElementType, |
| 6 | + HTMLAttributes, |
| 7 | + ReactNode, |
| 8 | + RefAttributes, |
| 9 | +} from "react" |
| 10 | + |
| 11 | +/** |
| 12 | + * Any object. |
| 13 | + */ |
| 14 | +export type AnyObject = Record<keyof any, any> |
| 15 | + |
| 16 | +/** |
| 17 | + * Render prop type. |
| 18 | + * @template P Props |
| 19 | + * @example |
| 20 | + * const children: RenderProp = (props) => <div {...props} />; |
| 21 | + */ |
| 22 | +export type RenderProp<P = AnyObject> = (props: P) => JSX.Element | null |
| 23 | + |
| 24 | +/** |
| 25 | + * The `as` prop. |
| 26 | + * @template P Props |
| 27 | + */ |
| 28 | +export type As<P = any> = ElementType<P> |
| 29 | + |
| 30 | +/** |
| 31 | + * The `children` prop that supports a function. |
| 32 | + * @template T Element type. |
| 33 | + */ |
| 34 | +export type Children<T = any> = |
| 35 | + | ReactNode |
| 36 | + | RenderProp<HTMLAttributes<T> & RefAttributes<T>> |
| 37 | + |
| 38 | +/** |
| 39 | + * Props with the `as` prop. |
| 40 | + * @template T The `as` prop |
| 41 | + * @example |
| 42 | + * type ButtonOptions = Options<"button">; |
| 43 | + */ |
| 44 | +export type Options<T extends As = any> = { as?: T } |
| 45 | + |
| 46 | +/** |
| 47 | + * Props that automatically includes HTML props based on the `as` prop. |
| 48 | + * @template O Options |
| 49 | + * @example |
| 50 | + * type ButtonHTMLProps = HTMLProps<Options<"button">>; |
| 51 | + */ |
| 52 | +export type HTMLProps<O extends Options> = { |
| 53 | + children?: Children |
| 54 | +} & Omit<ComponentPropsWithRef<NonNullable<O["as"]>>, keyof O> |
| 55 | + |
| 56 | +/** |
| 57 | + * Options & HTMLProps |
| 58 | + * @template O Options |
| 59 | + * @example |
| 60 | + * type ButtonProps = Props<Options<"button">>; |
| 61 | + */ |
| 62 | +export type Props<O extends Options> = O & HTMLProps<O> |
| 63 | + |
| 64 | +/** |
| 65 | + * A component that supports the `as` prop and the `children` prop as a |
| 66 | + * function. |
| 67 | + * @template O Options |
| 68 | + * @example |
| 69 | + * type ButtonComponent = Component<Options<"button">>; |
| 70 | + */ |
| 71 | +export type Component<O extends Options> = { |
| 72 | + <T extends As>( |
| 73 | + props: Omit<O, "as"> & |
| 74 | + Omit<HTMLProps<Options<T>>, keyof O> & |
| 75 | + Required<Options<T>>, |
| 76 | + ): JSX.Element | null |
| 77 | + (props: Props<O>): JSX.Element | null |
| 78 | + displayName?: string |
| 79 | +} |
0 commit comments