UNPKG

@gmana/react-hooks

Version:
1,407 lines (1,389 loc) 37.8 kB
import * as react0 from "react"; import React, { 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-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 type CopiedValue = string | null; type CopyFn = (text: string) => Promise<boolean>; /** * * @returns * @example * import React from 'react' * import { useCopyToClipboard } from '@gmana/hook' * * export default function Component() { * const [value, copy] = useCopyToClipboard() * return ( * <> * <h1>Click to copy:</h1> * <div style={{ display: 'flex' }}> * <button onClick={() => copy('A')}>A</button> * <button onClick={() => copy('B')}>B</button> * <button onClick={() => copy('C')}>C</button> * </div> * <p>Copied value: {value ?? 'Nothing is copied yet!'}</p> * </> * ) * } */ declare function useCopyToClipboard(): [CopiedValue, CopyFn]; //#endregion //#region src/lib/use-countdown.d.ts declare function useCountdown(initialTime?: number): { timeLeft: number; isActive: boolean; startTimer: () => void; resetTimer: () => void; canResend: boolean; }; //#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 /** * * @param value * @param delay default value `500` * @returns `debouncedValue` * @example * 'use client' import { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' import qs from 'query-string' import { useDebounce } from '@gmana/tw' import { Input } from '@gmana/react/input' const InputSearch = () => { const router = useRouter() const [value, setValue] = useState<string>('') const debouncedValue = useDebounce<string>(value, 500) useEffect(() => { const query = { title: debouncedValue, } const url = qs.stringifyUrl({ url: '/docs/hooks/use-debounce', query, }) router.push(url) }, [debouncedValue, router]) return <Input placeholder="What do you want to listen to?" value={value} onChange={(e) => setValue(e.target.value)} /> } export default InputSearch */ declare function useDebounce<T>(value: T, delay?: number): T; //#endregion //#region src/lib/use-debounce-a.d.ts /** * * @param value * @param delay * @returns * @example * import React, { ChangeEvent, useEffect, useState } from 'react' * import { useDebounce } from '@gmana/hook' * * export default function Component() { * const [value, setValue] = useState<string>('') * const debouncedValue = useDebounceA<string>(value, 500) * * const handleChange = (event: ChangeEvent<HTMLInputElement>) => { * setValue(event.target.value) * } * * // Fetch API (optional) * useEffect(() => { * // Do fetch here... * // Triggers when "debouncedValue" changes * }, [debouncedValue]) * * return ( * <div> * <p>Value real-time: {value}</p> * <p>Debounced value: {debouncedValue}</p> * * <input type="text" value={value} onChange={handleChange} /> * </div> * ) * } */ declare function useDebounceA<T>(value: T, delay?: number): T; //#endregion //#region src/lib/use-debounce-b.d.ts /** * * @deprecated `use useDebounce instead` * @example * import { useState } from "react" * import useDebounce from "./useDebounce" * * export default function DebounceComponent() { * const [count, setCount] = useState(10) * useDebounce(() => alert(count), 1000, [count]) * * return ( * <div> * <div>{count}</div> * <button onClick={() => setCount(c => c + 1)}>Increment</button> * </div> * ) * } */ declare function useDebounceB(callback: () => void, delay: number, dependencies: never[]): void; //#endregion //#region src/lib/use-dimensions.d.ts declare function useDimensions(containerRef: React.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; } /** * @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-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-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-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-sidebar.d.ts declare function useSidebar(): { open: boolean; onOpenChange: (open: boolean) => void; }; //#endregion //#region src/lib/use-ssr.d.ts /** * * @returns * @example * import React from 'react' * import { useSsr } from '@gmana/hook' * * export default function Component() { * const { isBrowser } = useSsr() * * return <p>{isBrowser ? 'Browser' : 'Server'}!</p> * } */ declare function useSsr(): { isBrowser: false | HTMLElement; isServer: 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-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-timeout-a.d.ts /** * @deprecated use useTimeout instead * @example * import React, { useState } from 'react' * import { useTimeout } from '@gmana/hook' * * export default function Component() { * const [visible, setVisible] = useState(true) * * const hide = () => setVisible(false) * * useTimeoutA(hide, 5000) * * return ( * <div> * <p> * {visible * ? "I'm visible for 5000ms" * : 'You can no longer see this content'} * </p> * </div> * ) * } */ declare function useTimeoutA(callback: () => void, delay: number | null): 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; }; /** * * @param initialState - boolean * @returns An array like object with `state`, `open`, `close`, and `toggle` properties * to allow both object and array destructuring * * ``` * const [showModal, openModal, closeModal, toggleModal] = useToggleState() * // or * const { state, open, close, toggle } = useToggleState() * ``` */ //#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, INetworkInformation, MapOrEntries, ScriptElt, StateType, Status, getCookie, removeCookie, setCookie, useArray, useBoolean, useClipboard, useCopyToClipboard, useCountdown, useCounter, useDarkMode, useDebounce, useDebounceA, useDebounceB, useDimensions, useEffectOnce, useElementSize, useEstimateStorage, useEventListener, useFetch, useHover, useImageOnLoad, useIntersection, useIntersectionObserver, useInterval, useIsClient, useIsFirstRender, useIsMobile, useIsMounted, useIsomorphicLayoutEffect, useLocalStorage, useLockedBody, useMap, useMediaQuery, useNetworkInformation, useOfflineDetector, useOnClickOutside, useReadLocalStorage, useScreen, useScript, useSidebar, useSsr, useStep, useTernaryDarkMode, useTimeout, useTimeoutA, useToggle, useUnloadWarning, useUpdateEffect, useWindowSize };