UNPKG

@mantine/hooks

Version:

A collection of 50+ hooks for state and UI management

1 lines 6.84 kB
{"version":3,"file":"use-debounced-callback.mjs","names":[],"sources":["../../src/use-debounced-callback/use-debounced-callback.ts"],"sourcesContent":["import { useEffect, useMemo, useRef } from 'react';\nimport { useCallbackRef } from '../utils';\n\nexport interface UseDebouncedCallbackOptions {\n delay: number;\n flushOnUnmount?: boolean;\n leading?: boolean;\n maxWait?: number;\n}\n\nexport type UseDebouncedCallbackReturnValue<T extends (...args: any[]) => any> = ((\n ...args: Parameters<T>\n) => void) & { flush: () => void; cancel: () => void; isPending: () => boolean };\n\nexport function useDebouncedCallback<T extends (...args: any[]) => any>(\n callback: T,\n options: number | UseDebouncedCallbackOptions\n) {\n const { delay, flushOnUnmount, leading, maxWait } =\n typeof options === 'number'\n ? {\n delay: options,\n flushOnUnmount: false,\n leading: false,\n maxWait: undefined as number | undefined,\n }\n : options;\n\n const handleCallback = useCallbackRef(callback);\n const debounceTimerRef = useRef(0);\n const maxWaitTimerRef = useRef(0);\n const latestArgsRef = useRef<Parameters<T> | null>(null);\n\n const lastCallback = useMemo(() => {\n const currentCallback = Object.assign(\n (...args: Parameters<T>) => {\n window.clearTimeout(debounceTimerRef.current);\n latestArgsRef.current = args;\n\n const isFirstCall = currentCallback._isFirstCall;\n currentCallback._isFirstCall = false;\n\n function clearTimeoutAndLeadingRef() {\n window.clearTimeout(debounceTimerRef.current);\n window.clearTimeout(maxWaitTimerRef.current);\n debounceTimerRef.current = 0;\n maxWaitTimerRef.current = 0;\n currentCallback._isFirstCall = true;\n currentCallback._hasPendingCallback = false;\n }\n\n function startMaxWaitTimer() {\n if (maxWait !== undefined && maxWaitTimerRef.current === 0) {\n maxWaitTimerRef.current = window.setTimeout(() => {\n if (debounceTimerRef.current !== 0) {\n const latestArgs = latestArgsRef.current!;\n clearTimeoutAndLeadingRef();\n handleCallback(...latestArgs);\n }\n }, maxWait);\n }\n }\n\n if (leading && isFirstCall) {\n handleCallback(...args);\n\n const resetLeadingState = () => {\n clearTimeoutAndLeadingRef();\n };\n\n const flush = () => {\n if (debounceTimerRef.current !== 0) {\n clearTimeoutAndLeadingRef();\n handleCallback(...args);\n }\n };\n\n const cancel = () => {\n clearTimeoutAndLeadingRef();\n };\n\n currentCallback.flush = flush;\n currentCallback.cancel = cancel;\n debounceTimerRef.current = window.setTimeout(resetLeadingState, delay);\n startMaxWaitTimer();\n return;\n }\n\n if (leading && !isFirstCall) {\n currentCallback._hasPendingCallback = true;\n const flush = () => {\n if (debounceTimerRef.current !== 0) {\n clearTimeoutAndLeadingRef();\n handleCallback(...args);\n }\n };\n\n const cancel = () => {\n clearTimeoutAndLeadingRef();\n };\n\n currentCallback.flush = flush;\n currentCallback.cancel = cancel;\n\n const resetLeadingState = () => {\n clearTimeoutAndLeadingRef();\n };\n debounceTimerRef.current = window.setTimeout(resetLeadingState, delay);\n startMaxWaitTimer();\n return;\n }\n\n currentCallback._hasPendingCallback = true;\n\n const flush = () => {\n if (debounceTimerRef.current !== 0) {\n clearTimeoutAndLeadingRef();\n handleCallback(...args);\n }\n };\n\n const cancel = () => {\n clearTimeoutAndLeadingRef();\n };\n\n currentCallback.flush = flush;\n currentCallback.cancel = cancel;\n debounceTimerRef.current = window.setTimeout(flush, delay);\n startMaxWaitTimer();\n },\n {\n flush: () => {},\n cancel: () => {},\n isPending: () => currentCallback._hasPendingCallback,\n _isFirstCall: true,\n _hasPendingCallback: false,\n }\n );\n return currentCallback;\n }, [handleCallback, delay, leading, maxWait]);\n\n useEffect(\n () => () => {\n if (flushOnUnmount) {\n lastCallback.flush();\n } else {\n lastCallback.cancel();\n }\n },\n [lastCallback, flushOnUnmount]\n );\n\n return lastCallback;\n}\n\nexport namespace useDebouncedCallback {\n export type Options = UseDebouncedCallbackOptions;\n export type ReturnValue<T extends (...args: any[]) => any> = UseDebouncedCallbackReturnValue<T>;\n}\n"],"mappings":";;;;AAcA,SAAgB,qBACd,UACA,SACA;CACA,MAAM,EAAE,OAAO,gBAAgB,SAAS,YACtC,OAAO,YAAY,WACf;EACE,OAAO;EACP,gBAAgB;EAChB,SAAS;EACT,SAAS,KAAA;CACX,IACA;CAEN,MAAM,iBAAiB,eAAe,QAAQ;CAC9C,MAAM,mBAAmB,OAAO,CAAC;CACjC,MAAM,kBAAkB,OAAO,CAAC;CAChC,MAAM,gBAAgB,OAA6B,IAAI;CAEvD,MAAM,eAAe,cAAc;EACjC,MAAM,kBAAkB,OAAO,QAC5B,GAAG,SAAwB;GAC1B,OAAO,aAAa,iBAAiB,OAAO;GAC5C,cAAc,UAAU;GAExB,MAAM,cAAc,gBAAgB;GACpC,gBAAgB,eAAe;GAE/B,SAAS,4BAA4B;IACnC,OAAO,aAAa,iBAAiB,OAAO;IAC5C,OAAO,aAAa,gBAAgB,OAAO;IAC3C,iBAAiB,UAAU;IAC3B,gBAAgB,UAAU;IAC1B,gBAAgB,eAAe;IAC/B,gBAAgB,sBAAsB;GACxC;GAEA,SAAS,oBAAoB;IAC3B,IAAI,YAAY,KAAA,KAAa,gBAAgB,YAAY,GACvD,gBAAgB,UAAU,OAAO,iBAAiB;KAChD,IAAI,iBAAiB,YAAY,GAAG;MAClC,MAAM,aAAa,cAAc;MACjC,0BAA0B;MAC1B,eAAe,GAAG,UAAU;KAC9B;IACF,GAAG,OAAO;GAEd;GAEA,IAAI,WAAW,aAAa;IAC1B,eAAe,GAAG,IAAI;IAEtB,MAAM,0BAA0B;KAC9B,0BAA0B;IAC5B;IAEA,MAAM,cAAc;KAClB,IAAI,iBAAiB,YAAY,GAAG;MAClC,0BAA0B;MAC1B,eAAe,GAAG,IAAI;KACxB;IACF;IAEA,MAAM,eAAe;KACnB,0BAA0B;IAC5B;IAEA,gBAAgB,QAAQ;IACxB,gBAAgB,SAAS;IACzB,iBAAiB,UAAU,OAAO,WAAW,mBAAmB,KAAK;IACrE,kBAAkB;IAClB;GACF;GAEA,IAAI,WAAW,CAAC,aAAa;IAC3B,gBAAgB,sBAAsB;IACtC,MAAM,cAAc;KAClB,IAAI,iBAAiB,YAAY,GAAG;MAClC,0BAA0B;MAC1B,eAAe,GAAG,IAAI;KACxB;IACF;IAEA,MAAM,eAAe;KACnB,0BAA0B;IAC5B;IAEA,gBAAgB,QAAQ;IACxB,gBAAgB,SAAS;IAEzB,MAAM,0BAA0B;KAC9B,0BAA0B;IAC5B;IACA,iBAAiB,UAAU,OAAO,WAAW,mBAAmB,KAAK;IACrE,kBAAkB;IAClB;GACF;GAEA,gBAAgB,sBAAsB;GAEtC,MAAM,cAAc;IAClB,IAAI,iBAAiB,YAAY,GAAG;KAClC,0BAA0B;KAC1B,eAAe,GAAG,IAAI;IACxB;GACF;GAEA,MAAM,eAAe;IACnB,0BAA0B;GAC5B;GAEA,gBAAgB,QAAQ;GACxB,gBAAgB,SAAS;GACzB,iBAAiB,UAAU,OAAO,WAAW,OAAO,KAAK;GACzD,kBAAkB;EACpB,GACA;GACE,aAAa,CAAC;GACd,cAAc,CAAC;GACf,iBAAiB,gBAAgB;GACjC,cAAc;GACd,qBAAqB;EACvB,CACF;EACA,OAAO;CACT,GAAG;EAAC;EAAgB;EAAO;EAAS;CAAO,CAAC;CAE5C,sBACc;EACV,IAAI,gBACF,aAAa,MAAM;OAEnB,aAAa,OAAO;CAExB,GACA,CAAC,cAAc,cAAc,CAC/B;CAEA,OAAO;AACT"}