import * as react0 from "react";
import React$1, { CSSProperties, DependencyList, Dispatch, EffectCallback, RefObject, SetStateAction, useEffect } from "react";

//#region src/lib/use-array.d.ts

/**
 *
 * @param defaultValue
 * @returns
 * @example
 * ```tsx
 * import { useArray } from '@gmana/hook';
 *
 * export default function ArrayComponent() {
 *   const { array, set, push, remove, filter, update, clear } = useArray([1, 2, 3, 4, 5, 6]);
 *
 *   return (
 *     <div className="space-x-3 text-white divide-x-2 divide-gray-400">
 *       <div>{array.join(', ')}</div>
 *       <button onClick={() => push(7)}>Add 7</button>
 *       <button onClick={() => update(1, 9)}>Change Second Element To 9</button>
 *       <button onClick={() => remove(1)}>Remove Second Element</button>
 *       <button onClick={() => filter((n) => n < 4)}>Keep Numbers Less Than 4</button>
 *       <button onClick={() => set([1, 2])}>Set To 1, 2</button>
 *       <button onClick={clear}>Clear</button>
 *     </div>
 *   );
 * }
 * ```
 */
declare function useArray<T>(defaultValue: T[]): {
  array: T[];
  set: react0.Dispatch<react0.SetStateAction<T[]>>;
  push: (element: T) => void;
  filter: (callback: (n: T) => boolean) => void;
  update: (index: number, newElement: T) => void;
  remove: (index: number) => void;
  clear: () => void;
};
//#endregion
//#region src/lib/use-async-effect.d.ts
/**
 * A hook that allows you to use async functions in useEffect.
 * Automatically handles cleanup to prevent memory leaks.
 *
 * @param asyncFunction - The async function to execute
 * @param deps - Dependency array for the effect
 *
 * @example
 * ```tsx
 * import { useAsyncEffect } from '@gmana/react-hooks'
 * import { useState } from 'react'
 *
 * function UserProfile({ userId }: { userId: string }) {
 *   const [user, setUser] = useState(null)
 *   const [loading, setLoading] = useState(true)
 *
 *   useAsyncEffect(async (isCancelled) => {
 *     setLoading(true)
 *
 *     try {
 *       const response = await fetch(`/api/users/${userId}`)
 *       const userData = await response.json()
 *
 *       // Check if component is still mounted before updating state
 *       if (!isCancelled()) {
 *         setUser(userData)
 *         setLoading(false)
 *       }
 *     } catch (error) {
 *       if (!isCancelled()) {
 *         console.error('Failed to fetch user:', error)
 *         setLoading(false)
 *       }
 *     }
 *   }, [userId])
 *
 *   if (loading) return <div>Loading...</div>
 *   if (!user) return <div>User not found</div>
 *
 *   return <div>Hello, {user.name}!</div>
 * }
 * ```
 */
declare function useAsyncEffect(asyncFunction: (isCancelled: () => boolean) => Promise<void>, deps?: React.DependencyList): void;
//#endregion
//#region src/lib/use-boolean.d.ts
interface ReturnType$2 {
  value: boolean;
  setValue: Dispatch<SetStateAction<boolean>>;
  setTrue: () => void;
  setFalse: () => void;
  toggle: () => void;
}
/**
 *
 * @param defaultValue
 * @returns
 * @example
 * import React from 'react'
 * import { useBoolean } from '@gmana/hook'
 *
 * export default function Component() {
 *   const { value, setValue, setTrue, setFalse, toggle } = useBoolean(false)
 *
 *   // Just an example to use "setValue"
 *   const customToggle = () => setValue(x => !x)
 *
 *   return (
 *    <>
 *       <p>
 *         Value is <code>{value.toString()}</code>
 *       </p>
 *       <button onClick={setTrue}>set true</button>
 *       <button onClick={setFalse}>set false</button>
 *       <button onClick={toggle}>toggle</button>
 *       <button onClick={customToggle}>custom toggle</button>
 *     </>
 *   )
 * }
 */
declare function useBoolean(defaultValue?: boolean): ReturnType$2;
//#endregion
//#region src/lib/use-clipboard.d.ts
/**
 * Hook to copy text to clipboard.
 */
declare function useClipboard(): {
  isCopied: boolean;
  copyToClipboard: (text: string) => Promise<void>;
};
//#endregion
//#region src/lib/use-cookies.d.ts
interface CookieOptions {
  days?: number;
  path?: string;
  [key: string]: string | number | boolean | undefined;
}
interface EnhancedCookieOptions extends CookieOptions {
  sameSite?: "strict" | "lax" | "none";
}
declare const setCookie: (name: string, value: string, options?: EnhancedCookieOptions) => void;
declare const getCookie: (name: string, initialValue?: string) => string;
declare const removeCookie: (name: string) => void;
//#endregion
//#region src/lib/use-copy-to-clipboard.d.ts
declare function useCopyToClipboard({
  timeout,
  onCopy
}?: {
  timeout?: number;
  onCopy?: () => void;
}): {
  isCopied: boolean;
  copyToClipboard: (value: string) => void;
};
//#endregion
//#region src/lib/use-countdown.d.ts
interface UseCountdownOptions {
  /** Initial countdown time in seconds */
  initialTime?: number;
  /** Callback fired when countdown completes */
  onComplete?: () => void;
  /** Callback fired on each tick */
  onTick?: (timeLeft: number) => void;
}
interface UseCountdownReturn {
  /** Remaining time in seconds */
  timeLeft: number;
  /** Whether the countdown is currently active */
  isActive: boolean;
  /** Start/restart the countdown */
  startTimer: () => void;
  /** Stop and reset the countdown */
  resetTimer: () => void;
  /** Pause the countdown without resetting */
  pauseTimer: () => void;
  /** Resume a paused countdown */
  resumeTimer: () => void;
  /** Whether user can trigger a new countdown */
  canResend: boolean;
}
/**
 *
 * @param options
 * @returns
 * @example
 * ```tsx
 * import { useCountdown } from '@gmana/react-hooks'
 *
 * // Simple usage (backward compatible)
  const { timeLeft, startTimer, canResend } = useCountdown(60)

  // Advanced usage with callbacks
  const timer = useCountdown({
    initialTime: 60,
    onComplete: () => console.log("Timer finished!"),
    onTick: (time) => console.log(`${time}s remaining`),
  })

  // New pause/resume functionality
  <button onClick={timer.pauseTimer}>Pause</button>
  <button onClick={timer.resumeTimer}>Resume</button>
 * ```
 */
declare function useCountdown(options?: UseCountdownOptions | number): UseCountdownReturn;
//#endregion
//#region src/lib/use-counter.d.ts
interface ReturnType$1 {
  count: number;
  increment: () => void;
  decrement: () => void;
  reset: () => void;
  setCount: Dispatch<SetStateAction<number>>;
}
/**
 *
 * @param initialValue
 * @returns
 * @example
 * import React from 'react'
 * import { useCounter } from '@gmana/hook'
 *
 * export default function Component() {
 *   const { count, setCount, increment, decrement, reset } = useCounter(0)
 *
 *   const multiplyBy2 = () => setCount(x => x * 2)
 *
 *   return (
 *     <>
 *       <p>Count is {count}</p>
 *       <button onClick={increment}>Increment</button>
 *       <button onClick={decrement}>Decrement</button>
 *       <button onClick={reset}>Reset</button>
 *       <button onClick={multiplyBy2}>Multiply by 2</button>
 *     </>
 *   )
 * }
 */
declare function useCounter(initialValue?: number): ReturnType$1;
//#endregion
//#region src/lib/use-dark-mode.d.ts
interface UseDarkModeOutput {
  isDarkMode: boolean;
  toggle: () => void;
  enable: () => void;
  disable: () => void;
}
/**
 *
 * @param defaultValue
 * @returns
 * @example
 * import React from 'react'
 * import { useDarkMode } from '@gmana/hook'
 *
 * export default function Component() {
 *   const { isDarkMode, toggle, enable, disable } = useDarkMode()
 *
 *   return (
 *     <div>
 *       <p>Current theme: {isDarkMode ? 'dark' : 'light'}</p>
 *       <button onClick={toggle}>Toggle</button>
 *       <button onClick={enable}>Enable</button>
 *       <button onClick={disable}>Disable</button>
 *     </div>
 *   )
 * }
 */
declare function useDarkMode(defaultValue?: boolean): UseDarkModeOutput;
//#endregion
//#region src/lib/use-debounce.d.ts
interface UseDebounceOptions {
  /** The number of milliseconds to delay (default: 500) */
  delay?: number;
  /** Update immediately on first call, then debounce (default: false) */
  leading?: boolean;
  /** Update on trailing edge after delay (default: true) */
  trailing?: boolean;
  /** Maximum time to wait before forcing an update (optional) */
  maxWait?: number;
}
interface UseDebounceReturn<T> {
  /** The debounced value */
  value: T;
  /** Immediately update to the latest value, canceling pending updates */
  flush: () => void;
  /** Cancel any pending updates */
  cancel: () => void;
  /** Whether there's a pending update */
  isPending: boolean;
}
/**
 * Debounces a value, delaying updates until after wait milliseconds have elapsed
 * since the last time the debounced value was invoked.
 *
 * @param value - The value to debounce
 * @param options - Debounce options (or delay number for backward compatibility)
 * @returns The debounced value (or object with value and controls if using options)
 *
 * @example
 * ```tsx
 * // Simple usage (backward compatible)
 * const debouncedSearch = useDebounce(searchTerm, 500)
 *
 * // Advanced usage with options
 * const { value, flush, cancel, isPending } = useDebounce(searchTerm, {
 *   delay: 500,
 *   leading: true,
 *   maxWait: 2000
 * })
 * ```
 */
declare function useDebounce<T>(value: T, delay?: number): T;
declare function useDebounce<T>(value: T, options: UseDebounceOptions): UseDebounceReturn<T>;
//#endregion
//#region src/lib/use-debounce-callback.d.ts
interface UseDebouncedCallbackOptions {
  /** The number of milliseconds to delay */
  delay: number;
  /** Execute immediately on first call, then debounce (default: false) */
  leading?: boolean;
  /** Execute on trailing edge after delay (default: true) */
  trailing?: boolean;
  /** Maximum time to wait before forcing execution (optional) */
  maxWait?: number;
}
interface DebouncedFunction<T extends (...args: any[]) => any> {
  /** The debounced function */
  (...args: Parameters<T>): void;
  /** Immediately execute with the last provided arguments */
  flush: () => void;
  /** Cancel any pending execution */
  cancel: () => void;
  /** Whether there's a pending execution */
  isPending: () => boolean;
}
/**
 * Debounces a callback function, delaying its execution until after `delay` milliseconds
 * have elapsed since the last time the debounced function was invoked.
 *
 * @param callback - The function to debounce
 * @param options - Debounce options (or delay number for backward compatibility)
 * @returns A debounced version of the callback with control methods
 *
 * @example
 * ```tsx
 * // Simple usage (backward compatible)
 * const debouncedSave = useDebouncedCallback(saveData, 500)
 *
 * // Advanced usage with options
 * const debouncedSearch = useDebouncedCallback(
 *   async (query: string) => {
 *     const results = await searchAPI(query)
 *     setResults(results)
 *   },
 *   {
 *     delay: 300,
 *     leading: true,
 *     maxWait: 1000
 *   }
 * )
 *
 * // Manual control
 * <button onClick={debouncedSearch.flush}>Search Now</button>
 * <button onClick={debouncedSearch.cancel}>Cancel</button>
 * // ✅ Form with manual controls
  function SearchForm() {
    const [query, setQuery] = useState('')

    const search = useDebouncedCallback(
      (searchQuery: string) => {
        console.log('Searching for:', searchQuery)
      },
      { delay: 500 }
    )

    const handleSubmit = (e: React.FormEvent) => {
      e.preventDefault()
      search.flush() // Execute immediately on submit
    }

    const handleCancel = () => {
      search.cancel() // Cancel pending search
      setQuery('')
    }

    return (
      <form onSubmit={handleSubmit}>
        <input
          value={query}
          onChange={(e) => {
            setQuery(e.target.value)
            search(e.target.value)
          }}
        />
        <button type="submit">Search Now</button>
        <button type="button" onClick={handleCancel}>
          Cancel
        </button>
        {search.isPending() && <span>Searching...</span>}
      </form>
    )
  }

  // ✅ Auto-save with maxWait
  const autoSave = useDebouncedCallback(
    (content: string) => saveDocument(content),
    {
      delay: 2000,      // Wait 2s after typing stops
      maxWait: 10000,   // Force save every 10s regardless
    }
  )

  // ✅ Scroll handler with leading edge
  const handleScroll = useDebouncedCallback(
    () => {
      const scrollTop = window.scrollY
      updateScrollPosition(scrollTop)
    },
    {
      delay: 150,
      leading: true,  // Update immediately on first scroll
      trailing: true  // Update again when scrolling stops
    }
  )

  useEffect(() => {
    window.addEventListener('scroll', handleScroll)
    return () => {
      window.removeEventListener('scroll', handleScroll)
      handleScroll.cancel() // Cleanup pending calls
    }
  }, [handleScroll])
 * ```
 */
declare function useDebouncedCallback<T extends (...args: any[]) => any>(callback: T, delay: number): DebouncedFunction<T>;
declare function useDebouncedCallback<T extends (...args: any[]) => any>(callback: T, options: UseDebouncedCallbackOptions): DebouncedFunction<T>;
//#endregion
//#region src/lib/use-dimensions.d.ts
declare function useDimensions(containerRef: React$1.RefObject<HTMLElement | null>): {
  width: number;
  height: number;
};
//#endregion
//#region src/lib/use-effect-once.d.ts
/**
 *
 * @param effect
 * @example
 * import React, { useEffect, useState } from 'react'
 * import { useEffectOnce } from '@gmana/hook'
 *
 * export default function Component() {
 *   const [data, setData] = useState<number>(0)
 *   useEffect(() => {
 *     console.log('Normal useEffect', { data })
 *   }, [data])
 *
 *   useEffectOnce(() => {
 *     console.log('Triggered only once, on mount', { data })
 *   })
 *
 *   return (
 *     <div>
 *       <p>Open your console</p>
 *       <button onClick={() => setData(Date.now())}>Update data</button>
 *     </div>
 *   )
 * }
 */
declare function useEffectOnce(effect: EffectCallback): void;
//#endregion
//#region src/lib/use-element-size.d.ts
interface Size {
  width: number;
  height: number;
}
/**
 * @description
 * Use EventListener with simplicity by React Hook. It takes as parameters a `eventName`,
 * a call-back functions (handler) and optionally a reference `element`. You can see above two examples using `useRef` and `window` based event.
 * @returns
 * @example
 * import React, { useState } from 'react'
 * import { useElementSize } from '@gmana/hook'
 *
 * export default function Component() {
 *   const [isVisible, setVisible] = useState(true)
 *   const [squareRef, { width, height }] = useElementSize()
 *
 *   const toggleVisibility = () => setVisible(x => !x)
 *
 *   return (
 *     <>
 *       <p>{`The square width is ${width}px and height ${height}px`}</p>
 *       <p>Try, resize your window and-or click on the button.</p>
 *
 *       <button onClick={toggleVisibility}>
 *         {isVisible ? 'Hide' : 'Show'} square
 *       </button>
 *
 *       {isVisible && (
 *         <div
 *           ref={squareRef}
 *           style={{
 *             width: '50%',
 *             paddingTop: '50%',
 *             backgroundColor: 'aquamarine',
 *             margin: 'auto',
 *           }}
 *         />
 *       )}
 *     </>
 *   )
 * }
 */
declare function useElementSize<T extends HTMLElement = HTMLDivElement>(): [(node: T | null) => void, Size];
//#endregion
//#region src/lib/use-estimate-storage.d.ts
/**
 * Estimates the available storage quota and usage.
 * Returns the estimated remaining storage space in MB.
 * @example
  'use client';

  import { useEstimateStorage } from '@gmana/hook';

  export function Quota() {
    const quota = useEstimateStorage();

    return (
      <div>
        <h1>Quota: {(quota / 1024).toFixed(2)} GB</h1>
      </div>
    );
  }
 */
declare function useEstimateStorage(): number;
//#endregion
//#region src/lib/use-event-listener.d.ts
/**
 *
 * @param eventName
 * @param handler
 * @param element
 * @example
 * import React, { useRef } from 'react'
 * import { useEventListener } from '@gmana/hook'
 *
 * export default function Component() {
 *   // Define button ref
 *   const buttonRef = useRef<HTMLButtonElement>(null)
 *
 *   const onScroll = (event: Event) => {
 *     console.log('window scrolled!', event)
 *   }
 *
 *   const onClick = (event: Event) => {
 *     console.log('button clicked!', event)
 *   }
 *
 *   // example with window based event
 *   useEventListener('scroll', onScroll)
 *
 *   // example with element based event
 *   useEventListener('click', onClick, buttonRef)
 *
 *   return (
 *     <div style={{ minHeight: '200vh' }}>
 *       <button ref={buttonRef}>Click me</button>
 *     </div>
 *   )
 * }
 */
declare function useEventListener<K extends keyof WindowEventMap>(eventName: K, handler: (event: WindowEventMap[K]) => void): void;
/**
 *
 * @param eventName
 * @param handler
 * @param element
 * @example
 * import React, { useRef } from 'react'
 * import { useEventListener } from '@gmana/hook'
 *
 * export default function Component() {
 *   // Define button ref
 *   const buttonRef = useRef<HTMLButtonElement>(null)
 *
 *   const onScroll = (event: Event) => {
 *     console.log('window scrolled!', event)
 *   }
 *
 *   const onClick = (event: Event) => {
 *     console.log('button clicked!', event)
 *   }
 *
 *   // example with window based event
 *   useEventListener('scroll', onScroll)
 *
 *   // example with element based event
 *   useEventListener('click', onClick, buttonRef)
 *
 *   return (
 *     <div style={{ minHeight: '200vh' }}>
 *       <button ref={buttonRef}>Click me</button>
 *     </div>
 *   )
 * }
 */
declare function useEventListener<K extends keyof HTMLElementEventMap, T extends HTMLElement = HTMLDivElement>(eventName: K, handler: (event: HTMLElementEventMap[K]) => void, element: RefObject<T>): void;
//#endregion
//#region src/lib/use-fetch.d.ts
interface State<T> {
  data?: T;
  error?: Error;
  isLoading?: boolean;
}
/**
 * @description
 * Here is a React Hook which aims to retrieve data on an API using the native Fetch API.
 *
 * For advanced usages and optimizations,
 * see these other hooks more powerful like
 * - `useSWR`,
 * - `useQuery`
 * - `Redux Toolkit` (`RTK Query`).
 * @param url
 * @param options
 * @returns
 * @example
 * import React from 'react'
 * import { useFetch } from '@gmana/hook'
 *
 * const url = `http://jsonplaceholder.typicode.com/posts`
 *
 * interface Post {
 *   userId: number
 *   id: number
 *   title: string
 *   body: string
 * }
 *
 * export default function Component() {
 *   const { data, error } = useFetch<Post[]>(url)
 *
 *   if (error) return <p>There is an error.</p>
 *   if (!data) return <p>Loading...</p>
 *   return <p>{data[0].title}</p>
 * }
 */
declare function useFetch<T = unknown>(url?: string, options?: RequestInit): State<T>;
//#endregion
//#region src/lib/use-focus-trap.d.ts
declare function useFocusTrap(isActive?: boolean): react0.RefObject<HTMLElement | null>;
//#endregion
//#region src/lib/use-hover.d.ts
/**
 * @example
 * import React, { useRef } from 'react'
 * import { useHover } from '@gmana/hook';
 *
 * export default function Component() {
 *   const hoverRef = useRef(null)
 *   const isHover = useHover(hoverRef)
 *
 *   return (
 *     <div ref={hoverRef}>
 *       {`The current div is ${isHover ? `hovered` : `un-hovered`}`}
 *     </div>
 *   )
 * }
 */
declare function useHover<T extends HTMLElement = HTMLElement>(ComponentRef: RefObject<T>): boolean;
//#endregion
//#region src/lib/use-hydrated.d.ts
/**
 * A hook that returns whether the component has been hydrated on the client side.
 * This is essential for preventing hydration mismatches in Next.js and other SSR frameworks.
 *
 * Unlike useIsClient, this hook is specifically designed to handle the hydration phase
 * and provides a safer way to conditionally render client-only content.
 *
 * @returns boolean indicating if the component is hydrated
 * @example
 * import React from 'react'
 * import { useHydrated } from '@gmana/react-hooks'
 *
 * export default function Component() {
 *   const isHydrated = useHydrated()
 *
 *   return (
 *     <div>
 *       <h1>My App</h1>
 *       {isHydrated ? (
 *         <ClientOnlyComponent />
 *       ) : (
 *         <div>Loading client content...</div>
 *       )}
 *     </div>
 *   )
 * }
 *
 * @example
 * // Using with media queries to prevent hydration mismatches
 * function ResponsiveComponent() {
 *   const isHydrated = useHydrated()
 *   const isMobile = useMediaQuery('(max-width: 768px)')
 *
 *   if (!isHydrated) {
 *     // Return a safe default that matches SSR
 *     return <div>Loading...</div>
 *   }
 *
 *   return (
 *     <div>
 *       {isMobile ? <MobileLayout /> : <DesktopLayout />}
 *     </div>
 *   )
 * }
 */
declare function useHydrated(): boolean;
//#endregion
//#region src/lib/use-image-on-load.d.ts
interface ImageStyle {
  thumbnail: CSSProperties;
  fullSize: CSSProperties;
}
interface ImageOnLoadType {
  handleImageOnLoad: () => void;
  css: ImageStyle;
}
/**
 *
 * @returns
 * @example
 * import React, { CSSProperties } from 'react'
 * import { useImageOnLoad } from '@gmana/hook'
 *
 * export default function Component() {
 *   const { handleImageOnLoad, css } = useImageOnLoad()
 *
 *   const style: { [key: string]: CSSProperties } = {
 *     wrap: {
 *       position: 'relative',
 *       width: 400,
 *       height: 400,
 *       margin: 'auto',
 *     },
 *     image: {
 *       position: 'absolute',
 *       top: 0,
 *       left: 0,
 *       width: `100%`,
 *       height: `100%`,
 *     },
 *   }
 *
 *   return (
 *     <div style={style.wrap}>
 *
 *       <img
 *         style={{ ...style.image, ...css.thumbnail }}
 *         src="https://via.placeholder.com/150"
 *         alt="thumbnail"
 *       />
 *
 *       <img
 *         onLoad={handleImageOnLoad}
 *         style={{ ...style.image, ...css.fullSize }}
 *         src="https://via.placeholder.com/600"
 *         alt="fullImage"
 *       />
 *     </div>
 *   )
 * }
 */
declare function useImageOnLoad(): ImageOnLoadType;
//#endregion
//#region src/lib/use-in-view.d.ts
declare const useIntersection: (element: RefObject<HTMLDivElement>, rootMargin: string) => boolean;
//#endregion
//#region src/lib/use-intersection-observer.d.ts
interface Args extends IntersectionObserverInit {
  freezeOnceVisible?: boolean;
}
/**
 *
 * @param ComponentRef
 * @param param1
 * @returns
 * @example
 * import React, { useRef } from 'react'
 * import { useIntersectionObserver } from '@gmana/hook'
 *
 * const Section = (props: { title: string }) => {
 *   const ref = useRef<HTMLDivElement | null>(null)
 *   const entry = useIntersectionObserver(ref, {})
 *   const isVisible = !!entry?.isIntersecting
 *
 *   console.log(`Render Section ${props.title}`, { isVisible })
 *
 *   return (
 *     <div
 *       ref={ref}
 *       style={{
 *         minHeight: '100vh',
 *         display: 'flex',
 *         border: '1px dashed #000',
 *         fontSize: '2rem',
 *       }}
 *     >
 *       <div style={{ margin: 'auto' }}>{props.title}</div>
 *     </div>
 *   )
 * }
 *
 * export default function Component() {
 *   return (
 *     <>
 *       {Array.from({ length: 5 }).map((_, index) => (
 *         <Section key={index + 1} title={`${index + 1}`} />
 *       ))}
 *     </>
 *   )
 * }
 */
declare function useIntersectionObserver(ComponentRef: RefObject<Element>, {
  threshold,
  root,
  rootMargin,
  freezeOnceVisible
}: Args): IntersectionObserverEntry | undefined;
//#endregion
//#region src/lib/use-interval.d.ts
/**
 *
 * @param callback
 * @param delay
 * @example
 * import React, { ChangeEvent, useState } from 'react'
 * import { useInterval } from '@gmana/hook'
 *
 * export default function Component() {
 *   // The counter
 *   const [count, setCount] = useState<number>(0)
 *   // Dynamic delay
 *   const [delay, setDelay] = useState<number>(1000)
 *  // ON/OFF
 *   const [isPlaying, setPlaying] = useState<boolean>(false)
 *
 *   useInterval(
 *     () => {
 *       // Your custom logic here
 *       setCount(count + 1)
 *     },
 *     // Delay in milliseconds or null to stop it
 *     isPlaying ? delay : null,
 *   )
 *
 *   const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
 *     setDelay(Number(event.target.value))
 *   }
 *
 *   return (
 *     <>
 *       <h1>{count}</h1>
 *       <button onClick={() => setPlaying(!isPlaying)}>
 *         {isPlaying ? 'pause' : 'play'}
 *       </button>
 *       <p>
 *         <label htmlFor="delay">Delay: </label>
 *         <input
 *           type="number"
 *           name="delay"
 *           onChange={handleChange}
 *           value={delay}
 *         />
 *       </p>
 *     </>
 *   )
 * }
 */
declare function useInterval(callback: () => void, delay: number | null): void;
//#endregion
//#region src/lib/use-is-client.d.ts
/**
 *
 * @returns
 * @example
 * import React from 'react'
 * import { useIsClient } from '@gmana/hook'
 *
 * export default function Component() {
 *   const isClient = useIsClient()
 *
 *   return <div>{isClient ? 'Client' : 'server'}</div>
 * }
 */
declare function useIsClient(): boolean;
//#endregion
//#region src/lib/use-is-first-render.d.ts
/**
 *
 * @returns
 * @example
 * import React, { useEffect, useState } from 'react'
 * import { useIsFirstRender } from '@gmana/hook'
 *
 * export default function Component() {
 *   const isFirst = useIsFirstRender()
 *   const [data, setData] = useState<number>(0)
 *
 *   useEffect(() => {
 *     console.log('Normal useEffect', { data })
 *   }, [data])
 *
 *   return (
 *     <div>
 *       <p>Open your console</p>
 *       <p>Is first render: {isFirst ? 'yes' : 'no'}</p>
 *       <button onClick={() => setData(Date.now())}>Update data</button>
 *     </div>
 *   )
 * }
 */
declare function useIsFirstRender(): boolean;
//#endregion
//#region src/lib/use-is-mounted.d.ts
/**
 *
 * @returns
 * @example
 * import React, { useEffect, useState } from 'react'
 * import { useIsMounted } from '@gmana/hook'
 *
 * const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
 *
 * function Child() {
 *   const [data, setData] = useState('loading')
 *   const isMounted = useIsMounted()
 *
 *   // simulate an api call and update state
 *   useEffect(() => {
 *     void delay(3000).then(() => {
 *       if (isMounted()) setData('OK')
 *     })
 *   }, [isMounted])
 *
 *   return <p>{data}</p>
 * }
 *
 * export default function Component() {
 *   const [isVisible, setVisible] = useState<boolean>(false)
 *
 *   const toggleVisibility = () => setVisible(state => !state)
 *
 *   return (
 *     <>
 *       <button onClick={toggleVisibility}>{isVisible ? 'Hide' : 'Show'}</button>
 *
 *       {isVisible && <Child />}
 *     </>
 *   )
 * }
 */
declare function useIsMounted(): () => boolean;
//#endregion
//#region src/lib/use-isomorphic-layout-effect.d.ts
/**
 *
 * @example
 * import React from 'react'
 * import { useIsomorphicLayoutEffect } from '@gmana/hook'
 *
 * export default function Component() {
 *   useIsomorphicLayoutEffect(() => {
 *     console.log(
 *       "In the browser, I'm an `useLayoutEffect`, but in SSR, I'm an `useEffect`.",
 *     )
 *   }, [])
 *
 *   return <p>Hello, world</p>
 * }
 */
declare const useIsomorphicLayoutEffect: typeof useEffect;
//#endregion
//#region src/lib/use-local-storage.d.ts
declare global {
  interface WindowEventMap {
    "local-storage": CustomEvent;
  }
}
type SetValue<T> = Dispatch<SetStateAction<T>>;
/**
 *
 * @param key
 * @param initialValue
 * @returns
 * @example
 * import React from 'react'
 * import { useLocalStorage } from '@gmana/hook'
 *
 * export default function Component() {
 *   const [isDarkTheme, setDarkTheme] = useLocalStorage('darkTheme', true)
 *
 *   const toggleTheme = () => {
 *     setDarkTheme(prevValue => !prevValue)
 *   }
 *
 *   return (
 *     <button onClick={toggleTheme}>
 *       {`The current theme is ${isDarkTheme ? `dark` : `light`}`}
 *     </button>
 *   )
 * }
 */
declare function useLocalStorage<T>(key: string, initialValue: T): [T, SetValue<T>];
//#endregion
//#region src/lib/use-locked-body.d.ts
type ReturnType = [boolean, (locked: boolean) => void];
/**
 *
 * @param initialLocked
 * @returns
 * @example
 * import React, { CSSProperties, useState } from 'react'
 * import { useLockedBody } from '@gmana/hook'
 *
 * const fixedCenterStyle: CSSProperties = {
 *   position: 'fixed',
 *   top: '50%',
 *   left: '50%',
 *   transform: 'translate(-50%, -50%)',
 * }
 *
 * const fakeScrollableStyle: CSSProperties = {
 *   minHeight: '150vh',
 *   background: 'linear-gradient(palegreen, palegoldenrod, palevioletred)',
 * }
 *
 * // Example 1: useLockedBody as useState()
 * export default function App() {
 *   const [locked, setLocked] = useLockedBody()
 *
 *   const toggleLocked = () => {
 *     setLocked(!locked)
 *   }
 *
 *   return (
 *     <div style={fakeScrollableStyle}>
 *       <button style={fixedCenterStyle} onClick={toggleLocked}>
 *         {locked ? 'unlock scroll' : 'lock scroll'}
 *       </button>
 *     </div>
 *   )
 * }
 *
 * // Example 2: useLockedBody with our custom state
 * export function App2() {
 *   const [locked, setLocked] = useState(false)
 *
 *   const toggleLocked = () => {
 *     setLocked(!locked)
 *   }
 *
 *   useLockedBody(locked)
 *
 *   return (
 *     <div style={fakeScrollableStyle}>
 *       <button style={fixedCenterStyle} onClick={toggleLocked}>
 *         {locked ? 'unlock scroll' : 'lock scroll'}
 *       </button>
 *     </div>
 *   )
 * }
 */
declare function useLockedBody(initialLocked?: boolean): ReturnType;
//#endregion
//#region src/lib/use-map.d.ts
type MapOrEntries<K, V> = Map<K, V> | [K, V][];
interface Actions<K, V> {
  set: (key: K, value: V) => void;
  setAll: (entries: MapOrEntries<K, V>) => void;
  remove: (key: K) => void;
  reset: Map<K, V>["clear"];
}
type Return<K, V> = [Omit<Map<K, V>, "set" | "clear" | "delete">, Actions<K, V>];
/**
 *
 * @param initialState
 * @returns
 * @example
 * import React, { Fragment } from 'react'
 * import { MapOrEntries, useMap } from '@gmana/hook'
 *
 * const initialValues: MapOrEntries<string, string> = [['key', '🆕']]
 * const otherValues: MapOrEntries<string, string> = [
 *   ['hello', '👋'],
 *   ['data', '📦'],
 * ]
 *
 * export default function Component() {
 *   const [map, actions] = useMap<string, string>(initialValues)
 *
 *   const set = () => actions.set(String(Date.now()), '📦')
 *   const setAll = () => actions.setAll(otherValues)
 *   const reset = () => actions.reset()
 *   const remove = () => actions.remove('hello')
 *
 *   return (
 *     <div>
 *       <button onClick={set}>Add</button>
 *       <button onClick={reset}>Reset</button>
 *       <button onClick={setAll}>Set new data</button>
 *       <button onClick={remove} disabled={!map.get('hello')}>
 *         {'Remove "hello"'}
 *       </button>
 *
 *       <pre>
 *         Map (
 *         {Array.from(map.entries()).map(([key, value]) => (
 *           <Fragment key={key}>{`\n  ${key}: ${value}`}</Fragment>
 *         ))}
 *         <br />)
 *       </pre>
 *     </div>
 *   )
 * }
 */
declare function useMap<K, V>(initialState?: MapOrEntries<K, V>): Return<K, V>;
//#endregion
//#region src/lib/use-media-query.d.ts
/**
 *
 * @param query
 * @returns
 * @example
    const isDesktop = useMediaQuery("(min-width: 768px)")
 */
declare function useMediaQuery(query: string): boolean;
//#endregion
//#region src/lib/use-mobile.d.ts
declare function useIsMobile(): boolean;
//#endregion
//#region src/lib/use-network-information.d.ts
interface INetworkInformation {
  isOnline: boolean;
  effectiveType: string;
  downlink: number;
  rtt: number;
}
/**
 * Hook that returns network information for the browser,
 * including online status, effective connection type,
 * downlink speed, and round trip latency.
 * @example
  import { useNetworkInformation } from "@gmana/hook";

  export default function Network() {
    const networkState = useNetworkInformation();
    return <pre>{JSON.stringify(networkState, null, 2)}</pre>;
  }
 */
declare const useNetworkInformation: () => INetworkInformation | null;
//#endregion
//#region src/lib/use-offline-detector.d.ts
/**
 * Hook to detect offline status.
 * Returns a boolean indicating if offline.
 * @example
  'use client';

  import { useOfflineDetector } from '@gmana/hook';
  import { useEffect, useState } from 'react';

  export function OfflineBanner() {
    const isOffline = useOfflineDetector();
    const [showBanner, setShowBanner] = useState(() => isOffline);

    useEffect(() => {
      setShowBanner(isOffline);
    }, [isOffline]);

    return showBanner ? (
      <div className="bg-gray-950 text-white px-3 py-1 flex justify-between items-center">
        {isOffline ? <p>You are currently offline.</p> : <p>You are currently online.</p>}
        <button onClick={() => setShowBanner(false)}>Close</button>
      </div>
    ) : null;
  }
 */
declare const useOfflineDetector: () => boolean;
//#endregion
//#region src/lib/use-on-click-outside.d.ts
type Handler = (event: MouseEvent) => void;
/**
 *
 * @param ref
 * @param handler
 * @param mouseEvent
 * @example
 * import React, { useRef } from 'react'
 * import { useOnClickOutside } from '@gmana/tw'
 *
 * export default function Component() {
 *   const ref = useRef(null)
 *
 *   const handleClickOutside = () => {
 *     // Your custom logic here
 *     console.log('clicked outside')
 *   }
 *
 *   const handleClickInside = () => {
 *     // Your custom logic here
 *     console.log('clicked inside')
 *   }
 *
 *   useOnClickOutside(ref, handleClickOutside)
 *
 *   return (
 *     <button
 *       ref={ref}
 *       onClick={handleClickInside}
 *       style={{ width: 200, height: 200, background: 'cyan' }}
 *     />
 *   )
 * }
 // OR
  const ref = useRef(null);
  useOnClickOutside(ref, () => {
    setIsClick(false);
  });
 */
declare function useOnClickOutside<T extends HTMLElement = HTMLElement>(ref: RefObject<T>, handler: Handler, mouseEvent?: "mousedown" | "mouseup"): void;
//#endregion
//#region src/lib/use-previous.d.ts
/**
 * Returns the previous value of a state or prop.
 * Useful for comparing current and previous values in effects.
 *
 * @param value - The value to track
 * @returns The previous value
 *
 * @example
 * ```tsx
 * import { usePrevious } from '@gmana/react-hooks'
 * import { useState, useEffect } from 'react'
 *
 * function Counter() {
 *   const [count, setCount] = useState(0)
 *   const prevCount = usePrevious(count)
 *
 *   useEffect(() => {
 *     if (prevCount !== undefined) {
 *       console.log(`Count changed from ${prevCount} to ${count}`)
 *     }
 *   }, [count, prevCount])
 *
 *   return (
 *     <div>
 *       <p>Current count: {count}</p>
 *       <p>Previous count: {prevCount}</p>
 *       <button onClick={() => setCount(count + 1)}>Increment</button>
 *     </div>
 *   )
 * }
 * ```
 */
declare function usePrevious<T>(value: T): T | undefined;
//#endregion
//#region src/lib/use-read-local-storage.d.ts
type Value<T> = T | null;
/**
 *
 * @param key
 * @returns
 * @example
 * import React from 'react'
 * import { useReadLocalStorage } from '@gmana/hook'
 *
 * export default function Component() {
 *   // Assuming a value was set in localStorage with this key
 *   const darkMode = useReadLocalStorage('darkMode')
 *
 *   return <p>DarkMode is {darkMode ? 'enabled' : 'disabled'}</p>
 * }
 */
declare function useReadLocalStorage<T>(key: string): Value<T>;
//#endregion
//#region src/lib/use-screen.d.ts
/**
 *
 * @returns
 * @example
 * import React from 'react'
 * import { useScreen } from '@gmana/hook'
 *
 * export default function Component() {
 *   const screen = useScreen()
 *
 *   return (
 *     <div>
 *       The current window dimensions are:{' '}
 *       <code>
 *         {JSON.stringify({ width: screen?.width, height: screen?.height })}
 *       </code>
 *     </div>
 *   )
 * }
 */
declare function useScreen(): Screen | undefined;
//#endregion
//#region src/lib/use-script.d.ts
type Status = "idle" | "loading" | "ready" | "error";
type ScriptElt = HTMLScriptElement | null;
/**
 *
 * @param src
 * @returns
 * @example
 * import React, { useEffect } from 'react'
 * import { useScript } from '@gmana/hook'
 *
 * // it's an example, use your types instead
 * // eslint-disable-next-line @typescript-eslint/no-explicit-any
 * declare const jQuery: any
 *
 * export default function Component() {
 *   // Load the script asynchronously
 *   const status = useScript(`https://code.jquery.com/jquery-3.5.1.min.js`)
 *
 *   useEffect(() => {
 *     if (typeof jQuery !== 'undefined') {
 *       // jQuery is loaded => print the version
 *       // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
 *       alert(jQuery.fn.jquery)
 *     }
 *   }, [status])
 *
 *   return (
 *     <div>
 *       <p>{`Current status: ${status}`}</p>
 *
 *       {status === 'ready' && <p>You can use the script here.</p>}
 *     </div>
 *   )
 * }
 */
declare function useScript(src: string): Status;
//#endregion
//#region src/lib/use-scroll.d.ts
/**
 * Hook to track scroll position and determine if scrolled beyond a threshold.
 * SSR-safe implementation that prevents hydration mismatches.
 *
 * @param threshold - The scroll threshold in pixels (default: 20)
 * @returns boolean indicating if scrolled beyond threshold
 * @example
 * import React from 'react'
 * import { useScroll } from '@gmana/react-hooks'
 *
 * export default function ScrollToTop() {
 *   const isScrolled = useScroll(100)
 *
 *   return (
 *     <div>
 *       {isScrolled && (
 *         <button onClick={() => window.scrollTo(0, 0)}>
 *           Back to top
 *         </button>
 *       )}
 *     </div>
 *   )
 * }
 */
declare function useScroll(threshold?: number): boolean;
//#endregion
//#region src/lib/use-sidebar.d.ts
declare function useSidebar(): {
  open: boolean;
  onOpenChange: (open: boolean) => void;
};
//#endregion
//#region src/lib/use-ssr.d.ts
/**
 * A hook that provides information about the current environment (server vs client)
 * and hydration status. Useful for preventing hydration mismatches in SSR applications.
 *
 * @returns Object containing environment and hydration status
 * @example
 * import React from 'react'
 * import { useSsr } from '@gmana/hook'
 *
 * export default function Component() {
 *   const { isBrowser, isServer, isHydrated } = useSsr()
 *
 *   // Prevents hydration mismatch by only showing client-specific content after hydration
 *   if (!isHydrated) {
 *     return <p>Loading...</p>
 *   }
 *
 *   return <p>{isBrowser ? 'Browser' : 'Server'}!</p>
 * }
 */
declare function useSsr(): {
  isBrowser: boolean;
  isServer: boolean;
  isHydrated: boolean;
};
//#endregion
//#region src/lib/use-step.d.ts
interface Helpers {
  goToNextStep: () => void;
  goToPrevStep: () => void;
  reset: () => void;
  canGoToNextStep: boolean;
  canGoToPrevStep: boolean;
  setStep: Dispatch<SetStateAction<number>>;
}
/**
 *
 * @param maxStep
 * @returns
 * @example
 * import React from 'react'
 * import { useStep } from '@gmana/hook'
 *
 * export default function Component() {
 *   const [currentStep, helpers] = useStep(5)
 *
 *   const {
 *     canGoToPrevStep,
 *     canGoToNextStep,
 *     goToNextStep,
 *     goToPrevStep,
 *     reset,
 *     setStep,
 *   } = helpers
 *
 *   return (
 *     <>
 *       <p>Current step is {currentStep}</p>
 *       <p>Can go to previous step {canGoToPrevStep ? 'yes' : 'no'}</p>
 *       <p>Can go to next step {canGoToNextStep ? 'yes' : 'no'}</p>
 *       <button onClick={goToNextStep}>Go to next step</button>
 *       <button onClick={goToPrevStep}>Go to previous step</button>
 *       <button onClick={reset}>Reset</button>
 *       <button onClick={() => setStep(3)}>Set to step 3</button>
 *     </>
 *   )
 * }
 *
 */
declare function useStep(maxStep: number): [number, Helpers];
//#endregion
//#region src/lib/use-ternary-dark-mode.d.ts
type TernaryDarkMode = "system" | "dark" | "light";
interface UseTernaryDarkModeOutput {
  isDarkMode: boolean;
  ternaryDarkMode: TernaryDarkMode;
  setTernaryDarkMode: Dispatch<SetStateAction<TernaryDarkMode>>;
  toggleTernaryDarkMode: () => void;
}
/**
 *
 * @returns
 * @example
 * import React from 'react'
 * import { useTernaryDarkMode } from '@gmana/hook'
 *
 * export default function Component() {
 *   const {
 *     isDarkMode,
 *     ternaryDarkMode,
 *     setTernaryDarkMode,
 *     toggleTernaryDarkMode,
 *   } = useTernaryDarkMode()
 *   type TernaryDarkMode = typeof ternaryDarkMode
 *
 *   return (
 *     <div>
 *       <p>Current theme: {isDarkMode ? 'dark' : 'light'}</p>
 *       <p>ternaryMode: {ternaryDarkMode}</p>
 *       <p>
 *         Toggle between three modes
 *         <button onClick={toggleTernaryDarkMode}>
 *           Toggle from {ternaryDarkMode}
 *         </button>
 *       </p>
 *       <p>
 *         Select a mode
 *         <br />
 *         <select
 *           name="select-ternaryDarkMode"
 *           onChange={ev =>
 *             setTernaryDarkMode(ev.target.value as TernaryDarkMode)
 *           }
 *           value={ternaryDarkMode}
 *         >
 *           <option value="light">light</option>
 *           <option value="system">system</option>
 *           <option value="dark">dark</option>
 *         </select>
 *       </p>
 *     </div>
 *   )
 * }
 *
 */
declare function useTernaryDarkMode(): UseTernaryDarkModeOutput;
//#endregion
//#region src/lib/use-throttle.d.ts
/**
 * Throttles a callback function, ensuring it's called at most once per wait milliseconds.
 * Unlike debouncing, throttling ensures the function is executed regularly at intervals.
 *
 * @param callback - The function to throttle
 * @param delay - The number of milliseconds to throttle executions to
 * @param deps - Dependency array for the callback
 * @returns A throttled version of the callback
 *
 * @example
 * ```tsx
 * import { useThrottle } from '@gmana/react-hooks'
 * import { useState } from 'react'
 *
 * function ScrollComponent() {
 *   const [scrollY, setScrollY] = useState(0)
 *
 *   const throttledScroll = useThrottle(
 *     () => setScrollY(window.scrollY),
 *     100, // Update scroll position at most every 100ms
 *     [setScrollY]
 *   )
 *
 *   React.useEffect(() => {
 *     window.addEventListener('scroll', throttledScroll)
 *     return () => window.removeEventListener('scroll', throttledScroll)
 *   }, [throttledScroll])
 *
 *   return <div>Scroll Y: {scrollY}</div>
 * }
 * ```
 */
declare function useThrottle<T extends (...args: never[]) => unknown>(callback: T, delay: number, deps?: React.DependencyList): T;
//#endregion
//#region src/lib/use-timeout.d.ts
/**
 * @example
 * ```ts
 * import { useState } from "react"
 * import useTimeout from "@gmana/use-timeout"
 *
 * export default function TimeoutComponent() {
 *   const [count, setCount] = useState(10)
 *   const { clear, reset } = useTimeout(() => setCount(0), 1000)
 *
 *   return (
 *     <div>
 *       <div>{count}</div>
 *       <button onClick={() => setCount(c => c + 1)}>Increment</button>
 *       <button onClick={clear}>Clear Timeout</button>
 *       <button onClick={reset}>Reset Timeout</button>
 *     </div>
 *  )
 * }
 * ```
 */
declare function useTimeout(callback: () => void, delay: number): {
  reset: () => void;
  clear: () => void;
};
//#endregion
//#region src/lib/use-toggle.d.ts
/**
 *
 * @param defaultValue
 * @returns
 * ```ts
 * import useToggle from "@gmana/use-toggle"
 *
 * export default function ToggleComponent() {
 *   const [value, toggleValue] = useToggle(false)
 *
 *   return (
 *     <div>
 *       <div>{value.toString()}</div>
 *       <button onClick={toggleValue}>Toggle</button>
 *       <button onClick={() => toggleValue(true)}>Make True</button>
 *       <button onClick={() => toggleValue(false)}>Make False</button>
 *     </div>
 *   )
 * }
 * ```
 */
declare function useToggle(defaultValue: boolean): (boolean | ((value: boolean) => void))[];
//#endregion
//#region src/lib/use-toggle-state.d.ts
type StateType = [boolean, () => void, () => void, () => void] & {
  state: boolean;
  open: () => void;
  close: () => void;
  toggle: () => void;
};
//#endregion
//#region src/lib/use-unload-warning.d.ts
declare function useUnloadWarning(condition?: boolean): void;
//#endregion
//#region src/lib/use-update-effect.d.ts
/**
 *
 * @param effect
 * @param deps
 * @example
 * import React, { useEffect, useState } from 'react'
 * import { useUpdateEffect } from '@gmana/hook'
 *
 * export default function Component() {
 *   const [data, setData] = useState<number>(0)
 *   useEffect(() => {
 *     console.log('Normal useEffect', { data })
 *   }, [data])
 *
 *   useUpdateEffect(() => {
 *     console.log('Update useEffect only', { data })
 *   }, [data])
 *
 *   return (
 *     <div>
 *       <p>Open your console</p>
 *       <button onClick={() => setData(Date.now())}>Update data</button>
 *     </div>
 *   )
 * }
 */
declare function useUpdateEffect(effect: EffectCallback, deps?: DependencyList): void;
//#endregion
//#region src/lib/use-window-size.d.ts
interface WindowSize {
  width: number;
  height: number;
}
/**
 *
 * @returns
 * @example
 * import React from 'react'
 * import { useWindowSize } from '@gmana/hook'
 *
 * export default function Component() {
 *   const { width, height } = useWindowSize()
 *
 *   return (
 *     <div>
 *       The current window dimensions are:{' '}
 *       <code>{JSON.stringify({ width, height })}</code>
 *     </div>
 *   )
 * }
 *
 */
declare function useWindowSize(): WindowSize;
//#endregion
export { Actions, DebouncedFunction, INetworkInformation, MapOrEntries, ScriptElt, StateType, Status, UseCountdownOptions, UseCountdownReturn, UseDebounceOptions, UseDebounceReturn, UseDebouncedCallbackOptions, getCookie, removeCookie, setCookie, useArray, useAsyncEffect, useBoolean, useClipboard, useCopyToClipboard, useCountdown, useCounter, useDarkMode, useDebounce, useDebouncedCallback, useDimensions, useEffectOnce, useElementSize, useEstimateStorage, useEventListener, useFetch, useFocusTrap, useHover, useHydrated, useImageOnLoad, useIntersection, useIntersectionObserver, useInterval, useIsClient, useIsFirstRender, useIsMobile, useIsMounted, useIsomorphicLayoutEffect, useLocalStorage, useLockedBody, useMap, useMediaQuery, useNetworkInformation, useOfflineDetector, useOnClickOutside, usePrevious, useReadLocalStorage, useScreen, useScript, useScroll, useSidebar, useSsr, useStep, useTernaryDarkMode, useThrottle, useTimeout, useToggle, useUnloadWarning, useUpdateEffect, useWindowSize };