@jk-core/hooks
Version:
hooks for jk
1 lines • 9.65 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../src/useDebounce/index.ts","../src/useHistory/index.ts","../src/useHistoryEvent/index.ts","../src/useInterectOutside/index.ts","../src/useIntersectionObserver/index.ts","../src/useMediaQuery/index.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype Procedure = (...args: any[]) => void;\n\nconst useDebounce = (func: Procedure, delay: number): Procedure => {\n const funcRef = useRef(func);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // 매 렌더링마다 func가 바뀔 수 있으니 ref에 최신 함수 저장\n useEffect(() => {\n funcRef.current = func;\n return () => {\n if (timeoutRef.current !== null) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, [func]);\n\n const debouncedFn = useCallback((...args: any[]) => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n timeoutRef.current = setTimeout(() => {\n funcRef.current(...args);\n }, delay);\n }, [delay]);\n\n return debouncedFn;\n};\n\nexport default useDebounce;\n","const useHistory = () => {\n const { history } = window;\n\n const push = (path: string) => {\n const currentUrl = new URL(window.location.href);\n const newUrl = `${currentUrl.origin}${currentUrl.pathname}${currentUrl.search}${currentUrl.hash}/${path}`;\n history.pushState({}, '', newUrl);\n };\n\n const back = () => {\n history.back();\n };\n\n return {\n push, back,\n };\n};\n\nexport default useHistory;\n","import { useEffect } from 'react';\n\ninterface Update {\n action: 'POP' | 'PUSH' | 'REPLACE';\n location: Location;\n}\n\ninterface Listener {\n (update: Update): void;\n}\nconst useHistoryEvent = (listener: Listener) => {\n useEffect(() => {\n const handlePopState = () => {\n const action = 'POP';\n const { location } = window;\n listener({ action, location });\n };\n\n const handlePushState = () => {\n const action = 'PUSH';\n const { location } = window;\n listener({ action, location });\n };\n\n const handleReplaceState = () => {\n const action = 'REPLACE';\n const { location } = window;\n listener({ action, location });\n };\n\n window.addEventListener('popstate', handlePopState);\n window.addEventListener('pushstate', handlePushState);\n window.addEventListener('replacestate', handleReplaceState);\n\n return () => {\n window.removeEventListener('popstate', handlePopState);\n window.removeEventListener('pushstate', handlePushState);\n window.removeEventListener('replacestate', handleReplaceState);\n };\n }, [listener]);\n};\n\nexport default useHistoryEvent;\n","import { RefObject, useEffect } from 'react';\n\ninterface Props {\n targetRef: RefObject<HTMLElement | null>;\n eventList: Array<string>;\n handler: () => void;\n}\n// 설정한 컴포넌트 이외의 영역을 클릭할 경우 handler에 등록된 동작을 수행\nconst useInterectOutside = ({ targetRef, eventList = [], handler = () => {} }:Props) => {\n useEffect(() => {\n const handleClickOutside = (event:Event) => {\n if (targetRef.current && !targetRef.current.contains(event.target as Node)) {\n handler();\n }\n };\n\n if (Array.isArray(eventList)) {\n eventList.map((event) => window.addEventListener(event, handleClickOutside));\n }\n\n return () => {\n if (Array.isArray(eventList)) {\n eventList.map((event) => window.removeEventListener(event, handleClickOutside));\n }\n };\n }, [targetRef, handler, eventList]);\n};\n\nexport default useInterectOutside;\n","import { useEffect } from 'react';\n\ninterface IntersectionObserverProps<T1 extends HTMLElement, T2 extends HTMLElement> {\n target: React.RefObject<T1 | null>;\n parent?: React.RefObject<T2 | null>;\n callback: () => void;\n options?: IntersectionObserverInit;\n}\n// 인피니티 스크롤 옵저버설정 훅\nconst useIntersectionObserver = <T1 extends HTMLElement, T2 extends HTMLElement>({\n target, parent, callback, options,\n}:IntersectionObserverProps<T1, T2>) => {\n useEffect(() => {\n const ref = target.current;\n const parentRef = parent?.current;\n\n if (!ref) return () => { };\n\n const observer = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting) callback();\n }, {\n ...parentRef ? { root: parentRef } : {}, threshold: 1, ...options,\n });\n\n observer.observe(ref);\n\n return () => {\n observer.unobserve(ref);\n };\n }, [callback, options, parent, target]);\n};\n\nexport default useIntersectionObserver;\n","import { useEffect, useRef, useState } from 'react';\n\nconst useMediaQuery = (width: number) => {\n const isWindowDefined =\n typeof window !== 'undefined' && typeof window.matchMedia !== 'undefined';\n\n const [matches, setMatches] = useState(() => {\n if (!isWindowDefined) {\n return false;\n }\n try {\n return window.matchMedia(`(max-width: ${width}px)`).matches;\n } catch {\n return false;\n }\n });\n\n const matchMediaRef = useRef<MediaQueryList | null>(null);\n\n useEffect(() => {\n if (!isWindowDefined) {\n return;\n }\n\n try {\n const matchMedia = window.matchMedia(`(max-width: ${width}px)`);\n matchMediaRef.current = matchMedia;\n\n const handleChange = () => {\n try {\n setMatches(window.matchMedia(`(max-width: ${width}px)`).matches);\n } catch {\n // 조용히 실패 처리\n }\n };\n\n // 최신 브라우저는 addEventListener를 지원\n if (matchMedia.addEventListener) {\n matchMedia.addEventListener('change', handleChange);\n return () => {\n matchMedia.removeEventListener('change', handleChange);\n };\n }\n\n // 구형 브라우저 호환성 (addListener/removeListener)\n matchMedia.addListener(handleChange);\n return () => {\n matchMedia.removeListener(handleChange);\n };\n } catch {\n // 조용히 실패 처리\n }\n }, [isWindowDefined, width]);\n\n return matches;\n};\n\nexport default useMediaQuery;\n"],"names":["useDebounce","func","delay","funcRef","useRef","timeoutRef","useEffect","useCallback","args","useHistory","history","path","currentUrl","newUrl","useHistoryEvent","listener","handlePopState","action","location","handlePushState","handleReplaceState","useInterectOutside","targetRef","eventList","handler","handleClickOutside","event","useIntersectionObserver","target","parent","callback","options","ref","parentRef","observer","entry","useMediaQuery","width","isWindowDefined","matches","setMatches","useState","matchMediaRef","matchMedia","handleChange"],"mappings":"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"}