@omnitron-dev/prism 0.3.5 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-DHTYHUYI.js → chunk-74TJGLFR.js} +4 -4
- package/dist/{chunk-DHTYHUYI.js.map → chunk-74TJGLFR.js.map} +1 -1
- package/dist/{chunk-D4GFAJAZ.js → chunk-FADV3QAS.js} +4 -4
- package/dist/{chunk-D4GFAJAZ.js.map → chunk-FADV3QAS.js.map} +1 -1
- package/dist/chunk-GCXRYSWU.js +132 -0
- package/dist/chunk-GCXRYSWU.js.map +1 -0
- package/dist/{chunk-UEINJFLS.js → chunk-HCADZXAK.js} +19 -10
- package/dist/chunk-HCADZXAK.js.map +1 -0
- package/dist/{chunk-RSWVYIXK.js → chunk-KOOKHWTH.js} +6 -133
- package/dist/chunk-KOOKHWTH.js.map +1 -0
- package/dist/{chunk-F6RZ7LW6.js → chunk-SPK7E7BD.js} +3 -3
- package/dist/{chunk-F6RZ7LW6.js.map → chunk-SPK7E7BD.js.map} +1 -1
- package/dist/{chunk-AATAOOSF.js → chunk-UWYLMSIQ.js} +3 -3
- package/dist/{chunk-AATAOOSF.js.map → chunk-UWYLMSIQ.js.map} +1 -1
- package/dist/{chunk-NSNM53WI.js → chunk-YYQWPEOP.js} +12 -11
- package/dist/chunk-YYQWPEOP.js.map +1 -0
- package/dist/components/admin-filters/index.js +2 -2
- package/dist/components/index.js +13 -12
- package/dist/core/index.js +4 -3
- package/dist/core/provider.d.ts +10 -4
- package/dist/core/provider.d.ts.map +1 -1
- package/dist/hooks/index.js +5 -4
- package/dist/identity/geometry.d.ts +25 -0
- package/dist/identity/geometry.d.ts.map +1 -0
- package/dist/identity/index.d.ts +6 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +278 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/omnitron-mark.d.ts +14 -0
- package/dist/identity/omnitron-mark.d.ts.map +1 -0
- package/dist/identity/omnitron-splash.d.ts +15 -0
- package/dist/identity/omnitron-splash.d.ts.map +1 -0
- package/dist/identity/theme.d.ts +7 -0
- package/dist/identity/theme.d.ts.map +1 -0
- package/dist/identity/tokens.d.ts +46 -0
- package/dist/identity/tokens.d.ts.map +1 -0
- package/dist/index.js +16 -15
- package/dist/index.js.map +1 -1
- package/dist/layouts/dashboard/sidenav.d.ts.map +1 -1
- package/dist/layouts/index.js +1 -1
- package/dist/theme/components/DataGrid.d.ts +0 -1
- package/dist/theme/components/DataGrid.d.ts.map +1 -1
- package/dist/theme/index.js +3 -2
- package/package.json +8 -4
- package/dist/chunk-NSNM53WI.js.map +0 -1
- package/dist/chunk-RSWVYIXK.js.map +0 -1
- package/dist/chunk-UEINJFLS.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-async.ts","../src/hooks/use-scroll-position.ts","../src/hooks/use-window-size.ts","../src/hooks/use-client-rect.ts","../src/hooks/use-popover-hover.ts","../src/utils/cookies.ts","../src/hooks/use-cookies.ts","../src/hooks/use-double-click.ts","../src/hooks/use-back-to-top.ts","../src/hooks/use-countdown-seconds.ts","../src/hooks/use-countdown-date.ts","../src/hooks/use-scroll-offset-top.ts","../src/hooks/use-config-from-query.ts","../src/hooks/use-image-dimensions.ts","../src/hooks/use-password-visibility.ts","../src/hooks/use-throttle.ts","../src/hooks/use-online-status.ts","../src/hooks/use-intersection-observer.ts","../src/hooks/use-keyboard-shortcut.ts","../src/hooks/use-focus-trap.ts","../src/hooks/use-update-effect.ts","../src/hooks/use-isomorphic-layout-effect.ts","../src/hooks/use-session-storage.ts","../src/hooks/use-array.ts","../src/hooks/use-mutation.ts","../src/hooks/use-lazy-query.ts","../src/hooks/use-infinite-scroll.ts"],"names":["useState","useRef","useCallback","useEffect","useMemo","useSyncExternalStore","defaultRetryDelay"],"mappings":"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","file":"chunk-DHTYHUYI.js","sourcesContent":["'use client';\n\n/**\n * useAsync Hook\n *\n * Manages async operations with loading, error, and data states.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useState, useCallback, useRef, useEffect, useMemo } from 'react';\n\n/**\n * Async state.\n */\nexport interface AsyncState<T> {\n /** Data result */\n data: T | null;\n /** Loading state */\n loading: boolean;\n /** Error state */\n error: Error | null;\n}\n\n/**\n * Return type for useAsync hook.\n */\nexport interface UseAsyncReturn<T, Args extends unknown[]> extends AsyncState<T> {\n /** Execute the async function */\n execute: (...args: Args) => Promise<T>;\n /** Reset state */\n reset: () => void;\n /** Set data manually */\n setData: (data: T | null) => void;\n /** Set error manually */\n setError: (error: Error | null) => void;\n}\n\n/**\n * Options for useAsync hook.\n */\nexport interface UseAsyncOptions<T> {\n /** Initial data */\n initialData?: T | null;\n /** Auto-execute on mount */\n immediate?: boolean;\n /** On success callback */\n onSuccess?: (data: T) => void;\n /** On error callback */\n onError?: (error: Error) => void;\n}\n\n/**\n * useAsync - Hook for managing async operations.\n *\n * @example\n * ```tsx\n * // Basic usage\n * const { data, loading, error, execute } = useAsync(fetchUser);\n *\n * // Auto-execute on mount\n * const { data, loading } = useAsync(fetchUsers, { immediate: true });\n *\n * // With callbacks\n * const { execute } = useAsync(createUser, {\n * onSuccess: (user) => toast.success(`Created ${user.name}`),\n * onError: (err) => toast.error(err.message),\n * });\n *\n * // In a component\n * const handleSubmit = async () => {\n * const result = await execute(formData);\n * if (result) navigate('/success');\n * };\n * ```\n */\nexport function useAsync<T, Args extends unknown[] = []>(\n asyncFn: (...args: Args) => Promise<T>,\n options: UseAsyncOptions<T> = {}\n): UseAsyncReturn<T, Args> {\n const { initialData = null, immediate = false, onSuccess, onError } = options;\n\n const [state, setState] = useState<AsyncState<T>>({\n data: initialData,\n loading: immediate,\n error: null,\n });\n\n // Track mounted state to prevent state updates after unmount\n const isMounted = useRef(true);\n\n // Track if we're currently executing\n const executingRef = useRef(false);\n\n useEffect(() => {\n isMounted.current = true;\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n const execute = useCallback(\n async (...args: Args): Promise<T> => {\n // Prevent concurrent executions\n if (executingRef.current) {\n return Promise.reject(new Error('Operation already in progress'));\n }\n\n executingRef.current = true;\n\n if (isMounted.current) {\n setState((prev) => ({ ...prev, loading: true, error: null }));\n }\n\n try {\n const result = await asyncFn(...args);\n\n if (isMounted.current) {\n setState({ data: result, loading: false, error: null });\n onSuccess?.(result);\n }\n\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n\n if (isMounted.current) {\n setState((prev) => ({ ...prev, loading: false, error }));\n onError?.(error);\n }\n\n throw error;\n } finally {\n executingRef.current = false;\n }\n },\n [asyncFn, onSuccess, onError]\n );\n\n const reset = useCallback(() => {\n setState({ data: initialData, loading: false, error: null });\n }, [initialData]);\n\n const setData = useCallback((data: T | null) => {\n setState((prev) => ({ ...prev, data }));\n }, []);\n\n const setError = useCallback((error: Error | null) => {\n setState((prev) => ({ ...prev, error }));\n }, []);\n\n // Auto-execute on mount if immediate is true\n useEffect(() => {\n if (immediate) {\n execute(...([] as unknown as Args)).catch(() => {\n // Error is already handled in execute\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Memoize return object to prevent unnecessary re-renders\n return useMemo(\n () => ({\n ...state,\n execute,\n reset,\n setData,\n setError,\n }),\n [state, execute, reset, setData, setError]\n );\n}\n\n/**\n * Return type for useAsyncFn hook (simpler version).\n */\nexport interface UseAsyncFnReturn<T, Args extends unknown[]> {\n /** Execute the async function */\n execute: (...args: Args) => Promise<T | undefined>;\n /** Loading state */\n loading: boolean;\n /** Error state */\n error: Error | null;\n}\n\n/**\n * useAsyncFn - Simpler hook for async functions without data tracking.\n *\n * @example\n * ```tsx\n * const { execute, loading, error } = useAsyncFn(deleteUser);\n *\n * const handleDelete = async (id: string) => {\n * await execute(id);\n * refetch(); // Trigger parent refresh\n * };\n * ```\n */\nexport function useAsyncFn<T, Args extends unknown[] = []>(\n asyncFn: (...args: Args) => Promise<T>\n): UseAsyncFnReturn<T, Args> {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const isMounted = useRef(true);\n\n useEffect(() => {\n isMounted.current = true;\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n const execute = useCallback(\n async (...args: Args): Promise<T | undefined> => {\n setLoading(true);\n setError(null);\n\n try {\n const result = await asyncFn(...args);\n if (isMounted.current) {\n setLoading(false);\n }\n return result;\n } catch (err) {\n const caughtError = err instanceof Error ? err : new Error(String(err));\n if (isMounted.current) {\n setLoading(false);\n setError(caughtError);\n }\n return undefined;\n }\n },\n [asyncFn]\n );\n\n return { execute, loading, error };\n}\n","'use client';\n\n/**\n * useScrollPosition Hook\n *\n * Tracks scroll position with performance optimization.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\n\n/**\n * Scroll position data.\n */\nexport interface ScrollPosition {\n /** Scroll position from top */\n x: number;\n /** Scroll position from left */\n y: number;\n /** Scroll direction (1 = down/right, -1 = up/left, 0 = initial) */\n directionX: -1 | 0 | 1;\n directionY: -1 | 0 | 1;\n /** Whether scrolled past threshold */\n isScrolled: boolean;\n /** Whether at the top */\n isAtTop: boolean;\n /** Whether at the bottom */\n isAtBottom: boolean;\n}\n\n/**\n * Options for useScrollPosition hook.\n */\nexport interface UseScrollPositionOptions {\n /** Element to track (default: window) */\n element?: HTMLElement | null;\n /** Throttle delay in ms (default: 100) */\n throttle?: number;\n /** Threshold to consider \"scrolled\" (default: 0) */\n threshold?: number;\n /** Offset from bottom to consider \"at bottom\" (default: 10) */\n bottomOffset?: number;\n}\n\n/**\n * useScrollPosition - Hook for tracking scroll position.\n *\n * @example\n * ```tsx\n * // Track window scroll\n * const { y, isScrolled, directionY } = useScrollPosition();\n *\n * // Show header shadow when scrolled\n * <Header className={isScrolled ? 'shadow' : ''} />\n *\n * // Hide header on scroll down, show on scroll up\n * const showHeader = directionY !== 1 || y < 50;\n *\n * // Track specific element\n * const containerRef = useRef<HTMLDivElement>(null);\n * const { isAtBottom } = useScrollPosition({ element: containerRef.current });\n *\n * // Load more when near bottom\n * useEffect(() => {\n * if (isAtBottom) loadMore();\n * }, [isAtBottom]);\n * ```\n */\nexport function useScrollPosition(options: UseScrollPositionOptions = {}): ScrollPosition {\n const { element = null, throttle = 100, threshold = 0, bottomOffset = 10 } = options;\n\n const [position, setPosition] = useState<ScrollPosition>({\n x: 0,\n y: 0,\n directionX: 0,\n directionY: 0,\n isScrolled: false,\n isAtTop: true,\n isAtBottom: false,\n });\n\n const lastPosition = useRef({ x: 0, y: 0 });\n const ticking = useRef(false);\n\n const updatePosition = useCallback(() => {\n // SSR guard - only run on client\n if (typeof window === 'undefined') return;\n\n const scrollX = element ? element.scrollLeft : window.scrollX;\n const scrollY = element ? element.scrollTop : window.scrollY;\n\n // Calculate max scroll\n const maxScrollY = element\n ? element.scrollHeight - element.clientHeight\n : document.documentElement.scrollHeight - window.innerHeight;\n\n // Calculate direction\n const directionX = scrollX > lastPosition.current.x ? 1 : scrollX < lastPosition.current.x ? -1 : 0;\n const directionY = scrollY > lastPosition.current.y ? 1 : scrollY < lastPosition.current.y ? -1 : 0;\n\n lastPosition.current = { x: scrollX, y: scrollY };\n\n setPosition({\n x: scrollX,\n y: scrollY,\n directionX: directionX as -1 | 0 | 1,\n directionY: directionY as -1 | 0 | 1,\n isScrolled: scrollY > threshold,\n isAtTop: scrollY <= 0,\n isAtBottom: scrollY >= maxScrollY - bottomOffset,\n });\n\n ticking.current = false;\n }, [element, threshold, bottomOffset]);\n\n const handleScroll = useCallback(() => {\n if (!ticking.current) {\n if (throttle > 0) {\n window.requestAnimationFrame(() => {\n updatePosition();\n });\n } else {\n updatePosition();\n }\n ticking.current = true;\n\n if (throttle > 0) {\n setTimeout(() => {\n ticking.current = false;\n }, throttle);\n }\n }\n }, [throttle, updatePosition]);\n\n useEffect(() => {\n // SSR guard\n if (typeof window === 'undefined') return undefined;\n\n const target = element ?? window;\n\n // Initial position\n updatePosition();\n\n target.addEventListener('scroll', handleScroll, { passive: true });\n\n return () => {\n target.removeEventListener('scroll', handleScroll);\n };\n }, [element, handleScroll, updatePosition]);\n\n return position;\n}\n\n/**\n * useScrollToTop - Hook for scrolling to top functionality.\n *\n * @example\n * ```tsx\n * const { scrollToTop, showButton } = useScrollToTop({ threshold: 300 });\n *\n * {showButton && (\n * <Fab onClick={scrollToTop}>\n * <ArrowUpIcon />\n * </Fab>\n * )}\n * ```\n */\nexport function useScrollToTop(options: { threshold?: number } = {}): {\n scrollToTop: () => void;\n showButton: boolean;\n} {\n const { threshold = 300 } = options;\n const { y } = useScrollPosition({ threshold });\n\n const scrollToTop = useCallback(() => {\n window.scrollTo({ top: 0, behavior: 'smooth' });\n }, []);\n\n return {\n scrollToTop,\n showButton: y > threshold,\n };\n}\n\n/**\n * useScrollLock - Hook for locking body scroll.\n *\n * @example\n * ```tsx\n * const { lock, unlock, isLocked } = useScrollLock();\n *\n * // Lock when modal opens\n * useEffect(() => {\n * if (isOpen) lock();\n * else unlock();\n * }, [isOpen]);\n * ```\n */\nexport function useScrollLock(): {\n lock: () => void;\n unlock: () => void;\n isLocked: boolean;\n} {\n const [isLocked, setIsLocked] = useState(false);\n const scrollY = useRef(0);\n\n const lock = useCallback(() => {\n if (typeof document === 'undefined') return;\n\n scrollY.current = window.scrollY;\n document.body.style.position = 'fixed';\n document.body.style.top = `-${scrollY.current}px`;\n document.body.style.width = '100%';\n document.body.style.overflow = 'hidden';\n setIsLocked(true);\n }, []);\n\n const unlock = useCallback(() => {\n if (typeof document === 'undefined') return;\n\n document.body.style.position = '';\n document.body.style.top = '';\n document.body.style.width = '';\n document.body.style.overflow = '';\n window.scrollTo(0, scrollY.current);\n setIsLocked(false);\n }, []);\n\n // Cleanup on unmount\n useEffect(\n () => () => {\n if (isLocked) {\n document.body.style.position = '';\n document.body.style.top = '';\n document.body.style.width = '';\n document.body.style.overflow = '';\n }\n },\n [isLocked]\n );\n\n return { lock, unlock, isLocked };\n}\n","'use client';\n\n/**\n * useWindowSize Hook\n *\n * Tracks window dimensions with responsive breakpoint utilities.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useState, useEffect, useCallback, useRef, useMemo } from 'react';\n\n/**\n * Window size data.\n */\nexport interface WindowSize {\n /** Window width */\n width: number;\n /** Window height */\n height: number;\n /** Is mobile (< 600px) */\n isMobile: boolean;\n /** Is tablet (600px - 960px) */\n isTablet: boolean;\n /** Is desktop (>= 960px) */\n isDesktop: boolean;\n /** Is large desktop (>= 1280px) */\n isLargeDesktop: boolean;\n}\n\n/**\n * Breakpoint definitions (following MUI defaults).\n */\nexport interface Breakpoints {\n xs: number;\n sm: number;\n md: number;\n lg: number;\n xl: number;\n}\n\n/**\n * Default breakpoints (MUI defaults).\n */\nconst defaultBreakpoints: Breakpoints = {\n xs: 0,\n sm: 600,\n md: 900,\n lg: 1200,\n xl: 1536,\n};\n\n/**\n * Options for useWindowSize hook.\n */\nexport interface UseWindowSizeOptions {\n /** Custom breakpoints */\n breakpoints?: Partial<Breakpoints>;\n /** Debounce delay in ms (default: 100) */\n debounce?: number;\n /** Initial width for SSR (default: 1200) */\n initialWidth?: number;\n /** Initial height for SSR (default: 800) */\n initialHeight?: number;\n}\n\n/**\n * useWindowSize - Hook for tracking window dimensions.\n *\n * @example\n * ```tsx\n * // Basic usage\n * const { width, height, isMobile, isDesktop } = useWindowSize();\n *\n * // Responsive rendering\n * if (isMobile) {\n * return <MobileLayout />;\n * }\n * return <DesktopLayout />;\n *\n * // Responsive columns\n * const columns = isMobile ? 1 : isTablet ? 2 : 4;\n *\n * // Custom breakpoints\n * const { isMobile } = useWindowSize({\n * breakpoints: { sm: 768 }\n * });\n * ```\n */\nexport function useWindowSize(options: UseWindowSizeOptions = {}): WindowSize {\n const { breakpoints: customBreakpoints, debounce = 100, initialWidth = 1200, initialHeight = 800 } = options;\n\n const breakpoints = { ...defaultBreakpoints, ...customBreakpoints };\n\n const getSize = useCallback((): WindowSize => {\n if (typeof window === 'undefined') {\n return {\n width: initialWidth,\n height: initialHeight,\n isMobile: initialWidth < breakpoints.sm,\n isTablet: initialWidth >= breakpoints.sm && initialWidth < breakpoints.md,\n isDesktop: initialWidth >= breakpoints.md,\n isLargeDesktop: initialWidth >= breakpoints.lg,\n };\n }\n\n const width = window.innerWidth;\n const height = window.innerHeight;\n\n return {\n width,\n height,\n isMobile: width < breakpoints.sm,\n isTablet: width >= breakpoints.sm && width < breakpoints.md,\n isDesktop: width >= breakpoints.md,\n isLargeDesktop: width >= breakpoints.lg,\n };\n }, [breakpoints.sm, breakpoints.md, breakpoints.lg, initialWidth, initialHeight]);\n\n const [size, setSize] = useState<WindowSize>(getSize);\n\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (typeof window === 'undefined') return undefined;\n\n const handleResize = () => {\n if (debounce > 0) {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = setTimeout(() => {\n setSize(getSize());\n }, debounce);\n } else {\n setSize(getSize());\n }\n };\n\n // Set initial size\n setSize(getSize());\n\n window.addEventListener('resize', handleResize);\n\n return () => {\n window.removeEventListener('resize', handleResize);\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, [debounce, getSize]);\n\n return size;\n}\n\n/**\n * Return type for useResponsiveQuery hook.\n */\nexport type UseResponsiveQueryReturn = boolean;\n\n/**\n * useResponsiveQuery - Hook for CSS media query matching.\n *\n * Note: For the simpler MUI-style useMediaQuery, see @omnitron-dev/prism/core.\n * This hook provides a standalone implementation without MUI dependency.\n *\n * @example\n * ```tsx\n * // Direct media query\n * const prefersDark = useResponsiveQuery('(prefers-color-scheme: dark)');\n * const isRetina = useResponsiveQuery('(min-resolution: 2dppx)');\n *\n * // Responsive\n * const isLargeScreen = useResponsiveQuery('(min-width: 1200px)');\n * ```\n */\nexport function useResponsiveQuery(query: string): UseResponsiveQueryReturn {\n const [matches, setMatches] = useState(() => {\n if (typeof window === 'undefined') return false;\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return undefined;\n\n const mediaQuery = window.matchMedia(query);\n\n const handleChange = (event: MediaQueryListEvent) => {\n setMatches(event.matches);\n };\n\n // Set initial value\n setMatches(mediaQuery.matches);\n\n // Modern browsers\n if (mediaQuery.addEventListener) {\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }\n\n // Fallback for older browsers\n mediaQuery.addListener(handleChange);\n return () => mediaQuery.removeListener(handleChange);\n }, [query]);\n\n return matches;\n}\n\n/**\n * useBreakpoint - Hook for checking current breakpoint.\n *\n * @example\n * ```tsx\n * const breakpoint = useBreakpoint();\n *\n * // Current breakpoint name\n * console.log(breakpoint); // 'md'\n *\n * // Check specific breakpoint\n * const { isUp, isDown, isOnly, isBetween } = useBreakpointChecks();\n *\n * if (isUp('md')) {\n * // Screen is md or larger\n * }\n * ```\n */\nexport function useBreakpoint(customBreakpoints?: Partial<Breakpoints>): 'xs' | 'sm' | 'md' | 'lg' | 'xl' {\n const breakpoints = { ...defaultBreakpoints, ...customBreakpoints };\n const { width } = useWindowSize({ breakpoints: customBreakpoints });\n\n if (width >= breakpoints.xl) return 'xl';\n if (width >= breakpoints.lg) return 'lg';\n if (width >= breakpoints.md) return 'md';\n if (width >= breakpoints.sm) return 'sm';\n return 'xs';\n}\n\n/**\n * Return type for useBreakpointChecks hook.\n */\nexport interface BreakpointChecks {\n /** Check if width is >= breakpoint */\n isUp: (breakpoint: keyof Breakpoints) => boolean;\n /** Check if width is < breakpoint */\n isDown: (breakpoint: keyof Breakpoints) => boolean;\n /** Check if width is within breakpoint range */\n isOnly: (breakpoint: keyof Breakpoints) => boolean;\n /** Check if width is between two breakpoints */\n isBetween: (start: keyof Breakpoints, end: keyof Breakpoints) => boolean;\n}\n\nconst orderedBreakpoints: (keyof Breakpoints)[] = ['xs', 'sm', 'md', 'lg', 'xl'];\n\nconst getNextBreakpoint = (bp: keyof Breakpoints): keyof Breakpoints | null => {\n const index = orderedBreakpoints.indexOf(bp);\n return index < orderedBreakpoints.length - 1 ? orderedBreakpoints[index + 1] : null;\n};\n\n\n/**\n * useBreakpointChecks - Hook for advanced breakpoint checking.\n *\n * @example\n * ```tsx\n * const { isUp, isDown, isOnly, isBetween } = useBreakpointChecks();\n *\n * isUp('md'); // true if >= 900px\n * isDown('lg'); // true if < 1200px\n * isOnly('md'); // true if 900px - 1199px\n * isBetween('sm', 'lg'); // true if 600px - 1199px\n * ```\n */\nexport function useBreakpointChecks(customBreakpoints?: Partial<Breakpoints>): BreakpointChecks {\n // Memoize breakpoints to prevent callback recreation on every render\n const breakpoints = useMemo(() => ({ ...defaultBreakpoints, ...customBreakpoints }), [customBreakpoints]);\n const { width } = useWindowSize({ breakpoints: customBreakpoints });\n\n const isUp = useCallback(\n (breakpoint: keyof Breakpoints): boolean => width >= breakpoints[breakpoint],\n [width, breakpoints]\n );\n\n const isDown = useCallback(\n (breakpoint: keyof Breakpoints): boolean => width < breakpoints[breakpoint],\n [width, breakpoints]\n );\n\n const isOnly = useCallback(\n (breakpoint: keyof Breakpoints): boolean => {\n const next = getNextBreakpoint(breakpoint);\n const min = breakpoints[breakpoint];\n const max = next ? breakpoints[next] : Infinity;\n return width >= min && width < max;\n },\n [width, breakpoints]\n );\n\n const isBetween = useCallback(\n (start: keyof Breakpoints, end: keyof Breakpoints): boolean =>\n width >= breakpoints[start] && width < breakpoints[end],\n [width, breakpoints]\n );\n\n return { isUp, isDown, isOnly, isBetween };\n}\n","'use client';\n\n/**\n * useClientRect Hook\n *\n * Gets bounding client rect and scroll dimensions of a DOM element.\n * SSR-safe with automatic updates on resize/scroll.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useState, useCallback, useEffect, useRef, type RefObject } from 'react';\n\n/**\n * Scroll element dimensions.\n */\nexport interface ScrollElValue {\n /** Scrollable width */\n scrollWidth: number;\n /** Scrollable height */\n scrollHeight: number;\n}\n\n/**\n * DOMRect values (SSR-safe).\n */\nexport interface DOMRectValue {\n top: number;\n right: number;\n bottom: number;\n left: number;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Return type for useClientRect hook.\n */\nexport interface UseClientRectReturn<T extends HTMLElement = HTMLElement> extends DOMRectValue, ScrollElValue {\n /** Ref to attach to the target element */\n elementRef: RefObject<T | null>;\n /** Force update measurements */\n update: () => void;\n}\n\n/**\n * Default values for SSR and when element is not available.\n */\nconst defaultValues: DOMRectValue & ScrollElValue = {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n scrollWidth: 0,\n scrollHeight: 0,\n};\n\n/**\n * useClientRect - Hook to get bounding rect and scroll dimensions.\n *\n * @example\n * ```tsx\n * // Basic usage - auto-creates ref\n * const { elementRef, width, height, top, left } = useClientRect();\n *\n * return (\n * <div ref={elementRef}>\n * Width: {width}, Height: {height}\n * </div>\n * );\n *\n * // With existing ref\n * const myRef = useRef<HTMLDivElement>(null);\n * const { width, scrollWidth } = useClientRect(myRef);\n *\n * // Listen to scroll events\n * const { y, scrollHeight } = useClientRect(ref, 'scroll');\n *\n * // Calculate scroll progress\n * const progress = y / (scrollHeight - height);\n * ```\n */\nexport function useClientRect<T extends HTMLElement = HTMLElement>(\n inputRef?: RefObject<T | null>,\n eventType?: 'scroll' | 'resize'\n): UseClientRectReturn<T> {\n const internalRef = useRef<T>(null);\n const elementRef = (inputRef ?? internalRef) as RefObject<T | null>;\n\n const [rect, setRect] = useState<DOMRectValue & ScrollElValue>(defaultValues);\n\n const update = useCallback(() => {\n const element = elementRef.current;\n\n if (!element) {\n setRect(defaultValues);\n return;\n }\n\n const domRect = element.getBoundingClientRect();\n\n setRect({\n top: domRect.top,\n right: domRect.right,\n bottom: domRect.bottom,\n left: domRect.left,\n x: domRect.x,\n y: domRect.y,\n width: domRect.width,\n height: domRect.height,\n scrollWidth: element.scrollWidth,\n scrollHeight: element.scrollHeight,\n });\n }, [elementRef]);\n\n useEffect(() => {\n const element = elementRef.current;\n\n // Initial measurement\n update();\n\n if (!element || typeof window === 'undefined') return undefined;\n\n // Observe resize with ResizeObserver\n const resizeObserver = new ResizeObserver(() => {\n update();\n });\n resizeObserver.observe(element);\n\n // Optional event listener\n const target = eventType === 'scroll' ? element : window;\n const event = eventType ?? 'resize';\n\n const handleEvent = () => {\n update();\n };\n\n target.addEventListener(event, handleEvent, { passive: true });\n\n return () => {\n resizeObserver.disconnect();\n target.removeEventListener(event, handleEvent);\n };\n }, [elementRef, eventType, update]);\n\n return {\n ...rect,\n elementRef,\n update,\n };\n}\n","'use client';\n\n/**\n * usePopoverHover Hook\n *\n * Manages hover-based popover state with proper enter/leave handling.\n * Different from click-based popovers - opens on mouse enter, closes on leave.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useState, useCallback, useRef, type RefObject, type Dispatch, type SetStateAction } from 'react';\n\n/**\n * Return type for usePopoverHover hook.\n */\nexport interface UsePopoverHoverReturn<T extends HTMLElement = HTMLElement> {\n /** Whether the popover is open */\n open: boolean;\n /** The element the popover is anchored to (for MUI Popover) */\n anchorEl: T | null;\n /** Handler for mouse enter - opens the popover */\n onOpen: () => void;\n /** Handler for mouse leave - closes the popover */\n onClose: () => void;\n /** Ref to attach to the trigger element */\n elementRef: RefObject<T | null>;\n /** Manual control of open state */\n setOpen: Dispatch<SetStateAction<boolean>>;\n}\n\n/**\n * usePopoverHover - Hook for hover-based popover management.\n *\n * This hook is SSR-safe. It doesn't access browser APIs directly.\n * During SSR, elementRef.current is null and open defaults to false,\n * so anchorEl will always be null on the server.\n *\n * @example\n * ```tsx\n * // Basic usage\n * const { open, anchorEl, onOpen, onClose, elementRef } = usePopoverHover<HTMLButtonElement>();\n *\n * return (\n * <>\n * <Button\n * ref={elementRef}\n * onMouseEnter={onOpen}\n * onMouseLeave={onClose}\n * >\n * Hover me\n * </Button>\n * <Popover\n * open={open}\n * anchorEl={anchorEl}\n * onClose={onClose}\n * anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n * >\n * <Typography sx={{ p: 2 }}>Popover content</Typography>\n * </Popover>\n * </>\n * );\n *\n * // With existing ref\n * const myRef = useRef<HTMLDivElement>(null);\n * const { open, onOpen, onClose } = usePopoverHover(myRef);\n *\n * // With delay (using inline)\n * const { open, anchorEl, elementRef, setOpen } = usePopoverHover();\n * const timeoutRef = useRef<NodeJS.Timeout>();\n *\n * const handleOpen = () => {\n * clearTimeout(timeoutRef.current);\n * setOpen(true);\n * };\n *\n * const handleClose = () => {\n * timeoutRef.current = setTimeout(() => setOpen(false), 200);\n * };\n * ```\n */\nexport function usePopoverHover<T extends HTMLElement = HTMLElement>(\n inputRef?: RefObject<T | null>\n): UsePopoverHoverReturn<T> {\n const internalRef = useRef<T>(null);\n const elementRef = (inputRef ?? internalRef) as RefObject<T | null>;\n\n const [open, setOpen] = useState(false);\n\n const onOpen = useCallback(() => {\n setOpen(true);\n }, []);\n\n const onClose = useCallback(() => {\n setOpen(false);\n }, []);\n\n // anchorEl is the current element when open, null when closed\n const anchorEl = open ? elementRef.current : null;\n\n return {\n open,\n anchorEl,\n onOpen,\n onClose,\n elementRef,\n setOpen,\n };\n}\n","/**\n * Cookie Utilities\n *\n * Type-safe cookie management with JSON serialization.\n *\n * @module utils\n */\n\n/**\n * Cookie options for setting cookies.\n */\nexport interface CookieOptions {\n /** Enable secure flag (HTTPS only) */\n secure?: boolean;\n /** Days until expiration */\n daysUntilExpiration?: number;\n /** SameSite policy */\n sameSite?: 'strict' | 'lax' | 'none';\n /** Cookie domain */\n domain?: string;\n /** Cookie path */\n path?: string;\n}\n\n/**\n * Check if cookies are available.\n *\n * @returns {boolean} True if cookies are available\n */\nexport function cookiesAvailable(): boolean {\n if (typeof document === 'undefined') {\n return false;\n }\n\n try {\n document.cookie = '__test__=1';\n const result = document.cookie.includes('__test__=1');\n document.cookie = '__test__=; expires=Thu, 01 Jan 1970 00:00:00 GMT';\n return result;\n } catch {\n return false;\n }\n}\n\n/**\n * Get a cookie value with JSON parsing.\n *\n * @template T - Type of the stored value\n * @param {string} key - Cookie name\n * @returns {T | null} Parsed value or null\n *\n * @example\n * ```ts\n * const user = getCookie<User>('user');\n * ```\n */\nexport function getCookie<T>(key: string): T | null {\n if (typeof document === 'undefined') {\n return null;\n }\n\n try {\n const name = `${key}=`;\n const decodedCookie = decodeURIComponent(document.cookie);\n const cookies = decodedCookie.split(';');\n\n for (const cookie of cookies) {\n const c = cookie.trim();\n if (c.startsWith(name)) {\n const value = c.substring(name.length);\n return JSON.parse(value) as T;\n }\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Set a cookie with JSON serialization.\n *\n * @template T - Type of the value\n * @param {string} key - Cookie name\n * @param {T} value - Value to store\n * @param {CookieOptions} [options] - Cookie options\n *\n * @example\n * ```ts\n * setCookie('user', { name: 'John' }, { daysUntilExpiration: 7 });\n * ```\n */\nexport function setCookie<T>(key: string, value: T, options: CookieOptions = {}): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n const { secure = false, daysUntilExpiration = 30, sameSite = 'lax', domain, path = '/' } = options;\n\n try {\n const serializedValue = JSON.stringify(value);\n let cookieString = `${key}=${encodeURIComponent(serializedValue)}`;\n\n if (daysUntilExpiration) {\n const date = new Date();\n date.setTime(date.getTime() + daysUntilExpiration * 24 * 60 * 60 * 1000);\n cookieString += `; expires=${date.toUTCString()}`;\n }\n\n cookieString += `; path=${path}`;\n cookieString += `; SameSite=${sameSite}`;\n\n if (secure) {\n cookieString += '; Secure';\n }\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n document.cookie = cookieString;\n } catch (error) {\n console.warn(`Failed to set cookie \"${key}\":`, error);\n }\n}\n\n/**\n * Remove a cookie.\n *\n * @param {string} key - Cookie name\n * @param {Pick<CookieOptions, 'domain' | 'path'>} [options] - Cookie options\n *\n * @example\n * ```ts\n * removeCookie('user');\n * ```\n */\nexport function removeCookie(key: string, options: Pick<CookieOptions, 'domain' | 'path'> = {}): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n const { domain, path = '/' } = options;\n\n let cookieString = `${key}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n document.cookie = cookieString;\n}\n","'use client';\n\n/**\n * useCookies Hook\n *\n * Manages state with cookies. Supports both primitive values\n * and objects with partial updates.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useMemo, useState, useEffect, useCallback } from 'react';\nimport type { CookieOptions } from '../utils/cookies.js';\nimport { setCookie, getCookie, removeCookie } from '../utils/cookies.js';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Options for useCookies hook.\n */\nexport interface UseCookiesOptions extends CookieOptions {\n /**\n * If true, initializes the cookie with the initial value if not set.\n * @default true\n */\n initializeWithValue?: boolean;\n}\n\n/**\n * Return type for useCookies hook.\n */\nexport interface UseCookiesReturn<T> {\n /** Current state value */\n state: T;\n /** Reset state to initial value and remove cookie */\n resetState: (defaultState?: T) => void;\n /** Update the entire state or merge partial state (for objects) */\n setState: (updateState: T | Partial<T>) => void;\n /** Update a specific field in an object state */\n setField: <K extends keyof T>(name: K, updateValue: T[K]) => void;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Hook to manage state with cookies.\n *\n * Automatically syncs state with cookies and supports:\n * - Primitive values (string, number, boolean)\n * - Object values with partial updates\n * - Type-safe field updates\n *\n * @template T - Type of the state value\n * @param key - Cookie name\n * @param initialState - Initial state value\n * @param options - Cookie options\n * @returns State and update functions\n *\n * @example\n * ```tsx\n * // Primitive value\n * const { state, setState, resetState } = useCookies('theme', 'light');\n *\n * // Object value with partial updates\n * const { state, setState, setField, resetState } = useCookies('user', {\n * name: '',\n * age: 0,\n * preferences: { notifications: true },\n * });\n *\n * // Update single field\n * setField('name', 'John');\n *\n * // Partial update\n * setState({ age: 25 });\n *\n * // Reset to initial value\n * resetState();\n * ```\n */\nexport function useCookies<T>(key: string, initialState: T, options?: UseCookiesOptions): UseCookiesReturn<T> {\n const { initializeWithValue = true, ...cookieOptions } = options ?? {};\n const [state, setStateInternal] = useState<T>(initialState);\n\n // Initialize from cookie on mount\n useEffect(() => {\n const storedValue = getCookie<T>(key);\n const isObject = initialState !== null && typeof initialState === 'object';\n\n if (storedValue !== null) {\n if (isObject) {\n // Merge stored value with initial state for object types\n setStateInternal((prev) => ({ ...prev, ...storedValue }));\n } else {\n setStateInternal(storedValue);\n }\n } else if (initializeWithValue) {\n // Initialize cookie with initial value if not set\n setCookie(key, initialState, cookieOptions);\n }\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const isObjectState = initialState !== null && typeof initialState === 'object';\n\n const updateState = useCallback(\n (newState: T | Partial<T>) => {\n if (isObjectState) {\n // The object branch writes the cookie INSIDE the updater and the\n // scalar branch writes it outside — an asymmetry that reads like an\n // oversight and is not. Merging needs the previous value, and taking\n // it from a ref instead would break composition: two `setField`\n // calls in one handler would both merge into the same snapshot and\n // the first field would be lost. See `useLocalStorage.setValue` for\n // the same trade-off and what it costs.\n setStateInternal((prev) => {\n const updatedState = { ...prev, ...newState } as T;\n setCookie(key, updatedState, cookieOptions);\n return updatedState;\n });\n } else {\n setCookie(key, newState as T, cookieOptions);\n setStateInternal(newState as T);\n }\n },\n [cookieOptions, isObjectState, key]\n );\n\n const updateField = useCallback(\n <K extends keyof T>(fieldName: K, updateValue: T[K]) => {\n if (isObjectState) {\n updateState({ [fieldName]: updateValue } as unknown as Partial<T>);\n } else {\n console.warn('[useCookies] setField is only available for object states. Use setState instead.');\n }\n },\n [isObjectState, updateState]\n );\n\n const resetState = useCallback(\n (defaultState?: T) => {\n setStateInternal(defaultState ?? initialState);\n removeCookie(key, { path: cookieOptions.path, domain: cookieOptions.domain });\n },\n [initialState, key, cookieOptions.path, cookieOptions.domain]\n );\n\n return useMemo(\n () => ({\n state,\n setState: updateState,\n setField: updateField,\n resetState,\n }),\n [state, updateState, updateField, resetState]\n );\n}\n","'use client';\n\n/**\n * useDoubleClick Hook\n *\n * Differentiates between single and double click events.\n * Single click is delayed to ensure it's not a double click.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport type { MouseEvent, SyntheticEvent } from 'react';\nimport { useRef, useCallback, useEffect } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Props for useDoubleClick hook.\n */\nexport interface UseDoubleClickProps {\n /**\n * Timeout in milliseconds to differentiate between single and double clicks.\n * @default 250\n */\n timeout?: number;\n /** Handler for single click (optional) */\n click?: (event: SyntheticEvent) => void;\n /** Handler for double click (required) */\n doubleClick: (event: SyntheticEvent) => void;\n}\n\n/**\n * Return type - a click handler function.\n */\nexport type UseDoubleClickReturn = (event: MouseEvent<HTMLElement>) => void;\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Hook to handle single and double click events on an element.\n *\n * Uses event.detail to detect click count:\n * - detail === 1: single click (delayed by timeout)\n * - detail === 2: double click (immediate)\n *\n * The single click handler is called after a timeout, but only if\n * no second click occurs within that time.\n *\n * @param props - Hook configuration\n * @returns Click handler function to attach to element\n *\n * @example\n * ```tsx\n * function FileItem({ file }) {\n * const handleClick = useDoubleClick({\n * click: () => selectFile(file),\n * doubleClick: () => openFile(file),\n * timeout: 300,\n * });\n *\n * return (\n * <div onClick={handleClick}>\n * {file.name}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Double-click only (no single click handler)\n * const handleClick = useDoubleClick({\n * doubleClick: () => console.log('Double clicked!'),\n * });\n * ```\n */\nexport function useDoubleClick({ click, doubleClick, timeout = 250 }: UseDoubleClickProps): UseDoubleClickReturn {\n const clickTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const clearClickTimeout = useCallback(() => {\n if (clickTimeout.current) {\n clearTimeout(clickTimeout.current);\n clickTimeout.current = null;\n }\n }, []);\n\n const handleEvent = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n clearClickTimeout();\n\n // Single click - delay execution\n if (click && event.detail === 1) {\n // React 17+ does not pool synthetic events, so the event reference remains valid\n clickTimeout.current = setTimeout(() => {\n click(event);\n }, timeout);\n }\n\n // Double click (or any even number of clicks) - execute immediately\n if (event.detail % 2 === 0) {\n doubleClick(event);\n }\n },\n [click, doubleClick, timeout, clearClickTimeout]\n );\n\n // Cleanup timeout on unmount to prevent memory leaks\n useEffect(\n () => () => {\n clearClickTimeout();\n },\n [clearClickTimeout]\n );\n\n return handleEvent;\n}\n","'use client';\n\n/**\n * useBackToTop Hook\n *\n * Manages visibility of a \"Back to Top\" button based on scroll position.\n * Supports both percentage-based and pixel-based visibility thresholds.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport type { Dispatch, SetStateAction } from 'react';\nimport { useMemo, useState, useEffect, useCallback, useRef } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Return type for useBackToTop hook.\n */\nexport interface UseBackToTopReturn {\n /** Whether the \"Back to Top\" button should be visible */\n isVisible: boolean;\n /** Function to scroll smoothly to top */\n onBackToTop: () => void;\n /** Manual visibility control */\n setIsVisible: Dispatch<SetStateAction<boolean>>;\n}\n\n/**\n * Parsed threshold value.\n */\ninterface ParsedThreshold {\n value: number;\n type: 'percentage' | 'pixels';\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Parse threshold input value.\n *\n * @param input - Percentage string (e.g., '90%') or pixel number\n * @returns Parsed threshold with type\n * @throws Error if invalid percentage string\n */\nfunction parseThreshold(input: string | number): ParsedThreshold {\n if (typeof input === 'string') {\n if (!input.endsWith('%')) {\n throw new Error('[useBackToTop] String threshold must end with % (e.g., \"90%\")');\n }\n const value = Number(input.slice(0, -1));\n if (isNaN(value)) {\n throw new Error('[useBackToTop] Invalid percentage value');\n }\n return { value, type: 'percentage' };\n }\n\n return { value: input, type: 'pixels' };\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Hook to manage the visibility of a \"Back to Top\" button based on scroll position.\n *\n * Two modes are supported:\n * - **Percentage mode**: Button becomes visible when scrolled past N% of the page.\n * Pass a string like '90%' as the threshold.\n * - **Pixel mode**: Button becomes visible when within N pixels of the bottom.\n * Pass a number like 80 as the threshold.\n *\n * @param threshold - Visibility threshold\n * - String with '%' (e.g., '90%'): Show when scroll progress >= this percentage\n * - Number (e.g., 80): Show when within this many pixels from bottom\n * @param debounce - Whether to debounce the scroll handler (100ms)\n * @returns Visibility state and scroll control functions\n *\n * @example\n * ```tsx\n * // Show when scrolled 90% down the page\n * const { isVisible, onBackToTop } = useBackToTop('90%');\n *\n * // Show when within 80px of the bottom\n * const { isVisible, onBackToTop } = useBackToTop(80);\n *\n * // With debouncing for better performance\n * const { isVisible, onBackToTop } = useBackToTop('85%', true);\n *\n * return (\n * <Fade in={isVisible}>\n * <Fab onClick={onBackToTop} sx={{ position: 'fixed', bottom: 16, right: 16 }}>\n * <KeyboardArrowUpIcon />\n * </Fab>\n * </Fade>\n * );\n * ```\n */\nexport function useBackToTop(threshold: string | number = '90%', debounce: boolean = false): UseBackToTopReturn {\n const [isVisible, setIsVisible] = useState(false);\n\n const parsedThreshold = useMemo(() => parseThreshold(threshold), [threshold]);\n\n const handleScroll = useCallback(() => {\n // SSR guard - only run on client\n if (typeof window === 'undefined') return;\n\n const windowHeight = window.innerHeight;\n const scrollY = Math.round(window.scrollY);\n const documentHeight = document.body.offsetHeight;\n\n // Calculate scroll progress (0-100)\n const maxScroll = documentHeight - windowHeight;\n const scrollProgress = maxScroll > 0 ? Math.round((scrollY / maxScroll) * 100) : 0;\n\n if (parsedThreshold.type === 'percentage') {\n // Percentage mode: visible when scroll progress >= threshold\n setIsVisible(scrollProgress >= parsedThreshold.value);\n } else {\n // Pixel mode: visible when within threshold pixels from bottom\n const distanceFromBottom = documentHeight - windowHeight - scrollY;\n setIsVisible(distanceFromBottom <= parsedThreshold.value);\n }\n }, [parsedThreshold]);\n\n // Debounced scroll handler with cleanup support\n const debounceTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const debouncedHandleScroll = useCallback(() => {\n if (debounceTimeoutRef.current !== null) clearTimeout(debounceTimeoutRef.current);\n debounceTimeoutRef.current = setTimeout(handleScroll, 100);\n }, [handleScroll]);\n\n useEffect(() => {\n // SSR guard\n if (typeof window === 'undefined') return undefined;\n\n const scrollHandler = debounce ? debouncedHandleScroll : handleScroll;\n\n // Check initial position\n handleScroll();\n\n window.addEventListener('scroll', scrollHandler, { passive: true });\n\n return () => {\n window.removeEventListener('scroll', scrollHandler);\n if (debounceTimeoutRef.current !== null) clearTimeout(debounceTimeoutRef.current);\n };\n }, [debounce, debouncedHandleScroll, handleScroll]);\n\n const onBackToTop = useCallback(() => {\n // SSR guard\n if (typeof window === 'undefined') return;\n window.scrollTo({ top: 0, behavior: 'smooth' });\n }, []);\n\n return { isVisible, onBackToTop, setIsVisible };\n}\n","'use client';\n\n/**\n * useCountdownSeconds Hook\n *\n * Simple countdown timer in seconds. Ideal for OTP resend timers,\n * session timeouts, and other time-limited operations.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport type { Dispatch, SetStateAction } from 'react';\nimport { useState, useEffect, useCallback, useMemo } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Return type for useCountdownSeconds hook.\n */\nexport interface UseCountdownSecondsReturn {\n /** Current countdown value in seconds */\n value: number;\n /** Start the countdown */\n start: () => void;\n /** Reset countdown to initial value and stop */\n reset: () => void;\n /** Whether countdown is currently active */\n isCounting: boolean;\n /** Manually set the countdown value */\n setValue: Dispatch<SetStateAction<number>>;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Hook to create a simple countdown timer in seconds.\n *\n * Perfect for:\n * - OTP resend timers\n * - Session timeout warnings\n * - Rate limiting UI feedback\n * - Game timers\n *\n * @param initialSeconds - Initial countdown value in seconds\n * @returns Countdown state and control functions\n *\n * @example\n * ```tsx\n * // OTP resend timer\n * function OTPForm() {\n * const { value, start, reset, isCounting } = useCountdownSeconds(60);\n *\n * const handleResend = async () => {\n * await resendOTP();\n * reset();\n * start();\n * };\n *\n * return (\n * <div>\n * <input placeholder=\"Enter OTP\" />\n * <button onClick={handleResend} disabled={isCounting}>\n * {isCounting ? `Resend in ${value}s` : 'Resend OTP'}\n * </button>\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Session timeout warning\n * function SessionWarning() {\n * const { value, start, isCounting } = useCountdownSeconds(30);\n *\n * useEffect(() => {\n * if (showWarning) start();\n * }, [showWarning]);\n *\n * useEffect(() => {\n * if (value === 0) logout();\n * }, [value]);\n *\n * return isCounting && (\n * <Alert severity=\"warning\">\n * Session expires in {value} seconds\n * </Alert>\n * );\n * }\n * ```\n */\nexport function useCountdownSeconds(initialSeconds: number): UseCountdownSecondsReturn {\n const [value, setValue] = useState(initialSeconds);\n const [isCounting, setIsCounting] = useState(false);\n\n const start = useCallback(() => {\n setIsCounting(true);\n }, []);\n\n const reset = useCallback(() => {\n setIsCounting(false);\n setValue(initialSeconds);\n }, [initialSeconds]);\n\n useEffect(() => {\n if (!isCounting) return undefined;\n\n // The updater only computes. Stopping used to happen inside it —\n // `setIsCounting(false)` from within a `setValue` updater — and an\n // updater must be pure: React is entitled to run it more than once, and\n // under `StrictMode` it does so deliberately. Nothing visible went wrong\n // here because stopping twice is stopping once, but the sibling hook\n // `useCountdown` had the same shape around an `onComplete` callback and\n // fired it four times.\n const intervalId = setInterval(() => {\n setValue((prev) => Math.max(0, prev - 1));\n }, 1000);\n\n return () => {\n clearInterval(intervalId);\n };\n }, [isCounting]);\n\n // Reaching zero is what stops the countdown, and that is a decision about\n // the state after it settles rather than part of computing it.\n useEffect(() => {\n if (value === 0) setIsCounting(false);\n }, [value]);\n\n return useMemo(\n () => ({\n value,\n setValue,\n isCounting,\n start,\n reset,\n }),\n [value, isCounting, start, reset]\n );\n}\n","'use client';\n\n/**\n * useCountdownDate Hook\n *\n * Creates a countdown timer to a target date, returning formatted\n * days, hours, minutes, and seconds.\n *\n * Ported from minimal-shared for Prism design system.\n *\n * @module hooks/use-countdown-date\n */\n\nimport { useState, useEffect, useCallback } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Return type for useCountdownDate hook.\n */\nexport type UseCountdownDateReturn = {\n /** Formatted days (with leading zero) */\n days: string;\n /** Formatted hours (with leading zero) */\n hours: string;\n /** Formatted minutes (with leading zero) */\n minutes: string;\n /** Formatted seconds (with leading zero) */\n seconds: string;\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Formats a time value to ensure it is always two digits.\n */\nfunction formatTime(value: number): string {\n return String(value).length === 1 ? `0${value}` : `${value}`;\n}\n\n/**\n * Calculates the time difference between a future date and the current date.\n */\nfunction calculateTimeDifference(\n futureDate: Date,\n currentDate: Date\n): {\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n} {\n const distance = futureDate.getTime() - currentDate.getTime();\n\n if (distance < 0) {\n return { days: 0, hours: 0, minutes: 0, seconds: 0 };\n }\n\n return {\n days: Math.floor(distance / (1000 * 60 * 60 * 24)),\n hours: Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)),\n minutes: Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)),\n seconds: Math.floor((distance % (1000 * 60)) / 1000),\n };\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Custom hook to create a countdown timer to a target date.\n *\n * @param targetDate - The target date to count down to\n * @param placeholder - The placeholder value to display before the countdown starts (default: '- -')\n *\n * @returns An object containing the current countdown values in days, hours, minutes, and seconds\n *\n * @example\n * ```tsx\n * function SaleCountdown() {\n * const { days, hours, minutes, seconds } = useCountdownDate(\n * new Date('2024-12-31T23:59:59')\n * );\n *\n * return (\n * <div>\n * <span>{days}d</span>\n * <span>{hours}h</span>\n * <span>{minutes}m</span>\n * <span>{seconds}s</span>\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With custom placeholder\n * const countdown = useCountdownDate(launchDate, '--');\n * ```\n */\nexport function useCountdownDate(targetDate: Date, placeholder = '- -'): UseCountdownDateReturn {\n const [value, setValue] = useState<UseCountdownDateReturn>({\n days: placeholder,\n hours: placeholder,\n minutes: placeholder,\n seconds: placeholder,\n });\n\n /**\n * The instant, not the object holding it.\n *\n * `targetDate` used to be the dependency directly, and a `Date` is compared\n * by identity. The documented call — `useCountdownDate(new Date('…'))` —\n * builds a fresh one on every render, so the callback changed, the effect\n * re-armed, `handleUpdate` ran, `setValue` produced a new object, and that\n * re-rendered the component: an unbounded loop measured at **5003 renders\n * in 200 ms** before it was capped. The countdown displayed correctly\n * throughout, which is why it could have shipped as \"sluggish page\".\n *\n * A number is compared by value, so the same instant is the same\n * dependency however many `Date` wrappers a caller creates.\n */\n const targetMs = targetDate.getTime();\n\n const handleUpdate = useCallback(() => {\n const now = new Date();\n const { days, hours, minutes, seconds } = calculateTimeDifference(new Date(targetMs), now);\n\n const next = {\n days: formatTime(days),\n hours: formatTime(hours),\n minutes: formatTime(minutes),\n seconds: formatTime(seconds),\n };\n\n // Keep the previous object when nothing changed, so React can bail out.\n // A fresh object every second re-renders the consumer whether or not the\n // display moved — including after the target has passed, when the answer\n // is `00:00:00:00` for as long as the component stays mounted.\n setValue((prev) =>\n prev.days === next.days &&\n prev.hours === next.hours &&\n prev.minutes === next.minutes &&\n prev.seconds === next.seconds\n ? prev\n : next\n );\n }, [targetMs]);\n\n useEffect(() => {\n // Initial update\n handleUpdate();\n\n // Set up interval for updates\n const interval = setInterval(handleUpdate, 1000);\n\n return () => clearInterval(interval);\n }, [handleUpdate]);\n\n return value;\n}\n","'use client';\n\n/**\n * useScrollOffsetTop Hook\n *\n * Manages offset top state based on scroll position.\n * Can track against window or a specific element's offset.\n *\n * This hook is SSR-safe - scroll tracking only runs on the client.\n *\n * Ported from minimal-shared for Prism design system.\n *\n * @module hooks/use-scroll-offset-top\n */\n\nimport type { RefObject } from 'react';\nimport { useRef, useState, useEffect, useCallback, useMemo } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Return type for useScrollOffsetTop hook.\n */\nexport type UseScrollOffsetTopReturn<T extends HTMLElement = HTMLElement> = {\n /** Whether the scroll position is past the offset threshold */\n offsetTop: boolean;\n /** Ref to attach to element for tracking its offset (optional) */\n elementRef: RefObject<T | null>;\n};\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Custom hook to manage the offset top state based on scroll position.\n *\n * Can be used in two ways:\n * 1. Track against a fixed pixel value (window scroll)\n * 2. Track against an element's offset (using returned ref)\n *\n * @param defaultValue - The offset value at which the state changes (default: 0)\n *\n * @returns An object containing offsetTop boolean and elementRef\n *\n * @example\n * ```tsx\n * // Track window scroll against fixed value\n * function StickyHeader() {\n * const { offsetTop } = useScrollOffsetTop(80);\n *\n * return (\n * <AppBar position={offsetTop ? 'fixed' : 'static'}>\n * <Toolbar>Header</Toolbar>\n * </AppBar>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Track scroll against element offset\n * function HeaderWithBanner() {\n * const { offsetTop, elementRef } = useScrollOffsetTop<HTMLDivElement>();\n *\n * return (\n * <>\n * <div ref={elementRef}>Banner Content</div>\n * <AppBar\n * position={offsetTop ? 'fixed' : 'static'}\n * sx={{ top: offsetTop ? 0 : 'auto' }}\n * >\n * <Toolbar>Header</Toolbar>\n * </AppBar>\n * </>\n * );\n * }\n * ```\n */\nexport function useScrollOffsetTop<T extends HTMLElement = HTMLElement>(\n defaultValue: number = 0\n): UseScrollOffsetTopReturn<T> {\n const elementRef = useRef<T | null>(null);\n const [offsetTop, setOffsetTop] = useState<boolean>(false);\n\n const handleScroll = useCallback(() => {\n // SSR guard - only run on client\n if (typeof window === 'undefined') return;\n\n const windowScrollY = window.scrollY;\n\n if (elementRef.current) {\n // Track element offset top\n const elementOffsetTop = elementRef.current.offsetTop;\n setOffsetTop(windowScrollY > elementOffsetTop - defaultValue);\n } else {\n // Track window offset top\n setOffsetTop(windowScrollY > defaultValue);\n }\n }, [defaultValue]);\n\n useEffect(() => {\n // SSR guard\n if (typeof window === 'undefined') return undefined;\n\n // Initial check\n handleScroll();\n\n // Add scroll listener with passive for better performance\n window.addEventListener('scroll', handleScroll, { passive: true });\n\n return () => {\n window.removeEventListener('scroll', handleScroll);\n };\n }, [handleScroll]);\n\n // Memoize return object to prevent unnecessary re-renders\n return useMemo(\n () => ({\n elementRef,\n offsetTop,\n }),\n [offsetTop]\n );\n}\n","'use client';\n\n/**\n * useConfigFromQuery Hook\n *\n * Syncs theme/config settings with URL query parameters.\n * Enables shareable configuration links for demos and previews.\n *\n * Query parameter format: ?preset=luxury&mode=dark&primary=%23FF5630\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useEffect, useCallback, useMemo, useRef, useSyncExternalStore } from 'react';\nimport { useEventCallback } from '@mui/material/utils';\nimport type { ThemePreset, ThemeMode, ThemeDirection, ComponentDensity } from '../types/theme.js';\nimport { PRESET_NAMES } from '../theme/create-theme.js';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Configuration values that can be controlled via URL params.\n */\nexport interface UrlConfigValues {\n /** Theme preset */\n preset?: ThemePreset;\n /** Light/dark/system mode */\n mode?: ThemeMode;\n /** Primary color (hex) */\n primary?: string;\n /** Text direction */\n direction?: ThemeDirection;\n /** Component density */\n density?: ComponentDensity;\n /** Contrast mode */\n contrast?: 'default' | 'high';\n}\n\n/**\n * Options for useConfigFromQuery hook.\n */\nexport interface UseConfigFromQueryOptions {\n /** Query parameter names mapping (default: 'preset', 'mode', 'primary', etc.) */\n paramNames?: {\n preset?: string;\n mode?: string;\n primary?: string;\n direction?: string;\n density?: string;\n contrast?: string;\n };\n /** Callback when config changes from URL */\n onConfigChange?: (config: UrlConfigValues) => void;\n /** Enable two-way sync (updates URL when config changes) */\n syncToUrl?: boolean;\n /** Settings to mirror when syncToUrl is enabled. A shared URL takes precedence on mount. */\n values?: UrlConfigValues;\n}\n\n/**\n * Return type for useConfigFromQuery hook.\n */\nexport interface UseConfigFromQueryReturn {\n /** Parsed config values from URL */\n configFromUrl: UrlConfigValues;\n /** Update URL with new config values */\n updateUrl: (values: Partial<UrlConfigValues>) => void;\n /** Clear all config from URL */\n clearUrl: () => void;\n /** Generate URL with config values */\n generateUrl: (values: Partial<UrlConfigValues>, baseUrl?: string) => string;\n /** Check if URL has any config params */\n hasUrlConfig: boolean;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst DEFAULT_PARAM_NAMES = {\n preset: 'preset',\n mode: 'mode',\n primary: 'primary',\n direction: 'dir',\n density: 'density',\n contrast: 'contrast',\n} as const;\n\nconst configKeys = Object.keys(DEFAULT_PARAM_NAMES) as (keyof UrlConfigValues)[];\nconst configUrlChanged = 'prism:config-url-change';\nconst readSearch = () => window.location.search;\nconst serverSearch = () => '';\n\nfunction subscribeToSearch(onChange: () => void) {\n window.addEventListener('popstate', onChange);\n window.addEventListener(configUrlChanged, onChange);\n return () => {\n window.removeEventListener('popstate', onChange);\n window.removeEventListener(configUrlChanged, onChange);\n };\n}\n\nfunction replaceUrl(url: URL) {\n if (url.href !== window.location.href) {\n window.history.replaceState(window.history.state, '', url);\n window.dispatchEvent(new Event(configUrlChanged));\n }\n}\n\nconst VALID_MODES: ThemeMode[] = ['light', 'dark', 'system'];\nconst VALID_DIRECTIONS: ThemeDirection[] = ['ltr', 'rtl'];\nconst VALID_DENSITIES: ComponentDensity[] = ['compact', 'standard', 'comfortable'];\nconst VALID_CONTRASTS = ['default', 'high'] as const;\n\n// =============================================================================\n// VALIDATORS\n// =============================================================================\n\nfunction isValidPreset(value: string | null): value is ThemePreset {\n return value !== null && PRESET_NAMES.includes(value as ThemePreset);\n}\n\nfunction isValidMode(value: string | null): value is ThemeMode {\n return value !== null && VALID_MODES.includes(value as ThemeMode);\n}\n\nfunction isValidDirection(value: string | null): value is ThemeDirection {\n return value !== null && VALID_DIRECTIONS.includes(value as ThemeDirection);\n}\n\nfunction isValidDensity(value: string | null): value is ComponentDensity {\n return value !== null && VALID_DENSITIES.includes(value as ComponentDensity);\n}\n\nfunction isValidContrast(value: string | null): value is 'default' | 'high' {\n return value !== null && (VALID_CONTRASTS as readonly string[]).includes(value);\n}\n\nfunction isValidHexColor(value: string | null): boolean {\n if (!value) return false;\n return /^#[0-9A-Fa-f]{6}$/.test(value);\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Hook to sync theme configuration with URL query parameters.\n *\n * Enables shareable configuration links for demos, previews, and design reviews.\n *\n * @param options - Hook options\n * @returns Object with URL config parsing and manipulation utilities\n *\n * @example\n * ```tsx\n * import { useConfigFromQuery } from '@omnitron-dev/prism/hooks';\n *\n * function ThemeSettings() {\n * const {\n * configFromUrl,\n * updateUrl,\n * generateUrl,\n * hasUrlConfig,\n * } = useConfigFromQuery({\n * onConfigChange: (config) => {\n * // Apply config to your theme context\n * if (config.preset) setPreset(config.preset);\n * if (config.mode) setMode(config.mode);\n * if (config.primary) setPrimaryColor(config.primary);\n * },\n * });\n *\n * // Generate shareable link\n * const shareUrl = generateUrl({\n * preset: currentPreset,\n * mode: currentMode,\n * primary: currentPrimary,\n * });\n *\n * return (\n * <div>\n * {hasUrlConfig && <Alert>Using config from URL</Alert>}\n * <Button onClick={() => navigator.clipboard.writeText(shareUrl)}>\n * Copy Share Link\n * </Button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useConfigFromQuery(options: UseConfigFromQueryOptions = {}): UseConfigFromQueryReturn {\n const { paramNames, onConfigChange, syncToUrl = false, values } = options;\n const { preset = 'preset', mode = 'mode', primary = 'primary', direction = 'dir', density = 'density', contrast = 'contrast' } = paramNames ?? DEFAULT_PARAM_NAMES;\n const params = useMemo(() => ({ preset, mode, primary, direction, density, contrast }),\n [preset, mode, primary, direction, density, contrast]);\n const search = useSyncExternalStore(subscribeToSearch, readSearch, serverSearch);\n const configFromUrl = useMemo<UrlConfigValues>(() => {\n const searchParams = new URLSearchParams(search);\n const config: UrlConfigValues = {};\n\n const presetValue = searchParams.get(params.preset);\n if (isValidPreset(presetValue)) {\n config.preset = presetValue;\n }\n\n const modeValue = searchParams.get(params.mode);\n if (isValidMode(modeValue)) {\n config.mode = modeValue;\n }\n\n const primaryValue = searchParams.get(params.primary);\n if (isValidHexColor(primaryValue)) {\n config.primary = primaryValue as string;\n }\n\n const directionValue = searchParams.get(params.direction);\n if (isValidDirection(directionValue)) {\n config.direction = directionValue;\n }\n\n const densityValue = searchParams.get(params.density);\n if (isValidDensity(densityValue)) {\n config.density = densityValue;\n }\n\n const contrastValue = searchParams.get(params.contrast);\n if (isValidContrast(contrastValue)) {\n config.contrast = contrastValue;\n }\n\n return config;\n }, [params, search]);\n\n const receivedConfig = useRef(false);\n const notifyConfig = useEventCallback((next: UrlConfigValues) => onConfigChange?.(next));\n useEffect(() => {\n const hasValues = Object.keys(configFromUrl).length > 0;\n if (hasValues || receivedConfig.current) notifyConfig(configFromUrl);\n receivedConfig.current = hasValues;\n }, [configFromUrl, notifyConfig]);\n\n const applyValues = useCallback((url: URL, next: Partial<UrlConfigValues>) => {\n for (const key of configKeys) {\n const value = next[key];\n if (value !== undefined) {\n if (value) url.searchParams.set(params[key], value);\n else url.searchParams.delete(params[key]);\n }\n }\n return url;\n }, [params]);\n\n const updateUrl = useCallback((next: Partial<UrlConfigValues>) => {\n if (typeof window !== 'undefined') replaceUrl(applyValues(new URL(window.location.href), next));\n }, [applyValues]);\n\n const clearUrl = useCallback(() => {\n if (typeof window === 'undefined') return;\n const url = new URL(window.location.href);\n for (const key of configKeys) url.searchParams.delete(params[key]);\n replaceUrl(url);\n }, [params]);\n\n // URL navigation is an independent input. Mirror only changes to the supplied\n // settings, so Back and a shared URL cannot be overwritten by an old render.\n const previousValues = useRef<string | undefined>(undefined);\n useEffect(() => {\n if (!syncToUrl || !values) { previousValues.current = undefined; return; }\n const signature = JSON.stringify(configKeys.map(key => values[key]));\n const previous = previousValues.current;\n previousValues.current = signature;\n if (previous === signature) return;\n if (previous !== undefined || !configKeys.some(key => new URLSearchParams(window.location.search).has(params[key]))) {\n updateUrl(values);\n }\n }, [syncToUrl, values, params, updateUrl]);\n\n const generateUrl = useCallback((next: Partial<UrlConfigValues>, baseUrl?: string) => {\n const origin = typeof window === 'undefined' ? 'http://localhost' : window.location.origin;\n const base = baseUrl ?? (typeof window === 'undefined' ? '' : origin + window.location.pathname);\n const url = applyValues(new URL(base || '/', origin), next);\n if (/^[a-z][a-z\\d+.-]*:/i.test(base)) return url.href;\n if (base.startsWith('//')) return `//${url.host}${url.pathname}${url.search}${url.hash}`;\n return (base ? base.split(/[?#]/, 1)[0] : '') + url.search + url.hash;\n }, [applyValues]);\n\n // Check if URL has any config params\n const hasUrlConfig = Object.keys(configFromUrl).length > 0;\n\n return {\n configFromUrl,\n updateUrl,\n clearUrl,\n generateUrl,\n hasUrlConfig,\n };\n}\n","'use client';\n\n/**\n * useImageDimensions Hook\n *\n * Detects the natural dimensions of an image from a URL.\n *\n * @module hooks/use-image-dimensions\n */\n\nimport { useCallback, useEffect, useState } from 'react';\n\n/**\n * Image dimensions result.\n */\nexport interface ImageDimensions {\n /** Natural width of the image in pixels */\n width: number;\n /** Natural height of the image in pixels */\n height: number;\n /** Aspect ratio (width / height) */\n aspectRatio: number;\n}\n\n/**\n * Return type for useImageDimensions hook.\n */\nexport interface UseImageDimensionsReturn {\n /** Image dimensions (null if not loaded or error) */\n dimensions: ImageDimensions | null;\n /** Loading state */\n loading: boolean;\n /** Error if image failed to load */\n error: Error | null;\n /** Manually retry loading the image */\n retry: () => void;\n}\n\n/**\n * Options for useImageDimensions hook.\n */\nexport interface UseImageDimensionsOptions {\n /** Cross-origin setting for image loading */\n crossOrigin?: 'anonymous' | 'use-credentials';\n /** Timeout in milliseconds (default: 10000) */\n timeout?: number;\n /** Whether to start loading immediately (default: true) */\n immediate?: boolean;\n}\n\n/**\n * useImageDimensions - Detects image dimensions from a URL.\n *\n * Loads an image in memory to get its natural width and height.\n *\n * @example\n * ```tsx\n * function ImagePreview({ src }: { src: string }) {\n * const { dimensions, loading, error } = useImageDimensions(src);\n *\n * if (loading) return <CircularProgress />;\n * if (error) return <Alert severity=\"error\">Failed to load image</Alert>;\n * if (!dimensions) return null;\n *\n * return (\n * <Box>\n * <Typography>\n * {dimensions.width} x {dimensions.height}\n * </Typography>\n * <Typography>\n * Aspect ratio: {dimensions.aspectRatio.toFixed(2)}\n * </Typography>\n * <img\n * src={src}\n * alt=\"preview\"\n * style={{ maxWidth: '100%', aspectRatio: dimensions.aspectRatio }}\n * />\n * </Box>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With manual control\n * function LazyImage({ src }: { src: string }) {\n * const { dimensions, loading, retry } = useImageDimensions(src, {\n * immediate: false,\n * });\n *\n * return (\n * <Box>\n * {!dimensions && !loading && (\n * <Button onClick={retry}>Load dimensions</Button>\n * )}\n * {loading && <CircularProgress />}\n * {dimensions && (\n * <Typography>{dimensions.width} x {dimensions.height}</Typography>\n * )}\n * </Box>\n * );\n * }\n * ```\n *\n * @param src - Image URL to load\n * @param options - Hook options\n * @returns Dimensions, loading state, error, and retry function\n */\nexport function useImageDimensions(\n src: string | null | undefined,\n options: UseImageDimensionsOptions = {}\n): UseImageDimensionsReturn {\n const { crossOrigin, timeout = 10000, immediate = true } = options;\n\n const [dimensions, setDimensions] = useState<ImageDimensions | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const loadImage = useCallback(() => {\n if (!src) {\n setDimensions(null);\n setLoading(false);\n setError(null);\n return undefined;\n }\n\n setLoading(true);\n setError(null);\n\n const img = new Image();\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n let cancelled = false;\n\n const cleanup = () => {\n cancelled = true;\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n img.onload = null;\n img.onerror = null;\n };\n\n img.onload = () => {\n if (cancelled) return;\n cleanup();\n\n const { naturalWidth: width, naturalHeight: height } = img;\n setDimensions({\n width,\n height,\n aspectRatio: height > 0 ? width / height : 1,\n });\n setLoading(false);\n setError(null);\n };\n\n img.onerror = () => {\n if (cancelled) return;\n cleanup();\n\n setDimensions(null);\n setLoading(false);\n setError(new Error(`Failed to load image: ${src}`));\n };\n\n // Set timeout\n timeoutId = setTimeout(() => {\n if (cancelled) return;\n cleanup();\n\n setDimensions(null);\n setLoading(false);\n setError(new Error(`Image load timeout: ${src}`));\n }, timeout);\n\n // Set cross-origin if specified\n if (crossOrigin) {\n img.crossOrigin = crossOrigin;\n }\n\n // Start loading\n img.src = src;\n\n // Return cleanup function for effect\n return cleanup;\n }, [src, crossOrigin, timeout]);\n\n // Auto-load when src changes (if immediate)\n useEffect(() => {\n if (!immediate) return undefined;\n return loadImage();\n }, [loadImage, immediate]);\n\n const retry = useCallback(() => {\n loadImage();\n }, [loadImage]);\n\n return {\n dimensions,\n loading,\n error,\n retry,\n };\n}\n\n/**\n * Get dimensions of multiple images.\n *\n * @example\n * ```tsx\n * // MUI v9 unified the Grid component — the `<Grid item>` shorthand\n * // from v1 is gone; size is expressed via `size={{ xs, sm, md, ... }}`.\n * function Gallery({ urls }: { urls: string[] }) {\n * const results = useMultipleImageDimensions(urls);\n *\n * return (\n * <Grid container>\n * {results.map((result, i) => (\n * <Grid key={urls[i]} size={{ xs: 12, sm: 6, md: 4 }}>\n * {result.loading && <Skeleton />}\n * {result.dimensions && (\n * <img\n * src={urls[i]}\n * style={{ aspectRatio: result.dimensions.aspectRatio }}\n * />\n * )}\n * </Grid>\n * ))}\n * </Grid>\n * );\n * }\n * ```\n */\nexport function useMultipleImageDimensions(\n urls: (string | null | undefined)[],\n options: UseImageDimensionsOptions = {}\n): UseImageDimensionsReturn[] {\n const { crossOrigin, timeout = 10000, immediate = true } = options;\n\n const [results, setResults] = useState<\n Map<string, { dimensions: ImageDimensions | null; loading: boolean; error: Error | null }>\n >(new Map());\n\n const sourcesKey = JSON.stringify([...new Set(urls.filter((url): url is string => Boolean(url)))]);\n useEffect(() => {\n if (!immediate) return undefined;\n\n const cleanups: (() => void)[] = [];\n\n const sources: string[] = JSON.parse(sourcesKey);\n sources.forEach((url) => {\n\n setResults((prev) => {\n const next = new Map(prev);\n next.set(url, { dimensions: null, loading: true, error: null });\n return next;\n });\n\n const img = new Image();\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n let cancelled = false;\n\n const cleanup = () => {\n cancelled = true;\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n img.onload = null;\n img.onerror = null;\n };\n\n cleanups.push(cleanup);\n\n img.onload = () => {\n if (cancelled) return;\n cleanup();\n\n const { naturalWidth: width, naturalHeight: height } = img;\n setResults((prev) => {\n const next = new Map(prev);\n next.set(url, {\n dimensions: { width, height, aspectRatio: height > 0 ? width / height : 1 },\n loading: false,\n error: null,\n });\n return next;\n });\n };\n\n img.onerror = () => {\n if (cancelled) return;\n cleanup();\n\n setResults((prev) => {\n const next = new Map(prev);\n next.set(url, {\n dimensions: null,\n loading: false,\n error: new Error(`Failed to load: ${url}`),\n });\n return next;\n });\n };\n\n timeoutId = setTimeout(() => {\n if (cancelled) return;\n cleanup();\n\n setResults((prev) => {\n const next = new Map(prev);\n next.set(url, {\n dimensions: null,\n loading: false,\n error: new Error(`Timeout: ${url}`),\n });\n return next;\n });\n }, timeout);\n\n if (crossOrigin) {\n img.crossOrigin = crossOrigin;\n }\n\n img.src = url;\n });\n\n return () => {\n cleanups.forEach((cleanup) => cleanup());\n };\n }, [sourcesKey, crossOrigin, timeout, immediate]);\n\n return urls.map((url) => {\n if (!url) {\n return {\n dimensions: null,\n loading: false,\n error: null,\n retry: () => {},\n };\n }\n\n const result = results.get(url);\n return {\n dimensions: result?.dimensions ?? null,\n loading: result?.loading ?? false,\n error: result?.error ?? null,\n retry: () => {\n // Trigger reload by updating state\n setResults((prev) => {\n const next = new Map(prev);\n next.delete(url);\n return next;\n });\n },\n };\n });\n}\n","'use client';\n\n/**\n * usePasswordVisibility Hook\n *\n * Manages password field visibility toggle state.\n * Commonly used in login, register, and password reset forms.\n *\n * @module hooks/use-password-visibility\n */\n\nimport { useCallback, useState, useMemo } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Return type for usePasswordVisibility hook.\n */\nexport interface UsePasswordVisibilityReturn {\n /** Whether password is visible (text) or hidden (password) */\n visible: boolean;\n /** Toggle visibility */\n toggle: () => void;\n /** Show password */\n show: () => void;\n /** Hide password */\n hide: () => void;\n /** Input type based on visibility ('text' | 'password') */\n type: 'text' | 'password';\n}\n\n/**\n * Options for usePasswordVisibility hook.\n */\nexport interface UsePasswordVisibilityOptions {\n /** Initial visibility state (default: false) */\n initialVisible?: boolean;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * usePasswordVisibility - Manage password field visibility toggle.\n *\n * Returns state and handlers for password visibility toggle,\n * commonly used with InputAdornment in MUI TextField.\n *\n * @example\n * ```tsx\n * function LoginForm() {\n * const password = usePasswordVisibility();\n *\n * return (\n * <TextField\n * type={password.type}\n * slotProps={{\n * input: {\n * endAdornment: (\n * <InputAdornment position=\"end\">\n * <IconButton onClick={password.toggle}>\n * {password.visible ? <VisibilityOff /> : <Visibility />}\n * </IconButton>\n * </InputAdornment>\n * ),\n * },\n * }}\n * />\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With confirm password field. MUI v9 routes slot props through\n * // the `slotProps` API rather than the legacy `InputProps` /\n * // `InputLabelProps` / `FormHelperTextProps` family.\n * function RegisterForm() {\n * const password = usePasswordVisibility();\n * const confirmPassword = usePasswordVisibility();\n *\n * return (\n * <Box>\n * <TextField\n * label=\"Password\"\n * type={password.type}\n * slotProps={{ input: { endAdornment: <PasswordToggle {...password} /> } }}\n * />\n * <TextField\n * label=\"Confirm Password\"\n * type={confirmPassword.type}\n * slotProps={{ input: { endAdornment: <PasswordToggle {...confirmPassword} /> } }}\n * />\n * </Box>\n * );\n * }\n * ```\n *\n * @param options - Hook options\n * @returns Visibility state, toggle handlers, and input type\n */\nexport function usePasswordVisibility(options: UsePasswordVisibilityOptions = {}): UsePasswordVisibilityReturn {\n const { initialVisible = false } = options;\n\n const [visible, setVisible] = useState(initialVisible);\n\n const toggle = useCallback(() => {\n setVisible((prev) => !prev);\n }, []);\n\n const show = useCallback(() => {\n setVisible(true);\n }, []);\n\n const hide = useCallback(() => {\n setVisible(false);\n }, []);\n\n // Memoize return object to prevent unnecessary re-renders\n return useMemo(\n () => ({\n visible,\n toggle,\n show,\n hide,\n type: visible ? 'text' : 'password',\n }),\n [visible, toggle, show, hide]\n );\n}\n","'use client';\n\n/**\n * useThrottle Hook\n *\n * Throttles a value or callback, limiting how often it can update.\n *\n * @module hooks/use-throttle\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface UseThrottleOptions {\n /** Whether to invoke on the leading edge (default: true) */\n leading?: boolean;\n /** Whether to invoke on the trailing edge (default: true) */\n trailing?: boolean;\n}\n\n// =============================================================================\n// USE THROTTLE VALUE\n// =============================================================================\n\n/**\n * useThrottle - Throttle a value.\n *\n * Returns a throttled version of the value that only updates\n * at most once per specified interval.\n *\n * @example\n * ```tsx\n * function SearchComponent() {\n * const [search, setSearch] = useState('');\n * const throttledSearch = useThrottle(search, 300);\n *\n * // API call only triggers when throttledSearch changes\n * useEffect(() => {\n * if (throttledSearch) {\n * searchApi(throttledSearch);\n * }\n * }, [throttledSearch]);\n *\n * return <input value={search} onChange={(e) => setSearch(e.target.value)} />;\n * }\n * ```\n *\n * @param value - Value to throttle\n * @param delay - Throttle delay in milliseconds\n * @param options - Throttle options\n * @returns Throttled value\n */\nexport function useThrottle<T>(value: T, delay: number, options: UseThrottleOptions = {}): T {\n const { leading = true, trailing = true } = options;\n\n const [throttledValue, setThrottledValue] = useState(value);\n const lastExecuted = useRef(0);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastValue = useRef(value);\n\n useEffect(() => {\n lastValue.current = value;\n const now = Date.now();\n const elapsed = now - lastExecuted.current;\n\n const execute = () => {\n lastExecuted.current = Date.now();\n setThrottledValue(lastValue.current);\n };\n\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n if (elapsed >= delay) {\n // Enough time has passed\n if (leading) {\n execute();\n } else if (trailing) {\n timeoutRef.current = setTimeout(execute, delay);\n }\n } else if (trailing) {\n // Schedule trailing call\n timeoutRef.current = setTimeout(execute, delay - elapsed);\n }\n\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, [value, delay, leading, trailing]);\n\n return throttledValue;\n}\n\n// =============================================================================\n// USE THROTTLE CALLBACK\n// =============================================================================\n\n/**\n * useThrottleCallback - Create a throttled callback function.\n *\n * Returns a memoized throttled version of the callback that only\n * invokes at most once per specified interval.\n *\n * @example\n * ```tsx\n * function ScrollTracker() {\n * const handleScroll = useThrottleCallback(\n * (e: Event) => {\n * console.log('Scroll position:', window.scrollY);\n * },\n * 100\n * );\n *\n * useEffect(() => {\n * window.addEventListener('scroll', handleScroll);\n * return () => window.removeEventListener('scroll', handleScroll);\n * }, [handleScroll]);\n *\n * return <div>Scroll me!</div>;\n * }\n * ```\n *\n * @param callback - Callback to throttle\n * @param delay - Throttle delay in milliseconds\n * @param options - Throttle options\n * @returns Throttled callback\n */\nexport function useThrottleCallback<T extends (...args: unknown[]) => unknown>(\n callback: T,\n delay: number,\n options: UseThrottleOptions = {}\n): T {\n const { leading = true, trailing = true } = options;\n\n const lastExecuted = useRef(0);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastArgs = useRef<Parameters<T> | null>(null);\n const callbackRef = useRef(callback);\n\n // Update callback ref on each render\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n\n // Cleanup on unmount\n useEffect(\n () => () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n },\n []\n );\n\n return useCallback(\n ((...args: Parameters<T>) => {\n lastArgs.current = args;\n const now = Date.now();\n const elapsed = now - lastExecuted.current;\n\n const execute = () => {\n lastExecuted.current = Date.now();\n if (lastArgs.current) {\n callbackRef.current(...lastArgs.current);\n }\n };\n\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n if (elapsed >= delay) {\n if (leading) {\n execute();\n } else if (trailing) {\n timeoutRef.current = setTimeout(execute, delay);\n }\n } else if (trailing) {\n timeoutRef.current = setTimeout(execute, delay - elapsed);\n }\n }) as T,\n [delay, leading, trailing]\n );\n}\n","'use client';\n\n/**\n * useOnlineStatus Hook\n *\n * Tracks browser online/offline status with event listeners.\n *\n * @module hooks/use-online-status\n */\n\nimport { useCallback, useEffect, useState, useSyncExternalStore } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface UseOnlineStatusReturn {\n /** Whether the browser is online */\n isOnline: boolean;\n /** Whether the browser is offline */\n isOffline: boolean;\n /** Time when status last changed (timestamp) */\n lastChanged: number | null;\n}\n\n// =============================================================================\n// EXTERNAL STORE (for SSR safety)\n// =============================================================================\n\nfunction subscribe(callback: () => void): () => void {\n window.addEventListener('online', callback);\n window.addEventListener('offline', callback);\n return () => {\n window.removeEventListener('online', callback);\n window.removeEventListener('offline', callback);\n };\n}\n\nfunction getSnapshot(): boolean {\n return navigator.onLine;\n}\n\nfunction getServerSnapshot(): boolean {\n // Assume online during SSR\n return true;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * useOnlineStatus - Track browser online/offline status.\n *\n * Uses navigator.onLine and online/offline events to track network status.\n * SSR-safe with server-side assumption of online status.\n *\n * @example\n * ```tsx\n * function ConnectionIndicator() {\n * const { isOnline, isOffline } = useOnlineStatus();\n *\n * if (isOffline) {\n * return (\n * <Alert severity=\"warning\">\n * You are offline. Changes will sync when you reconnect.\n * </Alert>\n * );\n * }\n *\n * return null;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With timestamp tracking\n * function NetworkStatus() {\n * const { isOnline, lastChanged } = useOnlineStatus();\n *\n * return (\n * <Box>\n * <Typography>\n * Status: {isOnline ? 'Online' : 'Offline'}\n * </Typography>\n * {lastChanged && (\n * <Typography variant=\"caption\">\n * Last changed: {new Date(lastChanged).toLocaleTimeString()}\n * </Typography>\n * )}\n * </Box>\n * );\n * }\n * ```\n *\n * @returns Online status and metadata\n */\nexport function useOnlineStatus(): UseOnlineStatusReturn {\n const isOnline = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const [lastChanged, setLastChanged] = useState<number | null>(null);\n\n const handleStatusChange = useCallback(() => {\n setLastChanged(Date.now());\n }, []);\n\n useEffect(() => {\n window.addEventListener('online', handleStatusChange);\n window.addEventListener('offline', handleStatusChange);\n return () => {\n window.removeEventListener('online', handleStatusChange);\n window.removeEventListener('offline', handleStatusChange);\n };\n }, [handleStatusChange]);\n\n return {\n isOnline,\n isOffline: !isOnline,\n lastChanged,\n };\n}\n","'use client';\n\n/**\n * useIntersectionObserver Hook\n *\n * Observe element visibility using the Intersection Observer API.\n *\n * @module hooks/use-intersection-observer\n */\n\nimport { useCallback, useEffect, useRef, useState, useMemo } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface UseIntersectionObserverOptions {\n /** Root element for intersection (default: viewport) */\n root?: Element | Document | null;\n /** Root margin (default: '0px') */\n rootMargin?: string;\n /** Threshold(s) at which to trigger (default: 0) */\n threshold?: number | number[];\n /** Whether to disconnect after first intersection (default: false) */\n triggerOnce?: boolean;\n /** Whether to start observing immediately (default: true) */\n enabled?: boolean;\n}\n\nexport interface UseIntersectionObserverReturn {\n /** Ref to attach to the target element */\n ref: (element: Element | null) => void;\n /** Current intersection entry */\n entry: IntersectionObserverEntry | null;\n /** Whether the element is intersecting */\n isIntersecting: boolean;\n /** Manually disconnect the observer */\n disconnect: () => void;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * useIntersectionObserver - Observe element visibility.\n *\n * Uses the Intersection Observer API to track when an element\n * enters or exits the viewport (or a custom root element).\n *\n * @example\n * ```tsx\n * // Lazy loading images\n * function LazyImage({ src }: { src: string }) {\n * const { ref, isIntersecting } = useIntersectionObserver({\n * triggerOnce: true,\n * });\n *\n * return (\n * <div ref={ref}>\n * {isIntersecting ? (\n * <img src={src} alt=\"\" />\n * ) : (\n * <Skeleton variant=\"rectangular\" height={200} />\n * )}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Infinite scroll\n * function InfiniteList({ items, onLoadMore }) {\n * const { ref, isIntersecting } = useIntersectionObserver({\n * threshold: 0.5,\n * });\n *\n * useEffect(() => {\n * if (isIntersecting) {\n * onLoadMore();\n * }\n * }, [isIntersecting, onLoadMore]);\n *\n * return (\n * <Box>\n * {items.map((item) => <Item key={item.id} {...item} />)}\n * <div ref={ref} style={{ height: 1 }} />\n * </Box>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Animate on scroll\n * function AnimatedSection({ children }) {\n * const { ref, isIntersecting } = useIntersectionObserver({\n * threshold: 0.1,\n * triggerOnce: true,\n * });\n *\n * return (\n * <Fade in={isIntersecting}>\n * <Box ref={ref}>{children}</Box>\n * </Fade>\n * );\n * }\n * ```\n *\n * @param options - Observer options\n * @returns Ref, entry, intersection state, and disconnect function\n */\nexport function useIntersectionObserver(options: UseIntersectionObserverOptions = {}): UseIntersectionObserverReturn {\n const { root = null, rootMargin = '0px', threshold = 0, triggerOnce = false, enabled = true } = options;\n\n const [entry, setEntry] = useState<IntersectionObserverEntry | null>(null);\n const elementRef = useRef<Element | null>(null);\n const observerRef = useRef<IntersectionObserver | null>(null);\n const frozenRef = useRef(false);\n\n const disconnect = useCallback(() => {\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n }, []);\n\n const ref = useCallback(\n (element: Element | null) => {\n // Disconnect previous observer\n disconnect();\n\n elementRef.current = element;\n\n // Don't observe if disabled, frozen, or no element\n if (!enabled || frozenRef.current || !element) {\n return;\n }\n\n // Check for IntersectionObserver support\n if (typeof IntersectionObserver === 'undefined') {\n // Fallback: assume visible\n setEntry({\n isIntersecting: true,\n intersectionRatio: 1,\n boundingClientRect: element.getBoundingClientRect(),\n intersectionRect: element.getBoundingClientRect(),\n rootBounds: null,\n target: element,\n time: Date.now(),\n } as IntersectionObserverEntry);\n return;\n }\n\n observerRef.current = new IntersectionObserver(\n ([observerEntry]) => {\n setEntry(observerEntry);\n\n if (triggerOnce && observerEntry.isIntersecting) {\n frozenRef.current = true;\n disconnect();\n }\n },\n { root, rootMargin, threshold }\n );\n\n observerRef.current.observe(element);\n },\n [enabled, root, rootMargin, threshold, triggerOnce, disconnect]\n );\n\n // Cleanup on unmount\n useEffect(\n () => () => {\n disconnect();\n },\n [disconnect]\n );\n\n // Memoize return object to prevent unnecessary re-renders.\n //\n // `ref` MUST be a dependency. It is a useCallback over the observer options,\n // so raising `threshold` (or `rootMargin`, `root`, `triggerOnce`, `enabled`)\n // mints a new callback — but if this memo does not see it, the caller keeps\n // holding the callback from the first render. React compares ref identity to\n // decide whether to re-attach, sees no change, and the observer keeps the\n // options it was constructed with. The new options then apply at the next\n // `entry` change, if one ever happens, and never at all once `triggerOnce`\n // has frozen it. Adding it cannot loop: `ref`'s own dependencies are the\n // destructured primitives, so its identity is stable while they are.\n return useMemo(\n () => ({\n ref,\n entry,\n isIntersecting: entry?.isIntersecting ?? false,\n disconnect,\n }),\n [ref, entry, disconnect]\n );\n}\n","'use client';\n\n/**\n * useKeyboardShortcut Hook\n *\n * Handle keyboard shortcuts with modifier key support.\n *\n * @module hooks/use-keyboard-shortcut\n */\n\nimport { useCallback, useEffect, useRef } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface KeyboardShortcut {\n /** Main key (e.g., 'k', 'Enter', 'Escape') */\n key: string;\n /** Require Ctrl/Cmd key */\n ctrl?: boolean;\n /** Require Shift key */\n shift?: boolean;\n /** Require Alt key */\n alt?: boolean;\n /** Require Meta key (Cmd on Mac) */\n meta?: boolean;\n}\n\nexport interface UseKeyboardShortcutOptions {\n /** Whether the shortcut is enabled (default: true) */\n enabled?: boolean;\n /** Prevent default browser behavior (default: true) */\n preventDefault?: boolean;\n /** Stop event propagation (default: false) */\n stopPropagation?: boolean;\n /** Target element (default: document) */\n target?: EventTarget | null;\n /** Event type (default: 'keydown') */\n event?: 'keydown' | 'keyup' | 'keypress';\n /** Ignore when focus is in input/textarea/contenteditable (default: false) */\n ignoreInputs?: boolean;\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\nfunction isInputElement(element: EventTarget | null): boolean {\n if (!element || !(element instanceof HTMLElement)) {\n return false;\n }\n\n const tagName = element.tagName.toLowerCase();\n if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {\n return true;\n }\n\n return element.isContentEditable;\n}\n\nfunction matchesShortcut(event: KeyboardEvent, shortcut: KeyboardShortcut): boolean {\n // Normalize key comparison (case-insensitive for letters)\n const eventKey = event.key.toLowerCase();\n const shortcutKey = shortcut.key.toLowerCase();\n\n if (eventKey !== shortcutKey) {\n return false;\n }\n\n // Check modifier keys\n const ctrlOrMeta = event.ctrlKey || event.metaKey;\n\n if (shortcut.ctrl && !ctrlOrMeta) return false;\n if (shortcut.meta && !event.metaKey) return false;\n if (shortcut.shift && !event.shiftKey) return false;\n if (shortcut.alt && !event.altKey) return false;\n\n // Ensure no extra modifiers unless specified\n if (!shortcut.ctrl && !shortcut.meta && ctrlOrMeta) return false;\n if (!shortcut.shift && event.shiftKey) return false;\n if (!shortcut.alt && event.altKey) return false;\n\n return true;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * useKeyboardShortcut - Handle keyboard shortcuts.\n *\n * Listens for keyboard events matching the specified shortcut\n * and invokes the callback when matched.\n *\n * @example\n * ```tsx\n * // Simple shortcut\n * function SearchDialog() {\n * const [open, setOpen] = useState(false);\n *\n * useKeyboardShortcut({ key: 'k', ctrl: true }, () => {\n * setOpen(true);\n * });\n *\n * return <Dialog open={open} onClose={() => setOpen(false)} />;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Save with Ctrl+S\n * function Editor({ onSave }) {\n * useKeyboardShortcut(\n * { key: 's', ctrl: true },\n * () => onSave(),\n * { preventDefault: true }\n * );\n *\n * return <TextField multiline />;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Escape to close\n * function Modal({ onClose }) {\n * useKeyboardShortcut({ key: 'Escape' }, onClose);\n *\n * return <div>Modal content</div>;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Multiple shortcuts\n * function App() {\n * useKeyboardShortcut({ key: 'k', ctrl: true }, openSearch);\n * useKeyboardShortcut({ key: 'n', ctrl: true }, createNew);\n * useKeyboardShortcut({ key: '/', ctrl: true }, toggleHelp);\n *\n * return <div>...</div>;\n * }\n * ```\n *\n * @param shortcut - Keyboard shortcut definition\n * @param callback - Function to call when shortcut is triggered\n * @param options - Hook options\n */\nexport function useKeyboardShortcut(\n shortcut: KeyboardShortcut,\n callback: (event: KeyboardEvent) => void,\n options: UseKeyboardShortcutOptions = {}\n): void {\n const {\n enabled = true,\n preventDefault = true,\n stopPropagation = false,\n target = typeof document !== 'undefined' ? document : null,\n event = 'keydown',\n ignoreInputs = false,\n } = options;\n\n const callbackRef = useRef(callback);\n\n // Update callback ref\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n\n const handleKeyEvent = useCallback(\n (e: Event) => {\n if (!enabled) return;\n\n const keyEvent = e as KeyboardEvent;\n if (keyEvent.defaultPrevented || keyEvent.isComposing) return;\n\n // Ignore if focused on input element\n if (ignoreInputs && isInputElement(keyEvent.target)) {\n return;\n }\n\n if (matchesShortcut(keyEvent, shortcut)) {\n if (preventDefault) {\n keyEvent.preventDefault();\n }\n if (stopPropagation) {\n keyEvent.stopPropagation();\n }\n callbackRef.current(keyEvent);\n }\n },\n [enabled, shortcut, preventDefault, stopPropagation, ignoreInputs]\n );\n\n useEffect(() => {\n if (!target || !enabled) return undefined;\n\n target.addEventListener(event, handleKeyEvent);\n return () => {\n target.removeEventListener(event, handleKeyEvent);\n };\n }, [target, event, handleKeyEvent, enabled]);\n}\n\n// =============================================================================\n// UTILITY HOOKS\n// =============================================================================\n\n/**\n * useEscapeKey - Convenience hook for Escape key handling.\n *\n * @example\n * ```tsx\n * function Modal({ onClose }) {\n * useEscapeKey(onClose);\n * return <div>Modal content</div>;\n * }\n * ```\n */\nexport function useEscapeKey(\n callback: (event: KeyboardEvent) => void,\n options: Omit<UseKeyboardShortcutOptions, 'ignoreInputs'> = {}\n): void {\n useKeyboardShortcut({ key: 'Escape' }, callback, {\n ...options,\n ignoreInputs: false, // Escape should work even in inputs\n });\n}\n\n/**\n * useEnterKey - Convenience hook for Enter key handling.\n *\n * @example\n * ```tsx\n * function SearchField({ onSearch }) {\n * useEnterKey(onSearch, { ignoreInputs: false });\n * return <TextField />;\n * }\n * ```\n */\nexport function useEnterKey(callback: (event: KeyboardEvent) => void, options: UseKeyboardShortcutOptions = {}): void {\n useKeyboardShortcut({ key: 'Enter' }, callback, options);\n}\n","'use client';\n\n/**\n * useFocusTrap Hook\n *\n * Traps focus within a container element for accessibility.\n * Essential for modals, dialogs, and dropdown menus.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useCallback, useEffect, useRef } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Options for useFocusTrap hook.\n */\nexport interface UseFocusTrapOptions {\n /**\n * Whether the focus trap is active.\n * @default true\n */\n enabled?: boolean;\n /**\n * Whether to auto-focus the first focusable element when enabled.\n * @default true\n */\n autoFocus?: boolean;\n /**\n * Whether to restore focus to the previously focused element when disabled.\n * @default true\n */\n restoreFocus?: boolean;\n /**\n * Selector for focusable elements.\n * @default FOCUSABLE_SELECTOR\n */\n focusableSelector?: string;\n}\n\n/**\n * Return type for useFocusTrap hook.\n */\nexport interface UseFocusTrapReturn<T extends HTMLElement = HTMLElement> {\n /**\n * Ref to attach to the container element.\n */\n ref: React.RefCallback<T>;\n /**\n * Focus the first focusable element.\n */\n focusFirst: () => void;\n /**\n * Focus the last focusable element.\n */\n focusLast: () => void;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/**\n * Default selector for focusable elements.\n */\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n].join(',');\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Trap focus within a container element.\n *\n * @param options - Hook options\n * @returns Ref and focus control functions\n *\n * @example\n * ```tsx\n * function Modal({ open, onClose, children }) {\n * const { ref } = useFocusTrap({ enabled: open });\n *\n * if (!open) return null;\n *\n * return (\n * <div ref={ref} role=\"dialog\" aria-modal=\"true\">\n * {children}\n * <button onClick={onClose}>Close</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useFocusTrap<T extends HTMLElement = HTMLElement>(\n options: UseFocusTrapOptions = {}\n): UseFocusTrapReturn<T> {\n const { enabled = true, autoFocus = true, restoreFocus = true, focusableSelector = FOCUSABLE_SELECTOR } = options;\n\n const containerRef = useRef<T | null>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n\n // Get all focusable elements within the container\n const getFocusableElements = useCallback(() => {\n if (!containerRef.current) return [];\n return Array.from(containerRef.current.querySelectorAll<HTMLElement>(focusableSelector)).filter(\n (el) => el.offsetParent !== null\n ); // Filter out hidden elements\n }, [focusableSelector]);\n\n // Focus the first focusable element\n const focusFirst = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n elements[0].focus();\n }\n }, [getFocusableElements]);\n\n // Focus the last focusable element\n const focusLast = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n elements[elements.length - 1].focus();\n }\n }, [getFocusableElements]);\n\n // Handle keydown for tab trapping\n useEffect(() => {\n if (!enabled || !containerRef.current) return undefined;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') return;\n\n const elements = getFocusableElements();\n if (elements.length === 0) return;\n\n const firstElement = elements[0];\n const lastElement = elements[elements.length - 1];\n const activeElement = document.activeElement;\n\n // Shift + Tab on first element -> go to last\n if (event.shiftKey && activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n return;\n }\n\n // Tab on last element -> go to first\n if (!event.shiftKey && activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n };\n\n const container = containerRef.current;\n container.addEventListener('keydown', handleKeyDown);\n\n return () => {\n container.removeEventListener('keydown', handleKeyDown);\n };\n }, [enabled, getFocusableElements]);\n\n // Auto-focus and restore focus\n useEffect(() => {\n if (enabled) {\n // Store the previously focused element\n if (restoreFocus) {\n previousActiveElement.current = document.activeElement as HTMLElement;\n }\n\n // Auto-focus the first element\n if (autoFocus) {\n // Use setTimeout to ensure the container is rendered\n const timeoutId = setTimeout(focusFirst, 0);\n return () => clearTimeout(timeoutId);\n }\n } else if (restoreFocus && previousActiveElement.current) {\n // Restore focus when disabled\n previousActiveElement.current.focus();\n previousActiveElement.current = null;\n }\n\n return undefined;\n }, [enabled, autoFocus, restoreFocus, focusFirst]);\n\n // Callback ref for the container\n const ref = useCallback((node: T | null) => {\n containerRef.current = node;\n }, []);\n\n return { ref, focusFirst, focusLast };\n}\n","'use client';\n\n/**\n * useUpdateEffect Hook\n *\n * Like useEffect, but skips the first render.\n * Useful for running effects only on updates, not on mount.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useEffect, useRef, type DependencyList, type EffectCallback } from 'react';\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Effect hook that only runs on updates, not on initial mount.\n *\n * @param effect - Effect callback function\n * @param deps - Dependency array\n *\n * @example\n * ```tsx\n * function SearchInput({ value, onSearch }) {\n * // Only search when value changes after initial render\n * useUpdateEffect(() => {\n * onSearch(value);\n * }, [value]);\n *\n * return <input value={value} />;\n * }\n * ```\n */\nexport function useUpdateEffect(effect: EffectCallback, deps?: DependencyList): void {\n const isFirstMount = useRef(true);\n\n useEffect(() => {\n if (isFirstMount.current) {\n isFirstMount.current = false;\n return undefined;\n }\n\n return effect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n}\n\n/**\n * Layout effect hook that only runs on updates, not on initial mount.\n * Uses useLayoutEffect for synchronous DOM measurements.\n *\n * @param effect - Effect callback function\n * @param deps - Dependency array\n *\n * @example\n * ```tsx\n * function AnimatedComponent({ size }) {\n * const ref = useRef<HTMLDivElement>(null);\n *\n * // Animate size changes, but not initial render\n * useUpdateLayoutEffect(() => {\n * if (ref.current) {\n * animate(ref.current, { width: size });\n * }\n * }, [size]);\n *\n * return <div ref={ref} />;\n * }\n * ```\n */\nexport function useUpdateLayoutEffect(effect: EffectCallback, deps?: DependencyList): void {\n const isFirstMount = useRef(true);\n\n // Use useEffect for SSR compatibility, but the pattern is the same\n useEffect(() => {\n if (isFirstMount.current) {\n isFirstMount.current = false;\n return undefined;\n }\n\n return effect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n}\n","'use client';\n\n/**\n * useIsomorphicLayoutEffect Hook\n *\n * SSR-safe version of useLayoutEffect.\n * Uses useLayoutEffect on client, useEffect on server.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useEffect, useLayoutEffect } from 'react';\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Isomorphic layout effect that works in both SSR and CSR environments.\n *\n * - On the client: Uses useLayoutEffect for synchronous DOM operations\n * - On the server: Uses useEffect to avoid SSR warnings\n *\n * @example\n * ```tsx\n * function Tooltip({ position }) {\n * const ref = useRef<HTMLDivElement>(null);\n *\n * // Synchronously measure and position on client\n * useIsomorphicLayoutEffect(() => {\n * if (ref.current) {\n * const rect = ref.current.getBoundingClientRect();\n * // Position tooltip based on measurements\n * }\n * }, [position]);\n *\n * return <div ref={ref}>Tooltip</div>;\n * }\n * ```\n */\nexport const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n","'use client';\n\n/**\n * useSessionStorage Hook\n *\n * A hook for persisting state in sessionStorage with automatic serialization.\n *\n * @module hooks/use-session-storage\n */\n\nimport { useState, useCallback, useEffect } from 'react';\nimport { useIsClient } from '../core/hooks/use-is-client.js';\n\n/**\n * Return type for useSessionStorage hook.\n */\nexport interface UseSessionStorageReturn<T> {\n /** Current state value */\n state: T;\n /** Update state and sessionStorage */\n setState: (value: T | ((prev: T) => T)) => void;\n /** Remove item from sessionStorage and reset to default */\n remove: () => void;\n /** Check if sessionStorage has the key */\n hasValue: boolean;\n}\n\n/**\n * Options for useSessionStorage hook.\n */\nexport interface UseSessionStorageOptions<T> {\n /** Serializer function (default: JSON.stringify) */\n serializer?: (value: T) => string;\n /** Deserializer function (default: JSON.parse) */\n deserializer?: (value: string) => T;\n}\n\n/**\n * Get sessionStorage value with fallback.\n */\nfunction getStorageValue<T>(key: string, defaultValue: T, deserializer: (value: string) => T): T {\n if (typeof window === 'undefined') {\n return defaultValue;\n }\n\n try {\n const item = window.sessionStorage.getItem(key);\n if (item === null) {\n return defaultValue;\n }\n return deserializer(item);\n } catch (error) {\n console.warn(`Error reading sessionStorage key \"${key}\":`, error);\n return defaultValue;\n }\n}\n\n/**\n * Hook for persisting state in sessionStorage.\n *\n * @param key - Storage key\n * @param defaultValue - Default value when key is not found\n * @param options - Configuration options\n * @returns State value and control methods\n *\n * @example\n * ```tsx\n * function SearchFilters() {\n * const { state: filters, setState: setFilters, remove } = useSessionStorage(\n * 'search-filters',\n * { query: '', category: 'all' }\n * );\n *\n * return (\n * <>\n * <input\n * value={filters.query}\n * onChange={(e) => setFilters({ ...filters, query: e.target.value })}\n * />\n * <button onClick={remove}>Clear Filters</button>\n * </>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With functional updates\n * function Counter() {\n * const { state: count, setState: setCount } = useSessionStorage('counter', 0);\n *\n * return (\n * <button onClick={() => setCount((prev) => prev + 1)}>\n * Count: {count}\n * </button>\n * );\n * }\n * ```\n */\nexport function useSessionStorage<T>(\n key: string,\n defaultValue: T,\n options: UseSessionStorageOptions<T> = {}\n): UseSessionStorageReturn<T> {\n const { serializer = JSON.stringify, deserializer = JSON.parse } = options;\n\n const isClient = useIsClient();\n\n // Initialize state from sessionStorage\n const [state, setStateInternal] = useState<T>(() => {\n if (typeof window === 'undefined') {\n return defaultValue;\n }\n return getStorageValue(key, defaultValue, deserializer);\n });\n\n // Track if sessionStorage has the key\n const [hasValue, setHasValue] = useState<boolean>(() => {\n if (typeof window === 'undefined') {\n return false;\n }\n return window.sessionStorage.getItem(key) !== null;\n });\n\n // Update sessionStorage when state changes\n const setState = useCallback(\n (value: T | ((prev: T) => T)) => {\n try {\n const newValue = value instanceof Function ? value(state) : value;\n window.sessionStorage.setItem(key, serializer(newValue));\n setStateInternal(newValue);\n setHasValue(true);\n\n // Dispatch storage event for other tabs/windows\n window.dispatchEvent(\n new StorageEvent('storage', {\n key,\n newValue: serializer(newValue),\n storageArea: window.sessionStorage,\n })\n );\n } catch (error) {\n console.warn(`Error setting sessionStorage key \"${key}\":`, error);\n }\n },\n [key, serializer, state]\n );\n\n // Remove from sessionStorage\n const remove = useCallback(() => {\n try {\n window.sessionStorage.removeItem(key);\n setStateInternal(defaultValue);\n setHasValue(false);\n\n // Dispatch storage event for other tabs/windows\n window.dispatchEvent(\n new StorageEvent('storage', {\n key,\n newValue: null,\n storageArea: window.sessionStorage,\n })\n );\n } catch (error) {\n console.warn(`Error removing sessionStorage key \"${key}\":`, error);\n }\n }, [key, defaultValue]);\n\n // Sync state from sessionStorage on mount and key change\n useEffect(() => {\n if (!isClient) return undefined;\n\n const value = getStorageValue(key, defaultValue, deserializer);\n setStateInternal(value);\n setHasValue(window.sessionStorage.getItem(key) !== null);\n return undefined;\n }, [key, isClient, defaultValue, deserializer]);\n\n // Listen for storage events from other tabs/windows\n useEffect(() => {\n if (!isClient) return undefined;\n\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key === key && event.storageArea === window.sessionStorage) {\n if (event.newValue === null) {\n setStateInternal(defaultValue);\n setHasValue(false);\n } else {\n try {\n setStateInternal(deserializer(event.newValue));\n setHasValue(true);\n } catch {\n // Ignore parse errors\n }\n }\n }\n };\n\n window.addEventListener('storage', handleStorageChange);\n return () => {\n window.removeEventListener('storage', handleStorageChange);\n };\n }, [key, isClient, defaultValue, deserializer]);\n\n return {\n state,\n setState,\n remove,\n hasValue,\n };\n}\n","'use client';\n\n/**\n * useArray Hook\n *\n * A hook for managing array state with convenient CRUD operations.\n *\n * @module hooks/use-array\n */\n\nimport { useState, useCallback, useMemo } from 'react';\n\n/**\n * Return type for useArray hook.\n */\nexport interface UseArrayReturn<T> {\n /** Current array value */\n value: T[];\n /** Set array to new value */\n setValue: React.Dispatch<React.SetStateAction<T[]>>;\n /** Add item to end of array */\n push: (item: T) => void;\n /** Add items to end of array */\n pushMany: (items: T[]) => void;\n /** Remove first occurrence of item (by reference or predicate) */\n remove: (itemOrPredicate: T | ((item: T) => boolean)) => void;\n /** Remove item at index */\n removeAt: (index: number) => void;\n /** Remove items matching predicate */\n removeWhere: (predicate: (item: T) => boolean) => void;\n /** Update item at index */\n updateAt: (index: number, item: T) => void;\n /** Update item at index with partial data (merge) */\n updateAtPartial: (index: number, partial: Partial<T>) => void;\n /** Update items matching predicate */\n updateWhere: (predicate: (item: T) => boolean, update: T | ((item: T) => T)) => void;\n /** Insert item at index */\n insertAt: (index: number, item: T) => void;\n /** Move item from one index to another */\n move: (fromIndex: number, toIndex: number) => void;\n /** Swap items at two indices */\n swap: (indexA: number, indexB: number) => void;\n /** Clear all items */\n clear: () => void;\n /** Reset to initial value */\n reset: () => void;\n /** Reverse array in place */\n reverse: () => void;\n /** Sort array */\n sort: (compareFn?: (a: T, b: T) => number) => void;\n /** Filter array (returns new array, does not modify state) */\n filter: (predicate: (item: T) => boolean) => T[];\n /** Find item (returns item, does not modify state) */\n find: (predicate: (item: T) => boolean) => T | undefined;\n /** Find item index (returns index, does not modify state) */\n findIndex: (predicate: (item: T) => boolean) => number;\n /** Check if array includes item */\n includes: (item: T) => boolean;\n /** Get array length */\n length: number;\n /** Check if array is empty */\n isEmpty: boolean;\n /** Get first item */\n first: T | undefined;\n /** Get last item */\n last: T | undefined;\n}\n\n/**\n * Hook for managing array state with CRUD operations.\n *\n * @param initialValue - Initial array value\n * @returns Array value and manipulation methods\n *\n * @example\n * ```tsx\n * function TodoList() {\n * const todos = useArray<{ id: number; text: string; done: boolean }>([]);\n *\n * const addTodo = (text: string) => {\n * todos.push({ id: Date.now(), text, done: false });\n * };\n *\n * const toggleTodo = (id: number) => {\n * todos.updateWhere(\n * (todo) => todo.id === id,\n * (todo) => ({ ...todo, done: !todo.done })\n * );\n * };\n *\n * return (\n * <ul>\n * {todos.value.map((todo) => (\n * <li key={todo.id} onClick={() => toggleTodo(todo.id)}>\n * {todo.text} {todo.done && '✓'}\n * </li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Drag and drop reordering\n * function SortableList() {\n * const items = useArray(['A', 'B', 'C', 'D']);\n *\n * const handleDragEnd = (fromIndex: number, toIndex: number) => {\n * items.move(fromIndex, toIndex);\n * };\n *\n * return <DraggableList items={items.value} onReorder={handleDragEnd} />;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With type-safe updates\n * interface User {\n * id: number;\n * name: string;\n * email: string;\n * }\n *\n * function UserList() {\n * const users = useArray<User>([\n * { id: 1, name: 'Alice', email: 'alice@example.com' },\n * ]);\n *\n * // Partial update (type-safe)\n * users.updateAtPartial(0, { email: 'alice@newdomain.com' });\n *\n * return <div>{users.value.map(u => u.name).join(', ')}</div>;\n * }\n * ```\n */\nexport function useArray<T>(initialValue: T[] = []): UseArrayReturn<T> {\n const [value, setValue] = useState<T[]>(initialValue);\n\n // Add single item to end\n const push = useCallback((item: T) => {\n setValue((arr) => [...arr, item]);\n }, []);\n\n // Add multiple items to end\n const pushMany = useCallback((items: T[]) => {\n setValue((arr) => [...arr, ...items]);\n }, []);\n\n // Remove first occurrence of item\n const remove = useCallback((itemOrPredicate: T | ((item: T) => boolean)) => {\n setValue((arr) => {\n const predicate =\n typeof itemOrPredicate === 'function'\n ? (itemOrPredicate as (item: T) => boolean)\n : (item: T) => item === itemOrPredicate;\n const index = arr.findIndex(predicate);\n if (index === -1) return arr;\n return [...arr.slice(0, index), ...arr.slice(index + 1)];\n });\n }, []);\n\n // Remove item at specific index\n const removeAt = useCallback((index: number) => {\n setValue((arr) => {\n if (index < 0 || index >= arr.length) return arr;\n return [...arr.slice(0, index), ...arr.slice(index + 1)];\n });\n }, []);\n\n // Remove all items matching predicate\n const removeWhere = useCallback((predicate: (item: T) => boolean) => {\n setValue((arr) => arr.filter((item) => !predicate(item)));\n }, []);\n\n // Update item at specific index\n const updateAt = useCallback((index: number, item: T) => {\n setValue((arr) => {\n if (index < 0 || index >= arr.length) return arr;\n return [...arr.slice(0, index), item, ...arr.slice(index + 1)];\n });\n }, []);\n\n // Update item at index with partial data\n const updateAtPartial = useCallback((index: number, partial: Partial<T>) => {\n setValue((arr) => {\n if (index < 0 || index >= arr.length) return arr;\n const item = arr[index];\n if (typeof item !== 'object' || item === null) {\n console.warn('updateAtPartial only works with object items');\n return arr;\n }\n return [...arr.slice(0, index), { ...item, ...partial }, ...arr.slice(index + 1)];\n });\n }, []);\n\n // Update all items matching predicate\n const updateWhere = useCallback((predicate: (item: T) => boolean, update: T | ((item: T) => T)) => {\n setValue((arr) =>\n arr.map((item) => {\n if (!predicate(item)) return item;\n return typeof update === 'function' ? (update as (item: T) => T)(item) : update;\n })\n );\n }, []);\n\n // Insert item at specific index\n const insertAt = useCallback((index: number, item: T) => {\n setValue((arr) => {\n const normalizedIndex = Math.max(0, Math.min(index, arr.length));\n return [...arr.slice(0, normalizedIndex), item, ...arr.slice(normalizedIndex)];\n });\n }, []);\n\n // Move item from one index to another\n const move = useCallback((fromIndex: number, toIndex: number) => {\n setValue((arr) => {\n if (fromIndex < 0 || fromIndex >= arr.length || toIndex < 0 || toIndex >= arr.length || fromIndex === toIndex) {\n return arr;\n }\n const newArr = [...arr];\n const [item] = newArr.splice(fromIndex, 1);\n newArr.splice(toIndex, 0, item);\n return newArr;\n });\n }, []);\n\n // Swap two items\n const swap = useCallback((indexA: number, indexB: number) => {\n setValue((arr) => {\n if (indexA < 0 || indexA >= arr.length || indexB < 0 || indexB >= arr.length || indexA === indexB) {\n return arr;\n }\n const newArr = [...arr];\n [newArr[indexA], newArr[indexB]] = [newArr[indexB], newArr[indexA]];\n return newArr;\n });\n }, []);\n\n // Clear all items\n const clear = useCallback(() => {\n setValue([]);\n }, []);\n\n // Reset to initial value\n const reset = useCallback(() => {\n setValue(initialValue);\n }, [initialValue]);\n\n // Reverse array\n const reverse = useCallback(() => {\n setValue((arr) => [...arr].reverse());\n }, []);\n\n // Sort array\n const sort = useCallback((compareFn?: (a: T, b: T) => number) => {\n setValue((arr) => [...arr].sort(compareFn));\n }, []);\n\n // Non-mutating operations (memoized for stability)\n const filter = useCallback((predicate: (item: T) => boolean) => value.filter(predicate), [value]);\n\n const find = useCallback((predicate: (item: T) => boolean) => value.find(predicate), [value]);\n\n const findIndex = useCallback((predicate: (item: T) => boolean) => value.findIndex(predicate), [value]);\n\n const includes = useCallback((item: T) => value.includes(item), [value]);\n\n // Computed properties\n const computed = useMemo(\n () => ({\n length: value.length,\n isEmpty: value.length === 0,\n first: value[0],\n last: value[value.length - 1],\n }),\n [value]\n );\n\n return {\n value,\n setValue,\n push,\n pushMany,\n remove,\n removeAt,\n removeWhere,\n updateAt,\n updateAtPartial,\n updateWhere,\n insertAt,\n move,\n swap,\n clear,\n reset,\n reverse,\n sort,\n filter,\n find,\n findIndex,\n includes,\n ...computed,\n };\n}\n","'use client';\n\n/**\n * useMutation Hook\n *\n * A hook for handling async mutations with loading, error, and success states.\n * Similar to TanStack Query's useMutation but framework-agnostic.\n *\n * @module hooks/use-mutation\n */\n\nimport { useState, useCallback, useRef } from 'react';\n\n/**\n * State for a mutation.\n */\nexport interface MutationState<TData, TError> {\n /** Mutation result data */\n data: TData | undefined;\n /** Error from mutation */\n error: TError | undefined;\n /** Whether mutation is currently executing */\n isLoading: boolean;\n /** Whether mutation has succeeded at least once */\n isSuccess: boolean;\n /** Whether mutation has failed */\n isError: boolean;\n /** Whether mutation is idle (never called or reset) */\n isIdle: boolean;\n /** Current status */\n status: 'idle' | 'loading' | 'success' | 'error';\n}\n\n/**\n * Options for useMutation hook.\n */\nexport interface UseMutationOptions<TData, TError, TVariables> {\n /** Called when mutation starts */\n onMutate?: (variables: TVariables) => void | Promise<void>;\n /** Called on successful mutation */\n onSuccess?: (data: TData, variables: TVariables) => void | Promise<void>;\n /** Called on mutation error */\n onError?: (error: TError, variables: TVariables) => void | Promise<void>;\n /** Called after mutation settles (success or error) */\n onSettled?: (data: TData | undefined, error: TError | undefined, variables: TVariables) => void | Promise<void>;\n /** Retry count on failure */\n retry?: number | boolean;\n /** Delay between retries in ms */\n retryDelay?: number | ((attempt: number) => number);\n}\n\n/**\n * Return type for useMutation hook.\n */\nexport interface UseMutationReturn<TData, TError, TVariables> {\n /** Current mutation state */\n data: TData | undefined;\n error: TError | undefined;\n isLoading: boolean;\n isSuccess: boolean;\n isError: boolean;\n isIdle: boolean;\n status: MutationState<TData, TError>['status'];\n /** Execute the mutation */\n mutate: (\n variables: TVariables,\n options?: {\n onSuccess?: (data: TData) => void;\n onError?: (error: TError) => void;\n onSettled?: (data: TData | undefined, error: TError | undefined) => void;\n }\n ) => void;\n /** Execute the mutation and return a promise */\n mutateAsync: (variables: TVariables) => Promise<TData>;\n /** Reset mutation state */\n reset: () => void;\n}\n\nconst defaultRetryDelay = (attempt: number) => Math.min(1000 * 2 ** attempt, 30000);\n\n/**\n * Hook for handling async mutations with loading/error states.\n *\n * @param mutationFn - Async function to execute\n * @param options - Configuration options\n * @returns Mutation state and control methods\n *\n * @example\n * ```tsx\n * function CreateUserForm() {\n * const createUser = useMutation(\n * async (data: { name: string; email: string }) => {\n * const response = await fetch('/api/users', {\n * method: 'POST',\n * body: JSON.stringify(data),\n * });\n * if (!response.ok) throw new Error('Failed to create user');\n * return response.json();\n * },\n * {\n * onSuccess: (user) => {\n * console.log('User created:', user);\n * },\n * onError: (error) => {\n * console.error('Failed:', error);\n * },\n * }\n * );\n *\n * const handleSubmit = (e: FormEvent) => {\n * e.preventDefault();\n * createUser.mutate({ name: 'John', email: 'john@example.com' });\n * };\n *\n * return (\n * <form onSubmit={handleSubmit}>\n * <button type=\"submit\" disabled={createUser.isLoading}>\n * {createUser.isLoading ? 'Creating...' : 'Create User'}\n * </button>\n * {createUser.isError && <div>Error: {String(createUser.error)}</div>}\n * {createUser.isSuccess && <div>User created!</div>}\n * </form>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With async/await\n * async function handleCreate() {\n * try {\n * const user = await createUser.mutateAsync({ name: 'Jane' });\n * navigate(`/users/${user.id}`);\n * } catch (error) {\n * // Error already captured in state\n * }\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With retry\n * const uploadFile = useMutation(\n * async (file: File) => {\n * const formData = new FormData();\n * formData.append('file', file);\n * const response = await fetch('/api/upload', {\n * method: 'POST',\n * body: formData,\n * });\n * if (!response.ok) throw new Error('Upload failed');\n * return response.json();\n * },\n * {\n * retry: 3,\n * retryDelay: (attempt) => attempt * 1000,\n * }\n * );\n * ```\n */\nexport function useMutation<TData = unknown, TError = Error, TVariables = void>(\n mutationFn: (variables: TVariables) => Promise<TData>,\n options: UseMutationOptions<TData, TError, TVariables> = {}\n): UseMutationReturn<TData, TError, TVariables> {\n const { onMutate, onSuccess, onError, onSettled, retry = 0, retryDelay = defaultRetryDelay } = options;\n\n const [state, setState] = useState<MutationState<TData, TError>>({\n data: undefined,\n error: undefined,\n isLoading: false,\n isSuccess: false,\n isError: false,\n isIdle: true,\n status: 'idle',\n });\n\n // Track mutation ID to handle race conditions\n const mutationIdRef = useRef(0);\n\n // Execute mutation with optional per-call callbacks\n const mutate = useCallback(\n (\n variables: TVariables,\n callOptions?: {\n onSuccess?: (data: TData) => void;\n onError?: (error: TError) => void;\n onSettled?: (data: TData | undefined, error: TError | undefined) => void;\n }\n ) => {\n const currentId = ++mutationIdRef.current;\n\n const executeWithRetry = async (attempt: number): Promise<void> => {\n // Check if this mutation was superseded\n if (mutationIdRef.current !== currentId) return;\n\n setState({\n data: undefined,\n error: undefined,\n isLoading: true,\n isSuccess: false,\n isError: false,\n isIdle: false,\n status: 'loading',\n });\n\n try {\n // Call onMutate\n await onMutate?.(variables);\n\n // Execute mutation\n const data = await mutationFn(variables);\n\n // Check if this mutation was superseded\n if (mutationIdRef.current !== currentId) return;\n\n setState({\n data,\n error: undefined,\n isLoading: false,\n isSuccess: true,\n isError: false,\n isIdle: false,\n status: 'success',\n });\n\n // Call success callbacks\n await onSuccess?.(data, variables);\n await callOptions?.onSuccess?.(data);\n await onSettled?.(data, undefined, variables);\n await callOptions?.onSettled?.(data, undefined);\n } catch (err) {\n // Check if this mutation was superseded\n if (mutationIdRef.current !== currentId) return;\n\n const error = err as TError;\n const maxRetries = typeof retry === 'boolean' ? (retry ? 3 : 0) : retry;\n\n // Retry if configured\n if (attempt < maxRetries) {\n const delay = typeof retryDelay === 'function' ? retryDelay(attempt) : retryDelay;\n await new Promise((resolve) => setTimeout(resolve, delay));\n await executeWithRetry(attempt + 1);\n return;\n }\n\n setState({\n data: undefined,\n error,\n isLoading: false,\n isSuccess: false,\n isError: true,\n isIdle: false,\n status: 'error',\n });\n\n // Call error callbacks\n await onError?.(error, variables);\n await callOptions?.onError?.(error);\n await onSettled?.(undefined, error, variables);\n await callOptions?.onSettled?.(undefined, error);\n }\n };\n\n executeWithRetry(0);\n },\n [mutationFn, onMutate, onSuccess, onError, onSettled, retry, retryDelay]\n );\n\n // Execute mutation and return promise\n const mutateAsync = useCallback(\n (variables: TVariables): Promise<TData> =>\n new Promise((resolve, reject) => {\n mutate(variables, {\n onSuccess: resolve,\n onError: reject,\n });\n }),\n [mutate]\n );\n\n // Reset mutation state\n const reset = useCallback(() => {\n mutationIdRef.current++;\n setState({\n data: undefined,\n error: undefined,\n isLoading: false,\n isSuccess: false,\n isError: false,\n isIdle: true,\n status: 'idle',\n });\n }, []);\n\n return {\n ...state,\n mutate,\n mutateAsync,\n reset,\n };\n}\n","'use client';\n\n/**\n * useLazyQuery Hook\n *\n * A hook for manual query execution with loading, error, and caching support.\n *\n * @module hooks/use-lazy-query\n */\n\nimport { useState, useCallback, useRef } from 'react';\n\n/**\n * State for a lazy query.\n */\nexport interface LazyQueryState<TData, TError> {\n /** Query result data */\n data: TData | undefined;\n /** Error from query */\n error: TError | undefined;\n /** Whether query is currently executing */\n isLoading: boolean;\n /** Whether query has succeeded at least once */\n isSuccess: boolean;\n /** Whether query has failed */\n isError: boolean;\n /** Whether query has been called at least once */\n isCalled: boolean;\n /** Whether query is fetching (includes refetch) */\n isFetching: boolean;\n /** Whether this is a refetch */\n isRefetching: boolean;\n}\n\n/**\n * Options for useLazyQuery hook.\n */\nexport interface UseLazyQueryOptions<TData, TError, TVariables> {\n /** Called on successful query */\n onSuccess?: (data: TData, variables: TVariables) => void | Promise<void>;\n /** Called on query error */\n onError?: (error: TError, variables: TVariables) => void | Promise<void>;\n /** Called after query settles (success or error) */\n onSettled?: (data: TData | undefined, error: TError | undefined, variables: TVariables) => void | Promise<void>;\n /** Cache time in ms (0 = no cache) */\n cacheTime?: number;\n /** Stale time in ms (data considered fresh for this duration) */\n staleTime?: number;\n /** Retry count on failure */\n retry?: number | boolean;\n /** Delay between retries in ms */\n retryDelay?: number | ((attempt: number) => number);\n /** Initial data */\n initialData?: TData;\n}\n\n/**\n * Return type for useLazyQuery hook.\n */\nexport interface UseLazyQueryReturn<TData, TError, TVariables> {\n /** Current query state */\n data: TData | undefined;\n error: TError | undefined;\n isLoading: boolean;\n isSuccess: boolean;\n isError: boolean;\n isCalled: boolean;\n isFetching: boolean;\n isRefetching: boolean;\n /** Execute the query */\n query: (variables: TVariables) => Promise<TData>;\n /** Refetch with last variables */\n refetch: () => Promise<TData | undefined>;\n /** Reset query state */\n reset: () => void;\n /** Manually set data */\n setData: (data: TData | ((prev: TData | undefined) => TData)) => void;\n}\n\ninterface CacheEntry<TData> {\n data: TData;\n timestamp: number;\n variables: unknown;\n}\n\nconst defaultRetryDelay = (attempt: number) => Math.min(1000 * 2 ** attempt, 30000);\n\n/**\n * Hook for manual query execution with caching support.\n *\n * @param queryFn - Async function to execute\n * @param options - Configuration options\n * @returns Query state and control methods\n *\n * @example\n * ```tsx\n * function UserSearch() {\n * const users = useLazyQuery(\n * async (query: string) => {\n * const response = await fetch(`/api/users?q=${query}`);\n * if (!response.ok) throw new Error('Search failed');\n * return response.json();\n * },\n * {\n * onSuccess: (data) => console.log('Found users:', data.length),\n * cacheTime: 5 * 60 * 1000, // 5 minutes\n * }\n * );\n *\n * const handleSearch = async (query: string) => {\n * const results = await users.query(query);\n * console.log('Results:', results);\n * };\n *\n * return (\n * <div>\n * <SearchInput onSearch={handleSearch} />\n * {users.isLoading && <Spinner />}\n * {users.isError && <div>Error: {String(users.error)}</div>}\n * {users.data?.map((user) => <UserCard key={user.id} user={user} />)}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With caching\n * const userDetails = useLazyQuery(\n * async (id: string) => fetchUser(id),\n * {\n * cacheTime: 10 * 60 * 1000, // Keep in cache for 10 min\n * staleTime: 60 * 1000, // Consider fresh for 1 min\n * }\n * );\n *\n * // First call fetches, subsequent calls within staleTime return cache\n * await userDetails.query('123');\n * await userDetails.query('123'); // Returns from cache if not stale\n * ```\n *\n * @example\n * ```tsx\n * // Manual data management\n * const { data, setData, reset } = useLazyQuery(fetchData);\n *\n * // Optimistic update\n * setData((prev) => prev ? { ...prev, count: prev.count + 1 } : prev);\n *\n * // Reset to clean state\n * reset();\n * ```\n */\nexport function useLazyQuery<TData = unknown, TError = Error, TVariables = void>(\n queryFn: (variables: TVariables) => Promise<TData>,\n options: UseLazyQueryOptions<TData, TError, TVariables> = {}\n): UseLazyQueryReturn<TData, TError, TVariables> {\n const {\n onSuccess,\n onError,\n onSettled,\n cacheTime = 0,\n staleTime = 0,\n retry = 0,\n retryDelay = defaultRetryDelay,\n initialData,\n } = options;\n\n const [state, setState] = useState<LazyQueryState<TData, TError>>({\n data: initialData,\n error: undefined,\n isLoading: false,\n isSuccess: !!initialData,\n isError: false,\n isCalled: !!initialData,\n isFetching: false,\n isRefetching: false,\n });\n\n // Track query ID for race conditions\n const queryIdRef = useRef(0);\n const lastVariablesRef = useRef<TVariables | null>(null);\n const cacheRef = useRef<Map<string, CacheEntry<TData>>>(new Map());\n\n // Generate cache key from variables\n const getCacheKey = useCallback((variables: TVariables): string => JSON.stringify(variables), []);\n\n // Check if cache entry is valid\n const isCacheValid = useCallback(\n (entry: CacheEntry<TData> | undefined): boolean => {\n if (!entry || cacheTime === 0) return false;\n const age = Date.now() - entry.timestamp;\n return age < cacheTime;\n },\n [cacheTime]\n );\n\n // Check if cache entry is fresh (not stale)\n const isCacheFresh = useCallback(\n (entry: CacheEntry<TData> | undefined): boolean => {\n if (!entry || staleTime === 0) return false;\n const age = Date.now() - entry.timestamp;\n return age < staleTime;\n },\n [staleTime]\n );\n\n // Execute query\n const query = useCallback(\n async (variables: TVariables): Promise<TData> => {\n const currentId = ++queryIdRef.current;\n lastVariablesRef.current = variables;\n\n // Check cache\n const cacheKey = getCacheKey(variables);\n const cached = cacheRef.current.get(cacheKey);\n\n if (isCacheFresh(cached)) {\n // Return fresh cached data immediately\n setState((prev) => ({\n ...prev,\n data: cached!.data,\n isSuccess: true,\n isCalled: true,\n }));\n return cached!.data;\n }\n\n // If cache is valid but stale, update state with cached data while fetching\n if (isCacheValid(cached)) {\n setState({\n data: cached!.data,\n error: undefined,\n isLoading: false,\n isSuccess: true,\n isError: false,\n isCalled: true,\n isFetching: true,\n isRefetching: true,\n });\n } else {\n setState({\n data: undefined,\n error: undefined,\n isLoading: true,\n isSuccess: false,\n isError: false,\n isCalled: true,\n isFetching: true,\n isRefetching: false,\n });\n }\n\n const executeWithRetry = async (attempt: number): Promise<TData> => {\n try {\n const data = await queryFn(variables);\n\n // Check if this query was superseded\n if (queryIdRef.current !== currentId) {\n return data;\n }\n\n // Update cache\n cacheRef.current.set(cacheKey, {\n data,\n timestamp: Date.now(),\n variables,\n });\n\n setState({\n data,\n error: undefined,\n isLoading: false,\n isSuccess: true,\n isError: false,\n isCalled: true,\n isFetching: false,\n isRefetching: false,\n });\n\n // Call success callbacks\n await onSuccess?.(data, variables);\n await onSettled?.(data, undefined, variables);\n\n return data;\n } catch (err) {\n // Check if this query was superseded\n if (queryIdRef.current !== currentId) {\n throw err;\n }\n\n const error = err as TError;\n const maxRetries = typeof retry === 'boolean' ? (retry ? 3 : 0) : retry;\n\n // Retry if configured\n if (attempt < maxRetries) {\n const delay = typeof retryDelay === 'function' ? retryDelay(attempt) : retryDelay;\n await new Promise((resolve) => setTimeout(resolve, delay));\n return executeWithRetry(attempt + 1);\n }\n\n setState({\n data: undefined,\n error,\n isLoading: false,\n isSuccess: false,\n isError: true,\n isCalled: true,\n isFetching: false,\n isRefetching: false,\n });\n\n // Call error callbacks\n await onError?.(error, variables);\n await onSettled?.(undefined, error, variables);\n\n throw error;\n }\n };\n\n return executeWithRetry(0);\n },\n [queryFn, getCacheKey, isCacheFresh, isCacheValid, onSuccess, onError, onSettled, retry, retryDelay]\n );\n\n // Refetch with last variables\n const refetch = useCallback(async (): Promise<TData | undefined> => {\n if (lastVariablesRef.current === null) {\n return undefined;\n }\n return query(lastVariablesRef.current);\n }, [query]);\n\n // Reset state\n const reset = useCallback(() => {\n queryIdRef.current++;\n lastVariablesRef.current = null;\n cacheRef.current.clear();\n setState({\n data: initialData,\n error: undefined,\n isLoading: false,\n isSuccess: !!initialData,\n isError: false,\n isCalled: !!initialData,\n isFetching: false,\n isRefetching: false,\n });\n }, [initialData]);\n\n // Manual data setter\n const setData = useCallback((data: TData | ((prev: TData | undefined) => TData)) => {\n setState((prev) => {\n const newData = typeof data === 'function' ? (data as (prev: TData | undefined) => TData)(prev.data) : data;\n return {\n ...prev,\n data: newData,\n isSuccess: true,\n };\n });\n }, []);\n\n return {\n ...state,\n query,\n refetch,\n reset,\n setData,\n };\n}\n","'use client';\n\n/**\n * useInfiniteScroll Hook\n *\n * A hook for infinite scrolling with paginated data loading.\n *\n * @module hooks/use-infinite-scroll\n */\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\n\n/**\n * Page info returned from fetch function.\n */\nexport interface PageInfo {\n /** Whether there are more pages */\n hasNextPage: boolean;\n /** Cursor or token for next page */\n endCursor?: string | number;\n /** Total count (optional) */\n totalCount?: number;\n}\n\n/**\n * Page data structure.\n */\nexport interface InfinitePage<TData> {\n /** Items in this page */\n items: TData[];\n /** Page information */\n pageInfo: PageInfo;\n}\n\n/**\n * State for infinite scroll.\n */\nexport interface InfiniteScrollState<TData, TError> {\n /** All loaded items (flattened) */\n items: TData[];\n /** All pages */\n pages: InfinitePage<TData>[];\n /** Error from last fetch */\n error: TError | undefined;\n /** Whether initial load is in progress */\n isLoading: boolean;\n /** Whether more data is being fetched */\n isFetchingMore: boolean;\n /** Whether there are more pages to fetch */\n hasNextPage: boolean;\n /** Whether any data has been loaded */\n isEmpty: boolean;\n /** Total count if available */\n totalCount: number | undefined;\n}\n\n/**\n * Options for useInfiniteScroll hook.\n */\nexport interface UseInfiniteScrollOptions<TData, TError> {\n /** Called on successful fetch */\n onSuccess?: (page: InfinitePage<TData>) => void | Promise<void>;\n /** Called on fetch error */\n onError?: (error: TError) => void | Promise<void>;\n /** Initial cursor/offset */\n initialCursor?: string | number;\n /** Initial page size */\n pageSize?: number;\n /** Retry count on failure */\n retry?: number | boolean;\n /** Retry delay in ms */\n retryDelay?: number | ((attempt: number) => number);\n /** Intersection observer options for auto-loading */\n observerOptions?: IntersectionObserverInit;\n}\n\n/**\n * Return type for useInfiniteScroll hook.\n */\nexport interface UseInfiniteScrollReturn<TData, TError> {\n /** All loaded items (flattened) */\n items: TData[];\n /** All pages */\n pages: InfinitePage<TData>[];\n /** Error from last fetch */\n error: TError | undefined;\n /** Whether initial load is in progress */\n isLoading: boolean;\n /** Whether more data is being fetched */\n isFetchingMore: boolean;\n /** Whether there are more pages to fetch */\n hasNextPage: boolean;\n /** Whether list is empty */\n isEmpty: boolean;\n /** Total count if available */\n totalCount: number | undefined;\n /** Fetch the next page */\n fetchNextPage: () => Promise<void>;\n /** Fetch first page (refresh) */\n refresh: () => Promise<void>;\n /** Reset to initial state */\n reset: () => void;\n /** Ref to attach to sentinel element for auto-loading */\n sentinelRef: React.RefCallback<HTMLElement>;\n /** Manually prepend items */\n prependItems: (items: TData[]) => void;\n /** Manually append items */\n appendItems: (items: TData[]) => void;\n /** Remove item by predicate */\n removeItem: (predicate: (item: TData) => boolean) => void;\n /** Update item by predicate */\n updateItem: (predicate: (item: TData) => boolean, update: Partial<TData> | ((item: TData) => TData)) => void;\n}\n\n/**\n * Fetch function signature.\n */\nexport type InfiniteFetchFn<TData> = (params: {\n cursor?: string | number;\n pageSize: number;\n}) => Promise<InfinitePage<TData>>;\n\nconst defaultRetryDelay = (attempt: number) => Math.min(1000 * 2 ** attempt, 30000);\n\n/**\n * Hook for infinite scrolling with paginated data.\n *\n * @param fetchFn - Function to fetch a page of data\n * @param options - Configuration options\n * @returns Infinite scroll state and controls\n *\n * @example\n * ```tsx\n * function UserList() {\n * const {\n * items,\n * isLoading,\n * isFetchingMore,\n * hasNextPage,\n * fetchNextPage,\n * sentinelRef,\n * } = useInfiniteScroll<User>(\n * async ({ cursor, pageSize }) => {\n * const response = await fetch(\n * `/api/users?cursor=${cursor ?? ''}&limit=${pageSize}`\n * );\n * const data = await response.json();\n * return {\n * items: data.users,\n * pageInfo: {\n * hasNextPage: data.hasMore,\n * endCursor: data.nextCursor,\n * totalCount: data.total,\n * },\n * };\n * },\n * { pageSize: 20 }\n * );\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * {items.map((user) => (\n * <UserCard key={user.id} user={user} />\n * ))}\n * {hasNextPage && (\n * <div ref={sentinelRef}>\n * {isFetchingMore ? <Spinner /> : 'Load more'}\n * </div>\n * )}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Manual loading\n * function ProductList() {\n * const { items, hasNextPage, fetchNextPage, isFetchingMore } = useInfiniteScroll(\n * fetchProducts,\n * { pageSize: 10 }\n * );\n *\n * return (\n * <>\n * <ProductGrid items={items} />\n * {hasNextPage && (\n * <Button onClick={fetchNextPage} loading={isFetchingMore}>\n * Load More\n * </Button>\n * )}\n * </>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With optimistic updates\n * const { items, removeItem, updateItem, prependItems } = useInfiniteScroll(\n * fetchComments,\n * { pageSize: 20 }\n * );\n *\n * // Add new comment at top\n * const handleNewComment = (comment: Comment) => {\n * prependItems([comment]);\n * };\n *\n * // Delete comment\n * const handleDelete = (id: string) => {\n * removeItem((c) => c.id === id);\n * };\n *\n * // Update comment\n * const handleEdit = (id: string, text: string) => {\n * updateItem((c) => c.id === id, { text });\n * };\n * ```\n */\nexport function useInfiniteScroll<TData = unknown, TError = Error>(\n fetchFn: InfiniteFetchFn<TData>,\n options: UseInfiniteScrollOptions<TData, TError> = {}\n): UseInfiniteScrollReturn<TData, TError> {\n const {\n onSuccess,\n onError,\n initialCursor,\n pageSize = 20,\n retry = 0,\n retryDelay = defaultRetryDelay,\n observerOptions = { threshold: 0.1 },\n } = options;\n\n const [state, setState] = useState<InfiniteScrollState<TData, TError>>({\n items: [],\n pages: [],\n error: undefined,\n isLoading: false,\n isFetchingMore: false,\n hasNextPage: true,\n isEmpty: true,\n totalCount: undefined,\n });\n\n /**\n * The caller's functions and options, read through refs.\n *\n * Everything here is something a caller writes inline — `fetchFn` as an\n * arrow, `onSuccess` as an arrow, `observerOptions` not at all, which\n * makes the default `{ threshold: 0.1 }` a fresh object on every render.\n * Each of those was a dependency, so `fetchPage` changed identity every\n * render, and with it `fetchNextPage`, and with it `sentinelRef`.\n *\n * `sentinelRef` is a REF CALLBACK. React invokes a ref callback with\n * `null` and then with the element every time its identity changes — so\n * every render tore down the `IntersectionObserver` and built a new one,\n * and a new observer whose target is already intersecting fires\n * immediately. A sentinel at the bottom of a short list always is.\n *\n * Measured before this change, with an observer that fires on `observe`\n * as the real one does: 53 observers created and React aborting the tree\n * with \"Maximum update depth exceeded\".\n *\n * Reading them through refs keeps the callbacks stable without asking\n * every caller to memoise. The cost is that changing `observerOptions`\n * after mount no longer rebuilds the observer, which is worth saying out\n * loud and is not something any caller does.\n */\n const fetchFnRef = useRef(fetchFn);\n fetchFnRef.current = fetchFn;\n const onSuccessRef = useRef(onSuccess);\n onSuccessRef.current = onSuccess;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const observerOptionsRef = useRef(observerOptions);\n observerOptionsRef.current = observerOptions;\n\n // Refs for tracking\n const fetchIdRef = useRef(0);\n const cursorRef = useRef<string | number | undefined>(initialCursor);\n const observerRef = useRef<IntersectionObserver | null>(null);\n const sentinelElementRef = useRef<HTMLElement | null>(null);\n const isMountedRef = useRef(true);\n\n // Cleanup on unmount\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n if (observerRef.current) {\n observerRef.current.disconnect();\n }\n };\n }, []);\n\n // Fetch a page with retry logic\n const fetchPage = useCallback(\n async (cursor: string | number | undefined, isRefresh = false) => {\n const currentId = ++fetchIdRef.current;\n\n const executeWithRetry = async (attempt: number): Promise<void> => {\n if (!isMountedRef.current) return;\n\n setState((prev) => ({\n ...prev,\n isLoading: isRefresh && prev.pages.length === 0,\n isFetchingMore: !isRefresh || prev.pages.length > 0,\n error: undefined,\n }));\n\n try {\n const page = await fetchFnRef.current({ cursor, pageSize });\n\n // Check if this fetch was superseded\n if (fetchIdRef.current !== currentId || !isMountedRef.current) return;\n\n setState((prev) => {\n const newPages = isRefresh ? [page] : [...prev.pages, page];\n const newItems = newPages.flatMap((p) => p.items);\n return {\n items: newItems,\n pages: newPages,\n error: undefined,\n isLoading: false,\n isFetchingMore: false,\n hasNextPage: page.pageInfo.hasNextPage,\n isEmpty: newItems.length === 0,\n totalCount: page.pageInfo.totalCount,\n };\n });\n\n cursorRef.current = page.pageInfo.endCursor;\n await onSuccessRef.current?.(page);\n } catch (err) {\n if (fetchIdRef.current !== currentId || !isMountedRef.current) return;\n\n const error = err as TError;\n const maxRetries = typeof retry === 'boolean' ? (retry ? 3 : 0) : retry;\n\n if (attempt < maxRetries) {\n const delay = typeof retryDelay === 'function' ? retryDelay(attempt) : retryDelay;\n await new Promise((resolve) => setTimeout(resolve, delay));\n await executeWithRetry(attempt + 1);\n return;\n }\n\n setState((prev) => ({\n ...prev,\n error,\n isLoading: false,\n isFetchingMore: false,\n }));\n\n await onErrorRef.current?.(error);\n }\n };\n\n return executeWithRetry(0);\n },\n [pageSize, retry, retryDelay]\n );\n\n // Fetch next page\n const fetchNextPage = useCallback(async () => {\n if (state.isFetchingMore || state.isLoading || !state.hasNextPage) return;\n await fetchPage(cursorRef.current);\n }, [fetchPage, state.isFetchingMore, state.isLoading, state.hasNextPage]);\n\n // Refresh (fetch first page)\n const refresh = useCallback(async () => {\n cursorRef.current = initialCursor;\n await fetchPage(initialCursor, true);\n }, [fetchPage, initialCursor]);\n\n // Reset to initial state\n const reset = useCallback(() => {\n fetchIdRef.current++;\n cursorRef.current = initialCursor;\n setState({\n items: [],\n pages: [],\n error: undefined,\n isLoading: false,\n isFetchingMore: false,\n hasNextPage: true,\n isEmpty: true,\n totalCount: undefined,\n });\n }, [initialCursor]);\n\n // Prepend items\n const prependItems = useCallback((newItems: TData[]) => {\n setState((prev) => ({\n ...prev,\n items: [...newItems, ...prev.items],\n isEmpty: newItems.length === 0 && prev.items.length === 0,\n }));\n }, []);\n\n // Append items\n const appendItems = useCallback((newItems: TData[]) => {\n setState((prev) => ({\n ...prev,\n items: [...prev.items, ...newItems],\n isEmpty: prev.items.length === 0 && newItems.length === 0,\n }));\n }, []);\n\n // Remove item by predicate\n const removeItem = useCallback((predicate: (item: TData) => boolean) => {\n setState((prev) => {\n const newItems = prev.items.filter((item) => !predicate(item));\n return {\n ...prev,\n items: newItems,\n isEmpty: newItems.length === 0,\n };\n });\n }, []);\n\n // Update item by predicate\n const updateItem = useCallback(\n (predicate: (item: TData) => boolean, update: Partial<TData> | ((item: TData) => TData)) => {\n setState((prev) => ({\n ...prev,\n items: prev.items.map((item) => {\n if (!predicate(item)) return item;\n if (typeof update === 'function') {\n return update(item);\n }\n return { ...item, ...update };\n }),\n }));\n },\n []\n );\n\n // Sentinel ref callback for auto-loading\n const sentinelRef = useCallback(\n (element: HTMLElement | null) => {\n // Disconnect previous observer\n if (observerRef.current) {\n observerRef.current.disconnect();\n }\n\n sentinelElementRef.current = element;\n\n if (!element) return;\n\n // Create new observer\n observerRef.current = new IntersectionObserver((entries) => {\n if (entries[0]?.isIntersecting) {\n fetchNextPage();\n }\n }, observerOptionsRef.current);\n\n observerRef.current.observe(element);\n },\n [fetchNextPage]\n );\n\n // Initial fetch on mount\n useEffect(() => {\n fetchPage(initialCursor, true);\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return {\n items: state.items,\n pages: state.pages,\n error: state.error,\n isLoading: state.isLoading,\n isFetchingMore: state.isFetchingMore,\n hasNextPage: state.hasNextPage,\n isEmpty: state.isEmpty,\n totalCount: state.totalCount,\n fetchNextPage,\n refresh,\n reset,\n sentinelRef,\n prependItems,\n appendItems,\n removeItem,\n updateItem,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-async.ts","../src/hooks/use-scroll-position.ts","../src/hooks/use-window-size.ts","../src/hooks/use-client-rect.ts","../src/hooks/use-popover-hover.ts","../src/utils/cookies.ts","../src/hooks/use-cookies.ts","../src/hooks/use-double-click.ts","../src/hooks/use-back-to-top.ts","../src/hooks/use-countdown-seconds.ts","../src/hooks/use-countdown-date.ts","../src/hooks/use-scroll-offset-top.ts","../src/hooks/use-config-from-query.ts","../src/hooks/use-image-dimensions.ts","../src/hooks/use-password-visibility.ts","../src/hooks/use-throttle.ts","../src/hooks/use-online-status.ts","../src/hooks/use-intersection-observer.ts","../src/hooks/use-keyboard-shortcut.ts","../src/hooks/use-focus-trap.ts","../src/hooks/use-update-effect.ts","../src/hooks/use-isomorphic-layout-effect.ts","../src/hooks/use-session-storage.ts","../src/hooks/use-array.ts","../src/hooks/use-mutation.ts","../src/hooks/use-lazy-query.ts","../src/hooks/use-infinite-scroll.ts"],"names":["useState","useRef","useCallback","useEffect","useMemo","useSyncExternalStore","defaultRetryDelay"],"mappings":"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","file":"chunk-74TJGLFR.js","sourcesContent":["'use client';\n\n/**\n * useAsync Hook\n *\n * Manages async operations with loading, error, and data states.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useState, useCallback, useRef, useEffect, useMemo } from 'react';\n\n/**\n * Async state.\n */\nexport interface AsyncState<T> {\n /** Data result */\n data: T | null;\n /** Loading state */\n loading: boolean;\n /** Error state */\n error: Error | null;\n}\n\n/**\n * Return type for useAsync hook.\n */\nexport interface UseAsyncReturn<T, Args extends unknown[]> extends AsyncState<T> {\n /** Execute the async function */\n execute: (...args: Args) => Promise<T>;\n /** Reset state */\n reset: () => void;\n /** Set data manually */\n setData: (data: T | null) => void;\n /** Set error manually */\n setError: (error: Error | null) => void;\n}\n\n/**\n * Options for useAsync hook.\n */\nexport interface UseAsyncOptions<T> {\n /** Initial data */\n initialData?: T | null;\n /** Auto-execute on mount */\n immediate?: boolean;\n /** On success callback */\n onSuccess?: (data: T) => void;\n /** On error callback */\n onError?: (error: Error) => void;\n}\n\n/**\n * useAsync - Hook for managing async operations.\n *\n * @example\n * ```tsx\n * // Basic usage\n * const { data, loading, error, execute } = useAsync(fetchUser);\n *\n * // Auto-execute on mount\n * const { data, loading } = useAsync(fetchUsers, { immediate: true });\n *\n * // With callbacks\n * const { execute } = useAsync(createUser, {\n * onSuccess: (user) => toast.success(`Created ${user.name}`),\n * onError: (err) => toast.error(err.message),\n * });\n *\n * // In a component\n * const handleSubmit = async () => {\n * const result = await execute(formData);\n * if (result) navigate('/success');\n * };\n * ```\n */\nexport function useAsync<T, Args extends unknown[] = []>(\n asyncFn: (...args: Args) => Promise<T>,\n options: UseAsyncOptions<T> = {}\n): UseAsyncReturn<T, Args> {\n const { initialData = null, immediate = false, onSuccess, onError } = options;\n\n const [state, setState] = useState<AsyncState<T>>({\n data: initialData,\n loading: immediate,\n error: null,\n });\n\n // Track mounted state to prevent state updates after unmount\n const isMounted = useRef(true);\n\n // Track if we're currently executing\n const executingRef = useRef(false);\n\n useEffect(() => {\n isMounted.current = true;\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n const execute = useCallback(\n async (...args: Args): Promise<T> => {\n // Prevent concurrent executions\n if (executingRef.current) {\n return Promise.reject(new Error('Operation already in progress'));\n }\n\n executingRef.current = true;\n\n if (isMounted.current) {\n setState((prev) => ({ ...prev, loading: true, error: null }));\n }\n\n try {\n const result = await asyncFn(...args);\n\n if (isMounted.current) {\n setState({ data: result, loading: false, error: null });\n onSuccess?.(result);\n }\n\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n\n if (isMounted.current) {\n setState((prev) => ({ ...prev, loading: false, error }));\n onError?.(error);\n }\n\n throw error;\n } finally {\n executingRef.current = false;\n }\n },\n [asyncFn, onSuccess, onError]\n );\n\n const reset = useCallback(() => {\n setState({ data: initialData, loading: false, error: null });\n }, [initialData]);\n\n const setData = useCallback((data: T | null) => {\n setState((prev) => ({ ...prev, data }));\n }, []);\n\n const setError = useCallback((error: Error | null) => {\n setState((prev) => ({ ...prev, error }));\n }, []);\n\n // Auto-execute on mount if immediate is true\n useEffect(() => {\n if (immediate) {\n execute(...([] as unknown as Args)).catch(() => {\n // Error is already handled in execute\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Memoize return object to prevent unnecessary re-renders\n return useMemo(\n () => ({\n ...state,\n execute,\n reset,\n setData,\n setError,\n }),\n [state, execute, reset, setData, setError]\n );\n}\n\n/**\n * Return type for useAsyncFn hook (simpler version).\n */\nexport interface UseAsyncFnReturn<T, Args extends unknown[]> {\n /** Execute the async function */\n execute: (...args: Args) => Promise<T | undefined>;\n /** Loading state */\n loading: boolean;\n /** Error state */\n error: Error | null;\n}\n\n/**\n * useAsyncFn - Simpler hook for async functions without data tracking.\n *\n * @example\n * ```tsx\n * const { execute, loading, error } = useAsyncFn(deleteUser);\n *\n * const handleDelete = async (id: string) => {\n * await execute(id);\n * refetch(); // Trigger parent refresh\n * };\n * ```\n */\nexport function useAsyncFn<T, Args extends unknown[] = []>(\n asyncFn: (...args: Args) => Promise<T>\n): UseAsyncFnReturn<T, Args> {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const isMounted = useRef(true);\n\n useEffect(() => {\n isMounted.current = true;\n return () => {\n isMounted.current = false;\n };\n }, []);\n\n const execute = useCallback(\n async (...args: Args): Promise<T | undefined> => {\n setLoading(true);\n setError(null);\n\n try {\n const result = await asyncFn(...args);\n if (isMounted.current) {\n setLoading(false);\n }\n return result;\n } catch (err) {\n const caughtError = err instanceof Error ? err : new Error(String(err));\n if (isMounted.current) {\n setLoading(false);\n setError(caughtError);\n }\n return undefined;\n }\n },\n [asyncFn]\n );\n\n return { execute, loading, error };\n}\n","'use client';\n\n/**\n * useScrollPosition Hook\n *\n * Tracks scroll position with performance optimization.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\n\n/**\n * Scroll position data.\n */\nexport interface ScrollPosition {\n /** Scroll position from top */\n x: number;\n /** Scroll position from left */\n y: number;\n /** Scroll direction (1 = down/right, -1 = up/left, 0 = initial) */\n directionX: -1 | 0 | 1;\n directionY: -1 | 0 | 1;\n /** Whether scrolled past threshold */\n isScrolled: boolean;\n /** Whether at the top */\n isAtTop: boolean;\n /** Whether at the bottom */\n isAtBottom: boolean;\n}\n\n/**\n * Options for useScrollPosition hook.\n */\nexport interface UseScrollPositionOptions {\n /** Element to track (default: window) */\n element?: HTMLElement | null;\n /** Throttle delay in ms (default: 100) */\n throttle?: number;\n /** Threshold to consider \"scrolled\" (default: 0) */\n threshold?: number;\n /** Offset from bottom to consider \"at bottom\" (default: 10) */\n bottomOffset?: number;\n}\n\n/**\n * useScrollPosition - Hook for tracking scroll position.\n *\n * @example\n * ```tsx\n * // Track window scroll\n * const { y, isScrolled, directionY } = useScrollPosition();\n *\n * // Show header shadow when scrolled\n * <Header className={isScrolled ? 'shadow' : ''} />\n *\n * // Hide header on scroll down, show on scroll up\n * const showHeader = directionY !== 1 || y < 50;\n *\n * // Track specific element\n * const containerRef = useRef<HTMLDivElement>(null);\n * const { isAtBottom } = useScrollPosition({ element: containerRef.current });\n *\n * // Load more when near bottom\n * useEffect(() => {\n * if (isAtBottom) loadMore();\n * }, [isAtBottom]);\n * ```\n */\nexport function useScrollPosition(options: UseScrollPositionOptions = {}): ScrollPosition {\n const { element = null, throttle = 100, threshold = 0, bottomOffset = 10 } = options;\n\n const [position, setPosition] = useState<ScrollPosition>({\n x: 0,\n y: 0,\n directionX: 0,\n directionY: 0,\n isScrolled: false,\n isAtTop: true,\n isAtBottom: false,\n });\n\n const lastPosition = useRef({ x: 0, y: 0 });\n const ticking = useRef(false);\n\n const updatePosition = useCallback(() => {\n // SSR guard - only run on client\n if (typeof window === 'undefined') return;\n\n const scrollX = element ? element.scrollLeft : window.scrollX;\n const scrollY = element ? element.scrollTop : window.scrollY;\n\n // Calculate max scroll\n const maxScrollY = element\n ? element.scrollHeight - element.clientHeight\n : document.documentElement.scrollHeight - window.innerHeight;\n\n // Calculate direction\n const directionX = scrollX > lastPosition.current.x ? 1 : scrollX < lastPosition.current.x ? -1 : 0;\n const directionY = scrollY > lastPosition.current.y ? 1 : scrollY < lastPosition.current.y ? -1 : 0;\n\n lastPosition.current = { x: scrollX, y: scrollY };\n\n setPosition({\n x: scrollX,\n y: scrollY,\n directionX: directionX as -1 | 0 | 1,\n directionY: directionY as -1 | 0 | 1,\n isScrolled: scrollY > threshold,\n isAtTop: scrollY <= 0,\n isAtBottom: scrollY >= maxScrollY - bottomOffset,\n });\n\n ticking.current = false;\n }, [element, threshold, bottomOffset]);\n\n const handleScroll = useCallback(() => {\n if (!ticking.current) {\n if (throttle > 0) {\n window.requestAnimationFrame(() => {\n updatePosition();\n });\n } else {\n updatePosition();\n }\n ticking.current = true;\n\n if (throttle > 0) {\n setTimeout(() => {\n ticking.current = false;\n }, throttle);\n }\n }\n }, [throttle, updatePosition]);\n\n useEffect(() => {\n // SSR guard\n if (typeof window === 'undefined') return undefined;\n\n const target = element ?? window;\n\n // Initial position\n updatePosition();\n\n target.addEventListener('scroll', handleScroll, { passive: true });\n\n return () => {\n target.removeEventListener('scroll', handleScroll);\n };\n }, [element, handleScroll, updatePosition]);\n\n return position;\n}\n\n/**\n * useScrollToTop - Hook for scrolling to top functionality.\n *\n * @example\n * ```tsx\n * const { scrollToTop, showButton } = useScrollToTop({ threshold: 300 });\n *\n * {showButton && (\n * <Fab onClick={scrollToTop}>\n * <ArrowUpIcon />\n * </Fab>\n * )}\n * ```\n */\nexport function useScrollToTop(options: { threshold?: number } = {}): {\n scrollToTop: () => void;\n showButton: boolean;\n} {\n const { threshold = 300 } = options;\n const { y } = useScrollPosition({ threshold });\n\n const scrollToTop = useCallback(() => {\n window.scrollTo({ top: 0, behavior: 'smooth' });\n }, []);\n\n return {\n scrollToTop,\n showButton: y > threshold,\n };\n}\n\n/**\n * useScrollLock - Hook for locking body scroll.\n *\n * @example\n * ```tsx\n * const { lock, unlock, isLocked } = useScrollLock();\n *\n * // Lock when modal opens\n * useEffect(() => {\n * if (isOpen) lock();\n * else unlock();\n * }, [isOpen]);\n * ```\n */\nexport function useScrollLock(): {\n lock: () => void;\n unlock: () => void;\n isLocked: boolean;\n} {\n const [isLocked, setIsLocked] = useState(false);\n const scrollY = useRef(0);\n\n const lock = useCallback(() => {\n if (typeof document === 'undefined') return;\n\n scrollY.current = window.scrollY;\n document.body.style.position = 'fixed';\n document.body.style.top = `-${scrollY.current}px`;\n document.body.style.width = '100%';\n document.body.style.overflow = 'hidden';\n setIsLocked(true);\n }, []);\n\n const unlock = useCallback(() => {\n if (typeof document === 'undefined') return;\n\n document.body.style.position = '';\n document.body.style.top = '';\n document.body.style.width = '';\n document.body.style.overflow = '';\n window.scrollTo(0, scrollY.current);\n setIsLocked(false);\n }, []);\n\n // Cleanup on unmount\n useEffect(\n () => () => {\n if (isLocked) {\n document.body.style.position = '';\n document.body.style.top = '';\n document.body.style.width = '';\n document.body.style.overflow = '';\n }\n },\n [isLocked]\n );\n\n return { lock, unlock, isLocked };\n}\n","'use client';\n\n/**\n * useWindowSize Hook\n *\n * Tracks window dimensions with responsive breakpoint utilities.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useState, useEffect, useCallback, useRef, useMemo } from 'react';\n\n/**\n * Window size data.\n */\nexport interface WindowSize {\n /** Window width */\n width: number;\n /** Window height */\n height: number;\n /** Is mobile (< 600px) */\n isMobile: boolean;\n /** Is tablet (600px - 960px) */\n isTablet: boolean;\n /** Is desktop (>= 960px) */\n isDesktop: boolean;\n /** Is large desktop (>= 1280px) */\n isLargeDesktop: boolean;\n}\n\n/**\n * Breakpoint definitions (following MUI defaults).\n */\nexport interface Breakpoints {\n xs: number;\n sm: number;\n md: number;\n lg: number;\n xl: number;\n}\n\n/**\n * Default breakpoints (MUI defaults).\n */\nconst defaultBreakpoints: Breakpoints = {\n xs: 0,\n sm: 600,\n md: 900,\n lg: 1200,\n xl: 1536,\n};\n\n/**\n * Options for useWindowSize hook.\n */\nexport interface UseWindowSizeOptions {\n /** Custom breakpoints */\n breakpoints?: Partial<Breakpoints>;\n /** Debounce delay in ms (default: 100) */\n debounce?: number;\n /** Initial width for SSR (default: 1200) */\n initialWidth?: number;\n /** Initial height for SSR (default: 800) */\n initialHeight?: number;\n}\n\n/**\n * useWindowSize - Hook for tracking window dimensions.\n *\n * @example\n * ```tsx\n * // Basic usage\n * const { width, height, isMobile, isDesktop } = useWindowSize();\n *\n * // Responsive rendering\n * if (isMobile) {\n * return <MobileLayout />;\n * }\n * return <DesktopLayout />;\n *\n * // Responsive columns\n * const columns = isMobile ? 1 : isTablet ? 2 : 4;\n *\n * // Custom breakpoints\n * const { isMobile } = useWindowSize({\n * breakpoints: { sm: 768 }\n * });\n * ```\n */\nexport function useWindowSize(options: UseWindowSizeOptions = {}): WindowSize {\n const { breakpoints: customBreakpoints, debounce = 100, initialWidth = 1200, initialHeight = 800 } = options;\n\n const breakpoints = { ...defaultBreakpoints, ...customBreakpoints };\n\n const getSize = useCallback((): WindowSize => {\n if (typeof window === 'undefined') {\n return {\n width: initialWidth,\n height: initialHeight,\n isMobile: initialWidth < breakpoints.sm,\n isTablet: initialWidth >= breakpoints.sm && initialWidth < breakpoints.md,\n isDesktop: initialWidth >= breakpoints.md,\n isLargeDesktop: initialWidth >= breakpoints.lg,\n };\n }\n\n const width = window.innerWidth;\n const height = window.innerHeight;\n\n return {\n width,\n height,\n isMobile: width < breakpoints.sm,\n isTablet: width >= breakpoints.sm && width < breakpoints.md,\n isDesktop: width >= breakpoints.md,\n isLargeDesktop: width >= breakpoints.lg,\n };\n }, [breakpoints.sm, breakpoints.md, breakpoints.lg, initialWidth, initialHeight]);\n\n const [size, setSize] = useState<WindowSize>(getSize);\n\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (typeof window === 'undefined') return undefined;\n\n const handleResize = () => {\n if (debounce > 0) {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = setTimeout(() => {\n setSize(getSize());\n }, debounce);\n } else {\n setSize(getSize());\n }\n };\n\n // Set initial size\n setSize(getSize());\n\n window.addEventListener('resize', handleResize);\n\n return () => {\n window.removeEventListener('resize', handleResize);\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, [debounce, getSize]);\n\n return size;\n}\n\n/**\n * Return type for useResponsiveQuery hook.\n */\nexport type UseResponsiveQueryReturn = boolean;\n\n/**\n * useResponsiveQuery - Hook for CSS media query matching.\n *\n * Note: For the simpler MUI-style useMediaQuery, see @omnitron-dev/prism/core.\n * This hook provides a standalone implementation without MUI dependency.\n *\n * @example\n * ```tsx\n * // Direct media query\n * const prefersDark = useResponsiveQuery('(prefers-color-scheme: dark)');\n * const isRetina = useResponsiveQuery('(min-resolution: 2dppx)');\n *\n * // Responsive\n * const isLargeScreen = useResponsiveQuery('(min-width: 1200px)');\n * ```\n */\nexport function useResponsiveQuery(query: string): UseResponsiveQueryReturn {\n const [matches, setMatches] = useState(() => {\n if (typeof window === 'undefined') return false;\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return undefined;\n\n const mediaQuery = window.matchMedia(query);\n\n const handleChange = (event: MediaQueryListEvent) => {\n setMatches(event.matches);\n };\n\n // Set initial value\n setMatches(mediaQuery.matches);\n\n // Modern browsers\n if (mediaQuery.addEventListener) {\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }\n\n // Fallback for older browsers\n mediaQuery.addListener(handleChange);\n return () => mediaQuery.removeListener(handleChange);\n }, [query]);\n\n return matches;\n}\n\n/**\n * useBreakpoint - Hook for checking current breakpoint.\n *\n * @example\n * ```tsx\n * const breakpoint = useBreakpoint();\n *\n * // Current breakpoint name\n * console.log(breakpoint); // 'md'\n *\n * // Check specific breakpoint\n * const { isUp, isDown, isOnly, isBetween } = useBreakpointChecks();\n *\n * if (isUp('md')) {\n * // Screen is md or larger\n * }\n * ```\n */\nexport function useBreakpoint(customBreakpoints?: Partial<Breakpoints>): 'xs' | 'sm' | 'md' | 'lg' | 'xl' {\n const breakpoints = { ...defaultBreakpoints, ...customBreakpoints };\n const { width } = useWindowSize({ breakpoints: customBreakpoints });\n\n if (width >= breakpoints.xl) return 'xl';\n if (width >= breakpoints.lg) return 'lg';\n if (width >= breakpoints.md) return 'md';\n if (width >= breakpoints.sm) return 'sm';\n return 'xs';\n}\n\n/**\n * Return type for useBreakpointChecks hook.\n */\nexport interface BreakpointChecks {\n /** Check if width is >= breakpoint */\n isUp: (breakpoint: keyof Breakpoints) => boolean;\n /** Check if width is < breakpoint */\n isDown: (breakpoint: keyof Breakpoints) => boolean;\n /** Check if width is within breakpoint range */\n isOnly: (breakpoint: keyof Breakpoints) => boolean;\n /** Check if width is between two breakpoints */\n isBetween: (start: keyof Breakpoints, end: keyof Breakpoints) => boolean;\n}\n\nconst orderedBreakpoints: (keyof Breakpoints)[] = ['xs', 'sm', 'md', 'lg', 'xl'];\n\nconst getNextBreakpoint = (bp: keyof Breakpoints): keyof Breakpoints | null => {\n const index = orderedBreakpoints.indexOf(bp);\n return index < orderedBreakpoints.length - 1 ? orderedBreakpoints[index + 1] : null;\n};\n\n\n/**\n * useBreakpointChecks - Hook for advanced breakpoint checking.\n *\n * @example\n * ```tsx\n * const { isUp, isDown, isOnly, isBetween } = useBreakpointChecks();\n *\n * isUp('md'); // true if >= 900px\n * isDown('lg'); // true if < 1200px\n * isOnly('md'); // true if 900px - 1199px\n * isBetween('sm', 'lg'); // true if 600px - 1199px\n * ```\n */\nexport function useBreakpointChecks(customBreakpoints?: Partial<Breakpoints>): BreakpointChecks {\n // Memoize breakpoints to prevent callback recreation on every render\n const breakpoints = useMemo(() => ({ ...defaultBreakpoints, ...customBreakpoints }), [customBreakpoints]);\n const { width } = useWindowSize({ breakpoints: customBreakpoints });\n\n const isUp = useCallback(\n (breakpoint: keyof Breakpoints): boolean => width >= breakpoints[breakpoint],\n [width, breakpoints]\n );\n\n const isDown = useCallback(\n (breakpoint: keyof Breakpoints): boolean => width < breakpoints[breakpoint],\n [width, breakpoints]\n );\n\n const isOnly = useCallback(\n (breakpoint: keyof Breakpoints): boolean => {\n const next = getNextBreakpoint(breakpoint);\n const min = breakpoints[breakpoint];\n const max = next ? breakpoints[next] : Infinity;\n return width >= min && width < max;\n },\n [width, breakpoints]\n );\n\n const isBetween = useCallback(\n (start: keyof Breakpoints, end: keyof Breakpoints): boolean =>\n width >= breakpoints[start] && width < breakpoints[end],\n [width, breakpoints]\n );\n\n return { isUp, isDown, isOnly, isBetween };\n}\n","'use client';\n\n/**\n * useClientRect Hook\n *\n * Gets bounding client rect and scroll dimensions of a DOM element.\n * SSR-safe with automatic updates on resize/scroll.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useState, useCallback, useEffect, useRef, type RefObject } from 'react';\n\n/**\n * Scroll element dimensions.\n */\nexport interface ScrollElValue {\n /** Scrollable width */\n scrollWidth: number;\n /** Scrollable height */\n scrollHeight: number;\n}\n\n/**\n * DOMRect values (SSR-safe).\n */\nexport interface DOMRectValue {\n top: number;\n right: number;\n bottom: number;\n left: number;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Return type for useClientRect hook.\n */\nexport interface UseClientRectReturn<T extends HTMLElement = HTMLElement> extends DOMRectValue, ScrollElValue {\n /** Ref to attach to the target element */\n elementRef: RefObject<T | null>;\n /** Force update measurements */\n update: () => void;\n}\n\n/**\n * Default values for SSR and when element is not available.\n */\nconst defaultValues: DOMRectValue & ScrollElValue = {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n scrollWidth: 0,\n scrollHeight: 0,\n};\n\n/**\n * useClientRect - Hook to get bounding rect and scroll dimensions.\n *\n * @example\n * ```tsx\n * // Basic usage - auto-creates ref\n * const { elementRef, width, height, top, left } = useClientRect();\n *\n * return (\n * <div ref={elementRef}>\n * Width: {width}, Height: {height}\n * </div>\n * );\n *\n * // With existing ref\n * const myRef = useRef<HTMLDivElement>(null);\n * const { width, scrollWidth } = useClientRect(myRef);\n *\n * // Listen to scroll events\n * const { y, scrollHeight } = useClientRect(ref, 'scroll');\n *\n * // Calculate scroll progress\n * const progress = y / (scrollHeight - height);\n * ```\n */\nexport function useClientRect<T extends HTMLElement = HTMLElement>(\n inputRef?: RefObject<T | null>,\n eventType?: 'scroll' | 'resize'\n): UseClientRectReturn<T> {\n const internalRef = useRef<T>(null);\n const elementRef = (inputRef ?? internalRef) as RefObject<T | null>;\n\n const [rect, setRect] = useState<DOMRectValue & ScrollElValue>(defaultValues);\n\n const update = useCallback(() => {\n const element = elementRef.current;\n\n if (!element) {\n setRect(defaultValues);\n return;\n }\n\n const domRect = element.getBoundingClientRect();\n\n setRect({\n top: domRect.top,\n right: domRect.right,\n bottom: domRect.bottom,\n left: domRect.left,\n x: domRect.x,\n y: domRect.y,\n width: domRect.width,\n height: domRect.height,\n scrollWidth: element.scrollWidth,\n scrollHeight: element.scrollHeight,\n });\n }, [elementRef]);\n\n useEffect(() => {\n const element = elementRef.current;\n\n // Initial measurement\n update();\n\n if (!element || typeof window === 'undefined') return undefined;\n\n // Observe resize with ResizeObserver\n const resizeObserver = new ResizeObserver(() => {\n update();\n });\n resizeObserver.observe(element);\n\n // Optional event listener\n const target = eventType === 'scroll' ? element : window;\n const event = eventType ?? 'resize';\n\n const handleEvent = () => {\n update();\n };\n\n target.addEventListener(event, handleEvent, { passive: true });\n\n return () => {\n resizeObserver.disconnect();\n target.removeEventListener(event, handleEvent);\n };\n }, [elementRef, eventType, update]);\n\n return {\n ...rect,\n elementRef,\n update,\n };\n}\n","'use client';\n\n/**\n * usePopoverHover Hook\n *\n * Manages hover-based popover state with proper enter/leave handling.\n * Different from click-based popovers - opens on mouse enter, closes on leave.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useState, useCallback, useRef, type RefObject, type Dispatch, type SetStateAction } from 'react';\n\n/**\n * Return type for usePopoverHover hook.\n */\nexport interface UsePopoverHoverReturn<T extends HTMLElement = HTMLElement> {\n /** Whether the popover is open */\n open: boolean;\n /** The element the popover is anchored to (for MUI Popover) */\n anchorEl: T | null;\n /** Handler for mouse enter - opens the popover */\n onOpen: () => void;\n /** Handler for mouse leave - closes the popover */\n onClose: () => void;\n /** Ref to attach to the trigger element */\n elementRef: RefObject<T | null>;\n /** Manual control of open state */\n setOpen: Dispatch<SetStateAction<boolean>>;\n}\n\n/**\n * usePopoverHover - Hook for hover-based popover management.\n *\n * This hook is SSR-safe. It doesn't access browser APIs directly.\n * During SSR, elementRef.current is null and open defaults to false,\n * so anchorEl will always be null on the server.\n *\n * @example\n * ```tsx\n * // Basic usage\n * const { open, anchorEl, onOpen, onClose, elementRef } = usePopoverHover<HTMLButtonElement>();\n *\n * return (\n * <>\n * <Button\n * ref={elementRef}\n * onMouseEnter={onOpen}\n * onMouseLeave={onClose}\n * >\n * Hover me\n * </Button>\n * <Popover\n * open={open}\n * anchorEl={anchorEl}\n * onClose={onClose}\n * anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n * >\n * <Typography sx={{ p: 2 }}>Popover content</Typography>\n * </Popover>\n * </>\n * );\n *\n * // With existing ref\n * const myRef = useRef<HTMLDivElement>(null);\n * const { open, onOpen, onClose } = usePopoverHover(myRef);\n *\n * // With delay (using inline)\n * const { open, anchorEl, elementRef, setOpen } = usePopoverHover();\n * const timeoutRef = useRef<NodeJS.Timeout>();\n *\n * const handleOpen = () => {\n * clearTimeout(timeoutRef.current);\n * setOpen(true);\n * };\n *\n * const handleClose = () => {\n * timeoutRef.current = setTimeout(() => setOpen(false), 200);\n * };\n * ```\n */\nexport function usePopoverHover<T extends HTMLElement = HTMLElement>(\n inputRef?: RefObject<T | null>\n): UsePopoverHoverReturn<T> {\n const internalRef = useRef<T>(null);\n const elementRef = (inputRef ?? internalRef) as RefObject<T | null>;\n\n const [open, setOpen] = useState(false);\n\n const onOpen = useCallback(() => {\n setOpen(true);\n }, []);\n\n const onClose = useCallback(() => {\n setOpen(false);\n }, []);\n\n // anchorEl is the current element when open, null when closed\n const anchorEl = open ? elementRef.current : null;\n\n return {\n open,\n anchorEl,\n onOpen,\n onClose,\n elementRef,\n setOpen,\n };\n}\n","/**\n * Cookie Utilities\n *\n * Type-safe cookie management with JSON serialization.\n *\n * @module utils\n */\n\n/**\n * Cookie options for setting cookies.\n */\nexport interface CookieOptions {\n /** Enable secure flag (HTTPS only) */\n secure?: boolean;\n /** Days until expiration */\n daysUntilExpiration?: number;\n /** SameSite policy */\n sameSite?: 'strict' | 'lax' | 'none';\n /** Cookie domain */\n domain?: string;\n /** Cookie path */\n path?: string;\n}\n\n/**\n * Check if cookies are available.\n *\n * @returns {boolean} True if cookies are available\n */\nexport function cookiesAvailable(): boolean {\n if (typeof document === 'undefined') {\n return false;\n }\n\n try {\n document.cookie = '__test__=1';\n const result = document.cookie.includes('__test__=1');\n document.cookie = '__test__=; expires=Thu, 01 Jan 1970 00:00:00 GMT';\n return result;\n } catch {\n return false;\n }\n}\n\n/**\n * Get a cookie value with JSON parsing.\n *\n * @template T - Type of the stored value\n * @param {string} key - Cookie name\n * @returns {T | null} Parsed value or null\n *\n * @example\n * ```ts\n * const user = getCookie<User>('user');\n * ```\n */\nexport function getCookie<T>(key: string): T | null {\n if (typeof document === 'undefined') {\n return null;\n }\n\n try {\n const name = `${key}=`;\n const decodedCookie = decodeURIComponent(document.cookie);\n const cookies = decodedCookie.split(';');\n\n for (const cookie of cookies) {\n const c = cookie.trim();\n if (c.startsWith(name)) {\n const value = c.substring(name.length);\n return JSON.parse(value) as T;\n }\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Set a cookie with JSON serialization.\n *\n * @template T - Type of the value\n * @param {string} key - Cookie name\n * @param {T} value - Value to store\n * @param {CookieOptions} [options] - Cookie options\n *\n * @example\n * ```ts\n * setCookie('user', { name: 'John' }, { daysUntilExpiration: 7 });\n * ```\n */\nexport function setCookie<T>(key: string, value: T, options: CookieOptions = {}): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n const { secure = false, daysUntilExpiration = 30, sameSite = 'lax', domain, path = '/' } = options;\n\n try {\n const serializedValue = JSON.stringify(value);\n let cookieString = `${key}=${encodeURIComponent(serializedValue)}`;\n\n if (daysUntilExpiration) {\n const date = new Date();\n date.setTime(date.getTime() + daysUntilExpiration * 24 * 60 * 60 * 1000);\n cookieString += `; expires=${date.toUTCString()}`;\n }\n\n cookieString += `; path=${path}`;\n cookieString += `; SameSite=${sameSite}`;\n\n if (secure) {\n cookieString += '; Secure';\n }\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n document.cookie = cookieString;\n } catch (error) {\n console.warn(`Failed to set cookie \"${key}\":`, error);\n }\n}\n\n/**\n * Remove a cookie.\n *\n * @param {string} key - Cookie name\n * @param {Pick<CookieOptions, 'domain' | 'path'>} [options] - Cookie options\n *\n * @example\n * ```ts\n * removeCookie('user');\n * ```\n */\nexport function removeCookie(key: string, options: Pick<CookieOptions, 'domain' | 'path'> = {}): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n const { domain, path = '/' } = options;\n\n let cookieString = `${key}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n document.cookie = cookieString;\n}\n","'use client';\n\n/**\n * useCookies Hook\n *\n * Manages state with cookies. Supports both primitive values\n * and objects with partial updates.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useMemo, useState, useEffect, useCallback } from 'react';\nimport type { CookieOptions } from '../utils/cookies.js';\nimport { setCookie, getCookie, removeCookie } from '../utils/cookies.js';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Options for useCookies hook.\n */\nexport interface UseCookiesOptions extends CookieOptions {\n /**\n * If true, initializes the cookie with the initial value if not set.\n * @default true\n */\n initializeWithValue?: boolean;\n}\n\n/**\n * Return type for useCookies hook.\n */\nexport interface UseCookiesReturn<T> {\n /** Current state value */\n state: T;\n /** Reset state to initial value and remove cookie */\n resetState: (defaultState?: T) => void;\n /** Update the entire state or merge partial state (for objects) */\n setState: (updateState: T | Partial<T>) => void;\n /** Update a specific field in an object state */\n setField: <K extends keyof T>(name: K, updateValue: T[K]) => void;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Hook to manage state with cookies.\n *\n * Automatically syncs state with cookies and supports:\n * - Primitive values (string, number, boolean)\n * - Object values with partial updates\n * - Type-safe field updates\n *\n * @template T - Type of the state value\n * @param key - Cookie name\n * @param initialState - Initial state value\n * @param options - Cookie options\n * @returns State and update functions\n *\n * @example\n * ```tsx\n * // Primitive value\n * const { state, setState, resetState } = useCookies('theme', 'light');\n *\n * // Object value with partial updates\n * const { state, setState, setField, resetState } = useCookies('user', {\n * name: '',\n * age: 0,\n * preferences: { notifications: true },\n * });\n *\n * // Update single field\n * setField('name', 'John');\n *\n * // Partial update\n * setState({ age: 25 });\n *\n * // Reset to initial value\n * resetState();\n * ```\n */\nexport function useCookies<T>(key: string, initialState: T, options?: UseCookiesOptions): UseCookiesReturn<T> {\n const { initializeWithValue = true, ...cookieOptions } = options ?? {};\n const [state, setStateInternal] = useState<T>(initialState);\n\n // Initialize from cookie on mount\n useEffect(() => {\n const storedValue = getCookie<T>(key);\n const isObject = initialState !== null && typeof initialState === 'object';\n\n if (storedValue !== null) {\n if (isObject) {\n // Merge stored value with initial state for object types\n setStateInternal((prev) => ({ ...prev, ...storedValue }));\n } else {\n setStateInternal(storedValue);\n }\n } else if (initializeWithValue) {\n // Initialize cookie with initial value if not set\n setCookie(key, initialState, cookieOptions);\n }\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const isObjectState = initialState !== null && typeof initialState === 'object';\n\n const updateState = useCallback(\n (newState: T | Partial<T>) => {\n if (isObjectState) {\n // The object branch writes the cookie INSIDE the updater and the\n // scalar branch writes it outside — an asymmetry that reads like an\n // oversight and is not. Merging needs the previous value, and taking\n // it from a ref instead would break composition: two `setField`\n // calls in one handler would both merge into the same snapshot and\n // the first field would be lost. See `useLocalStorage.setValue` for\n // the same trade-off and what it costs.\n setStateInternal((prev) => {\n const updatedState = { ...prev, ...newState } as T;\n setCookie(key, updatedState, cookieOptions);\n return updatedState;\n });\n } else {\n setCookie(key, newState as T, cookieOptions);\n setStateInternal(newState as T);\n }\n },\n [cookieOptions, isObjectState, key]\n );\n\n const updateField = useCallback(\n <K extends keyof T>(fieldName: K, updateValue: T[K]) => {\n if (isObjectState) {\n updateState({ [fieldName]: updateValue } as unknown as Partial<T>);\n } else {\n console.warn('[useCookies] setField is only available for object states. Use setState instead.');\n }\n },\n [isObjectState, updateState]\n );\n\n const resetState = useCallback(\n (defaultState?: T) => {\n setStateInternal(defaultState ?? initialState);\n removeCookie(key, { path: cookieOptions.path, domain: cookieOptions.domain });\n },\n [initialState, key, cookieOptions.path, cookieOptions.domain]\n );\n\n return useMemo(\n () => ({\n state,\n setState: updateState,\n setField: updateField,\n resetState,\n }),\n [state, updateState, updateField, resetState]\n );\n}\n","'use client';\n\n/**\n * useDoubleClick Hook\n *\n * Differentiates between single and double click events.\n * Single click is delayed to ensure it's not a double click.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport type { MouseEvent, SyntheticEvent } from 'react';\nimport { useRef, useCallback, useEffect } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Props for useDoubleClick hook.\n */\nexport interface UseDoubleClickProps {\n /**\n * Timeout in milliseconds to differentiate between single and double clicks.\n * @default 250\n */\n timeout?: number;\n /** Handler for single click (optional) */\n click?: (event: SyntheticEvent) => void;\n /** Handler for double click (required) */\n doubleClick: (event: SyntheticEvent) => void;\n}\n\n/**\n * Return type - a click handler function.\n */\nexport type UseDoubleClickReturn = (event: MouseEvent<HTMLElement>) => void;\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Hook to handle single and double click events on an element.\n *\n * Uses event.detail to detect click count:\n * - detail === 1: single click (delayed by timeout)\n * - detail === 2: double click (immediate)\n *\n * The single click handler is called after a timeout, but only if\n * no second click occurs within that time.\n *\n * @param props - Hook configuration\n * @returns Click handler function to attach to element\n *\n * @example\n * ```tsx\n * function FileItem({ file }) {\n * const handleClick = useDoubleClick({\n * click: () => selectFile(file),\n * doubleClick: () => openFile(file),\n * timeout: 300,\n * });\n *\n * return (\n * <div onClick={handleClick}>\n * {file.name}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Double-click only (no single click handler)\n * const handleClick = useDoubleClick({\n * doubleClick: () => console.log('Double clicked!'),\n * });\n * ```\n */\nexport function useDoubleClick({ click, doubleClick, timeout = 250 }: UseDoubleClickProps): UseDoubleClickReturn {\n const clickTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const clearClickTimeout = useCallback(() => {\n if (clickTimeout.current) {\n clearTimeout(clickTimeout.current);\n clickTimeout.current = null;\n }\n }, []);\n\n const handleEvent = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n clearClickTimeout();\n\n // Single click - delay execution\n if (click && event.detail === 1) {\n // React 17+ does not pool synthetic events, so the event reference remains valid\n clickTimeout.current = setTimeout(() => {\n click(event);\n }, timeout);\n }\n\n // Double click (or any even number of clicks) - execute immediately\n if (event.detail % 2 === 0) {\n doubleClick(event);\n }\n },\n [click, doubleClick, timeout, clearClickTimeout]\n );\n\n // Cleanup timeout on unmount to prevent memory leaks\n useEffect(\n () => () => {\n clearClickTimeout();\n },\n [clearClickTimeout]\n );\n\n return handleEvent;\n}\n","'use client';\n\n/**\n * useBackToTop Hook\n *\n * Manages visibility of a \"Back to Top\" button based on scroll position.\n * Supports both percentage-based and pixel-based visibility thresholds.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport type { Dispatch, SetStateAction } from 'react';\nimport { useMemo, useState, useEffect, useCallback, useRef } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Return type for useBackToTop hook.\n */\nexport interface UseBackToTopReturn {\n /** Whether the \"Back to Top\" button should be visible */\n isVisible: boolean;\n /** Function to scroll smoothly to top */\n onBackToTop: () => void;\n /** Manual visibility control */\n setIsVisible: Dispatch<SetStateAction<boolean>>;\n}\n\n/**\n * Parsed threshold value.\n */\ninterface ParsedThreshold {\n value: number;\n type: 'percentage' | 'pixels';\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Parse threshold input value.\n *\n * @param input - Percentage string (e.g., '90%') or pixel number\n * @returns Parsed threshold with type\n * @throws Error if invalid percentage string\n */\nfunction parseThreshold(input: string | number): ParsedThreshold {\n if (typeof input === 'string') {\n if (!input.endsWith('%')) {\n throw new Error('[useBackToTop] String threshold must end with % (e.g., \"90%\")');\n }\n const value = Number(input.slice(0, -1));\n if (isNaN(value)) {\n throw new Error('[useBackToTop] Invalid percentage value');\n }\n return { value, type: 'percentage' };\n }\n\n return { value: input, type: 'pixels' };\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Hook to manage the visibility of a \"Back to Top\" button based on scroll position.\n *\n * Two modes are supported:\n * - **Percentage mode**: Button becomes visible when scrolled past N% of the page.\n * Pass a string like '90%' as the threshold.\n * - **Pixel mode**: Button becomes visible when within N pixels of the bottom.\n * Pass a number like 80 as the threshold.\n *\n * @param threshold - Visibility threshold\n * - String with '%' (e.g., '90%'): Show when scroll progress >= this percentage\n * - Number (e.g., 80): Show when within this many pixels from bottom\n * @param debounce - Whether to debounce the scroll handler (100ms)\n * @returns Visibility state and scroll control functions\n *\n * @example\n * ```tsx\n * // Show when scrolled 90% down the page\n * const { isVisible, onBackToTop } = useBackToTop('90%');\n *\n * // Show when within 80px of the bottom\n * const { isVisible, onBackToTop } = useBackToTop(80);\n *\n * // With debouncing for better performance\n * const { isVisible, onBackToTop } = useBackToTop('85%', true);\n *\n * return (\n * <Fade in={isVisible}>\n * <Fab onClick={onBackToTop} sx={{ position: 'fixed', bottom: 16, right: 16 }}>\n * <KeyboardArrowUpIcon />\n * </Fab>\n * </Fade>\n * );\n * ```\n */\nexport function useBackToTop(threshold: string | number = '90%', debounce: boolean = false): UseBackToTopReturn {\n const [isVisible, setIsVisible] = useState(false);\n\n const parsedThreshold = useMemo(() => parseThreshold(threshold), [threshold]);\n\n const handleScroll = useCallback(() => {\n // SSR guard - only run on client\n if (typeof window === 'undefined') return;\n\n const windowHeight = window.innerHeight;\n const scrollY = Math.round(window.scrollY);\n const documentHeight = document.body.offsetHeight;\n\n // Calculate scroll progress (0-100)\n const maxScroll = documentHeight - windowHeight;\n const scrollProgress = maxScroll > 0 ? Math.round((scrollY / maxScroll) * 100) : 0;\n\n if (parsedThreshold.type === 'percentage') {\n // Percentage mode: visible when scroll progress >= threshold\n setIsVisible(scrollProgress >= parsedThreshold.value);\n } else {\n // Pixel mode: visible when within threshold pixels from bottom\n const distanceFromBottom = documentHeight - windowHeight - scrollY;\n setIsVisible(distanceFromBottom <= parsedThreshold.value);\n }\n }, [parsedThreshold]);\n\n // Debounced scroll handler with cleanup support\n const debounceTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const debouncedHandleScroll = useCallback(() => {\n if (debounceTimeoutRef.current !== null) clearTimeout(debounceTimeoutRef.current);\n debounceTimeoutRef.current = setTimeout(handleScroll, 100);\n }, [handleScroll]);\n\n useEffect(() => {\n // SSR guard\n if (typeof window === 'undefined') return undefined;\n\n const scrollHandler = debounce ? debouncedHandleScroll : handleScroll;\n\n // Check initial position\n handleScroll();\n\n window.addEventListener('scroll', scrollHandler, { passive: true });\n\n return () => {\n window.removeEventListener('scroll', scrollHandler);\n if (debounceTimeoutRef.current !== null) clearTimeout(debounceTimeoutRef.current);\n };\n }, [debounce, debouncedHandleScroll, handleScroll]);\n\n const onBackToTop = useCallback(() => {\n // SSR guard\n if (typeof window === 'undefined') return;\n window.scrollTo({ top: 0, behavior: 'smooth' });\n }, []);\n\n return { isVisible, onBackToTop, setIsVisible };\n}\n","'use client';\n\n/**\n * useCountdownSeconds Hook\n *\n * Simple countdown timer in seconds. Ideal for OTP resend timers,\n * session timeouts, and other time-limited operations.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport type { Dispatch, SetStateAction } from 'react';\nimport { useState, useEffect, useCallback, useMemo } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Return type for useCountdownSeconds hook.\n */\nexport interface UseCountdownSecondsReturn {\n /** Current countdown value in seconds */\n value: number;\n /** Start the countdown */\n start: () => void;\n /** Reset countdown to initial value and stop */\n reset: () => void;\n /** Whether countdown is currently active */\n isCounting: boolean;\n /** Manually set the countdown value */\n setValue: Dispatch<SetStateAction<number>>;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Hook to create a simple countdown timer in seconds.\n *\n * Perfect for:\n * - OTP resend timers\n * - Session timeout warnings\n * - Rate limiting UI feedback\n * - Game timers\n *\n * @param initialSeconds - Initial countdown value in seconds\n * @returns Countdown state and control functions\n *\n * @example\n * ```tsx\n * // OTP resend timer\n * function OTPForm() {\n * const { value, start, reset, isCounting } = useCountdownSeconds(60);\n *\n * const handleResend = async () => {\n * await resendOTP();\n * reset();\n * start();\n * };\n *\n * return (\n * <div>\n * <input placeholder=\"Enter OTP\" />\n * <button onClick={handleResend} disabled={isCounting}>\n * {isCounting ? `Resend in ${value}s` : 'Resend OTP'}\n * </button>\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Session timeout warning\n * function SessionWarning() {\n * const { value, start, isCounting } = useCountdownSeconds(30);\n *\n * useEffect(() => {\n * if (showWarning) start();\n * }, [showWarning]);\n *\n * useEffect(() => {\n * if (value === 0) logout();\n * }, [value]);\n *\n * return isCounting && (\n * <Alert severity=\"warning\">\n * Session expires in {value} seconds\n * </Alert>\n * );\n * }\n * ```\n */\nexport function useCountdownSeconds(initialSeconds: number): UseCountdownSecondsReturn {\n const [value, setValue] = useState(initialSeconds);\n const [isCounting, setIsCounting] = useState(false);\n\n const start = useCallback(() => {\n setIsCounting(true);\n }, []);\n\n const reset = useCallback(() => {\n setIsCounting(false);\n setValue(initialSeconds);\n }, [initialSeconds]);\n\n useEffect(() => {\n if (!isCounting) return undefined;\n\n // The updater only computes. Stopping used to happen inside it —\n // `setIsCounting(false)` from within a `setValue` updater — and an\n // updater must be pure: React is entitled to run it more than once, and\n // under `StrictMode` it does so deliberately. Nothing visible went wrong\n // here because stopping twice is stopping once, but the sibling hook\n // `useCountdown` had the same shape around an `onComplete` callback and\n // fired it four times.\n const intervalId = setInterval(() => {\n setValue((prev) => Math.max(0, prev - 1));\n }, 1000);\n\n return () => {\n clearInterval(intervalId);\n };\n }, [isCounting]);\n\n // Reaching zero is what stops the countdown, and that is a decision about\n // the state after it settles rather than part of computing it.\n useEffect(() => {\n if (value === 0) setIsCounting(false);\n }, [value]);\n\n return useMemo(\n () => ({\n value,\n setValue,\n isCounting,\n start,\n reset,\n }),\n [value, isCounting, start, reset]\n );\n}\n","'use client';\n\n/**\n * useCountdownDate Hook\n *\n * Creates a countdown timer to a target date, returning formatted\n * days, hours, minutes, and seconds.\n *\n * Ported from minimal-shared for Prism design system.\n *\n * @module hooks/use-countdown-date\n */\n\nimport { useState, useEffect, useCallback } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Return type for useCountdownDate hook.\n */\nexport type UseCountdownDateReturn = {\n /** Formatted days (with leading zero) */\n days: string;\n /** Formatted hours (with leading zero) */\n hours: string;\n /** Formatted minutes (with leading zero) */\n minutes: string;\n /** Formatted seconds (with leading zero) */\n seconds: string;\n};\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Formats a time value to ensure it is always two digits.\n */\nfunction formatTime(value: number): string {\n return String(value).length === 1 ? `0${value}` : `${value}`;\n}\n\n/**\n * Calculates the time difference between a future date and the current date.\n */\nfunction calculateTimeDifference(\n futureDate: Date,\n currentDate: Date\n): {\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n} {\n const distance = futureDate.getTime() - currentDate.getTime();\n\n if (distance < 0) {\n return { days: 0, hours: 0, minutes: 0, seconds: 0 };\n }\n\n return {\n days: Math.floor(distance / (1000 * 60 * 60 * 24)),\n hours: Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)),\n minutes: Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)),\n seconds: Math.floor((distance % (1000 * 60)) / 1000),\n };\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Custom hook to create a countdown timer to a target date.\n *\n * @param targetDate - The target date to count down to\n * @param placeholder - The placeholder value to display before the countdown starts (default: '- -')\n *\n * @returns An object containing the current countdown values in days, hours, minutes, and seconds\n *\n * @example\n * ```tsx\n * function SaleCountdown() {\n * const { days, hours, minutes, seconds } = useCountdownDate(\n * new Date('2024-12-31T23:59:59')\n * );\n *\n * return (\n * <div>\n * <span>{days}d</span>\n * <span>{hours}h</span>\n * <span>{minutes}m</span>\n * <span>{seconds}s</span>\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With custom placeholder\n * const countdown = useCountdownDate(launchDate, '--');\n * ```\n */\nexport function useCountdownDate(targetDate: Date, placeholder = '- -'): UseCountdownDateReturn {\n const [value, setValue] = useState<UseCountdownDateReturn>({\n days: placeholder,\n hours: placeholder,\n minutes: placeholder,\n seconds: placeholder,\n });\n\n /**\n * The instant, not the object holding it.\n *\n * `targetDate` used to be the dependency directly, and a `Date` is compared\n * by identity. The documented call — `useCountdownDate(new Date('…'))` —\n * builds a fresh one on every render, so the callback changed, the effect\n * re-armed, `handleUpdate` ran, `setValue` produced a new object, and that\n * re-rendered the component: an unbounded loop measured at **5003 renders\n * in 200 ms** before it was capped. The countdown displayed correctly\n * throughout, which is why it could have shipped as \"sluggish page\".\n *\n * A number is compared by value, so the same instant is the same\n * dependency however many `Date` wrappers a caller creates.\n */\n const targetMs = targetDate.getTime();\n\n const handleUpdate = useCallback(() => {\n const now = new Date();\n const { days, hours, minutes, seconds } = calculateTimeDifference(new Date(targetMs), now);\n\n const next = {\n days: formatTime(days),\n hours: formatTime(hours),\n minutes: formatTime(minutes),\n seconds: formatTime(seconds),\n };\n\n // Keep the previous object when nothing changed, so React can bail out.\n // A fresh object every second re-renders the consumer whether or not the\n // display moved — including after the target has passed, when the answer\n // is `00:00:00:00` for as long as the component stays mounted.\n setValue((prev) =>\n prev.days === next.days &&\n prev.hours === next.hours &&\n prev.minutes === next.minutes &&\n prev.seconds === next.seconds\n ? prev\n : next\n );\n }, [targetMs]);\n\n useEffect(() => {\n // Initial update\n handleUpdate();\n\n // Set up interval for updates\n const interval = setInterval(handleUpdate, 1000);\n\n return () => clearInterval(interval);\n }, [handleUpdate]);\n\n return value;\n}\n","'use client';\n\n/**\n * useScrollOffsetTop Hook\n *\n * Manages offset top state based on scroll position.\n * Can track against window or a specific element's offset.\n *\n * This hook is SSR-safe - scroll tracking only runs on the client.\n *\n * Ported from minimal-shared for Prism design system.\n *\n * @module hooks/use-scroll-offset-top\n */\n\nimport type { RefObject } from 'react';\nimport { useRef, useState, useEffect, useCallback, useMemo } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Return type for useScrollOffsetTop hook.\n */\nexport type UseScrollOffsetTopReturn<T extends HTMLElement = HTMLElement> = {\n /** Whether the scroll position is past the offset threshold */\n offsetTop: boolean;\n /** Ref to attach to element for tracking its offset (optional) */\n elementRef: RefObject<T | null>;\n};\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Custom hook to manage the offset top state based on scroll position.\n *\n * Can be used in two ways:\n * 1. Track against a fixed pixel value (window scroll)\n * 2. Track against an element's offset (using returned ref)\n *\n * @param defaultValue - The offset value at which the state changes (default: 0)\n *\n * @returns An object containing offsetTop boolean and elementRef\n *\n * @example\n * ```tsx\n * // Track window scroll against fixed value\n * function StickyHeader() {\n * const { offsetTop } = useScrollOffsetTop(80);\n *\n * return (\n * <AppBar position={offsetTop ? 'fixed' : 'static'}>\n * <Toolbar>Header</Toolbar>\n * </AppBar>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Track scroll against element offset\n * function HeaderWithBanner() {\n * const { offsetTop, elementRef } = useScrollOffsetTop<HTMLDivElement>();\n *\n * return (\n * <>\n * <div ref={elementRef}>Banner Content</div>\n * <AppBar\n * position={offsetTop ? 'fixed' : 'static'}\n * sx={{ top: offsetTop ? 0 : 'auto' }}\n * >\n * <Toolbar>Header</Toolbar>\n * </AppBar>\n * </>\n * );\n * }\n * ```\n */\nexport function useScrollOffsetTop<T extends HTMLElement = HTMLElement>(\n defaultValue: number = 0\n): UseScrollOffsetTopReturn<T> {\n const elementRef = useRef<T | null>(null);\n const [offsetTop, setOffsetTop] = useState<boolean>(false);\n\n const handleScroll = useCallback(() => {\n // SSR guard - only run on client\n if (typeof window === 'undefined') return;\n\n const windowScrollY = window.scrollY;\n\n if (elementRef.current) {\n // Track element offset top\n const elementOffsetTop = elementRef.current.offsetTop;\n setOffsetTop(windowScrollY > elementOffsetTop - defaultValue);\n } else {\n // Track window offset top\n setOffsetTop(windowScrollY > defaultValue);\n }\n }, [defaultValue]);\n\n useEffect(() => {\n // SSR guard\n if (typeof window === 'undefined') return undefined;\n\n // Initial check\n handleScroll();\n\n // Add scroll listener with passive for better performance\n window.addEventListener('scroll', handleScroll, { passive: true });\n\n return () => {\n window.removeEventListener('scroll', handleScroll);\n };\n }, [handleScroll]);\n\n // Memoize return object to prevent unnecessary re-renders\n return useMemo(\n () => ({\n elementRef,\n offsetTop,\n }),\n [offsetTop]\n );\n}\n","'use client';\n\n/**\n * useConfigFromQuery Hook\n *\n * Syncs theme/config settings with URL query parameters.\n * Enables shareable configuration links for demos and previews.\n *\n * Query parameter format: ?preset=luxury&mode=dark&primary=%23FF5630\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useEffect, useCallback, useMemo, useRef, useSyncExternalStore } from 'react';\nimport { useEventCallback } from '@mui/material/utils';\nimport type { ThemePreset, ThemeMode, ThemeDirection, ComponentDensity } from '../types/theme.js';\nimport { PRESET_NAMES } from '../theme/create-theme.js';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Configuration values that can be controlled via URL params.\n */\nexport interface UrlConfigValues {\n /** Theme preset */\n preset?: ThemePreset;\n /** Light/dark/system mode */\n mode?: ThemeMode;\n /** Primary color (hex) */\n primary?: string;\n /** Text direction */\n direction?: ThemeDirection;\n /** Component density */\n density?: ComponentDensity;\n /** Contrast mode */\n contrast?: 'default' | 'high';\n}\n\n/**\n * Options for useConfigFromQuery hook.\n */\nexport interface UseConfigFromQueryOptions {\n /** Query parameter names mapping (default: 'preset', 'mode', 'primary', etc.) */\n paramNames?: {\n preset?: string;\n mode?: string;\n primary?: string;\n direction?: string;\n density?: string;\n contrast?: string;\n };\n /** Callback when config changes from URL */\n onConfigChange?: (config: UrlConfigValues) => void;\n /** Enable two-way sync (updates URL when config changes) */\n syncToUrl?: boolean;\n /** Settings to mirror when syncToUrl is enabled. A shared URL takes precedence on mount. */\n values?: UrlConfigValues;\n}\n\n/**\n * Return type for useConfigFromQuery hook.\n */\nexport interface UseConfigFromQueryReturn {\n /** Parsed config values from URL */\n configFromUrl: UrlConfigValues;\n /** Update URL with new config values */\n updateUrl: (values: Partial<UrlConfigValues>) => void;\n /** Clear all config from URL */\n clearUrl: () => void;\n /** Generate URL with config values */\n generateUrl: (values: Partial<UrlConfigValues>, baseUrl?: string) => string;\n /** Check if URL has any config params */\n hasUrlConfig: boolean;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\nconst DEFAULT_PARAM_NAMES = {\n preset: 'preset',\n mode: 'mode',\n primary: 'primary',\n direction: 'dir',\n density: 'density',\n contrast: 'contrast',\n} as const;\n\nconst configKeys = Object.keys(DEFAULT_PARAM_NAMES) as (keyof UrlConfigValues)[];\nconst configUrlChanged = 'prism:config-url-change';\nconst readSearch = () => window.location.search;\nconst serverSearch = () => '';\n\nfunction subscribeToSearch(onChange: () => void) {\n window.addEventListener('popstate', onChange);\n window.addEventListener(configUrlChanged, onChange);\n return () => {\n window.removeEventListener('popstate', onChange);\n window.removeEventListener(configUrlChanged, onChange);\n };\n}\n\nfunction replaceUrl(url: URL) {\n if (url.href !== window.location.href) {\n window.history.replaceState(window.history.state, '', url);\n window.dispatchEvent(new Event(configUrlChanged));\n }\n}\n\nconst VALID_MODES: ThemeMode[] = ['light', 'dark', 'system'];\nconst VALID_DIRECTIONS: ThemeDirection[] = ['ltr', 'rtl'];\nconst VALID_DENSITIES: ComponentDensity[] = ['compact', 'standard', 'comfortable'];\nconst VALID_CONTRASTS = ['default', 'high'] as const;\n\n// =============================================================================\n// VALIDATORS\n// =============================================================================\n\nfunction isValidPreset(value: string | null): value is ThemePreset {\n return value !== null && PRESET_NAMES.includes(value as ThemePreset);\n}\n\nfunction isValidMode(value: string | null): value is ThemeMode {\n return value !== null && VALID_MODES.includes(value as ThemeMode);\n}\n\nfunction isValidDirection(value: string | null): value is ThemeDirection {\n return value !== null && VALID_DIRECTIONS.includes(value as ThemeDirection);\n}\n\nfunction isValidDensity(value: string | null): value is ComponentDensity {\n return value !== null && VALID_DENSITIES.includes(value as ComponentDensity);\n}\n\nfunction isValidContrast(value: string | null): value is 'default' | 'high' {\n return value !== null && (VALID_CONTRASTS as readonly string[]).includes(value);\n}\n\nfunction isValidHexColor(value: string | null): boolean {\n if (!value) return false;\n return /^#[0-9A-Fa-f]{6}$/.test(value);\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Hook to sync theme configuration with URL query parameters.\n *\n * Enables shareable configuration links for demos, previews, and design reviews.\n *\n * @param options - Hook options\n * @returns Object with URL config parsing and manipulation utilities\n *\n * @example\n * ```tsx\n * import { useConfigFromQuery } from '@omnitron-dev/prism/hooks';\n *\n * function ThemeSettings() {\n * const {\n * configFromUrl,\n * updateUrl,\n * generateUrl,\n * hasUrlConfig,\n * } = useConfigFromQuery({\n * onConfigChange: (config) => {\n * // Apply config to your theme context\n * if (config.preset) setPreset(config.preset);\n * if (config.mode) setMode(config.mode);\n * if (config.primary) setPrimaryColor(config.primary);\n * },\n * });\n *\n * // Generate shareable link\n * const shareUrl = generateUrl({\n * preset: currentPreset,\n * mode: currentMode,\n * primary: currentPrimary,\n * });\n *\n * return (\n * <div>\n * {hasUrlConfig && <Alert>Using config from URL</Alert>}\n * <Button onClick={() => navigator.clipboard.writeText(shareUrl)}>\n * Copy Share Link\n * </Button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useConfigFromQuery(options: UseConfigFromQueryOptions = {}): UseConfigFromQueryReturn {\n const { paramNames, onConfigChange, syncToUrl = false, values } = options;\n const { preset = 'preset', mode = 'mode', primary = 'primary', direction = 'dir', density = 'density', contrast = 'contrast' } = paramNames ?? DEFAULT_PARAM_NAMES;\n const params = useMemo(() => ({ preset, mode, primary, direction, density, contrast }),\n [preset, mode, primary, direction, density, contrast]);\n const search = useSyncExternalStore(subscribeToSearch, readSearch, serverSearch);\n const configFromUrl = useMemo<UrlConfigValues>(() => {\n const searchParams = new URLSearchParams(search);\n const config: UrlConfigValues = {};\n\n const presetValue = searchParams.get(params.preset);\n if (isValidPreset(presetValue)) {\n config.preset = presetValue;\n }\n\n const modeValue = searchParams.get(params.mode);\n if (isValidMode(modeValue)) {\n config.mode = modeValue;\n }\n\n const primaryValue = searchParams.get(params.primary);\n if (isValidHexColor(primaryValue)) {\n config.primary = primaryValue as string;\n }\n\n const directionValue = searchParams.get(params.direction);\n if (isValidDirection(directionValue)) {\n config.direction = directionValue;\n }\n\n const densityValue = searchParams.get(params.density);\n if (isValidDensity(densityValue)) {\n config.density = densityValue;\n }\n\n const contrastValue = searchParams.get(params.contrast);\n if (isValidContrast(contrastValue)) {\n config.contrast = contrastValue;\n }\n\n return config;\n }, [params, search]);\n\n const receivedConfig = useRef(false);\n const notifyConfig = useEventCallback((next: UrlConfigValues) => onConfigChange?.(next));\n useEffect(() => {\n const hasValues = Object.keys(configFromUrl).length > 0;\n if (hasValues || receivedConfig.current) notifyConfig(configFromUrl);\n receivedConfig.current = hasValues;\n }, [configFromUrl, notifyConfig]);\n\n const applyValues = useCallback((url: URL, next: Partial<UrlConfigValues>) => {\n for (const key of configKeys) {\n const value = next[key];\n if (value !== undefined) {\n if (value) url.searchParams.set(params[key], value);\n else url.searchParams.delete(params[key]);\n }\n }\n return url;\n }, [params]);\n\n const updateUrl = useCallback((next: Partial<UrlConfigValues>) => {\n if (typeof window !== 'undefined') replaceUrl(applyValues(new URL(window.location.href), next));\n }, [applyValues]);\n\n const clearUrl = useCallback(() => {\n if (typeof window === 'undefined') return;\n const url = new URL(window.location.href);\n for (const key of configKeys) url.searchParams.delete(params[key]);\n replaceUrl(url);\n }, [params]);\n\n // URL navigation is an independent input. Mirror only changes to the supplied\n // settings, so Back and a shared URL cannot be overwritten by an old render.\n const previousValues = useRef<string | undefined>(undefined);\n useEffect(() => {\n if (!syncToUrl || !values) { previousValues.current = undefined; return; }\n const signature = JSON.stringify(configKeys.map(key => values[key]));\n const previous = previousValues.current;\n previousValues.current = signature;\n if (previous === signature) return;\n if (previous !== undefined || !configKeys.some(key => new URLSearchParams(window.location.search).has(params[key]))) {\n updateUrl(values);\n }\n }, [syncToUrl, values, params, updateUrl]);\n\n const generateUrl = useCallback((next: Partial<UrlConfigValues>, baseUrl?: string) => {\n const origin = typeof window === 'undefined' ? 'http://localhost' : window.location.origin;\n const base = baseUrl ?? (typeof window === 'undefined' ? '' : origin + window.location.pathname);\n const url = applyValues(new URL(base || '/', origin), next);\n if (/^[a-z][a-z\\d+.-]*:/i.test(base)) return url.href;\n if (base.startsWith('//')) return `//${url.host}${url.pathname}${url.search}${url.hash}`;\n return (base ? base.split(/[?#]/, 1)[0] : '') + url.search + url.hash;\n }, [applyValues]);\n\n // Check if URL has any config params\n const hasUrlConfig = Object.keys(configFromUrl).length > 0;\n\n return {\n configFromUrl,\n updateUrl,\n clearUrl,\n generateUrl,\n hasUrlConfig,\n };\n}\n","'use client';\n\n/**\n * useImageDimensions Hook\n *\n * Detects the natural dimensions of an image from a URL.\n *\n * @module hooks/use-image-dimensions\n */\n\nimport { useCallback, useEffect, useState } from 'react';\n\n/**\n * Image dimensions result.\n */\nexport interface ImageDimensions {\n /** Natural width of the image in pixels */\n width: number;\n /** Natural height of the image in pixels */\n height: number;\n /** Aspect ratio (width / height) */\n aspectRatio: number;\n}\n\n/**\n * Return type for useImageDimensions hook.\n */\nexport interface UseImageDimensionsReturn {\n /** Image dimensions (null if not loaded or error) */\n dimensions: ImageDimensions | null;\n /** Loading state */\n loading: boolean;\n /** Error if image failed to load */\n error: Error | null;\n /** Manually retry loading the image */\n retry: () => void;\n}\n\n/**\n * Options for useImageDimensions hook.\n */\nexport interface UseImageDimensionsOptions {\n /** Cross-origin setting for image loading */\n crossOrigin?: 'anonymous' | 'use-credentials';\n /** Timeout in milliseconds (default: 10000) */\n timeout?: number;\n /** Whether to start loading immediately (default: true) */\n immediate?: boolean;\n}\n\n/**\n * useImageDimensions - Detects image dimensions from a URL.\n *\n * Loads an image in memory to get its natural width and height.\n *\n * @example\n * ```tsx\n * function ImagePreview({ src }: { src: string }) {\n * const { dimensions, loading, error } = useImageDimensions(src);\n *\n * if (loading) return <CircularProgress />;\n * if (error) return <Alert severity=\"error\">Failed to load image</Alert>;\n * if (!dimensions) return null;\n *\n * return (\n * <Box>\n * <Typography>\n * {dimensions.width} x {dimensions.height}\n * </Typography>\n * <Typography>\n * Aspect ratio: {dimensions.aspectRatio.toFixed(2)}\n * </Typography>\n * <img\n * src={src}\n * alt=\"preview\"\n * style={{ maxWidth: '100%', aspectRatio: dimensions.aspectRatio }}\n * />\n * </Box>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With manual control\n * function LazyImage({ src }: { src: string }) {\n * const { dimensions, loading, retry } = useImageDimensions(src, {\n * immediate: false,\n * });\n *\n * return (\n * <Box>\n * {!dimensions && !loading && (\n * <Button onClick={retry}>Load dimensions</Button>\n * )}\n * {loading && <CircularProgress />}\n * {dimensions && (\n * <Typography>{dimensions.width} x {dimensions.height}</Typography>\n * )}\n * </Box>\n * );\n * }\n * ```\n *\n * @param src - Image URL to load\n * @param options - Hook options\n * @returns Dimensions, loading state, error, and retry function\n */\nexport function useImageDimensions(\n src: string | null | undefined,\n options: UseImageDimensionsOptions = {}\n): UseImageDimensionsReturn {\n const { crossOrigin, timeout = 10000, immediate = true } = options;\n\n const [dimensions, setDimensions] = useState<ImageDimensions | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const loadImage = useCallback(() => {\n if (!src) {\n setDimensions(null);\n setLoading(false);\n setError(null);\n return undefined;\n }\n\n setLoading(true);\n setError(null);\n\n const img = new Image();\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n let cancelled = false;\n\n const cleanup = () => {\n cancelled = true;\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n img.onload = null;\n img.onerror = null;\n };\n\n img.onload = () => {\n if (cancelled) return;\n cleanup();\n\n const { naturalWidth: width, naturalHeight: height } = img;\n setDimensions({\n width,\n height,\n aspectRatio: height > 0 ? width / height : 1,\n });\n setLoading(false);\n setError(null);\n };\n\n img.onerror = () => {\n if (cancelled) return;\n cleanup();\n\n setDimensions(null);\n setLoading(false);\n setError(new Error(`Failed to load image: ${src}`));\n };\n\n // Set timeout\n timeoutId = setTimeout(() => {\n if (cancelled) return;\n cleanup();\n\n setDimensions(null);\n setLoading(false);\n setError(new Error(`Image load timeout: ${src}`));\n }, timeout);\n\n // Set cross-origin if specified\n if (crossOrigin) {\n img.crossOrigin = crossOrigin;\n }\n\n // Start loading\n img.src = src;\n\n // Return cleanup function for effect\n return cleanup;\n }, [src, crossOrigin, timeout]);\n\n // Auto-load when src changes (if immediate)\n useEffect(() => {\n if (!immediate) return undefined;\n return loadImage();\n }, [loadImage, immediate]);\n\n const retry = useCallback(() => {\n loadImage();\n }, [loadImage]);\n\n return {\n dimensions,\n loading,\n error,\n retry,\n };\n}\n\n/**\n * Get dimensions of multiple images.\n *\n * @example\n * ```tsx\n * // MUI v9 unified the Grid component — the `<Grid item>` shorthand\n * // from v1 is gone; size is expressed via `size={{ xs, sm, md, ... }}`.\n * function Gallery({ urls }: { urls: string[] }) {\n * const results = useMultipleImageDimensions(urls);\n *\n * return (\n * <Grid container>\n * {results.map((result, i) => (\n * <Grid key={urls[i]} size={{ xs: 12, sm: 6, md: 4 }}>\n * {result.loading && <Skeleton />}\n * {result.dimensions && (\n * <img\n * src={urls[i]}\n * style={{ aspectRatio: result.dimensions.aspectRatio }}\n * />\n * )}\n * </Grid>\n * ))}\n * </Grid>\n * );\n * }\n * ```\n */\nexport function useMultipleImageDimensions(\n urls: (string | null | undefined)[],\n options: UseImageDimensionsOptions = {}\n): UseImageDimensionsReturn[] {\n const { crossOrigin, timeout = 10000, immediate = true } = options;\n\n const [results, setResults] = useState<\n Map<string, { dimensions: ImageDimensions | null; loading: boolean; error: Error | null }>\n >(new Map());\n\n const sourcesKey = JSON.stringify([...new Set(urls.filter((url): url is string => Boolean(url)))]);\n useEffect(() => {\n if (!immediate) return undefined;\n\n const cleanups: (() => void)[] = [];\n\n const sources: string[] = JSON.parse(sourcesKey);\n sources.forEach((url) => {\n\n setResults((prev) => {\n const next = new Map(prev);\n next.set(url, { dimensions: null, loading: true, error: null });\n return next;\n });\n\n const img = new Image();\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n let cancelled = false;\n\n const cleanup = () => {\n cancelled = true;\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n img.onload = null;\n img.onerror = null;\n };\n\n cleanups.push(cleanup);\n\n img.onload = () => {\n if (cancelled) return;\n cleanup();\n\n const { naturalWidth: width, naturalHeight: height } = img;\n setResults((prev) => {\n const next = new Map(prev);\n next.set(url, {\n dimensions: { width, height, aspectRatio: height > 0 ? width / height : 1 },\n loading: false,\n error: null,\n });\n return next;\n });\n };\n\n img.onerror = () => {\n if (cancelled) return;\n cleanup();\n\n setResults((prev) => {\n const next = new Map(prev);\n next.set(url, {\n dimensions: null,\n loading: false,\n error: new Error(`Failed to load: ${url}`),\n });\n return next;\n });\n };\n\n timeoutId = setTimeout(() => {\n if (cancelled) return;\n cleanup();\n\n setResults((prev) => {\n const next = new Map(prev);\n next.set(url, {\n dimensions: null,\n loading: false,\n error: new Error(`Timeout: ${url}`),\n });\n return next;\n });\n }, timeout);\n\n if (crossOrigin) {\n img.crossOrigin = crossOrigin;\n }\n\n img.src = url;\n });\n\n return () => {\n cleanups.forEach((cleanup) => cleanup());\n };\n }, [sourcesKey, crossOrigin, timeout, immediate]);\n\n return urls.map((url) => {\n if (!url) {\n return {\n dimensions: null,\n loading: false,\n error: null,\n retry: () => {},\n };\n }\n\n const result = results.get(url);\n return {\n dimensions: result?.dimensions ?? null,\n loading: result?.loading ?? false,\n error: result?.error ?? null,\n retry: () => {\n // Trigger reload by updating state\n setResults((prev) => {\n const next = new Map(prev);\n next.delete(url);\n return next;\n });\n },\n };\n });\n}\n","'use client';\n\n/**\n * usePasswordVisibility Hook\n *\n * Manages password field visibility toggle state.\n * Commonly used in login, register, and password reset forms.\n *\n * @module hooks/use-password-visibility\n */\n\nimport { useCallback, useState, useMemo } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Return type for usePasswordVisibility hook.\n */\nexport interface UsePasswordVisibilityReturn {\n /** Whether password is visible (text) or hidden (password) */\n visible: boolean;\n /** Toggle visibility */\n toggle: () => void;\n /** Show password */\n show: () => void;\n /** Hide password */\n hide: () => void;\n /** Input type based on visibility ('text' | 'password') */\n type: 'text' | 'password';\n}\n\n/**\n * Options for usePasswordVisibility hook.\n */\nexport interface UsePasswordVisibilityOptions {\n /** Initial visibility state (default: false) */\n initialVisible?: boolean;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * usePasswordVisibility - Manage password field visibility toggle.\n *\n * Returns state and handlers for password visibility toggle,\n * commonly used with InputAdornment in MUI TextField.\n *\n * @example\n * ```tsx\n * function LoginForm() {\n * const password = usePasswordVisibility();\n *\n * return (\n * <TextField\n * type={password.type}\n * slotProps={{\n * input: {\n * endAdornment: (\n * <InputAdornment position=\"end\">\n * <IconButton onClick={password.toggle}>\n * {password.visible ? <VisibilityOff /> : <Visibility />}\n * </IconButton>\n * </InputAdornment>\n * ),\n * },\n * }}\n * />\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With confirm password field. MUI v9 routes slot props through\n * // the `slotProps` API rather than the legacy `InputProps` /\n * // `InputLabelProps` / `FormHelperTextProps` family.\n * function RegisterForm() {\n * const password = usePasswordVisibility();\n * const confirmPassword = usePasswordVisibility();\n *\n * return (\n * <Box>\n * <TextField\n * label=\"Password\"\n * type={password.type}\n * slotProps={{ input: { endAdornment: <PasswordToggle {...password} /> } }}\n * />\n * <TextField\n * label=\"Confirm Password\"\n * type={confirmPassword.type}\n * slotProps={{ input: { endAdornment: <PasswordToggle {...confirmPassword} /> } }}\n * />\n * </Box>\n * );\n * }\n * ```\n *\n * @param options - Hook options\n * @returns Visibility state, toggle handlers, and input type\n */\nexport function usePasswordVisibility(options: UsePasswordVisibilityOptions = {}): UsePasswordVisibilityReturn {\n const { initialVisible = false } = options;\n\n const [visible, setVisible] = useState(initialVisible);\n\n const toggle = useCallback(() => {\n setVisible((prev) => !prev);\n }, []);\n\n const show = useCallback(() => {\n setVisible(true);\n }, []);\n\n const hide = useCallback(() => {\n setVisible(false);\n }, []);\n\n // Memoize return object to prevent unnecessary re-renders\n return useMemo(\n () => ({\n visible,\n toggle,\n show,\n hide,\n type: visible ? 'text' : 'password',\n }),\n [visible, toggle, show, hide]\n );\n}\n","'use client';\n\n/**\n * useThrottle Hook\n *\n * Throttles a value or callback, limiting how often it can update.\n *\n * @module hooks/use-throttle\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface UseThrottleOptions {\n /** Whether to invoke on the leading edge (default: true) */\n leading?: boolean;\n /** Whether to invoke on the trailing edge (default: true) */\n trailing?: boolean;\n}\n\n// =============================================================================\n// USE THROTTLE VALUE\n// =============================================================================\n\n/**\n * useThrottle - Throttle a value.\n *\n * Returns a throttled version of the value that only updates\n * at most once per specified interval.\n *\n * @example\n * ```tsx\n * function SearchComponent() {\n * const [search, setSearch] = useState('');\n * const throttledSearch = useThrottle(search, 300);\n *\n * // API call only triggers when throttledSearch changes\n * useEffect(() => {\n * if (throttledSearch) {\n * searchApi(throttledSearch);\n * }\n * }, [throttledSearch]);\n *\n * return <input value={search} onChange={(e) => setSearch(e.target.value)} />;\n * }\n * ```\n *\n * @param value - Value to throttle\n * @param delay - Throttle delay in milliseconds\n * @param options - Throttle options\n * @returns Throttled value\n */\nexport function useThrottle<T>(value: T, delay: number, options: UseThrottleOptions = {}): T {\n const { leading = true, trailing = true } = options;\n\n const [throttledValue, setThrottledValue] = useState(value);\n const lastExecuted = useRef(0);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastValue = useRef(value);\n\n useEffect(() => {\n lastValue.current = value;\n const now = Date.now();\n const elapsed = now - lastExecuted.current;\n\n const execute = () => {\n lastExecuted.current = Date.now();\n setThrottledValue(lastValue.current);\n };\n\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n if (elapsed >= delay) {\n // Enough time has passed\n if (leading) {\n execute();\n } else if (trailing) {\n timeoutRef.current = setTimeout(execute, delay);\n }\n } else if (trailing) {\n // Schedule trailing call\n timeoutRef.current = setTimeout(execute, delay - elapsed);\n }\n\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, [value, delay, leading, trailing]);\n\n return throttledValue;\n}\n\n// =============================================================================\n// USE THROTTLE CALLBACK\n// =============================================================================\n\n/**\n * useThrottleCallback - Create a throttled callback function.\n *\n * Returns a memoized throttled version of the callback that only\n * invokes at most once per specified interval.\n *\n * @example\n * ```tsx\n * function ScrollTracker() {\n * const handleScroll = useThrottleCallback(\n * (e: Event) => {\n * console.log('Scroll position:', window.scrollY);\n * },\n * 100\n * );\n *\n * useEffect(() => {\n * window.addEventListener('scroll', handleScroll);\n * return () => window.removeEventListener('scroll', handleScroll);\n * }, [handleScroll]);\n *\n * return <div>Scroll me!</div>;\n * }\n * ```\n *\n * @param callback - Callback to throttle\n * @param delay - Throttle delay in milliseconds\n * @param options - Throttle options\n * @returns Throttled callback\n */\nexport function useThrottleCallback<T extends (...args: unknown[]) => unknown>(\n callback: T,\n delay: number,\n options: UseThrottleOptions = {}\n): T {\n const { leading = true, trailing = true } = options;\n\n const lastExecuted = useRef(0);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastArgs = useRef<Parameters<T> | null>(null);\n const callbackRef = useRef(callback);\n\n // Update callback ref on each render\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n\n // Cleanup on unmount\n useEffect(\n () => () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n },\n []\n );\n\n return useCallback(\n ((...args: Parameters<T>) => {\n lastArgs.current = args;\n const now = Date.now();\n const elapsed = now - lastExecuted.current;\n\n const execute = () => {\n lastExecuted.current = Date.now();\n if (lastArgs.current) {\n callbackRef.current(...lastArgs.current);\n }\n };\n\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n\n if (elapsed >= delay) {\n if (leading) {\n execute();\n } else if (trailing) {\n timeoutRef.current = setTimeout(execute, delay);\n }\n } else if (trailing) {\n timeoutRef.current = setTimeout(execute, delay - elapsed);\n }\n }) as T,\n [delay, leading, trailing]\n );\n}\n","'use client';\n\n/**\n * useOnlineStatus Hook\n *\n * Tracks browser online/offline status with event listeners.\n *\n * @module hooks/use-online-status\n */\n\nimport { useCallback, useEffect, useState, useSyncExternalStore } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface UseOnlineStatusReturn {\n /** Whether the browser is online */\n isOnline: boolean;\n /** Whether the browser is offline */\n isOffline: boolean;\n /** Time when status last changed (timestamp) */\n lastChanged: number | null;\n}\n\n// =============================================================================\n// EXTERNAL STORE (for SSR safety)\n// =============================================================================\n\nfunction subscribe(callback: () => void): () => void {\n window.addEventListener('online', callback);\n window.addEventListener('offline', callback);\n return () => {\n window.removeEventListener('online', callback);\n window.removeEventListener('offline', callback);\n };\n}\n\nfunction getSnapshot(): boolean {\n return navigator.onLine;\n}\n\nfunction getServerSnapshot(): boolean {\n // Assume online during SSR\n return true;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * useOnlineStatus - Track browser online/offline status.\n *\n * Uses navigator.onLine and online/offline events to track network status.\n * SSR-safe with server-side assumption of online status.\n *\n * @example\n * ```tsx\n * function ConnectionIndicator() {\n * const { isOnline, isOffline } = useOnlineStatus();\n *\n * if (isOffline) {\n * return (\n * <Alert severity=\"warning\">\n * You are offline. Changes will sync when you reconnect.\n * </Alert>\n * );\n * }\n *\n * return null;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With timestamp tracking\n * function NetworkStatus() {\n * const { isOnline, lastChanged } = useOnlineStatus();\n *\n * return (\n * <Box>\n * <Typography>\n * Status: {isOnline ? 'Online' : 'Offline'}\n * </Typography>\n * {lastChanged && (\n * <Typography variant=\"caption\">\n * Last changed: {new Date(lastChanged).toLocaleTimeString()}\n * </Typography>\n * )}\n * </Box>\n * );\n * }\n * ```\n *\n * @returns Online status and metadata\n */\nexport function useOnlineStatus(): UseOnlineStatusReturn {\n const isOnline = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n const [lastChanged, setLastChanged] = useState<number | null>(null);\n\n const handleStatusChange = useCallback(() => {\n setLastChanged(Date.now());\n }, []);\n\n useEffect(() => {\n window.addEventListener('online', handleStatusChange);\n window.addEventListener('offline', handleStatusChange);\n return () => {\n window.removeEventListener('online', handleStatusChange);\n window.removeEventListener('offline', handleStatusChange);\n };\n }, [handleStatusChange]);\n\n return {\n isOnline,\n isOffline: !isOnline,\n lastChanged,\n };\n}\n","'use client';\n\n/**\n * useIntersectionObserver Hook\n *\n * Observe element visibility using the Intersection Observer API.\n *\n * @module hooks/use-intersection-observer\n */\n\nimport { useCallback, useEffect, useRef, useState, useMemo } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface UseIntersectionObserverOptions {\n /** Root element for intersection (default: viewport) */\n root?: Element | Document | null;\n /** Root margin (default: '0px') */\n rootMargin?: string;\n /** Threshold(s) at which to trigger (default: 0) */\n threshold?: number | number[];\n /** Whether to disconnect after first intersection (default: false) */\n triggerOnce?: boolean;\n /** Whether to start observing immediately (default: true) */\n enabled?: boolean;\n}\n\nexport interface UseIntersectionObserverReturn {\n /** Ref to attach to the target element */\n ref: (element: Element | null) => void;\n /** Current intersection entry */\n entry: IntersectionObserverEntry | null;\n /** Whether the element is intersecting */\n isIntersecting: boolean;\n /** Manually disconnect the observer */\n disconnect: () => void;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * useIntersectionObserver - Observe element visibility.\n *\n * Uses the Intersection Observer API to track when an element\n * enters or exits the viewport (or a custom root element).\n *\n * @example\n * ```tsx\n * // Lazy loading images\n * function LazyImage({ src }: { src: string }) {\n * const { ref, isIntersecting } = useIntersectionObserver({\n * triggerOnce: true,\n * });\n *\n * return (\n * <div ref={ref}>\n * {isIntersecting ? (\n * <img src={src} alt=\"\" />\n * ) : (\n * <Skeleton variant=\"rectangular\" height={200} />\n * )}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Infinite scroll\n * function InfiniteList({ items, onLoadMore }) {\n * const { ref, isIntersecting } = useIntersectionObserver({\n * threshold: 0.5,\n * });\n *\n * useEffect(() => {\n * if (isIntersecting) {\n * onLoadMore();\n * }\n * }, [isIntersecting, onLoadMore]);\n *\n * return (\n * <Box>\n * {items.map((item) => <Item key={item.id} {...item} />)}\n * <div ref={ref} style={{ height: 1 }} />\n * </Box>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Animate on scroll\n * function AnimatedSection({ children }) {\n * const { ref, isIntersecting } = useIntersectionObserver({\n * threshold: 0.1,\n * triggerOnce: true,\n * });\n *\n * return (\n * <Fade in={isIntersecting}>\n * <Box ref={ref}>{children}</Box>\n * </Fade>\n * );\n * }\n * ```\n *\n * @param options - Observer options\n * @returns Ref, entry, intersection state, and disconnect function\n */\nexport function useIntersectionObserver(options: UseIntersectionObserverOptions = {}): UseIntersectionObserverReturn {\n const { root = null, rootMargin = '0px', threshold = 0, triggerOnce = false, enabled = true } = options;\n\n const [entry, setEntry] = useState<IntersectionObserverEntry | null>(null);\n const elementRef = useRef<Element | null>(null);\n const observerRef = useRef<IntersectionObserver | null>(null);\n const frozenRef = useRef(false);\n\n const disconnect = useCallback(() => {\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n }, []);\n\n const ref = useCallback(\n (element: Element | null) => {\n // Disconnect previous observer\n disconnect();\n\n elementRef.current = element;\n\n // Don't observe if disabled, frozen, or no element\n if (!enabled || frozenRef.current || !element) {\n return;\n }\n\n // Check for IntersectionObserver support\n if (typeof IntersectionObserver === 'undefined') {\n // Fallback: assume visible\n setEntry({\n isIntersecting: true,\n intersectionRatio: 1,\n boundingClientRect: element.getBoundingClientRect(),\n intersectionRect: element.getBoundingClientRect(),\n rootBounds: null,\n target: element,\n time: Date.now(),\n } as IntersectionObserverEntry);\n return;\n }\n\n observerRef.current = new IntersectionObserver(\n ([observerEntry]) => {\n setEntry(observerEntry);\n\n if (triggerOnce && observerEntry.isIntersecting) {\n frozenRef.current = true;\n disconnect();\n }\n },\n { root, rootMargin, threshold }\n );\n\n observerRef.current.observe(element);\n },\n [enabled, root, rootMargin, threshold, triggerOnce, disconnect]\n );\n\n // Cleanup on unmount\n useEffect(\n () => () => {\n disconnect();\n },\n [disconnect]\n );\n\n // Memoize return object to prevent unnecessary re-renders.\n //\n // `ref` MUST be a dependency. It is a useCallback over the observer options,\n // so raising `threshold` (or `rootMargin`, `root`, `triggerOnce`, `enabled`)\n // mints a new callback — but if this memo does not see it, the caller keeps\n // holding the callback from the first render. React compares ref identity to\n // decide whether to re-attach, sees no change, and the observer keeps the\n // options it was constructed with. The new options then apply at the next\n // `entry` change, if one ever happens, and never at all once `triggerOnce`\n // has frozen it. Adding it cannot loop: `ref`'s own dependencies are the\n // destructured primitives, so its identity is stable while they are.\n return useMemo(\n () => ({\n ref,\n entry,\n isIntersecting: entry?.isIntersecting ?? false,\n disconnect,\n }),\n [ref, entry, disconnect]\n );\n}\n","'use client';\n\n/**\n * useKeyboardShortcut Hook\n *\n * Handle keyboard shortcuts with modifier key support.\n *\n * @module hooks/use-keyboard-shortcut\n */\n\nimport { useCallback, useEffect, useRef } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface KeyboardShortcut {\n /** Main key (e.g., 'k', 'Enter', 'Escape') */\n key: string;\n /** Require Ctrl/Cmd key */\n ctrl?: boolean;\n /** Require Shift key */\n shift?: boolean;\n /** Require Alt key */\n alt?: boolean;\n /** Require Meta key (Cmd on Mac) */\n meta?: boolean;\n}\n\nexport interface UseKeyboardShortcutOptions {\n /** Whether the shortcut is enabled (default: true) */\n enabled?: boolean;\n /** Prevent default browser behavior (default: true) */\n preventDefault?: boolean;\n /** Stop event propagation (default: false) */\n stopPropagation?: boolean;\n /** Target element (default: document) */\n target?: EventTarget | null;\n /** Event type (default: 'keydown') */\n event?: 'keydown' | 'keyup' | 'keypress';\n /** Ignore when focus is in input/textarea/contenteditable (default: false) */\n ignoreInputs?: boolean;\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\nfunction isInputElement(element: EventTarget | null): boolean {\n if (!element || !(element instanceof HTMLElement)) {\n return false;\n }\n\n const tagName = element.tagName.toLowerCase();\n if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {\n return true;\n }\n\n return element.isContentEditable;\n}\n\nfunction matchesShortcut(event: KeyboardEvent, shortcut: KeyboardShortcut): boolean {\n // Normalize key comparison (case-insensitive for letters)\n const eventKey = event.key.toLowerCase();\n const shortcutKey = shortcut.key.toLowerCase();\n\n if (eventKey !== shortcutKey) {\n return false;\n }\n\n // Check modifier keys\n const ctrlOrMeta = event.ctrlKey || event.metaKey;\n\n if (shortcut.ctrl && !ctrlOrMeta) return false;\n if (shortcut.meta && !event.metaKey) return false;\n if (shortcut.shift && !event.shiftKey) return false;\n if (shortcut.alt && !event.altKey) return false;\n\n // Ensure no extra modifiers unless specified\n if (!shortcut.ctrl && !shortcut.meta && ctrlOrMeta) return false;\n if (!shortcut.shift && event.shiftKey) return false;\n if (!shortcut.alt && event.altKey) return false;\n\n return true;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * useKeyboardShortcut - Handle keyboard shortcuts.\n *\n * Listens for keyboard events matching the specified shortcut\n * and invokes the callback when matched.\n *\n * @example\n * ```tsx\n * // Simple shortcut\n * function SearchDialog() {\n * const [open, setOpen] = useState(false);\n *\n * useKeyboardShortcut({ key: 'k', ctrl: true }, () => {\n * setOpen(true);\n * });\n *\n * return <Dialog open={open} onClose={() => setOpen(false)} />;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Save with Ctrl+S\n * function Editor({ onSave }) {\n * useKeyboardShortcut(\n * { key: 's', ctrl: true },\n * () => onSave(),\n * { preventDefault: true }\n * );\n *\n * return <TextField multiline />;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Escape to close\n * function Modal({ onClose }) {\n * useKeyboardShortcut({ key: 'Escape' }, onClose);\n *\n * return <div>Modal content</div>;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Multiple shortcuts\n * function App() {\n * useKeyboardShortcut({ key: 'k', ctrl: true }, openSearch);\n * useKeyboardShortcut({ key: 'n', ctrl: true }, createNew);\n * useKeyboardShortcut({ key: '/', ctrl: true }, toggleHelp);\n *\n * return <div>...</div>;\n * }\n * ```\n *\n * @param shortcut - Keyboard shortcut definition\n * @param callback - Function to call when shortcut is triggered\n * @param options - Hook options\n */\nexport function useKeyboardShortcut(\n shortcut: KeyboardShortcut,\n callback: (event: KeyboardEvent) => void,\n options: UseKeyboardShortcutOptions = {}\n): void {\n const {\n enabled = true,\n preventDefault = true,\n stopPropagation = false,\n target = typeof document !== 'undefined' ? document : null,\n event = 'keydown',\n ignoreInputs = false,\n } = options;\n\n const callbackRef = useRef(callback);\n\n // Update callback ref\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n\n const handleKeyEvent = useCallback(\n (e: Event) => {\n if (!enabled) return;\n\n const keyEvent = e as KeyboardEvent;\n if (keyEvent.defaultPrevented || keyEvent.isComposing) return;\n\n // Ignore if focused on input element\n if (ignoreInputs && isInputElement(keyEvent.target)) {\n return;\n }\n\n if (matchesShortcut(keyEvent, shortcut)) {\n if (preventDefault) {\n keyEvent.preventDefault();\n }\n if (stopPropagation) {\n keyEvent.stopPropagation();\n }\n callbackRef.current(keyEvent);\n }\n },\n [enabled, shortcut, preventDefault, stopPropagation, ignoreInputs]\n );\n\n useEffect(() => {\n if (!target || !enabled) return undefined;\n\n target.addEventListener(event, handleKeyEvent);\n return () => {\n target.removeEventListener(event, handleKeyEvent);\n };\n }, [target, event, handleKeyEvent, enabled]);\n}\n\n// =============================================================================\n// UTILITY HOOKS\n// =============================================================================\n\n/**\n * useEscapeKey - Convenience hook for Escape key handling.\n *\n * @example\n * ```tsx\n * function Modal({ onClose }) {\n * useEscapeKey(onClose);\n * return <div>Modal content</div>;\n * }\n * ```\n */\nexport function useEscapeKey(\n callback: (event: KeyboardEvent) => void,\n options: Omit<UseKeyboardShortcutOptions, 'ignoreInputs'> = {}\n): void {\n useKeyboardShortcut({ key: 'Escape' }, callback, {\n ...options,\n ignoreInputs: false, // Escape should work even in inputs\n });\n}\n\n/**\n * useEnterKey - Convenience hook for Enter key handling.\n *\n * @example\n * ```tsx\n * function SearchField({ onSearch }) {\n * useEnterKey(onSearch, { ignoreInputs: false });\n * return <TextField />;\n * }\n * ```\n */\nexport function useEnterKey(callback: (event: KeyboardEvent) => void, options: UseKeyboardShortcutOptions = {}): void {\n useKeyboardShortcut({ key: 'Enter' }, callback, options);\n}\n","'use client';\n\n/**\n * useFocusTrap Hook\n *\n * Traps focus within a container element for accessibility.\n * Essential for modals, dialogs, and dropdown menus.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useCallback, useEffect, useRef } from 'react';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Options for useFocusTrap hook.\n */\nexport interface UseFocusTrapOptions {\n /**\n * Whether the focus trap is active.\n * @default true\n */\n enabled?: boolean;\n /**\n * Whether to auto-focus the first focusable element when enabled.\n * @default true\n */\n autoFocus?: boolean;\n /**\n * Whether to restore focus to the previously focused element when disabled.\n * @default true\n */\n restoreFocus?: boolean;\n /**\n * Selector for focusable elements.\n * @default FOCUSABLE_SELECTOR\n */\n focusableSelector?: string;\n}\n\n/**\n * Return type for useFocusTrap hook.\n */\nexport interface UseFocusTrapReturn<T extends HTMLElement = HTMLElement> {\n /**\n * Ref to attach to the container element.\n */\n ref: React.RefCallback<T>;\n /**\n * Focus the first focusable element.\n */\n focusFirst: () => void;\n /**\n * Focus the last focusable element.\n */\n focusLast: () => void;\n}\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/**\n * Default selector for focusable elements.\n */\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n].join(',');\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Trap focus within a container element.\n *\n * @param options - Hook options\n * @returns Ref and focus control functions\n *\n * @example\n * ```tsx\n * function Modal({ open, onClose, children }) {\n * const { ref } = useFocusTrap({ enabled: open });\n *\n * if (!open) return null;\n *\n * return (\n * <div ref={ref} role=\"dialog\" aria-modal=\"true\">\n * {children}\n * <button onClick={onClose}>Close</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useFocusTrap<T extends HTMLElement = HTMLElement>(\n options: UseFocusTrapOptions = {}\n): UseFocusTrapReturn<T> {\n const { enabled = true, autoFocus = true, restoreFocus = true, focusableSelector = FOCUSABLE_SELECTOR } = options;\n\n const containerRef = useRef<T | null>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n\n // Get all focusable elements within the container\n const getFocusableElements = useCallback(() => {\n if (!containerRef.current) return [];\n return Array.from(containerRef.current.querySelectorAll<HTMLElement>(focusableSelector)).filter(\n (el) => el.offsetParent !== null\n ); // Filter out hidden elements\n }, [focusableSelector]);\n\n // Focus the first focusable element\n const focusFirst = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n elements[0].focus();\n }\n }, [getFocusableElements]);\n\n // Focus the last focusable element\n const focusLast = useCallback(() => {\n const elements = getFocusableElements();\n if (elements.length > 0) {\n elements[elements.length - 1].focus();\n }\n }, [getFocusableElements]);\n\n // Handle keydown for tab trapping\n useEffect(() => {\n if (!enabled || !containerRef.current) return undefined;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') return;\n\n const elements = getFocusableElements();\n if (elements.length === 0) return;\n\n const firstElement = elements[0];\n const lastElement = elements[elements.length - 1];\n const activeElement = document.activeElement;\n\n // Shift + Tab on first element -> go to last\n if (event.shiftKey && activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n return;\n }\n\n // Tab on last element -> go to first\n if (!event.shiftKey && activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n };\n\n const container = containerRef.current;\n container.addEventListener('keydown', handleKeyDown);\n\n return () => {\n container.removeEventListener('keydown', handleKeyDown);\n };\n }, [enabled, getFocusableElements]);\n\n // Auto-focus and restore focus\n useEffect(() => {\n if (enabled) {\n // Store the previously focused element\n if (restoreFocus) {\n previousActiveElement.current = document.activeElement as HTMLElement;\n }\n\n // Auto-focus the first element\n if (autoFocus) {\n // Use setTimeout to ensure the container is rendered\n const timeoutId = setTimeout(focusFirst, 0);\n return () => clearTimeout(timeoutId);\n }\n } else if (restoreFocus && previousActiveElement.current) {\n // Restore focus when disabled\n previousActiveElement.current.focus();\n previousActiveElement.current = null;\n }\n\n return undefined;\n }, [enabled, autoFocus, restoreFocus, focusFirst]);\n\n // Callback ref for the container\n const ref = useCallback((node: T | null) => {\n containerRef.current = node;\n }, []);\n\n return { ref, focusFirst, focusLast };\n}\n","'use client';\n\n/**\n * useUpdateEffect Hook\n *\n * Like useEffect, but skips the first render.\n * Useful for running effects only on updates, not on mount.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useEffect, useRef, type DependencyList, type EffectCallback } from 'react';\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Effect hook that only runs on updates, not on initial mount.\n *\n * @param effect - Effect callback function\n * @param deps - Dependency array\n *\n * @example\n * ```tsx\n * function SearchInput({ value, onSearch }) {\n * // Only search when value changes after initial render\n * useUpdateEffect(() => {\n * onSearch(value);\n * }, [value]);\n *\n * return <input value={value} />;\n * }\n * ```\n */\nexport function useUpdateEffect(effect: EffectCallback, deps?: DependencyList): void {\n const isFirstMount = useRef(true);\n\n useEffect(() => {\n if (isFirstMount.current) {\n isFirstMount.current = false;\n return undefined;\n }\n\n return effect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n}\n\n/**\n * Layout effect hook that only runs on updates, not on initial mount.\n * Uses useLayoutEffect for synchronous DOM measurements.\n *\n * @param effect - Effect callback function\n * @param deps - Dependency array\n *\n * @example\n * ```tsx\n * function AnimatedComponent({ size }) {\n * const ref = useRef<HTMLDivElement>(null);\n *\n * // Animate size changes, but not initial render\n * useUpdateLayoutEffect(() => {\n * if (ref.current) {\n * animate(ref.current, { width: size });\n * }\n * }, [size]);\n *\n * return <div ref={ref} />;\n * }\n * ```\n */\nexport function useUpdateLayoutEffect(effect: EffectCallback, deps?: DependencyList): void {\n const isFirstMount = useRef(true);\n\n // Use useEffect for SSR compatibility, but the pattern is the same\n useEffect(() => {\n if (isFirstMount.current) {\n isFirstMount.current = false;\n return undefined;\n }\n\n return effect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n}\n","'use client';\n\n/**\n * useIsomorphicLayoutEffect Hook\n *\n * SSR-safe version of useLayoutEffect.\n * Uses useLayoutEffect on client, useEffect on server.\n *\n * @module @omnitron-dev/prism/hooks\n */\n\nimport { useEffect, useLayoutEffect } from 'react';\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * Isomorphic layout effect that works in both SSR and CSR environments.\n *\n * - On the client: Uses useLayoutEffect for synchronous DOM operations\n * - On the server: Uses useEffect to avoid SSR warnings\n *\n * @example\n * ```tsx\n * function Tooltip({ position }) {\n * const ref = useRef<HTMLDivElement>(null);\n *\n * // Synchronously measure and position on client\n * useIsomorphicLayoutEffect(() => {\n * if (ref.current) {\n * const rect = ref.current.getBoundingClientRect();\n * // Position tooltip based on measurements\n * }\n * }, [position]);\n *\n * return <div ref={ref}>Tooltip</div>;\n * }\n * ```\n */\nexport const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n","'use client';\n\n/**\n * useSessionStorage Hook\n *\n * A hook for persisting state in sessionStorage with automatic serialization.\n *\n * @module hooks/use-session-storage\n */\n\nimport { useState, useCallback, useEffect } from 'react';\nimport { useIsClient } from '../core/hooks/use-is-client.js';\n\n/**\n * Return type for useSessionStorage hook.\n */\nexport interface UseSessionStorageReturn<T> {\n /** Current state value */\n state: T;\n /** Update state and sessionStorage */\n setState: (value: T | ((prev: T) => T)) => void;\n /** Remove item from sessionStorage and reset to default */\n remove: () => void;\n /** Check if sessionStorage has the key */\n hasValue: boolean;\n}\n\n/**\n * Options for useSessionStorage hook.\n */\nexport interface UseSessionStorageOptions<T> {\n /** Serializer function (default: JSON.stringify) */\n serializer?: (value: T) => string;\n /** Deserializer function (default: JSON.parse) */\n deserializer?: (value: string) => T;\n}\n\n/**\n * Get sessionStorage value with fallback.\n */\nfunction getStorageValue<T>(key: string, defaultValue: T, deserializer: (value: string) => T): T {\n if (typeof window === 'undefined') {\n return defaultValue;\n }\n\n try {\n const item = window.sessionStorage.getItem(key);\n if (item === null) {\n return defaultValue;\n }\n return deserializer(item);\n } catch (error) {\n console.warn(`Error reading sessionStorage key \"${key}\":`, error);\n return defaultValue;\n }\n}\n\n/**\n * Hook for persisting state in sessionStorage.\n *\n * @param key - Storage key\n * @param defaultValue - Default value when key is not found\n * @param options - Configuration options\n * @returns State value and control methods\n *\n * @example\n * ```tsx\n * function SearchFilters() {\n * const { state: filters, setState: setFilters, remove } = useSessionStorage(\n * 'search-filters',\n * { query: '', category: 'all' }\n * );\n *\n * return (\n * <>\n * <input\n * value={filters.query}\n * onChange={(e) => setFilters({ ...filters, query: e.target.value })}\n * />\n * <button onClick={remove}>Clear Filters</button>\n * </>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With functional updates\n * function Counter() {\n * const { state: count, setState: setCount } = useSessionStorage('counter', 0);\n *\n * return (\n * <button onClick={() => setCount((prev) => prev + 1)}>\n * Count: {count}\n * </button>\n * );\n * }\n * ```\n */\nexport function useSessionStorage<T>(\n key: string,\n defaultValue: T,\n options: UseSessionStorageOptions<T> = {}\n): UseSessionStorageReturn<T> {\n const { serializer = JSON.stringify, deserializer = JSON.parse } = options;\n\n const isClient = useIsClient();\n\n // Initialize state from sessionStorage\n const [state, setStateInternal] = useState<T>(() => {\n if (typeof window === 'undefined') {\n return defaultValue;\n }\n return getStorageValue(key, defaultValue, deserializer);\n });\n\n // Track if sessionStorage has the key\n const [hasValue, setHasValue] = useState<boolean>(() => {\n if (typeof window === 'undefined') {\n return false;\n }\n return window.sessionStorage.getItem(key) !== null;\n });\n\n // Update sessionStorage when state changes\n const setState = useCallback(\n (value: T | ((prev: T) => T)) => {\n try {\n const newValue = value instanceof Function ? value(state) : value;\n window.sessionStorage.setItem(key, serializer(newValue));\n setStateInternal(newValue);\n setHasValue(true);\n\n // Dispatch storage event for other tabs/windows\n window.dispatchEvent(\n new StorageEvent('storage', {\n key,\n newValue: serializer(newValue),\n storageArea: window.sessionStorage,\n })\n );\n } catch (error) {\n console.warn(`Error setting sessionStorage key \"${key}\":`, error);\n }\n },\n [key, serializer, state]\n );\n\n // Remove from sessionStorage\n const remove = useCallback(() => {\n try {\n window.sessionStorage.removeItem(key);\n setStateInternal(defaultValue);\n setHasValue(false);\n\n // Dispatch storage event for other tabs/windows\n window.dispatchEvent(\n new StorageEvent('storage', {\n key,\n newValue: null,\n storageArea: window.sessionStorage,\n })\n );\n } catch (error) {\n console.warn(`Error removing sessionStorage key \"${key}\":`, error);\n }\n }, [key, defaultValue]);\n\n // Sync state from sessionStorage on mount and key change\n useEffect(() => {\n if (!isClient) return undefined;\n\n const value = getStorageValue(key, defaultValue, deserializer);\n setStateInternal(value);\n setHasValue(window.sessionStorage.getItem(key) !== null);\n return undefined;\n }, [key, isClient, defaultValue, deserializer]);\n\n // Listen for storage events from other tabs/windows\n useEffect(() => {\n if (!isClient) return undefined;\n\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key === key && event.storageArea === window.sessionStorage) {\n if (event.newValue === null) {\n setStateInternal(defaultValue);\n setHasValue(false);\n } else {\n try {\n setStateInternal(deserializer(event.newValue));\n setHasValue(true);\n } catch {\n // Ignore parse errors\n }\n }\n }\n };\n\n window.addEventListener('storage', handleStorageChange);\n return () => {\n window.removeEventListener('storage', handleStorageChange);\n };\n }, [key, isClient, defaultValue, deserializer]);\n\n return {\n state,\n setState,\n remove,\n hasValue,\n };\n}\n","'use client';\n\n/**\n * useArray Hook\n *\n * A hook for managing array state with convenient CRUD operations.\n *\n * @module hooks/use-array\n */\n\nimport { useState, useCallback, useMemo } from 'react';\n\n/**\n * Return type for useArray hook.\n */\nexport interface UseArrayReturn<T> {\n /** Current array value */\n value: T[];\n /** Set array to new value */\n setValue: React.Dispatch<React.SetStateAction<T[]>>;\n /** Add item to end of array */\n push: (item: T) => void;\n /** Add items to end of array */\n pushMany: (items: T[]) => void;\n /** Remove first occurrence of item (by reference or predicate) */\n remove: (itemOrPredicate: T | ((item: T) => boolean)) => void;\n /** Remove item at index */\n removeAt: (index: number) => void;\n /** Remove items matching predicate */\n removeWhere: (predicate: (item: T) => boolean) => void;\n /** Update item at index */\n updateAt: (index: number, item: T) => void;\n /** Update item at index with partial data (merge) */\n updateAtPartial: (index: number, partial: Partial<T>) => void;\n /** Update items matching predicate */\n updateWhere: (predicate: (item: T) => boolean, update: T | ((item: T) => T)) => void;\n /** Insert item at index */\n insertAt: (index: number, item: T) => void;\n /** Move item from one index to another */\n move: (fromIndex: number, toIndex: number) => void;\n /** Swap items at two indices */\n swap: (indexA: number, indexB: number) => void;\n /** Clear all items */\n clear: () => void;\n /** Reset to initial value */\n reset: () => void;\n /** Reverse array in place */\n reverse: () => void;\n /** Sort array */\n sort: (compareFn?: (a: T, b: T) => number) => void;\n /** Filter array (returns new array, does not modify state) */\n filter: (predicate: (item: T) => boolean) => T[];\n /** Find item (returns item, does not modify state) */\n find: (predicate: (item: T) => boolean) => T | undefined;\n /** Find item index (returns index, does not modify state) */\n findIndex: (predicate: (item: T) => boolean) => number;\n /** Check if array includes item */\n includes: (item: T) => boolean;\n /** Get array length */\n length: number;\n /** Check if array is empty */\n isEmpty: boolean;\n /** Get first item */\n first: T | undefined;\n /** Get last item */\n last: T | undefined;\n}\n\n/**\n * Hook for managing array state with CRUD operations.\n *\n * @param initialValue - Initial array value\n * @returns Array value and manipulation methods\n *\n * @example\n * ```tsx\n * function TodoList() {\n * const todos = useArray<{ id: number; text: string; done: boolean }>([]);\n *\n * const addTodo = (text: string) => {\n * todos.push({ id: Date.now(), text, done: false });\n * };\n *\n * const toggleTodo = (id: number) => {\n * todos.updateWhere(\n * (todo) => todo.id === id,\n * (todo) => ({ ...todo, done: !todo.done })\n * );\n * };\n *\n * return (\n * <ul>\n * {todos.value.map((todo) => (\n * <li key={todo.id} onClick={() => toggleTodo(todo.id)}>\n * {todo.text} {todo.done && '✓'}\n * </li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Drag and drop reordering\n * function SortableList() {\n * const items = useArray(['A', 'B', 'C', 'D']);\n *\n * const handleDragEnd = (fromIndex: number, toIndex: number) => {\n * items.move(fromIndex, toIndex);\n * };\n *\n * return <DraggableList items={items.value} onReorder={handleDragEnd} />;\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With type-safe updates\n * interface User {\n * id: number;\n * name: string;\n * email: string;\n * }\n *\n * function UserList() {\n * const users = useArray<User>([\n * { id: 1, name: 'Alice', email: 'alice@example.com' },\n * ]);\n *\n * // Partial update (type-safe)\n * users.updateAtPartial(0, { email: 'alice@newdomain.com' });\n *\n * return <div>{users.value.map(u => u.name).join(', ')}</div>;\n * }\n * ```\n */\nexport function useArray<T>(initialValue: T[] = []): UseArrayReturn<T> {\n const [value, setValue] = useState<T[]>(initialValue);\n\n // Add single item to end\n const push = useCallback((item: T) => {\n setValue((arr) => [...arr, item]);\n }, []);\n\n // Add multiple items to end\n const pushMany = useCallback((items: T[]) => {\n setValue((arr) => [...arr, ...items]);\n }, []);\n\n // Remove first occurrence of item\n const remove = useCallback((itemOrPredicate: T | ((item: T) => boolean)) => {\n setValue((arr) => {\n const predicate =\n typeof itemOrPredicate === 'function'\n ? (itemOrPredicate as (item: T) => boolean)\n : (item: T) => item === itemOrPredicate;\n const index = arr.findIndex(predicate);\n if (index === -1) return arr;\n return [...arr.slice(0, index), ...arr.slice(index + 1)];\n });\n }, []);\n\n // Remove item at specific index\n const removeAt = useCallback((index: number) => {\n setValue((arr) => {\n if (index < 0 || index >= arr.length) return arr;\n return [...arr.slice(0, index), ...arr.slice(index + 1)];\n });\n }, []);\n\n // Remove all items matching predicate\n const removeWhere = useCallback((predicate: (item: T) => boolean) => {\n setValue((arr) => arr.filter((item) => !predicate(item)));\n }, []);\n\n // Update item at specific index\n const updateAt = useCallback((index: number, item: T) => {\n setValue((arr) => {\n if (index < 0 || index >= arr.length) return arr;\n return [...arr.slice(0, index), item, ...arr.slice(index + 1)];\n });\n }, []);\n\n // Update item at index with partial data\n const updateAtPartial = useCallback((index: number, partial: Partial<T>) => {\n setValue((arr) => {\n if (index < 0 || index >= arr.length) return arr;\n const item = arr[index];\n if (typeof item !== 'object' || item === null) {\n console.warn('updateAtPartial only works with object items');\n return arr;\n }\n return [...arr.slice(0, index), { ...item, ...partial }, ...arr.slice(index + 1)];\n });\n }, []);\n\n // Update all items matching predicate\n const updateWhere = useCallback((predicate: (item: T) => boolean, update: T | ((item: T) => T)) => {\n setValue((arr) =>\n arr.map((item) => {\n if (!predicate(item)) return item;\n return typeof update === 'function' ? (update as (item: T) => T)(item) : update;\n })\n );\n }, []);\n\n // Insert item at specific index\n const insertAt = useCallback((index: number, item: T) => {\n setValue((arr) => {\n const normalizedIndex = Math.max(0, Math.min(index, arr.length));\n return [...arr.slice(0, normalizedIndex), item, ...arr.slice(normalizedIndex)];\n });\n }, []);\n\n // Move item from one index to another\n const move = useCallback((fromIndex: number, toIndex: number) => {\n setValue((arr) => {\n if (fromIndex < 0 || fromIndex >= arr.length || toIndex < 0 || toIndex >= arr.length || fromIndex === toIndex) {\n return arr;\n }\n const newArr = [...arr];\n const [item] = newArr.splice(fromIndex, 1);\n newArr.splice(toIndex, 0, item);\n return newArr;\n });\n }, []);\n\n // Swap two items\n const swap = useCallback((indexA: number, indexB: number) => {\n setValue((arr) => {\n if (indexA < 0 || indexA >= arr.length || indexB < 0 || indexB >= arr.length || indexA === indexB) {\n return arr;\n }\n const newArr = [...arr];\n [newArr[indexA], newArr[indexB]] = [newArr[indexB], newArr[indexA]];\n return newArr;\n });\n }, []);\n\n // Clear all items\n const clear = useCallback(() => {\n setValue([]);\n }, []);\n\n // Reset to initial value\n const reset = useCallback(() => {\n setValue(initialValue);\n }, [initialValue]);\n\n // Reverse array\n const reverse = useCallback(() => {\n setValue((arr) => [...arr].reverse());\n }, []);\n\n // Sort array\n const sort = useCallback((compareFn?: (a: T, b: T) => number) => {\n setValue((arr) => [...arr].sort(compareFn));\n }, []);\n\n // Non-mutating operations (memoized for stability)\n const filter = useCallback((predicate: (item: T) => boolean) => value.filter(predicate), [value]);\n\n const find = useCallback((predicate: (item: T) => boolean) => value.find(predicate), [value]);\n\n const findIndex = useCallback((predicate: (item: T) => boolean) => value.findIndex(predicate), [value]);\n\n const includes = useCallback((item: T) => value.includes(item), [value]);\n\n // Computed properties\n const computed = useMemo(\n () => ({\n length: value.length,\n isEmpty: value.length === 0,\n first: value[0],\n last: value[value.length - 1],\n }),\n [value]\n );\n\n return {\n value,\n setValue,\n push,\n pushMany,\n remove,\n removeAt,\n removeWhere,\n updateAt,\n updateAtPartial,\n updateWhere,\n insertAt,\n move,\n swap,\n clear,\n reset,\n reverse,\n sort,\n filter,\n find,\n findIndex,\n includes,\n ...computed,\n };\n}\n","'use client';\n\n/**\n * useMutation Hook\n *\n * A hook for handling async mutations with loading, error, and success states.\n * Similar to TanStack Query's useMutation but framework-agnostic.\n *\n * @module hooks/use-mutation\n */\n\nimport { useState, useCallback, useRef } from 'react';\n\n/**\n * State for a mutation.\n */\nexport interface MutationState<TData, TError> {\n /** Mutation result data */\n data: TData | undefined;\n /** Error from mutation */\n error: TError | undefined;\n /** Whether mutation is currently executing */\n isLoading: boolean;\n /** Whether mutation has succeeded at least once */\n isSuccess: boolean;\n /** Whether mutation has failed */\n isError: boolean;\n /** Whether mutation is idle (never called or reset) */\n isIdle: boolean;\n /** Current status */\n status: 'idle' | 'loading' | 'success' | 'error';\n}\n\n/**\n * Options for useMutation hook.\n */\nexport interface UseMutationOptions<TData, TError, TVariables> {\n /** Called when mutation starts */\n onMutate?: (variables: TVariables) => void | Promise<void>;\n /** Called on successful mutation */\n onSuccess?: (data: TData, variables: TVariables) => void | Promise<void>;\n /** Called on mutation error */\n onError?: (error: TError, variables: TVariables) => void | Promise<void>;\n /** Called after mutation settles (success or error) */\n onSettled?: (data: TData | undefined, error: TError | undefined, variables: TVariables) => void | Promise<void>;\n /** Retry count on failure */\n retry?: number | boolean;\n /** Delay between retries in ms */\n retryDelay?: number | ((attempt: number) => number);\n}\n\n/**\n * Return type for useMutation hook.\n */\nexport interface UseMutationReturn<TData, TError, TVariables> {\n /** Current mutation state */\n data: TData | undefined;\n error: TError | undefined;\n isLoading: boolean;\n isSuccess: boolean;\n isError: boolean;\n isIdle: boolean;\n status: MutationState<TData, TError>['status'];\n /** Execute the mutation */\n mutate: (\n variables: TVariables,\n options?: {\n onSuccess?: (data: TData) => void;\n onError?: (error: TError) => void;\n onSettled?: (data: TData | undefined, error: TError | undefined) => void;\n }\n ) => void;\n /** Execute the mutation and return a promise */\n mutateAsync: (variables: TVariables) => Promise<TData>;\n /** Reset mutation state */\n reset: () => void;\n}\n\nconst defaultRetryDelay = (attempt: number) => Math.min(1000 * 2 ** attempt, 30000);\n\n/**\n * Hook for handling async mutations with loading/error states.\n *\n * @param mutationFn - Async function to execute\n * @param options - Configuration options\n * @returns Mutation state and control methods\n *\n * @example\n * ```tsx\n * function CreateUserForm() {\n * const createUser = useMutation(\n * async (data: { name: string; email: string }) => {\n * const response = await fetch('/api/users', {\n * method: 'POST',\n * body: JSON.stringify(data),\n * });\n * if (!response.ok) throw new Error('Failed to create user');\n * return response.json();\n * },\n * {\n * onSuccess: (user) => {\n * console.log('User created:', user);\n * },\n * onError: (error) => {\n * console.error('Failed:', error);\n * },\n * }\n * );\n *\n * const handleSubmit = (e: FormEvent) => {\n * e.preventDefault();\n * createUser.mutate({ name: 'John', email: 'john@example.com' });\n * };\n *\n * return (\n * <form onSubmit={handleSubmit}>\n * <button type=\"submit\" disabled={createUser.isLoading}>\n * {createUser.isLoading ? 'Creating...' : 'Create User'}\n * </button>\n * {createUser.isError && <div>Error: {String(createUser.error)}</div>}\n * {createUser.isSuccess && <div>User created!</div>}\n * </form>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With async/await\n * async function handleCreate() {\n * try {\n * const user = await createUser.mutateAsync({ name: 'Jane' });\n * navigate(`/users/${user.id}`);\n * } catch (error) {\n * // Error already captured in state\n * }\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With retry\n * const uploadFile = useMutation(\n * async (file: File) => {\n * const formData = new FormData();\n * formData.append('file', file);\n * const response = await fetch('/api/upload', {\n * method: 'POST',\n * body: formData,\n * });\n * if (!response.ok) throw new Error('Upload failed');\n * return response.json();\n * },\n * {\n * retry: 3,\n * retryDelay: (attempt) => attempt * 1000,\n * }\n * );\n * ```\n */\nexport function useMutation<TData = unknown, TError = Error, TVariables = void>(\n mutationFn: (variables: TVariables) => Promise<TData>,\n options: UseMutationOptions<TData, TError, TVariables> = {}\n): UseMutationReturn<TData, TError, TVariables> {\n const { onMutate, onSuccess, onError, onSettled, retry = 0, retryDelay = defaultRetryDelay } = options;\n\n const [state, setState] = useState<MutationState<TData, TError>>({\n data: undefined,\n error: undefined,\n isLoading: false,\n isSuccess: false,\n isError: false,\n isIdle: true,\n status: 'idle',\n });\n\n // Track mutation ID to handle race conditions\n const mutationIdRef = useRef(0);\n\n // Execute mutation with optional per-call callbacks\n const mutate = useCallback(\n (\n variables: TVariables,\n callOptions?: {\n onSuccess?: (data: TData) => void;\n onError?: (error: TError) => void;\n onSettled?: (data: TData | undefined, error: TError | undefined) => void;\n }\n ) => {\n const currentId = ++mutationIdRef.current;\n\n const executeWithRetry = async (attempt: number): Promise<void> => {\n // Check if this mutation was superseded\n if (mutationIdRef.current !== currentId) return;\n\n setState({\n data: undefined,\n error: undefined,\n isLoading: true,\n isSuccess: false,\n isError: false,\n isIdle: false,\n status: 'loading',\n });\n\n try {\n // Call onMutate\n await onMutate?.(variables);\n\n // Execute mutation\n const data = await mutationFn(variables);\n\n // Check if this mutation was superseded\n if (mutationIdRef.current !== currentId) return;\n\n setState({\n data,\n error: undefined,\n isLoading: false,\n isSuccess: true,\n isError: false,\n isIdle: false,\n status: 'success',\n });\n\n // Call success callbacks\n await onSuccess?.(data, variables);\n await callOptions?.onSuccess?.(data);\n await onSettled?.(data, undefined, variables);\n await callOptions?.onSettled?.(data, undefined);\n } catch (err) {\n // Check if this mutation was superseded\n if (mutationIdRef.current !== currentId) return;\n\n const error = err as TError;\n const maxRetries = typeof retry === 'boolean' ? (retry ? 3 : 0) : retry;\n\n // Retry if configured\n if (attempt < maxRetries) {\n const delay = typeof retryDelay === 'function' ? retryDelay(attempt) : retryDelay;\n await new Promise((resolve) => setTimeout(resolve, delay));\n await executeWithRetry(attempt + 1);\n return;\n }\n\n setState({\n data: undefined,\n error,\n isLoading: false,\n isSuccess: false,\n isError: true,\n isIdle: false,\n status: 'error',\n });\n\n // Call error callbacks\n await onError?.(error, variables);\n await callOptions?.onError?.(error);\n await onSettled?.(undefined, error, variables);\n await callOptions?.onSettled?.(undefined, error);\n }\n };\n\n executeWithRetry(0);\n },\n [mutationFn, onMutate, onSuccess, onError, onSettled, retry, retryDelay]\n );\n\n // Execute mutation and return promise\n const mutateAsync = useCallback(\n (variables: TVariables): Promise<TData> =>\n new Promise((resolve, reject) => {\n mutate(variables, {\n onSuccess: resolve,\n onError: reject,\n });\n }),\n [mutate]\n );\n\n // Reset mutation state\n const reset = useCallback(() => {\n mutationIdRef.current++;\n setState({\n data: undefined,\n error: undefined,\n isLoading: false,\n isSuccess: false,\n isError: false,\n isIdle: true,\n status: 'idle',\n });\n }, []);\n\n return {\n ...state,\n mutate,\n mutateAsync,\n reset,\n };\n}\n","'use client';\n\n/**\n * useLazyQuery Hook\n *\n * A hook for manual query execution with loading, error, and caching support.\n *\n * @module hooks/use-lazy-query\n */\n\nimport { useState, useCallback, useRef } from 'react';\n\n/**\n * State for a lazy query.\n */\nexport interface LazyQueryState<TData, TError> {\n /** Query result data */\n data: TData | undefined;\n /** Error from query */\n error: TError | undefined;\n /** Whether query is currently executing */\n isLoading: boolean;\n /** Whether query has succeeded at least once */\n isSuccess: boolean;\n /** Whether query has failed */\n isError: boolean;\n /** Whether query has been called at least once */\n isCalled: boolean;\n /** Whether query is fetching (includes refetch) */\n isFetching: boolean;\n /** Whether this is a refetch */\n isRefetching: boolean;\n}\n\n/**\n * Options for useLazyQuery hook.\n */\nexport interface UseLazyQueryOptions<TData, TError, TVariables> {\n /** Called on successful query */\n onSuccess?: (data: TData, variables: TVariables) => void | Promise<void>;\n /** Called on query error */\n onError?: (error: TError, variables: TVariables) => void | Promise<void>;\n /** Called after query settles (success or error) */\n onSettled?: (data: TData | undefined, error: TError | undefined, variables: TVariables) => void | Promise<void>;\n /** Cache time in ms (0 = no cache) */\n cacheTime?: number;\n /** Stale time in ms (data considered fresh for this duration) */\n staleTime?: number;\n /** Retry count on failure */\n retry?: number | boolean;\n /** Delay between retries in ms */\n retryDelay?: number | ((attempt: number) => number);\n /** Initial data */\n initialData?: TData;\n}\n\n/**\n * Return type for useLazyQuery hook.\n */\nexport interface UseLazyQueryReturn<TData, TError, TVariables> {\n /** Current query state */\n data: TData | undefined;\n error: TError | undefined;\n isLoading: boolean;\n isSuccess: boolean;\n isError: boolean;\n isCalled: boolean;\n isFetching: boolean;\n isRefetching: boolean;\n /** Execute the query */\n query: (variables: TVariables) => Promise<TData>;\n /** Refetch with last variables */\n refetch: () => Promise<TData | undefined>;\n /** Reset query state */\n reset: () => void;\n /** Manually set data */\n setData: (data: TData | ((prev: TData | undefined) => TData)) => void;\n}\n\ninterface CacheEntry<TData> {\n data: TData;\n timestamp: number;\n variables: unknown;\n}\n\nconst defaultRetryDelay = (attempt: number) => Math.min(1000 * 2 ** attempt, 30000);\n\n/**\n * Hook for manual query execution with caching support.\n *\n * @param queryFn - Async function to execute\n * @param options - Configuration options\n * @returns Query state and control methods\n *\n * @example\n * ```tsx\n * function UserSearch() {\n * const users = useLazyQuery(\n * async (query: string) => {\n * const response = await fetch(`/api/users?q=${query}`);\n * if (!response.ok) throw new Error('Search failed');\n * return response.json();\n * },\n * {\n * onSuccess: (data) => console.log('Found users:', data.length),\n * cacheTime: 5 * 60 * 1000, // 5 minutes\n * }\n * );\n *\n * const handleSearch = async (query: string) => {\n * const results = await users.query(query);\n * console.log('Results:', results);\n * };\n *\n * return (\n * <div>\n * <SearchInput onSearch={handleSearch} />\n * {users.isLoading && <Spinner />}\n * {users.isError && <div>Error: {String(users.error)}</div>}\n * {users.data?.map((user) => <UserCard key={user.id} user={user} />)}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With caching\n * const userDetails = useLazyQuery(\n * async (id: string) => fetchUser(id),\n * {\n * cacheTime: 10 * 60 * 1000, // Keep in cache for 10 min\n * staleTime: 60 * 1000, // Consider fresh for 1 min\n * }\n * );\n *\n * // First call fetches, subsequent calls within staleTime return cache\n * await userDetails.query('123');\n * await userDetails.query('123'); // Returns from cache if not stale\n * ```\n *\n * @example\n * ```tsx\n * // Manual data management\n * const { data, setData, reset } = useLazyQuery(fetchData);\n *\n * // Optimistic update\n * setData((prev) => prev ? { ...prev, count: prev.count + 1 } : prev);\n *\n * // Reset to clean state\n * reset();\n * ```\n */\nexport function useLazyQuery<TData = unknown, TError = Error, TVariables = void>(\n queryFn: (variables: TVariables) => Promise<TData>,\n options: UseLazyQueryOptions<TData, TError, TVariables> = {}\n): UseLazyQueryReturn<TData, TError, TVariables> {\n const {\n onSuccess,\n onError,\n onSettled,\n cacheTime = 0,\n staleTime = 0,\n retry = 0,\n retryDelay = defaultRetryDelay,\n initialData,\n } = options;\n\n const [state, setState] = useState<LazyQueryState<TData, TError>>({\n data: initialData,\n error: undefined,\n isLoading: false,\n isSuccess: !!initialData,\n isError: false,\n isCalled: !!initialData,\n isFetching: false,\n isRefetching: false,\n });\n\n // Track query ID for race conditions\n const queryIdRef = useRef(0);\n const lastVariablesRef = useRef<TVariables | null>(null);\n const cacheRef = useRef<Map<string, CacheEntry<TData>>>(new Map());\n\n // Generate cache key from variables\n const getCacheKey = useCallback((variables: TVariables): string => JSON.stringify(variables), []);\n\n // Check if cache entry is valid\n const isCacheValid = useCallback(\n (entry: CacheEntry<TData> | undefined): boolean => {\n if (!entry || cacheTime === 0) return false;\n const age = Date.now() - entry.timestamp;\n return age < cacheTime;\n },\n [cacheTime]\n );\n\n // Check if cache entry is fresh (not stale)\n const isCacheFresh = useCallback(\n (entry: CacheEntry<TData> | undefined): boolean => {\n if (!entry || staleTime === 0) return false;\n const age = Date.now() - entry.timestamp;\n return age < staleTime;\n },\n [staleTime]\n );\n\n // Execute query\n const query = useCallback(\n async (variables: TVariables): Promise<TData> => {\n const currentId = ++queryIdRef.current;\n lastVariablesRef.current = variables;\n\n // Check cache\n const cacheKey = getCacheKey(variables);\n const cached = cacheRef.current.get(cacheKey);\n\n if (isCacheFresh(cached)) {\n // Return fresh cached data immediately\n setState((prev) => ({\n ...prev,\n data: cached!.data,\n isSuccess: true,\n isCalled: true,\n }));\n return cached!.data;\n }\n\n // If cache is valid but stale, update state with cached data while fetching\n if (isCacheValid(cached)) {\n setState({\n data: cached!.data,\n error: undefined,\n isLoading: false,\n isSuccess: true,\n isError: false,\n isCalled: true,\n isFetching: true,\n isRefetching: true,\n });\n } else {\n setState({\n data: undefined,\n error: undefined,\n isLoading: true,\n isSuccess: false,\n isError: false,\n isCalled: true,\n isFetching: true,\n isRefetching: false,\n });\n }\n\n const executeWithRetry = async (attempt: number): Promise<TData> => {\n try {\n const data = await queryFn(variables);\n\n // Check if this query was superseded\n if (queryIdRef.current !== currentId) {\n return data;\n }\n\n // Update cache\n cacheRef.current.set(cacheKey, {\n data,\n timestamp: Date.now(),\n variables,\n });\n\n setState({\n data,\n error: undefined,\n isLoading: false,\n isSuccess: true,\n isError: false,\n isCalled: true,\n isFetching: false,\n isRefetching: false,\n });\n\n // Call success callbacks\n await onSuccess?.(data, variables);\n await onSettled?.(data, undefined, variables);\n\n return data;\n } catch (err) {\n // Check if this query was superseded\n if (queryIdRef.current !== currentId) {\n throw err;\n }\n\n const error = err as TError;\n const maxRetries = typeof retry === 'boolean' ? (retry ? 3 : 0) : retry;\n\n // Retry if configured\n if (attempt < maxRetries) {\n const delay = typeof retryDelay === 'function' ? retryDelay(attempt) : retryDelay;\n await new Promise((resolve) => setTimeout(resolve, delay));\n return executeWithRetry(attempt + 1);\n }\n\n setState({\n data: undefined,\n error,\n isLoading: false,\n isSuccess: false,\n isError: true,\n isCalled: true,\n isFetching: false,\n isRefetching: false,\n });\n\n // Call error callbacks\n await onError?.(error, variables);\n await onSettled?.(undefined, error, variables);\n\n throw error;\n }\n };\n\n return executeWithRetry(0);\n },\n [queryFn, getCacheKey, isCacheFresh, isCacheValid, onSuccess, onError, onSettled, retry, retryDelay]\n );\n\n // Refetch with last variables\n const refetch = useCallback(async (): Promise<TData | undefined> => {\n if (lastVariablesRef.current === null) {\n return undefined;\n }\n return query(lastVariablesRef.current);\n }, [query]);\n\n // Reset state\n const reset = useCallback(() => {\n queryIdRef.current++;\n lastVariablesRef.current = null;\n cacheRef.current.clear();\n setState({\n data: initialData,\n error: undefined,\n isLoading: false,\n isSuccess: !!initialData,\n isError: false,\n isCalled: !!initialData,\n isFetching: false,\n isRefetching: false,\n });\n }, [initialData]);\n\n // Manual data setter\n const setData = useCallback((data: TData | ((prev: TData | undefined) => TData)) => {\n setState((prev) => {\n const newData = typeof data === 'function' ? (data as (prev: TData | undefined) => TData)(prev.data) : data;\n return {\n ...prev,\n data: newData,\n isSuccess: true,\n };\n });\n }, []);\n\n return {\n ...state,\n query,\n refetch,\n reset,\n setData,\n };\n}\n","'use client';\n\n/**\n * useInfiniteScroll Hook\n *\n * A hook for infinite scrolling with paginated data loading.\n *\n * @module hooks/use-infinite-scroll\n */\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\n\n/**\n * Page info returned from fetch function.\n */\nexport interface PageInfo {\n /** Whether there are more pages */\n hasNextPage: boolean;\n /** Cursor or token for next page */\n endCursor?: string | number;\n /** Total count (optional) */\n totalCount?: number;\n}\n\n/**\n * Page data structure.\n */\nexport interface InfinitePage<TData> {\n /** Items in this page */\n items: TData[];\n /** Page information */\n pageInfo: PageInfo;\n}\n\n/**\n * State for infinite scroll.\n */\nexport interface InfiniteScrollState<TData, TError> {\n /** All loaded items (flattened) */\n items: TData[];\n /** All pages */\n pages: InfinitePage<TData>[];\n /** Error from last fetch */\n error: TError | undefined;\n /** Whether initial load is in progress */\n isLoading: boolean;\n /** Whether more data is being fetched */\n isFetchingMore: boolean;\n /** Whether there are more pages to fetch */\n hasNextPage: boolean;\n /** Whether any data has been loaded */\n isEmpty: boolean;\n /** Total count if available */\n totalCount: number | undefined;\n}\n\n/**\n * Options for useInfiniteScroll hook.\n */\nexport interface UseInfiniteScrollOptions<TData, TError> {\n /** Called on successful fetch */\n onSuccess?: (page: InfinitePage<TData>) => void | Promise<void>;\n /** Called on fetch error */\n onError?: (error: TError) => void | Promise<void>;\n /** Initial cursor/offset */\n initialCursor?: string | number;\n /** Initial page size */\n pageSize?: number;\n /** Retry count on failure */\n retry?: number | boolean;\n /** Retry delay in ms */\n retryDelay?: number | ((attempt: number) => number);\n /** Intersection observer options for auto-loading */\n observerOptions?: IntersectionObserverInit;\n}\n\n/**\n * Return type for useInfiniteScroll hook.\n */\nexport interface UseInfiniteScrollReturn<TData, TError> {\n /** All loaded items (flattened) */\n items: TData[];\n /** All pages */\n pages: InfinitePage<TData>[];\n /** Error from last fetch */\n error: TError | undefined;\n /** Whether initial load is in progress */\n isLoading: boolean;\n /** Whether more data is being fetched */\n isFetchingMore: boolean;\n /** Whether there are more pages to fetch */\n hasNextPage: boolean;\n /** Whether list is empty */\n isEmpty: boolean;\n /** Total count if available */\n totalCount: number | undefined;\n /** Fetch the next page */\n fetchNextPage: () => Promise<void>;\n /** Fetch first page (refresh) */\n refresh: () => Promise<void>;\n /** Reset to initial state */\n reset: () => void;\n /** Ref to attach to sentinel element for auto-loading */\n sentinelRef: React.RefCallback<HTMLElement>;\n /** Manually prepend items */\n prependItems: (items: TData[]) => void;\n /** Manually append items */\n appendItems: (items: TData[]) => void;\n /** Remove item by predicate */\n removeItem: (predicate: (item: TData) => boolean) => void;\n /** Update item by predicate */\n updateItem: (predicate: (item: TData) => boolean, update: Partial<TData> | ((item: TData) => TData)) => void;\n}\n\n/**\n * Fetch function signature.\n */\nexport type InfiniteFetchFn<TData> = (params: {\n cursor?: string | number;\n pageSize: number;\n}) => Promise<InfinitePage<TData>>;\n\nconst defaultRetryDelay = (attempt: number) => Math.min(1000 * 2 ** attempt, 30000);\n\n/**\n * Hook for infinite scrolling with paginated data.\n *\n * @param fetchFn - Function to fetch a page of data\n * @param options - Configuration options\n * @returns Infinite scroll state and controls\n *\n * @example\n * ```tsx\n * function UserList() {\n * const {\n * items,\n * isLoading,\n * isFetchingMore,\n * hasNextPage,\n * fetchNextPage,\n * sentinelRef,\n * } = useInfiniteScroll<User>(\n * async ({ cursor, pageSize }) => {\n * const response = await fetch(\n * `/api/users?cursor=${cursor ?? ''}&limit=${pageSize}`\n * );\n * const data = await response.json();\n * return {\n * items: data.users,\n * pageInfo: {\n * hasNextPage: data.hasMore,\n * endCursor: data.nextCursor,\n * totalCount: data.total,\n * },\n * };\n * },\n * { pageSize: 20 }\n * );\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * {items.map((user) => (\n * <UserCard key={user.id} user={user} />\n * ))}\n * {hasNextPage && (\n * <div ref={sentinelRef}>\n * {isFetchingMore ? <Spinner /> : 'Load more'}\n * </div>\n * )}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Manual loading\n * function ProductList() {\n * const { items, hasNextPage, fetchNextPage, isFetchingMore } = useInfiniteScroll(\n * fetchProducts,\n * { pageSize: 10 }\n * );\n *\n * return (\n * <>\n * <ProductGrid items={items} />\n * {hasNextPage && (\n * <Button onClick={fetchNextPage} loading={isFetchingMore}>\n * Load More\n * </Button>\n * )}\n * </>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With optimistic updates\n * const { items, removeItem, updateItem, prependItems } = useInfiniteScroll(\n * fetchComments,\n * { pageSize: 20 }\n * );\n *\n * // Add new comment at top\n * const handleNewComment = (comment: Comment) => {\n * prependItems([comment]);\n * };\n *\n * // Delete comment\n * const handleDelete = (id: string) => {\n * removeItem((c) => c.id === id);\n * };\n *\n * // Update comment\n * const handleEdit = (id: string, text: string) => {\n * updateItem((c) => c.id === id, { text });\n * };\n * ```\n */\nexport function useInfiniteScroll<TData = unknown, TError = Error>(\n fetchFn: InfiniteFetchFn<TData>,\n options: UseInfiniteScrollOptions<TData, TError> = {}\n): UseInfiniteScrollReturn<TData, TError> {\n const {\n onSuccess,\n onError,\n initialCursor,\n pageSize = 20,\n retry = 0,\n retryDelay = defaultRetryDelay,\n observerOptions = { threshold: 0.1 },\n } = options;\n\n const [state, setState] = useState<InfiniteScrollState<TData, TError>>({\n items: [],\n pages: [],\n error: undefined,\n isLoading: false,\n isFetchingMore: false,\n hasNextPage: true,\n isEmpty: true,\n totalCount: undefined,\n });\n\n /**\n * The caller's functions and options, read through refs.\n *\n * Everything here is something a caller writes inline — `fetchFn` as an\n * arrow, `onSuccess` as an arrow, `observerOptions` not at all, which\n * makes the default `{ threshold: 0.1 }` a fresh object on every render.\n * Each of those was a dependency, so `fetchPage` changed identity every\n * render, and with it `fetchNextPage`, and with it `sentinelRef`.\n *\n * `sentinelRef` is a REF CALLBACK. React invokes a ref callback with\n * `null` and then with the element every time its identity changes — so\n * every render tore down the `IntersectionObserver` and built a new one,\n * and a new observer whose target is already intersecting fires\n * immediately. A sentinel at the bottom of a short list always is.\n *\n * Measured before this change, with an observer that fires on `observe`\n * as the real one does: 53 observers created and React aborting the tree\n * with \"Maximum update depth exceeded\".\n *\n * Reading them through refs keeps the callbacks stable without asking\n * every caller to memoise. The cost is that changing `observerOptions`\n * after mount no longer rebuilds the observer, which is worth saying out\n * loud and is not something any caller does.\n */\n const fetchFnRef = useRef(fetchFn);\n fetchFnRef.current = fetchFn;\n const onSuccessRef = useRef(onSuccess);\n onSuccessRef.current = onSuccess;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const observerOptionsRef = useRef(observerOptions);\n observerOptionsRef.current = observerOptions;\n\n // Refs for tracking\n const fetchIdRef = useRef(0);\n const cursorRef = useRef<string | number | undefined>(initialCursor);\n const observerRef = useRef<IntersectionObserver | null>(null);\n const sentinelElementRef = useRef<HTMLElement | null>(null);\n const isMountedRef = useRef(true);\n\n // Cleanup on unmount\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n if (observerRef.current) {\n observerRef.current.disconnect();\n }\n };\n }, []);\n\n // Fetch a page with retry logic\n const fetchPage = useCallback(\n async (cursor: string | number | undefined, isRefresh = false) => {\n const currentId = ++fetchIdRef.current;\n\n const executeWithRetry = async (attempt: number): Promise<void> => {\n if (!isMountedRef.current) return;\n\n setState((prev) => ({\n ...prev,\n isLoading: isRefresh && prev.pages.length === 0,\n isFetchingMore: !isRefresh || prev.pages.length > 0,\n error: undefined,\n }));\n\n try {\n const page = await fetchFnRef.current({ cursor, pageSize });\n\n // Check if this fetch was superseded\n if (fetchIdRef.current !== currentId || !isMountedRef.current) return;\n\n setState((prev) => {\n const newPages = isRefresh ? [page] : [...prev.pages, page];\n const newItems = newPages.flatMap((p) => p.items);\n return {\n items: newItems,\n pages: newPages,\n error: undefined,\n isLoading: false,\n isFetchingMore: false,\n hasNextPage: page.pageInfo.hasNextPage,\n isEmpty: newItems.length === 0,\n totalCount: page.pageInfo.totalCount,\n };\n });\n\n cursorRef.current = page.pageInfo.endCursor;\n await onSuccessRef.current?.(page);\n } catch (err) {\n if (fetchIdRef.current !== currentId || !isMountedRef.current) return;\n\n const error = err as TError;\n const maxRetries = typeof retry === 'boolean' ? (retry ? 3 : 0) : retry;\n\n if (attempt < maxRetries) {\n const delay = typeof retryDelay === 'function' ? retryDelay(attempt) : retryDelay;\n await new Promise((resolve) => setTimeout(resolve, delay));\n await executeWithRetry(attempt + 1);\n return;\n }\n\n setState((prev) => ({\n ...prev,\n error,\n isLoading: false,\n isFetchingMore: false,\n }));\n\n await onErrorRef.current?.(error);\n }\n };\n\n return executeWithRetry(0);\n },\n [pageSize, retry, retryDelay]\n );\n\n // Fetch next page\n const fetchNextPage = useCallback(async () => {\n if (state.isFetchingMore || state.isLoading || !state.hasNextPage) return;\n await fetchPage(cursorRef.current);\n }, [fetchPage, state.isFetchingMore, state.isLoading, state.hasNextPage]);\n\n // Refresh (fetch first page)\n const refresh = useCallback(async () => {\n cursorRef.current = initialCursor;\n await fetchPage(initialCursor, true);\n }, [fetchPage, initialCursor]);\n\n // Reset to initial state\n const reset = useCallback(() => {\n fetchIdRef.current++;\n cursorRef.current = initialCursor;\n setState({\n items: [],\n pages: [],\n error: undefined,\n isLoading: false,\n isFetchingMore: false,\n hasNextPage: true,\n isEmpty: true,\n totalCount: undefined,\n });\n }, [initialCursor]);\n\n // Prepend items\n const prependItems = useCallback((newItems: TData[]) => {\n setState((prev) => ({\n ...prev,\n items: [...newItems, ...prev.items],\n isEmpty: newItems.length === 0 && prev.items.length === 0,\n }));\n }, []);\n\n // Append items\n const appendItems = useCallback((newItems: TData[]) => {\n setState((prev) => ({\n ...prev,\n items: [...prev.items, ...newItems],\n isEmpty: prev.items.length === 0 && newItems.length === 0,\n }));\n }, []);\n\n // Remove item by predicate\n const removeItem = useCallback((predicate: (item: TData) => boolean) => {\n setState((prev) => {\n const newItems = prev.items.filter((item) => !predicate(item));\n return {\n ...prev,\n items: newItems,\n isEmpty: newItems.length === 0,\n };\n });\n }, []);\n\n // Update item by predicate\n const updateItem = useCallback(\n (predicate: (item: TData) => boolean, update: Partial<TData> | ((item: TData) => TData)) => {\n setState((prev) => ({\n ...prev,\n items: prev.items.map((item) => {\n if (!predicate(item)) return item;\n if (typeof update === 'function') {\n return update(item);\n }\n return { ...item, ...update };\n }),\n }));\n },\n []\n );\n\n // Sentinel ref callback for auto-loading\n const sentinelRef = useCallback(\n (element: HTMLElement | null) => {\n // Disconnect previous observer\n if (observerRef.current) {\n observerRef.current.disconnect();\n }\n\n sentinelElementRef.current = element;\n\n if (!element) return;\n\n // Create new observer\n observerRef.current = new IntersectionObserver((entries) => {\n if (entries[0]?.isIntersecting) {\n fetchNextPage();\n }\n }, observerOptionsRef.current);\n\n observerRef.current.observe(element);\n },\n [fetchNextPage]\n );\n\n // Initial fetch on mount\n useEffect(() => {\n fetchPage(initialCursor, true);\n // Only run on mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return {\n items: state.items,\n pages: state.pages,\n error: state.error,\n isLoading: state.isLoading,\n isFetchingMore: state.isFetchingMore,\n hasNextPage: state.hasNextPage,\n isEmpty: state.isEmpty,\n totalCount: state.totalCount,\n fetchNextPage,\n refresh,\n reset,\n sentinelRef,\n prependItems,\n appendItems,\n removeItem,\n updateItem,\n };\n}\n"]}
|