import { default as default_2 } from 'react';
import { JSX as JSX_2 } from 'react/jsx-runtime';

export declare interface AnimatePresenceProps {
    /**
     * Visibility of the component.
     */
    isVisible: boolean;
    /**
     * Initial state of the animation, if `true` the component won't animate in on render.
     * @defaultValue false
     */
    initial?: boolean;
    /**
     * Duration in miliseconds or object with enter and exit duration in miliseconds.
     * @defaultValue = 300
     */
    duration?: number | {
        enter: number;
        exit: number;
    };
}

export declare interface AnimatePresenceReturn {
    /**
     * Render your component **only** if `shouldRender` is `true`.
     */
    render: boolean;
    /**
     * `shouldAnimate` is an shorthand for animating the component in and out.
     */
    animate: boolean;
    /**
     * Duration of the current animation. Not necessary to use, but very useful if you have different durations for enter and exit.
     * You can use this so you don't have to repeat those values in your styles.
     */
    currentDuration: number;
    /**
     * Current state of the animation. Use it for full control of the animation in all states.
     */
    state: AnimatePresenceState;
}

export declare enum AnimatePresenceState {
    ENTERED = "entered",
    EXITED = "exited",
    EXITING = "exiting",
    ENTERING = "entering",
    MOUNTED = "mounted"
}

export declare type InViewHook<T extends HTMLElement> = [
/**
 * Pass this function to the `ref` prop of the DOM element you want to track visibility of.
 */
(node: T) => void,
/**
* Whether the target DOM element is in view, based on the provided options.
*/
boolean,
/**
* The DOM node itself, once set by the `setTargetRef` function.
*/
T | undefined
];

export declare interface PreferencesContext {
    /**
     * Whether the user has either turned on "prefers dark color scheme" in their OS-level settings, or has chosen the option exposed by your site via some UI.
     * @defaultValue false
     */
    prefersDarkColorScheme: boolean | null;
    /**
     * Accepts a single argument (Boolean) which toggles the `localStorage` state of `prefersDarkColorScheme`.
     */
    setPrefersDarkColorScheme: (value: boolean) => void;
    /**
     * Whether the user has either turned on "prefers reduced data" in their OS-level settings, or has chosen the option exposed by your site via some UI.
     * @defaultValue false
     */
    prefersReducedData: boolean | null;
    /**
     * Accepts a single argument (Boolean) which toggles the `localStorage` state of `prefersReducedData`.
     */
    setPrefersReducedData: (value: boolean) => void;
    /**
     * Whether the user has either turned on "prefers reduced motion" in their OS-level settings, or has chosen the option exposed by your site via some UI.
     */
    prefersReducedMotion: boolean | null;
    /**
     * Accepts a single argument (Boolean) which toggles the `localStorage` state of `prefersReducedMotion`.
     */
    setPrefersReducedMotion: (value: boolean) => void;
}

export declare enum Status {
    Idle = "idle",
    Pending = "pending",
    Success = "success",
    Error = "error"
}

/**
 * Helps you animate components in and out of the DOM
 *
 * @param {AnimatePresenceProps} props
 * @example
 * ```tsx
 * import { useState } from 'react'
 * import { useAnimatePresence } from '@wethegit/react-hooks'
 *
 * function Comp() {
 *   const [isVisibile, setIsVisible] = useState();
 *   const { render, animate } = useAnimatePresence({
 *     isVisible
 *   })
 *
 *   return (
 *     <>
 *       <button onClick={() => setIsVisible(cur => !cur)}>{render && 'Hide' : 'Show'}</button>
 *       {render && (
 *         <div classNames={`component ${animate && 'component-in'}`>Animate me</div>
 *       )}
 *     </>
 *   )
 * }
 * ```
 */
export declare function useAnimatePresence({ initial, duration, isVisible, }: AnimatePresenceProps): AnimatePresenceReturn;

/**
 * useAsync
 * @deprecated Use the new React `use` or `cache` APIs or `useDeferredValue` hook.
 * @param {Function} asyncFn - The asynchronous function to run
 * @param {Boolean} [deferred=false] - whether to save the function to a variable for later use (true) or run it instantly (false).
 * @returns {Object} Properties include a run() function which is used to subsequently call the function (if deferred); the resulting data; and the status and error states.
 *
 * @example
 * Run it instantly:
 * const { data, status, error } = useAsync(() => fetch("https://my-cool-api.com/some-endpoint"))
 * console.log(data)
 *
 * Deferred execution:
 * const { run, data, status, error } = useAsync(() => fetch("https://my-cool-api.com/some-endpoint"))
 * const handleClick = (event) => run()
 *
 */
export declare function useAsync<T>(asyncFn: () => Promise<T>, deferred?: boolean): useAsyncReturn<T>;

export declare interface useAsyncReturn<T> {
    run: () => void;
    data: T | null;
    status: Status;
    error: Error | null;
}

/**
 * useInView
 *
 * @param {number|IntersectionObserverInit} [observerOptions=0] - Number between 0 and 1, or an IntersectionObserver options object.
 * @param {Boolean} [once=false] - Whether to detach the observer from the DOM element after the first intersection callback is invoked.
 * @param {Boolean} [setInViewIfScrolledPast=false] - Whether to consider the element already "in-view", if it is already scrolled beyond the bounds of the viewport when the target element is mounted.
 *
 * @example
 * const [setSectionRef, sectionInView] = useInView(0.3);
 * <section ref={setSectionRef} className={sectionInView ? "in-view" : ""}>
 *
 * @example
 * const [setSectionRef, sectionInView] = useInView({ threshold: 0.3, rootMargin: "0px 40% 0px 0px" });
 * <section ref={setSectionRef} className={sectionInView ? "in-view" : ""}>
 */
export declare function useInView<T extends HTMLElement>(observerOptions?: number | IntersectionObserverInit, once?: boolean, setInViewIfScrolledPast?: boolean): InViewHook<T>;

/**
 * React hook for matching a media query
 * It returns `null` if the `window` object is not available, e.g. during SSR. Or a boolean if the media query matches or not.
 */
export declare function useMediaQuery(mediaQueryString: string): boolean | null;

/**
 * React hook for matching a media query and persisting the result in localStorage.
 * It returns `null` if the `window` object is not available, e.g. during SSR. Or a `boolean` if the media query matches or not.
 * Important to note that the hook prioritizes the media query over the localStorage value and will update the localStorage value when the media query changes.
 */
export declare function usePersistedMediaQuery(storageKey: string, mediaQuery: string): [boolean | null, (val: boolean) => void];

/**
 * Manage state which also gets saved to the browser's localStorage
 * Returns null if the `window` object is not available, e.g. during SSR.
 * `defaultValue` should not be `null` or `undefined` as it will be used to determine the type of the state.
 */
export declare function usePersistedState<T = string>(key: string, defaultValue: T): [T | null, (v: T | null) => void];

/**
 * usePreventScroll
 * Toggles the `overflow: hidden` CSS declaration on the `<body>` DOM element.
 *
 * @param {Boolean} state - Whether to prevent scrolling on the `<body>` element.
 *
 */
export declare function usePreventScroll(state: boolean): void;

/**
 * Maintains a globally-available data store for the user's a11y preferences.
 *
 * This keeps track of the following properties:
 * - prefersReduceMotion
 * - prefersReducedData
 * - prefersDarkColorScheme
 *
 * It also toggles the following classes on the `<body>` element:
 * - `is-reduced-motion`
 * - `is-reduced-data`
 * - `is-dark-color-scheme`
 *
 * These classes can be customized by passing in a `globalClassNames` object to the provider.
 *
 * For the most part, you should use the `useUserPrefs` interface to work with this context (see `/hooks/use-user-prefs.js`)
 *
 * @param {UserPreferencesProviderProps} props
 */
export declare function UserPreferencesProvider({ children, globalClassNames, }: UserPreferencesProviderProps): JSX_2.Element;

export declare interface UserPreferencesProviderProps {
    children: default_2.ReactNode;
    globalClassNames?: {
        prefersDarkColorScheme: string;
        prefersReducedData: string;
        prefersReducedMotion: string;
    };
}

export declare function useUserPrefs(): PreferencesContext;

export { }
