import { AnyFunction, AnyObject, EmptyObject } from "@ariakit/utils";
import * as React from "react";
import { ComponentType, DependencyList, EffectCallback, HTMLAttributes, MutableRefObject, ReactElement, Ref, RefCallback, RefObject, SetStateAction } from "react";
import { Store } from "@ariakit/store";
//#region src/types.d.ts
/**
 * Render prop type.
 * @template P Props
 * @example
 * const children: RenderProp = (props) => <div {...props} />;
 */
type RenderProp<P = React.HTMLAttributes<any> & {
  ref?: React.Ref<any>;
}> = (props: P) => React.ReactNode;
/**
 * The `wrapElement` prop.
 */
type WrapElement = (element: React.ReactElement) => React.ReactElement;
/**
 * Custom props including the `render` prop.
 */
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
   * <Checkbox
   *   key={custom ? "custom" : "native"}
   *   checked={checked}
   *   onChange={() => setChecked(!checked)}
   *   render={custom ? <div /> : <input />}
   * />
   * ```
   *
   * 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 }>;
 */
type HTMLProps<T extends React.ElementType, P extends AnyObject = EmptyObject> = Omit<React.ComponentPropsWithRef<T>, keyof P> & {
  [index: `data-${string}`]: unknown;
};
/**
 * Props based on the element type, including custom props.
 * @template T The element type.
 * @template P Custom props.
 */
type Props<T extends React.ElementType, P extends AnyObject = EmptyObject> = P & HTMLProps<T, P>;
/**
 * 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 }>;
 */
type Hook<T extends React.ElementType, P extends AnyObject = EmptyObject> = <ElementType extends React.ElementType = T>(props?: Props<ElementType, P>) => HTMLProps<ElementType, P>;
//#endregion
//#region src/hooks.d.ts
/**
 * `React.useLayoutEffect` that fallbacks to `React.useEffect` on server side.
 */
declare const useSafeLayoutEffect: typeof React.useLayoutEffect;
/**
 * Returns a value that never changes even if the argument is updated.
 * @example
 * function Component({ prop }) {
 *   const initialProp = useInitialValue(prop);
 * }
 */
declare function useInitialValue<T>(value: T | (() => T)): T;
/**
 * Creates a `React.RefObject` that is constantly updated with the incoming
 * value.
 * @example
 * function Component({ prop }) {
 *   const propRef = useLiveRef(prop);
 * }
 */
declare function useLiveRef<T>(value: T): RefObject<T>;
/**
 * Creates a stable callback function that has access to the latest state and
 * can be used within event handlers and effect callbacks. Throws when used in
 * the render phase.
 * @example
 * function Component(props) {
 *   const onClick = useEvent(props.onClick);
 *   React.useEffect(() => {}, [onClick]);
 * }
 */
declare function useEvent<T extends AnyFunction>(callback?: T): T;
/**
 * Creates a React state that calls a callback function whenever the state
 * changes and rolls back to the previous state on cleanup.
 */
declare function useTransactionState<T>(callback?: ((state: SetStateAction<T | null>) => void) | null): readonly [T | null, React.Dispatch<SetStateAction<T | null>>];
/**
 * Merges React Refs into a single memoized function ref so you can pass it to
 * an element.
 * @example
 * const Component = React.forwardRef((props, ref) => {
 *   const internalRef = React.useRef();
 *   return <div {...props} ref={useMergeRefs(internalRef, ref)} />;
 * });
 */
declare function useMergeRefs(...refs: Array<Ref<any> | undefined>): ((value: unknown) => (() => void) | undefined) | undefined;
/**
 * Generates a unique ID. Uses React's useId if available.
 */
declare function useId(defaultId?: string): string | undefined;
/**
 * Uses React's useDeferredValue if available.
 */
declare function useDeferredValue<T>(value: T): T;
/**
 * Returns the tag name by parsing an element ref.
 * @example
 * function Component(props) {
 *   const ref = React.useRef();
 *   const tagName = useTagName(ref, "button"); // div
 *   return <div ref={ref} {...props} />;
 * }
 */
declare function useTagName(refOrElement?: RefObject<HTMLElement | null> | HTMLElement | null, type?: string | ComponentType): string | undefined;
/**
 * Returns the attribute value of an element.
 * @example
 * function Component(props) {
 *   const ref = React.useRef();
 *   const role = useAttribute(ref, "role", props.role);
 *   return <div ref={ref} {...props} />;
 * }
 */
declare function useAttribute(refOrElement: RefObject<HTMLElement | null> | HTMLElement | null, attributeName: string, defaultValue?: string): string | undefined;
/**
 * A `React.useEffect` that will not run on the first render.
 */
declare function useUpdateEffect(effect: EffectCallback, deps?: DependencyList): void;
/**
 * A `React.useLayoutEffect` that will not run on the first render.
 */
declare function useUpdateLayoutEffect(effect: EffectCallback, deps?: DependencyList): void;
/**
 * A React hook similar to `useState` and `useReducer`, but with the only
 * purpose of re-rendering the component.
 */
declare function useForceUpdate(): [never[], React.ActionDispatch<[]>];
/**
 * Returns an event callback similar to `useEvent`, but this also accepts a
 * boolean value, which will be turned into a function.
 */
declare function useBooleanEvent<T extends unknown[]>(booleanOrCallback: boolean | ((...args: T) => boolean)): (...args: T) => boolean;
/**
 * Returns props with an additional `wrapElement` prop.
 */
declare function useWrapElement<P>(props: P & {
  wrapElement?: WrapElement;
}, callback: WrapElement, deps?: DependencyList): P & {
  wrapElement: WrapElement;
};
/**
 * Merges the portalRef prop and returns a `domReady` to be used in the
 * components that use Portal underneath.
 */
declare function usePortalRef(portalProp?: boolean, portalRefProp?: RefCallback<HTMLElement> | MutableRefObject<HTMLElement | null>): {
  portalRef: ((value: unknown) => (() => void) | undefined) | undefined;
  portalNode: HTMLElement | null;
  domReady: true | HTMLElement | null;
};
/**
 * A hook that passes metadata props around without leaking them to the DOM.
 */
declare function useMetadataProps<T, K extends keyof any>(props: {
  onLoadedMetadataCapture?: AnyFunction & { [key in K]?: T; };
}, key: K, value: T): readonly [(AnyFunction & { [key in K]?: T | undefined; })[K] | undefined, {
  readonly onLoadedMetadataCapture: any;
}];
/**
 * Returns a function that checks whether the mouse is moving.
 */
declare function useIsMouseMoving(): () => boolean;
//#endregion
//#region src/misc.d.ts
/**
 * Sets both a function and object React ref.
 *
 * Returns a callback ref cleanup function when one is provided.
 */
declare function setRef<T>(ref: RefCallback<T> | MutableRefObject<T> | null | undefined, value: T): void | (() => void);
/**
 * Checks if an element is a valid React element with a ref.
 */
declare function isValidElementWithRef<P extends {
  ref?: Ref<any>;
}>(element: unknown): element is ReactElement<P> & {
  ref?: Ref<any>;
};
/**
 * Gets the ref property from a React element.
 */
declare function getRefProperty(element: unknown): Ref<any> | undefined;
/**
 * Merges two sets of props.
 */
declare function mergeProps<T extends HTMLAttributes<any>>(base: T, overrides: T): T;
//#endregion
//#region src/system.d.ts
/**
 * The same as `React.forwardRef` but passes the `ref` as a prop and returns a
 * component with the same generic type.
 *
 * Props holding `undefined` are dropped, so passing one behaves the same as
 * omitting it and the component keeps the value it computes for itself.
 */
declare function forwardRef<T extends React.FC<any>>(render: T): T;
/**
 * The same as `React.memo` but returns a component with the same generic type.
 */
declare function memo<T extends React.FC<any>>(Component: T, propsAreEqual?: (prevProps: Readonly<React.ComponentPropsWithoutRef<T>>, nextProps: Readonly<React.ComponentPropsWithoutRef<T>>) => boolean): T;
/**
 * Creates a React element that supports the `render` and `wrapElement` props.
 */
declare function createElement(Type: React.ElementType, props: Props<React.ElementType, Options>): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
/**
 * Creates a component hook that accepts props and returns props so they can be
 * passed to a React element.
 */
declare function createHook<T extends React.ElementType, P extends AnyObject = EmptyObject>(useProps: (props: Props<T, P>) => HTMLProps<T, P>): Hook<T, P>;
type StoreProvider<T extends Store> = React.ComponentType<{
  value: T | undefined;
  children?: React.ReactNode;
}>;
/**
 * Creates an Ariakit store context with hooks and provider components.
 */
declare function createStoreContext<T extends Store>(providers?: StoreProvider<T>[], scopedProviders?: StoreProvider<T>[]): {
  context: React.Context<T | undefined>;
  scopedContext: React.Context<T | undefined>;
  useContext: () => T | undefined;
  useScopedContext: (onlyScoped?: boolean) => T | undefined;
  useProviderContext: () => T | undefined;
  ContextProvider: (props: React.ComponentPropsWithoutRef<React.Provider<T | undefined>>) => React.JSX.Element;
  ScopedContextProvider: (props: React.ComponentPropsWithoutRef<React.Provider<T | undefined>>) => React.JSX.Element;
};
//#endregion
export { HTMLProps, Hook, Options, Props, RenderProp, WrapElement, createElement, createHook, createStoreContext, forwardRef, getRefProperty, isValidElementWithRef, memo, mergeProps, setRef, useAttribute, useBooleanEvent, useDeferredValue, useEvent, useForceUpdate, useId, useInitialValue, useIsMouseMoving, useLiveRef, useMergeRefs, useMetadataProps, usePortalRef, useSafeLayoutEffect, useTagName, useTransactionState, useUpdateEffect, useUpdateLayoutEffect, useWrapElement };
//# sourceMappingURL=index.d.ts.map