UNPKG

@mantine/hooks

Version:

A collection of 50+ hooks for state and UI management

92 lines (91 loc) 2.7 kB
"use client"; import { useCallbackRef } from "../utils/use-callback-ref/use-callback-ref.mjs"; import { useEffect, useMemo, useRef } from "react"; //#region packages/@mantine/hooks/src/use-debounced-callback/use-debounced-callback.ts function useDebouncedCallback(callback, options) { const { delay, flushOnUnmount, leading } = typeof options === "number" ? { delay: options, flushOnUnmount: false, leading: false } : options; const handleCallback = useCallbackRef(callback); const debounceTimerRef = useRef(0); const lastCallback = useMemo(() => { const currentCallback = Object.assign((...args) => { window.clearTimeout(debounceTimerRef.current); const isFirstCall = currentCallback._isFirstCall; currentCallback._isFirstCall = false; function clearTimeoutAndLeadingRef() { window.clearTimeout(debounceTimerRef.current); debounceTimerRef.current = 0; currentCallback._isFirstCall = true; } if (leading && isFirstCall) { handleCallback(...args); const resetLeadingState = () => { clearTimeoutAndLeadingRef(); }; const flush = () => { if (debounceTimerRef.current !== 0) { clearTimeoutAndLeadingRef(); handleCallback(...args); } }; const cancel = () => { clearTimeoutAndLeadingRef(); }; currentCallback.flush = flush; currentCallback.cancel = cancel; debounceTimerRef.current = window.setTimeout(resetLeadingState, delay); return; } if (leading && !isFirstCall) { const flush = () => { if (debounceTimerRef.current !== 0) { clearTimeoutAndLeadingRef(); handleCallback(...args); } }; const cancel = () => { clearTimeoutAndLeadingRef(); }; currentCallback.flush = flush; currentCallback.cancel = cancel; const resetLeadingState = () => { clearTimeoutAndLeadingRef(); }; debounceTimerRef.current = window.setTimeout(resetLeadingState, delay); return; } const flush = () => { if (debounceTimerRef.current !== 0) { clearTimeoutAndLeadingRef(); handleCallback(...args); } }; const cancel = () => { clearTimeoutAndLeadingRef(); }; currentCallback.flush = flush; currentCallback.cancel = cancel; debounceTimerRef.current = window.setTimeout(flush, delay); }, { flush: () => {}, cancel: () => {}, _isFirstCall: true }); return currentCallback; }, [ handleCallback, delay, leading ]); useEffect(() => () => { if (flushOnUnmount) lastCallback.flush(); else lastCallback.cancel(); }, [lastCallback, flushOnUnmount]); return lastCallback; } //#endregion export { useDebouncedCallback }; //# sourceMappingURL=use-debounced-callback.mjs.map