import * as react from 'react'; import { RefObject, LegacyRef, MutableRefObject } from 'react'; import { Maybe, AnyFunction } from 'yummies/types'; /** * Assigns the same value to multiple React refs, including callback refs. * * @template T Referenced value type. * @param value Value that should be written into every provided ref. * @param refs Target refs to update. * * @example * ```ts * attachRefs(node, localRef, forwardedRef); * ``` * * @example * ```ts * attachRefs(null, inputRef, (value) => console.log(value)); * ``` */ declare const attachRefs: (value: T | null, ...refs: Maybe | RefObject | LegacyRef>[]) => void; /** * Creates a single `AbortController` instance for the component lifetime. * * The controller is aborted automatically during unmount. * * @returns Stable abort controller instance. * * @example * ```ts * const controller = useAbortController(); * fetch('/api', { signal: controller.signal }); * ``` * * @example * ```ts * const controller = useAbortController(); * controller.abort(); * ``` */ declare const useAbortController: () => AbortController; /** * Returns an `AbortSignal` tied to the component lifecycle. * * The signal is aborted automatically on unmount. * * @returns Lifecycle-bound abort signal. * * @example * ```ts * const signal = useAbortSignal(); * fetch('/api/users', { signal }); * ``` * * @example * ```ts * const signal = useAbortSignal(); * someAsyncTask({ signal }); * ``` */ declare const useAbortSignal: () => AbortSignal; type ClickOutsideInput = { contentRef: MutableRefObject; onClick: VoidFunction; options?: AddEventListenerOptions; }; /** * Calls a handler when a pointer interaction happens outside the referenced element. * * @param input Target element ref, callback and event listener options. * * @example * ```ts * useClickOutside({ * contentRef: modalRef, * onClick: () => closeModal(), * }); * ``` * * @example * ```ts * useClickOutside({ * contentRef: dropdownRef, * onClick: hideDropdown, * options: { capture: true }, * }); * ``` */ declare const useClickOutside: ({ contentRef, onClick, options, }: ClickOutsideInput) => void; /** * React hook for creating a value exactly once. * * Unlike `useMemo`, this guarantees that the initializer is executed only once * for the component lifetime. * * @template T Value type. * @param defineValue Function that lazily creates the value. * @returns Stable value created on the first render. * * @example * ```ts * const id = useConstant(() => crypto.randomUUID()); * ``` * * @example * ```ts * const formatter = useConstant(() => new Intl.NumberFormat('en-US')); * ``` */ declare const useConstant: (defineValue: () => T) => T; /** * Creates a mutable ref whose value is initialized exactly once. * * @template T Ref value type. * @param defineFn Function that lazily creates the initial ref value. * @returns Mutable ref with a stable initialized value. * * @example * ```ts * const cacheRef = useDefineRef(() => new Map()); * ``` * * @example * ```ts * const observerRef = useDefineRef(() => new ResizeObserver(() => {})); * ``` */ declare const useDefineRef: (defineFn: () => T) => MutableRefObject; /** * Resolves an element once after mount and stores it in a ref. * * @template T Element type. * @param selector Function returning the target element. * @returns Ref containing the selected element. * * @example * ```ts * const buttonRef = useElementRef(() => document.getElementById('save') as HTMLButtonElement); * ``` * * @example * ```ts * const modalRef = useElementRef(() => document.querySelector('.modal') as HTMLDivElement); * ``` */ declare const useElementRef: (selector: () => T) => react.MutableRefObject; /** * Creates an event callback with a stable function identity and up-to-date logic. * * Borrowed from the `useEvent` RFC idea by React contributors. * * @template H Handler function type. * @param handler Latest callback implementation. * @returns Stable callback that always delegates to the latest handler. * * @example * ```ts * const onClick = useEvent(() => { * console.log('clicked'); * }); * ``` * * @example * ```ts * const onSubmit = useEvent((value: string) => save(value)); * ``` */ declare const useEvent: (handler: H) => H; /** * Subscribes to a DOM event and keeps the latest handler without resubscribing * on every render. * * Supports optional debounce and custom effect dependencies. * * @template EventName DOM event name from `HTMLElementEventMap`. * @param config Event subscription configuration. * * @example * ```ts * useEventListener({ * event: 'click', * handler: () => console.log('clicked'), * }); * ``` * * @example * ```ts * useEventListener({ * event: 'scroll', * node: window, * debounce: 100, * handler: () => console.log('scroll'), * }); * ``` */ declare const useEventListener: ({ event, handler, options, deps, debounce, node, }: { event: EventName; handler: (e: HTMLElementEventMap[EventName]) => void; options?: boolean | AddEventListenerOptions; deps?: unknown[]; debounce?: number; node?: HTMLElement | Document | Window; }) => void; interface FlagHook { enabled: boolean; toggle: VoidFunction; enable: VoidFunction; disable: VoidFunction; } /** * Manages a reusable boolean flag object with stable helper methods. * * @param defaultValue Initial enabled state. * @returns Stable object exposing current state and mutators. * * @example * ```ts * const modal = useFlag(); * modal.enable(); * ``` * * @example * ```ts * const loading = useFlag(true); * loading.disable(); * ``` */ declare const useFlag: (defaultValue?: boolean) => FlagHook; /** * Forces a component re-render by updating an internal dummy state. * * @returns Stable callback that triggers a re-render. * * @example * ```ts * const forceUpdate = useForceUpdate(); * forceUpdate(); * ``` * * @example * ```ts * const rerender = useForceUpdate(); * setTimeout(rerender, 1000); * ``` */ declare const useForceUpdate: () => () => void; /** * Captures an element's height the first time its ref becomes available. * * @template T Element type attached to the returned ref. * @returns Ref and the initial measured height. * * @example * ```ts * const { ref, initialHeight } = useInitialHeight(); * ``` * * @example * ```ts * const state = useInitialHeight(); * state.initialHeight; * ``` */ declare const useInitialHeight: () => { ref: react.MutableRefObject; initialHeight: number | undefined; }; type InstanceCreateConfig = TExtension & { abortSignal: AbortSignal; payload: TPayload; }; /** * Builds a custom hook that creates an instance once and wires lifecycle helpers * such as an `AbortSignal` and optional extension data into the factory. * * @template TExtension Extra configuration injected into every factory call. * @param extension Optional static extension object merged into the factory config. * @returns Hook factory that creates stable instances from a supplied factory. * * @example * ```ts * const useStoreInstance = createUseInstanceHook({ api }); * ``` * * @example * ```ts * const useService = createUseInstanceHook({ logger }); * const service = useService(({ logger, payload }) => new Service(logger, payload)); * ``` */ declare const createUseInstanceHook: (extension?: TExtension) => (factory: (config: InstanceCreateConfig, TExtension>) => TInstance, config?: { payload?: TPayload; onUpdate?: (payload: TPayload) => void; }) => TInstance; /** * The `useInstance` hook is used to create and manage an instance of an object * that requires access to the root store and an abort signal. * * You can create YOUR OWN CUSTOM `useInstance` hook using `createUseInstanceHook` if you need * to provide some specific data * * @param factory - A factory function that takes a configuration and returns an instance. * @param config - An optional configuration containing additional input parameters and an update function. * @returns An instance created by the factory function. * * @example * ```ts * const service = useInstance(({ abortSignal }) => new UsersService({ abortSignal })); * ``` * * @example * ```ts * const store = useInstance( * ({ payload }) => new UserStore(payload), * { payload: userId, onUpdate: (nextId) => console.log(nextId) }, * ); * ``` */ declare const useInstance: (factory: (config: { abortSignal: AbortSignal; payload: NoInfer; }) => TInstance, config?: { payload?: TPayload | undefined; onUpdate?: ((payload: TPayload) => void) | undefined; } | undefined) => TInstance; /** * Creates a single `IntersectionObserver` instance and disposes it on unmount. * * @param callback Observer callback invoked for intersection changes. * @param options Optional observer configuration. * @returns Stable `IntersectionObserver` instance. * * @example * ```ts * const observer = useIntersectionObserver((entries) => { * console.log(entries[0]?.isIntersecting); * }); * ``` * * @example * ```ts * const observer = useIntersectionObserver(handleIntersect, { threshold: 0.5 }); * observer.observe(element); * ``` */ declare const useIntersectionObserver: (callback: IntersectionObserverCallback, options?: IntersectionObserverInit) => IntersectionObserver; /** * Remembers and returns the last non-nullish value passed to the hook. * * @template T Value type. * @param value Current value that may be `null` or `undefined`. * @returns Current value when defined, otherwise the previous defined value. * * @example * ```ts * const title = useLastDefinedValue(props.title); * ``` * * @example * ```ts * const user = useLastDefinedValue(selectedUser); * ``` */ declare const useLastDefinedValue: (value: T) => T; /** * Returns a ref that always points to the last non-nullish value. * * @template T Value type. * @param value Current value that may temporarily become `null` or `undefined`. * @returns Ref containing the last defined value. * * @example * ```ts * const latestUserRef = useLastValueRef(user); * latestUserRef.current; * ``` * * @example * ```ts * const latestNodeRef = useLastValueRef(node); * ``` */ declare const useLastValueRef: (value: T | null | undefined) => react.MutableRefObject; /** * Runs mount and unmount callbacks returned by a factory function. * * The latest factory is stored in a ref, while the effect itself is only * subscribed once. * * @param fn Factory returning optional `mount` and `unmount` handlers. * * @example * ```ts * useLifeCycle(() => ({ * mount: () => console.log('mounted'), * unmount: () => console.log('unmounted'), * })); * ``` * * @example * ```ts * useLifeCycle(() => ({ * mount: subscribe, * unmount: unsubscribe, * })); * ``` */ declare const useLifeCycle: (fn: () => { mount?: VoidFunction; unmount?: VoidFunction; }) => void; /** * Creates a stable `ResizeObserver` instance and disconnects it on unmount. * * @param callback Resize observer callback. * @returns Ref containing the observer instance. * * @example * ```ts * const observerRef = useResizeObserver((entries) => { * console.log(entries[0]?.contentRect.width); * }); * ``` * * @example * ```ts * const resizeObserver = useResizeObserver(handleResize); * resizeObserver.current.observe(element); * ``` */ declare const useResizeObserver: (callback: ResizeObserverCallback) => react.MutableRefObject; /** * Returns a ref whose `current` value is synchronized with the latest input * on every render. * * @template T Value type. * @param value Current value to expose through the ref. * @returns Ref containing the latest value. * * @example * ```ts * const latestHandler = useSyncRef(onSubmit); * latestHandler.current(); * ``` * * @example * ```ts * const latestValue = useSyncRef(props.value); * latestValue.current; * ``` */ declare const useSyncRef: (value: T) => react.MutableRefObject; /** * Manages a boolean state and returns helpers to toggle or set it directly. * * @param initialState Initial boolean value. * @returns Tuple with current state, toggle callback and raw setter. * * @example * ```ts * const [open, toggleOpen] = useToggle(); * toggleOpen(); * ``` * * @example * ```ts * const [enabled, , setEnabled] = useToggle(true); * setEnabled(false); * ``` */ declare const useToggle: (initialState?: boolean) => readonly [boolean, () => void, react.Dispatch>]; /** * Wraps `useState` and returns the state value as an object with a `set` method. * * @template T State value type. * @param defaults Initial state value or lazy initializer. * @returns Object containing the current value and setter. * * @example * ```ts * const counter = useValue(0); * counter.set(1); * ``` * * @example * ```ts * const user = useValue(() => ({ name: 'Ann' })); * user.value.name; * ``` */ declare const useValue: (defaults: T | (() => T)) => { value: T; set: react.Dispatch>; }; /** * Tracks `document.visibilityState` and updates when the page visibility changes. * * @returns Current document visibility state. * * @example * ```ts * const visibility = useVisibilityState(); * ``` * * @example * ```ts * const isHidden = useVisibilityState() === 'hidden'; * ``` */ declare const useVisibilityState: () => DocumentVisibilityState | undefined; export { attachRefs, createUseInstanceHook, useAbortController, useAbortSignal, useClickOutside, useConstant, useDefineRef, useElementRef, useEvent, useEventListener, useFlag, useForceUpdate, useInitialHeight, useInstance, useIntersectionObserver, useLastDefinedValue, useLastValueRef, useLifeCycle, useResizeObserver, useSyncRef, useToggle, useValue, useVisibilityState }; export type { FlagHook, InstanceCreateConfig };