/** * Shared types for Ariakit React components. * @module Type utilities */ import type { AnyObject, EmptyObject } from "@ariakit/utils"; import type * as React from "react"; /** * Render prop type. * @template P Props * @example * const children: RenderProp = (props) =>
; */ export type RenderProp< P = React.HTMLAttributes & { ref?: React.Ref }, > = (props: P) => React.ReactNode; /** * The `wrapElement` prop. */ export type WrapElement = (element: React.ReactElement) => React.ReactElement; /** * Custom props including the `render` prop. */ export interface Options { wrapElement?: WrapElement; /** * Allows the component to be rendered as a different HTML element or React * component. The value can be a React element or a function that takes in the * original component props and gives back a React element with the props * merged. * * Some Ariakit components detect the type of the underlying element when * they mount. If the render element's type may change while the component * is mounted, pass a * [`key`](https://react.dev/learn/preserving-and-resetting-state) prop that * changes with the element type so React remounts the component with the * new element. Remounting resets uncontrolled state, so keep the relevant * state controlled: * ```jsx * setChecked(!checked)} * render={custom ?
: } * /> * ``` * * Check out the [Composition](https://ariakit.com/guide/composition) guide * for more details. */ render?: RenderProp | React.ReactElement; } /** * HTML props based on the element type, excluding custom props. * @template T The element type. * @template P Custom props. * @example * type ButtonHTMLProps = HTMLProps<"button", { custom?: boolean }>; */ export type HTMLProps< T extends React.ElementType, P extends AnyObject = EmptyObject, > = Omit, keyof P> & { [index: `data-${string}`]: unknown; }; /** * Props based on the element type, including custom props. * @template T The element type. * @template P Custom props. */ export type Props< T extends React.ElementType, P extends AnyObject = EmptyObject, > = P & HTMLProps; /** * A component hook that supports the `render` prop and returns HTML props based * on the element type. * @template T The element type. * @template P Custom props. * @example * type UseButton = Hook<"button", { custom?: boolean }>; */ export type Hook< T extends React.ElementType, P extends AnyObject = EmptyObject, > = ( props?: Props, ) => HTMLProps;