# Reactuse **Version 1.0.0** Siberiacancode January 2026 > **Note:** > This document is mainly for agents and LLMs to follow when maintaining, > generating, or refactoring React and Next.js codebases. Humans > may also find it useful, but guidance here is optimized for automation > and consistency by AI-assisted workflows. --- ## Abstract Comprehensive performance optimization guide for React and Next.js applications, designed for AI agents and LLMs. Contains 40+ rules across 8 categories, prioritized by impact from critical (eliminating waterfalls, reducing bundle size) to incremental (advanced patterns). Each rule includes detailed explanations, real-world examples comparing incorrect vs. correct implementations, and specific impact metrics to guide automated refactoring and code generation. --- ## Table of Contents 1. [Helpers](#1-helpers) - 1.1 [createContext](#11-createcontext) - 1.2 [createEventEmitter](#12-createeventemitter) - 1.3 [createReactiveContext](#13-createreactivecontext) - 1.4 [createStore](#14-createstore) - 1.5 [target](#15-target) 2. [Elements](#2-elements) - 2.1 [useActiveElement](#21-useactiveelement) - 2.2 [useAutoScroll](#22-useautoscroll) - 2.3 [useClickOutside](#23-useclickoutside) - 2.4 [useDoubleClick](#24-usedoubleclick) - 2.5 [useDropZone](#25-usedropzone) - 2.6 [useFileDialog](#26-usefiledialog) - 2.7 [useFocus](#27-usefocus) - 2.8 [useFocusTrap](#28-usefocustrap) - 2.9 [useHover](#29-usehover) - 2.10 [useImage](#210-useimage) - 2.11 [useLockScroll](#211-uselockscroll) - 2.12 [useLongPress](#212-uselongpress) - 2.13 [usePaint](#213-usepaint) - 2.14 [useRightClick](#214-userightclick) - 2.15 [useScript](#215-usescript) - 2.16 [useSize](#216-usesize) - 2.17 [useSticky](#217-usesticky) - 2.18 [useTextareaAutosize](#218-usetextareaautosize) - 2.19 [useTextDirection](#219-usetextdirection) - 2.20 [useWindowFocus](#220-usewindowfocus) - 2.21 [useWindowSize](#221-usewindowsize) 3. [Async](#3-async) - 3.1 [useAsync](#31-useasync) - 3.2 [useLockCallback](#32-uselockcallback) - 3.3 [useMutation](#33-usemutation) - 3.4 [useOptimistic](#34-useoptimistic) - 3.5 [useQuery](#35-usequery) 4. [Lifecycle](#4-lifecycle) - 4.1 [useAsyncEffect](#41-useasynceffect) - 4.2 [useDidUpdate](#42-usedidupdate) - 4.3 [useIsFirstRender](#43-useisfirstrender) - 4.4 [useIsomorphicLayoutEffect](#44-useisomorphiclayouteffect) - 4.5 [useMount](#45-usemount) - 4.6 [useShallowEffect](#46-useshalloweffect) - 4.7 [useUnmount](#47-useunmount) 5. [Browser](#5-browser) - 5.1 [useAudio](#51-useaudio) - 5.2 [useBattery](#52-usebattery) - 5.3 [useBluetooth](#53-usebluetooth) - 5.4 [useBreakpoints](#54-usebreakpoints) - 5.5 [useBroadcastChannel](#55-usebroadcastchannel) - 5.6 [useClipboard](#56-useclipboard) - 5.7 [useCopy](#57-usecopy) - 5.8 [useCssVar](#58-usecssvar) - 5.9 [useDisplayMedia](#59-usedisplaymedia) - 5.10 [useDocumentEvent](#510-usedocumentevent) - 5.11 [useDocumentTitle](#511-usedocumenttitle) - 5.12 [useDocumentVisibility](#512-usedocumentvisibility) - 5.13 [useEventListener](#513-useeventlistener) - 5.14 [useEventSource](#514-useeventsource) - 5.15 [useEyeDropper](#515-useeyedropper) - 5.16 [useFavicon](#516-usefavicon) - 5.17 [useFileSystemAccess](#517-usefilesystemaccess) - 5.18 [useFps](#518-usefps) - 5.19 [useFullscreen](#519-usefullscreen) - 5.20 [useGamepad](#520-usegamepad) - 5.21 [useGeolocation](#521-usegeolocation) - 5.22 [useMeasure](#522-usemeasure) - 5.23 [useMediaControls](#523-usemediacontrols) - 5.24 [useMediaQuery](#524-usemediaquery) - 5.25 [useMemory](#525-usememory) - 5.26 [useNetwork](#526-usenetwork) - 5.27 [useOnline](#527-useonline) - 5.28 [useObjectUrl](#528-useobjecturl) - 5.29 [useOtpCredential](#529-useotpcredential) - 5.30 [usePermission](#530-usepermission) - 5.31 [usePictureInPicture](#531-usepictureinpicture) - 5.32 [usePointerLock](#532-usepointerlock) - 5.33 [usePostMessage](#533-usepostmessage) - 5.34 [useRaf](#534-useraf) - 5.35 [useShare](#535-useshare) - 5.36 [useSpeechRecognition](#536-usespeechrecognition) - 5.37 [useSpeechSynthesis](#537-usespeechsynthesis) - 5.38 [useVibrate](#538-usevibrate) - 5.39 [useVirtualKeyboard](#539-usevirtualkeyboard) - 5.40 [useWakeLock](#540-usewakelock) - 5.41 [useWebSocket](#541-usewebsocket) 6. [Utilities](#6-utilities) - 6.1 [useBatchedCallback](#61-usebatchedcallback) - 6.2 [useConst](#62-useconst) - 6.3 [useDebounceCallback](#63-usedebouncecallback) - 6.4 [useDebounceEffect](#64-usedebounceeffect) - 6.5 [useDebounceState](#65-usedebouncestate) - 6.6 [useDebounceValue](#66-usedebouncevalue) - 6.7 [useDevicePixelRatio](#67-usedevicepixelratio) - 6.8 [useEvent](#68-useevent) - 6.9 [useLastChanged](#69-uselastchanged) - 6.10 [useLatest](#610-uselatest) - 6.11 [usePrevious](#611-useprevious) - 6.12 [useThrottleCallback](#612-usethrottlecallback) - 6.13 [useThrottleEffect](#613-usethrottleeffect) - 6.14 [useThrottleState](#614-usethrottlestate) - 6.15 [useThrottleValue](#615-usethrottlevalue) 7. [State](#7-state) - 7.1 [useBoolean](#71-useboolean) - 7.2 [useControllableState](#72-usecontrollablestate) - 7.3 [useCookie](#73-usecookie) - 7.4 [useCookies](#74-usecookies) - 7.5 [useCounter](#75-usecounter) - 7.6 [useDefault](#76-usedefault) - 7.7 [useDisclosure](#77-usedisclosure) - 7.8 [useField](#78-usefield) - 7.9 [useHash](#79-usehash) - 7.10 [useList](#710-uselist) - 7.11 [useLocalStorage](#711-uselocalstorage) - 7.12 [useMap](#712-usemap) - 7.13 [useMergedRef](#713-usemergedref) - 7.14 [useObject](#714-useobject) - 7.15 [useOffsetPagination](#715-useoffsetpagination) - 7.16 [useQueue](#716-usequeue) - 7.17 [useRafState](#717-userafstate) - 7.18 [useRefState](#718-userefstate) - 7.19 [useSessionStorage](#719-usesessionstorage) - 7.20 [useSet](#720-useset) - 7.21 [useStateHistory](#721-usestatehistory) - 7.22 [useStep](#722-usestep) - 7.23 [useStorage](#723-usestorage) - 7.24 [useToggle](#724-usetoggle) - 7.25 [useUrlSearchParam](#725-useurlsearchparam) - 7.26 [useUrlSearchParams](#726-useurlsearchparams) - 7.27 [useWizard](#727-usewizard) 8. [User](#8-user) - 8.1 [useBrowserLanguage](#81-usebrowserlanguage) - 8.2 [useOperatingSystem](#82-useoperatingsystem) - 8.3 [usePreferredColorScheme](#83-usepreferredcolorscheme) - 8.4 [usePreferredContrast](#84-usepreferredcontrast) - 8.5 [usePreferredDark](#85-usepreferreddark) - 8.6 [usePreferredLanguages](#86-usepreferredlanguages) - 8.7 [usePreferredReducedMotion](#87-usepreferredreducedmotion) 9. [Sensors](#9-sensors) - 9.1 [useDeviceMotion](#91-usedevicemotion) - 9.2 [useDeviceOrientation](#92-usedeviceorientation) - 9.3 [useHotkeys](#93-usehotkeys) - 9.4 [useIdle](#94-useidle) - 9.5 [useInfiniteScroll](#95-useinfinitescroll) - 9.6 [useIntersectionObserver](#96-useintersectionobserver) - 9.7 [useKeyboard](#97-usekeyboard) - 9.8 [useKeyPress](#98-usekeypress) - 9.9 [useKeyPressEvent](#99-usekeypressevent) - 9.10 [useKeysPressed](#910-usekeyspressed) - 9.11 [useMouse](#911-usemouse) - 9.12 [useMutationObserver](#912-usemutationobserver) - 9.13 [useOrientation](#913-useorientation) - 9.14 [usePageLeave](#914-usepageleave) - 9.15 [useParallax](#915-useparallax) - 9.16 [usePerformanceObserver](#916-useperformanceobserver) - 9.17 [useResizeObserver](#917-useresizeobserver) - 9.18 [useScroll](#918-usescroll) - 9.19 [useScrollIntoView](#919-usescrollintoview) - 9.20 [useScrollTo](#920-usescrollto) - 9.21 [useTextSelection](#921-usetextselection) - 9.22 [useVisibility](#922-usevisibility) - 9.23 [useWindowEvent](#923-usewindowevent) - 9.24 [useWindowScroll](#924-usewindowscroll) 10. [Time](#10-time) - 10.1 [useInterval](#101-useinterval) - 10.2 [useStopwatch](#102-usestopwatch) - 10.3 [useTime](#103-usetime) - 10.4 [useTimeout](#104-usetimeout) - 10.5 [useTimer](#105-usetimer) - 10.6 [useProgress](#106-useprogress) 11. [Debug](#11-debug) - 11.1 [useLogger](#111-uselogger) - 11.2 [useRenderCount](#112-userendercount) - 11.3 [useRenderInfo](#113-userenderinfo) - 11.4 [useRerender](#114-usererender) --- ## 1. Helpers ### 1.1 createContext Creates a typed context with provider and selector hook. #### Usage ```ts import { createContext } from "@siberiacancode/reactuse"; const context = createContext(0); ``` #### Example ```tsx import { createContext } from "@siberiacancode/reactuse"; import type { ReactNode } from "react"; const themeContext = createContext("light"); interface ThemeProviderProps { children: ReactNode; } export const ThemeProvider = ({ children }: ThemeProviderProps) => ( {children} ); export const CounterValue = () => { const theme = ThemeContext.useSelect((value) => value); return {theme}; }; ``` #### Type Declarations ```ts import type { JSX, ReactNode } from "react"; export interface CreateContextOptions { name?: string; strict?: boolean; } export interface ContextValue { value: Value | undefined; set: (value: Value) => void; } export interface ProviderProps { children?: ReactNode; initialValue?: Value; } export interface CreateContextReturn { instance: React.Context>; Provider: (props: ProviderProps) => JSX.Element; useSelect: { (selector: (value: Value) => Selected): Selected; (): ContextValue; }; } export declare const createContext: ( defaultValue?: Value, options?: CreateContextOptions ) => CreateContextReturn; ``` ### 1.2 createEventEmitter Creates a type-safe event emitter with a subscription hook. #### Usage ```ts import { createEventEmitter } from "@siberiacancode/reactuse"; const emitter = createEventEmitter<{ foo: number; }>(); ``` #### Example ```tsx const emitter = createEventEmitter<{ message: string }>(); export const Listener = () => { const value = emitter.useSubscribe("message"); return
{value ?? "none"}
; }; emitter.subscribe("message", (value) => console.log(value)); emitter.push("message", "hello"); ``` #### Type Declarations ```ts export declare const createEventEmitter: < Events extends Record = Record >() => { push: (event: Event, data: Events[Event]) => void; subscribe: ( event: Key, listener: (data: Events[Key]) => void ) => () => void; unsubscribe: ( event: Key, listener: (data: Events[Key]) => void ) => void; useSubscribe: ( event: Event, listener?: (data: Events[Event]) => void ) => Events[Event] | undefined; }; ``` ### 1.3 createReactiveContext Creates a typed context selector with optimized updates. #### Usage ```ts import { createReactiveContext } from "@siberiacancode/reactuse"; const context = createReactiveContext({ count: 0 }); ``` #### Example ```tsx import { createReactiveContext } from "@siberiacancode/reactuse"; import type { ReactNode } from "react"; interface UserProviderProps { children: ReactNode; } const userContext = createReactiveContext({ name: "", email: "" }); export const UserProvider = ({ children }: UserProviderProps) => ( {children} ); export const UserLabel = () => { const name = userContext.useSelector((state) => state.name); return {name}; }; ``` #### Notes - For complex interfaces, prefer external state management instead of context. #### Type Declarations ```ts import type { Context, Provider, RefObject } from "react"; export interface CreateReactiveContextOptions { name?: string; strict?: boolean; } export interface CreateReactiveContextReturn { instance: Context>; Provider: Provider; useSelector: (selector?: (state: Value) => Selected) => Selected; } interface ReactiveContextValue { listeners: Set<(value: Value) => void>; value: RefObject; } export declare const createReactiveContext: >( defaultValue?: Value, options?: CreateReactiveContextOptions ) => CreateReactiveContextReturn; ``` ### 1.4 createStore Creates a external store with state, subscriptions, and a hook. #### Usage ```ts import { createStore } from "@siberiacancode/reactuse"; const store = createStore({ count: 0 }); ``` #### Example ```tsx import { createStore } from "@siberiacancode/reactuse"; const counter = createStore((set) => ({ count: 0, inc: () => set((state) => ({ count: state.count + 1 })), dec: () => set((state) => ({ count: state.count - 1 })), reset: () => set({ count: 0 }), })); export const Counter = () => { const value = counter.use((state) => state.count); return (
{value}
); }; ``` Subscriptions: ```tsx const unsubscribe = counter.subscribe((state) => { console.log("count", state.count); }); ``` #### Type Declarations ```ts type StoreSetAction = ((prev: Value) => Partial) | Partial; type StoreListener = (state: Value, prevState: Value) => void; type StoreCreator = ( set: (action: StoreSetAction) => void, get: () => Value ) => Value; export interface StoreApi { get: () => Value; getInitial: () => Value; set: (action: StoreSetAction) => void; subscribe: (listener: StoreListener) => () => void; use: (() => Value) & ((selector: (state: Value) => Selected) => Selected) & ((selector?: (state: Value) => Selected) => Selected | Value); } export declare const createStore: ( createState: StoreCreator | Value ) => StoreApi; ``` ### 1.5 target Flexible helper to reference DOM targets for hooks. #### Usage ```ts import { target, useClickOutside } from "@siberiacancode/reactuse"; useClickOutside(target("#container"), () => console.log("outside")); ``` #### Example Selector and element targets: ```tsx import { target, useClickOutside } from "@siberiacancode/reactuse"; useClickOutside(target("#container"), () => console.log("outside")); useClickOutside(target(document.getElementById("container")!), () => console.log("outside") ); ``` #### Notes - `target` accepts refs, DOM elements, functions returning elements, or selectors. - Use it when you want to avoid creating a ref callback from the hook. ## 2. Elements ### 2.1 useActiveElement Tracks the currently focused element. #### Usage ```ts import { useActiveElement } from "@siberiacancode/reactuse"; const activeElement = useActiveElement(); // or const activeElement = useActiveElement(ref); ``` #### Example ```tsx const activeElement = useActiveElement(); return ( <>

Active element: {activeElement.value?.getAttribute("data-id") ?? "none"}

); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export type UseActiveElementReturn< ActiveElement extends HTMLElement = HTMLElement > = ActiveElement | null; export interface UseActiveElement { (): UseActiveElementReturn; ( target?: never ): { ref: StateRef; value: UseActiveElementReturn; }; ( target: HookTarget ): UseActiveElementReturn; } export declare const useActiveElement: UseActiveElement; ``` ### 2.2 useAutoScroll Automatically scrolls a container to the bottom. #### Usage ```ts import { useAutoScroll } from "@siberiacancode/reactuse"; const autoScrollRef = useAutoScroll(); // or useAutoScroll(ref); ``` #### Example ```tsx const autoScrollRef = useAutoScroll(); return (
First message
Second message
); ``` `enabled`: Disable auto scroll. ```tsx const autoScrollRef = useAutoScroll({ enabled: false }); ``` `force`: Always jump to bottom. ```tsx const autoScrollRef = useAutoScroll({ force: true }); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export interface UseAutoScrollOptions { enabled?: boolean; force?: boolean; } export interface UseAutoScroll { (target: HookTarget, options?: UseAutoScrollOptions): void; ( options?: UseAutoScrollOptions ): StateRef; } export declare const useAutoScroll: UseAutoScroll; ``` ### 2.3 useClickOutside Calls a callback when clicking outside the target element. #### Usage ```ts import { useClickOutside } from "@siberiacancode/reactuse"; const ref = useClickOutside(() => console.log("outside")); // or useClickOutside(ref, () => console.log("outside")); ``` #### Example ```tsx const [open, setOpen] = useState(true); const ref = useClickOutside(() => setOpen(false)); if (!open) return ; return
Modal
; ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export interface UseClickOutside { (target: HookTarget, callback: (event: Event) => void): void; ( callback: (event: Event) => void, target?: never ): StateRef; } export declare const useClickOutside: UseClickOutside; ``` ### 2.4 useDoubleClick Detects double-clicks with optional single-click handler. #### Usage ```ts import { useDoubleClick } from "@siberiacancode/reactuse"; const ref = useDoubleClick(() => console.log("double")); // or useDoubleClick(ref, () => console.log("double")); ``` #### Example ```tsx import { useDoubleClick } from "@siberiacancode/reactuse"; export const LikeButton = () => { const ref = useDoubleClick(() => console.log("double"), { onSingleClick: () => console.log("single"), }); return ; }; ``` `threshold`: Max time between clicks. ```tsx const ref = useDoubleClick(() => {}, { threshold: 400 }); ``` `onSingleClick`: Single-click handler. ```tsx const ref = useDoubleClick(() => {}, { onSingleClick: () => console.log("single"), }); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export type DoubleClickEvents = MouseEvent | TouchEvent; export interface UseDoubleClickOptions { threshold?: number; onSingleClick?: (event: DoubleClickEvents) => void; } export interface UseDoubleClick { ( target: HookTarget, callback: (event: DoubleClickEvents) => void, options?: UseDoubleClickOptions ): boolean; ( callback: (event: DoubleClickEvents) => void, options?: UseDoubleClickOptions, target?: never ): StateRef; } export declare const useDoubleClick: UseDoubleClick; ``` ### 2.5 useDropZone Creates a drag-and-drop area with file state. #### Usage ```ts import { useDropZone } from "@siberiacancode/reactuse"; const dropZone = useDropZone(); // or const dropZone = useDropZone(ref, { multiple: true }); ``` #### Example ```tsx import { useDropZone } from "@siberiacancode/reactuse"; export const AvatarDrop = () => { const dropZone = useDropZone({ dataTypes: ["image/jpeg", "image/png"], multiple: false, onDrop: (files) => console.log("files", files), }); const ref = dropZone.ref; return (
{dropZone.overed ? "Drop now" : "Drag image here"}
Files: {dropZone.files?.length ?? 0}
); }; ``` `dataTypes`: Allowed types. ```tsx const dropZone = useDropZone({ dataTypes: ["image/jpeg"] }); ``` `multiple`: Allow multiple. ```tsx const dropZone = useDropZone({ multiple: false }); ``` `onDrop`: Handle drop. ```tsx const dropZone = useDropZone({ onDrop: (files) => console.log(files?.length ?? 0), }); ``` `onEnter`: Drag enter. ```tsx const dropZone = useDropZone({ onEnter: () => console.log("enter"), }); ``` `onLeave`: Drag leave. ```tsx const dropZone = useDropZone({ onLeave: () => console.log("leave"), }); ``` `onOver`: Drag over. ```tsx const dropZone = useDropZone({ onOver: () => console.log("over"), }); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export type DropZoneDataTypes = ((types: string[]) => boolean) | string[]; export interface UseDropZoneOptions { dataTypes?: DropZoneDataTypes; multiple?: boolean; onDrop?: (files: File[] | null, event: DragEvent) => void; onEnter?: (event: DragEvent) => void; onLeave?: (event: DragEvent) => void; onOver?: (event: DragEvent) => void; } export interface UseDropZoneReturn { files: File[] | null; overed: boolean; } export interface UseDropZone { ( target: HookTarget, callback?: (files: File[] | null, event: DragEvent) => void ): UseDropZoneReturn; ( callback?: (files: File[] | null, event: DragEvent) => void, target?: never ): UseDropZoneReturn & { ref: StateRef }; (target: HookTarget, options?: UseDropZoneOptions): UseDropZoneReturn; ( options?: UseDropZoneOptions, target?: never ): UseDropZoneReturn & { ref: StateRef }; } export declare const useDropZone: UseDropZone; ``` ### 2.6 useFileDialog Opens a file picker and returns selected files. #### Usage ```ts import { useFileDialog } from "@siberiacancode/reactuse"; const dialog = useFileDialog(); ``` #### Example ```tsx const dialog = useFileDialog({ accept: "image/*" }); return ( ); ``` `multiple`: ```tsx const dialog = useFileDialog({ multiple: false }); ``` `accept`: ```tsx const dialog = useFileDialog({ accept: "image/*" }); ``` `reset`: ```tsx const dialog = useFileDialog({ reset: true }); ``` `capture`: ```tsx const dialog = useFileDialog({ capture: "environment" }); ``` #### Type Declarations ```ts import type { ComponentProps } from "react"; export interface UseFileDialogOptions extends Pick, "accept" | "multiple"> { capture?: string; reset?: boolean; } export interface UseFileDialogReturn { value: FileList | null; open: (openParams?: UseFileDialogOptions) => void; reset: () => void; } export interface UseFileDialog { ( callback?: (value: FileList | null) => void, options?: UseFileDialogOptions ): UseFileDialogReturn; (options?: UseFileDialogOptions, callback?: never): UseFileDialogReturn; } export declare const useFileDialog: UseFileDialog; ``` ### 2.7 useFocus Tracks focus state and provides focus/blur controls. #### Usage ```ts import { useFocus } from "@siberiacancode/reactuse"; const focus = useFocus(); // or const focus = useFocus(ref, { enabled: true }); ``` #### Example ```tsx import { useFocus } from "@siberiacancode/reactuse"; export const FocusInput = () => { const focus = useFocus(); return (
); }; ``` `enabled`: Enable focus tracking. ```tsx const focus = useFocus({ enabled: false }); ``` `initialValue`: Initial focus state. ```tsx const focus = useFocus({ initialValue: true }); ``` `onFocus`: Focus callback. ```tsx const focus = useFocus({ onFocus: () => console.log("focus"), }); ``` `onBlur`: Blur callback. ```tsx const focus = useFocus({ onBlur: () => console.log("blur") }); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export interface UseFocusOptions { enabled?: boolean; initialValue?: boolean; onBlur?: (event: FocusEvent) => void; onFocus?: (event: FocusEvent) => void; } export interface UseFocusReturn { focused: boolean; blur: () => void; focus: () => void; } export interface UseFocus { (target: HookTarget, callback?: (event: FocusEvent) => void): UseFocusReturn; (target: HookTarget, options?: UseFocusOptions): UseFocusReturn; ( callback?: (event: FocusEvent) => void, target?: never ): UseFocusReturn & { ref: StateRef }; ( options?: UseFocusOptions, target?: never ): UseFocusReturn & { ref: StateRef }; } export declare const useFocus: UseFocus; ``` ### 2.8 useFocusTrap Traps focus within a given element. #### Usage ```ts import { useFocusTrap } from "@siberiacancode/reactuse"; const trap = useFocusTrap(true); // or const trap = useFocusTrap(ref, true); ``` #### Example ```tsx import { useFocusTrap } from "@siberiacancode/reactuse"; export const Modal = () => { const trap = useFocusTrap(true); return (
); }; ``` `active`: Initially active. ```tsx const trap = useFocusTrap(true); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export interface UseFocusTrapReturn { active: boolean; disable: () => void; enable: () => void; toggle: () => void; } export interface UseFocusTrap { (target: HookTarget, active?: boolean): UseFocusTrapReturn; ( active?: boolean, target?: never ): UseFocusTrapReturn & { ref: StateRef }; } export declare const useFocusTrap: UseFocusTrap; ``` ### 2.9 useHover Tracks hover state for an element. #### Usage ```ts import { useHover } from "@siberiacancode/reactuse"; const hover = useHover(); // or const hover = useHover(targetRef, { enabled: true }); ``` #### Example ```tsx import { useHover } from "@siberiacancode/reactuse"; const hover = useHover(); return
{hover.value ? "Hovering" : "Idle"}
; ``` `enabled`: Toggle tracking. ```tsx const hover = useHover({ enabled: false }); ``` `onEntry`: Enter callback. ```tsx const hover = useHover({ onEntry: () => console.log("enter") }); ``` `onLeave`: Leave callback. ```tsx const hover = useHover({ onLeave: () => console.log("leave") }); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export interface UseHoverOptions { enabled?: boolean; onEntry?: (event: Event) => void; onLeave?: (event: Event) => void; } export interface UseHoverReturn { value: boolean; } export interface UseHover { (target: HookTarget, callback?: (event: Event) => void): boolean; (target: HookTarget, options?: UseHoverOptions): boolean; (callback?: (event: Event) => void, target?: never): { ref: StateRef; } & UseHoverReturn; (options?: UseHoverOptions, target?: never): { ref: StateRef; } & UseHoverReturn; } export declare const useHover: UseHover; ``` ### 2.10 useImage Loads an image with query-style state. #### Usage ```ts import { useImage } from "@siberiacancode/reactuse"; const image = useImage("https://example.com/image.png"); ``` #### Example `srcset`: Source of the image. ```tsx const image = useImage("/img.png", { srcset: "/img@2x.png 2x" }); ``` `sizes`: Sizes of the image. ```tsx const image = useImage("/img.png", { sizes: "(max-width: 600px) 100vw, 600px", }); ``` `alt`: Alt of the image. ```tsx const image = useImage("/img.png", { alt: "Preview" }); ``` `class`: Class of the image. ```tsx const image = useImage("/img.png", { class: "rounded" }); ``` `loading`: Loading of the image. ```tsx const image = useImage("/img.png", { loading: "lazy" }); ``` `crossorigin`: Crossorigin of the image. ```tsx const image = useImage("/img.png", { crossorigin: "anonymous" }); ``` `referrerPolicy`: Referrer policy of the image. ```tsx const image = useImage("/img.png", { referrerPolicy: "no-referrer" }); ``` `keys`: Keys of the image. ```tsx const image = useImage("/img.png", { keys: [theme] }); ``` `onSuccess`: On success callback. ```tsx const image = useImage("/img.png", { onSuccess: (img) => console.log(img) }); ``` `onError`: On error callback. ```tsx const image = useImage("/img.png", { onError: (err) => console.error(err) }); ``` `refetchInterval`: Refetch interval of the image. ```tsx const image = useImage("/img.png", { refetchInterval: 5000 }); ``` `retry`: Retry count of the image. ```tsx const image = useImage("/img.png", { retry: 2 }); ``` #### Type Declarations ```ts import type { UseQueryOptions, UseQueryReturn } from "@siberiacancode/reactuse"; export interface UseImageOptions { alt?: string; class?: string; crossorigin?: string; loading?: HTMLImageElement["loading"]; referrerPolicy?: HTMLImageElement["referrerPolicy"]; sizes?: string; srcset?: string; } export type UseImageReturn = UseQueryReturn; export declare const useImage: ( src: string, options?: UseImageOptions & Omit< UseQueryOptions, "initialData" | "placeholderData" | "select" > ) => UseImageReturn; ``` ### 2.11 useLockScroll Locks scrolling on an element or the document body. #### Usage ```ts import { useLockScroll } from "@siberiacancode/reactuse"; const lock = useLockScroll(); // or const lock = useLockScroll(ref, { enabled: true }); ``` #### Example ```tsx import { useLockScroll } from "@siberiacancode/reactuse"; export const Modal = () => { const lock = useLockScroll(); return (
); }; ``` `enabled`: Start locked. ```tsx const lock = useLockScroll({ enabled: false }); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export interface UseLockScrollOptions { enabled?: boolean; } export interface UseLockScrollReturn { ref: StateRef; value: boolean; lock: () => void; toggle: (value?: boolean) => void; unlock: () => void; } export interface UseLockScroll { ( target: HookTarget, options?: UseLockScrollOptions ): UseLockScrollReturn; ( options?: UseLockScrollOptions, target?: never ): UseLockScrollReturn & { ref: StateRef }; } export declare const useLockScroll: UseLockScroll; ``` ### 2.12 useLongPress Detects long press interactions. #### Usage ```ts import { useLongPress } from "@siberiacancode/reactuse"; const pressed = useLongPress(() => console.log("long press") ); // or const pressed = useLongPress(ref, () => console.log("long press")); ``` #### Example ```tsx import { useLongPress } from "@siberiacancode/reactuse"; export const HoldButton = () => { const press = useLongPress(() => console.log("long press") ); return ; }; ``` `threshold`: Press duration. ```tsx const ref = useLongPress(() => {}, { threshold: 600 }); ``` `onStart`: Press start. ```tsx const ref = useLongPress(() => {}, { onStart: () => console.log("start"), }); ``` `onFinish`: Press finish. ```tsx const ref = useLongPress(() => {}, { onFinish: () => console.log("finish"), }); ``` `onCancel`: Press cancel. ```tsx const ref = useLongPress(() => {}, { onCancel: () => console.log("cancel"), }); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export type LongPressEvents = MouseEvent | TouchEvent; export interface UseLongPressOptions { threshold?: number; onCancel?: (event: LongPressEvents) => void; onFinish?: (event: LongPressEvents) => void; onStart?: (event: LongPressEvents) => void; } export interface UseLongPress { ( target: HookTarget, callback: (event: LongPressEvents) => void, options?: UseLongPressOptions ): boolean; ( callback: (event: LongPressEvents) => void, options?: UseLongPressOptions, target?: never ): { ref: StateRef; pressed: boolean }; } export declare const useLongPress: UseLongPress; ``` ### 2.13 usePaint Draws on a canvas and exposes drawing controls. #### Usage ```ts import { usePaint } from "@siberiacancode/reactuse"; const paint = usePaint(); // or const paint = usePaint(ref, { color: "red" }); ``` #### Example ```tsx import { usePaint } from "@siberiacancode/reactuse"; export const Sketch = () => { const paint = usePaint({ color: "red", radius: 4 }); const ref = paint.ref; return (
); }; ``` `color`: Brush color. ```tsx const paint = usePaint({ color: "red" }); ``` `opacity`: Brush opacity. ```tsx const paint = usePaint({ opacity: 0.5 }); ``` `radius`: Brush size. ```tsx const paint = usePaint({ radius: 6 }); ``` `smooth`: Smoothing toggle. ```tsx const paint = usePaint({ smooth: true }); ``` `initialLines`: Restore drawings. ```tsx const paint = usePaint({ initialLines: [] }); ``` `onMouseDown`: Start drawing. ```tsx const paint = usePaint({ onMouseDown: () => console.log("down"), }); ``` `onMouseMove`: During drawing. ```tsx const paint = usePaint({ onMouseMove: () => console.log("move"), }); ``` `onMouseUp`: Stop drawing. ```tsx const paint = usePaint({ onMouseUp: () => console.log("up"), }); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export interface Point { x: number; y: number; } export interface UsePaintOptions { color?: string; initialLines?: Array<{ points: Point[]; color: string; radius: number; opacity: number; }>; opacity?: number; radius?: number; smooth?: boolean; onMouseDown?: (event: MouseEvent, paint: Paint) => void; onMouseMove?: (event: MouseEvent, paint: Paint) => void; onMouseUp?: (event: MouseEvent, paint: Paint) => void; } export interface UsePaintReturn { drawing: boolean; lines: Paint["lines"]; clear: () => void; draw: ( points: Point[], color: string, opacity: number, radius: number ) => void; undo: () => void; } export interface UsePaint { (target: HookTarget, options?: UsePaintOptions): UsePaintReturn; ( options?: UsePaintOptions, target?: never ): UsePaintReturn & { ref: StateRef }; } export declare const usePaint: UsePaint; ``` ### 2.14 useRightClick Handles right-click and long press events. #### Usage ```ts import { useRightClick } from "@siberiacancode/reactuse"; const ref = useRightClick(() => console.log("clicked")); // or useRightClick(ref, () => console.log("clicked")); ``` #### Example ```tsx import { useRightClick } from "@siberiacancode/reactuse"; import { useState } from "react"; export const Menu = () => { const [pos, setPos] = useState({ x: 0, y: 0 }); const ref = useRightClick(({ x, y }) => setPos({ x, y })); return (
Right click at {pos.x}, {pos.y}
); }; ``` `onStart`: Press start. ```tsx const ref = useRightClick(() => {}, { onStart: () => console.log("start"), }); ``` `onEnd`: Press end. ```tsx const ref = useRightClick(() => {}, { onEnd: () => console.log("end"), }); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export type RightClickEvent = MouseEvent | TouchEvent; export interface RightClickPositions { x: number; y: number; } export interface UseRightClickOptions { onEnd?: (event: RightClickEvent) => void; onStart?: (event: RightClickEvent) => void; } export interface UseRightClick { ( target: HookTarget, callback: (event: Event) => void, options?: UseRightClickOptions ): void; ( callback: (positions: RightClickPositions, event: Event) => void, options?: UseRightClickOptions, target?: never ): StateRef; } export declare const useRightClick: UseRightClick; ``` ### 2.15 useScript Loads a script and returns its status. #### Usage ```ts import { useScript } from "@siberiacancode/reactuse"; const status = useScript("https://example.com/script.js"); ``` #### Example ```tsx import { useScript } from "@siberiacancode/reactuse"; const status = useScript("https://example.com/script.js"); return
Status: {status}
; ``` `async`: ```tsx const status = useScript("https://example.com/script.js", { async: false }); ``` `removeOnUnmount`: ```tsx const status = useScript("https://example.com/script.js", { removeOnUnmount: false, }); ``` #### Type Declarations ```ts import type { ComponentProps } from "react"; export type UseScriptStatus = "error" | "loading" | "ready" | "unknown"; export interface UseScriptOptions extends ComponentProps<"script"> { removeOnUnmount?: boolean; } export declare const useScript: ( src: string, options?: UseScriptOptions ) => UseScriptStatus; ``` ### 2.16 useSize Observes element width and height. #### Usage ```ts import { useSize } from "@siberiacancode/reactuse"; const size = useSize(); // or useSize(ref); ``` #### Example ```tsx import { useSize } from "@siberiacancode/reactuse"; const size = useSize(); return (
{Math.round(size.value.width)}x{Math.round(size.value.height)}
); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export interface UseSizeValue { height: number; width: number; } export interface UseSizeReturn { observer?: ResizeObserver; value: UseSizeValue; } export interface UseSize { (target: HookTarget): UseSizeReturn; (target?: never): { ref: StateRef; } & UseSizeReturn; } export declare const useSize: UseSize; ``` ### 2.17 useSticky Detects whether a sticky element is stuck. #### Usage ```ts import { useSticky } from "@siberiacancode/reactuse"; const sticky = useSticky(); // or useSticky(ref, { axis: "vertical" }); ``` #### Example ```tsx const sticky = useSticky(); return
{sticky.stuck ? "Stuck" : "Scrolling"}
; ``` `axis`: Track axis. ```tsx const sticky = useSticky({ axis: "horizontal" }); ``` `root`: Scroll container. ```tsx const sticky = useSticky({ root: containerRef }); ``` #### Type Declarations ```ts import type { HookTarget } from "@siberiacancode/reactuse"; import type { StateRef } from "@siberiacancode/reactuse"; export interface UseStickyReturn { stuck: boolean; } export type UseStickyAxis = "horizontal" | "vertical"; export interface UseStickyOptions { axis?: UseStickyAxis; root?: HookTarget; } export interface UseSticky { (target: HookTarget, options?: UseStickyOptions): boolean; (options?: UseStickyOptions, target?: never): { ref: StateRef; } & UseStickyReturn; } export declare const useSticky: UseSticky; ``` ### 2.18 useTextareaAutosize Auto-resizes a textarea based on content. #### Usage ```ts import { useTextareaAutosize } from "@siberiacancode/reactuse"; const textarea = useTextareaAutosize(); // or const textarea = useTextareaAutosize(ref); ``` #### Example ```tsx import { useTextareaAutosize } from "@siberiacancode/reactuse"; export const Notes = () => { const textarea = useTextareaAutosize( "Write your thoughts..." ); const ref = textarea.ref; return (