UNPKG

@neo4j-ndl/react

Version:

React implementation of Neo4j Design System

162 lines 5.67 kB
"use strict"; /** * * Copyright (c) "Neo4j" * Neo4j Sweden AB [http://neo4j.com] * * This file is part of Neo4j. * * Neo4j is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.useDebounceCallback = useDebounceCallback; const react_1 = require("react"); const createDebouncedFunction = (callback, delay, options) => { var _a, _b; let timeoutId; let maxWaitTimeoutId; let lastArgs; let result; const isLeading = (_a = options.leading) !== null && _a !== void 0 ? _a : false; const isTrailing = (_b = options.trailing) !== null && _b !== void 0 ? _b : true; const maxWait = options.maxWait; const clearTimers = () => { if (timeoutId !== undefined) { clearTimeout(timeoutId); timeoutId = undefined; } if (maxWaitTimeoutId !== undefined) { clearTimeout(maxWaitTimeoutId); maxWaitTimeoutId = undefined; } }; const invoke = () => { if (lastArgs === undefined) { return result; } const args = lastArgs; lastArgs = undefined; result = callback(...args); return result; }; const scheduleTrailing = () => { if (!isTrailing) { if (isLeading) { if (timeoutId !== undefined) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { timeoutId = undefined; }, delay); } return; } if (timeoutId !== undefined) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { timeoutId = undefined; if (maxWaitTimeoutId !== undefined) { clearTimeout(maxWaitTimeoutId); maxWaitTimeoutId = undefined; } invoke(); }, delay); }; const scheduleMaxWait = () => { if (maxWait === undefined || maxWaitTimeoutId !== undefined) { return; } maxWaitTimeoutId = setTimeout(() => { if (timeoutId !== undefined) { clearTimeout(timeoutId); timeoutId = undefined; } maxWaitTimeoutId = undefined; invoke(); }, maxWait); }; const debounced = (...args) => { const isFirstInvocationInBurst = timeoutId === undefined && maxWaitTimeoutId === undefined; lastArgs = args; if (isLeading && isFirstInvocationInBurst) { result = callback(...args); lastArgs = undefined; } scheduleTrailing(); scheduleMaxWait(); return result; }; const cancel = () => { clearTimers(); lastArgs = undefined; }; const flush = () => { clearTimers(); return invoke(); }; const isPending = () => timeoutId !== undefined || maxWaitTimeoutId !== undefined || lastArgs !== undefined; return { cancel, debounced, flush, isPending }; }; /** * Local override for usehooks-ts useDebounceCallback. * * This keeps one debounced function instance across rerenders (unless delay/options change) * while always calling the latest callback. It avoids resetting debounce timing when * inline callbacks are recreated every render. */ function useDebounceCallback(func, delay = 500, options = {}) { var _a, _b; const latestCallbackRef = (0, react_1.useRef)(func); const debouncedStateRef = (0, react_1.useRef)(undefined); const isLeading = (_a = options.leading) !== null && _a !== void 0 ? _a : false; const isTrailing = (_b = options.trailing) !== null && _b !== void 0 ? _b : true; const maxWait = options.maxWait; (0, react_1.useEffect)(() => { latestCallbackRef.current = func; }, [func]); (0, react_1.useEffect)(() => { return () => { var _a; (_a = debouncedStateRef.current) === null || _a === void 0 ? void 0 : _a.cancel(); }; }, []); const debouncedState = (0, react_1.useMemo)(() => { var _a; (_a = debouncedStateRef.current) === null || _a === void 0 ? void 0 : _a.cancel(); const nextDebouncedState = createDebouncedFunction((...args) => latestCallbackRef.current(...args), delay, { leading: isLeading, maxWait, trailing: isTrailing, }); debouncedStateRef.current = nextDebouncedState; return nextDebouncedState; }, [delay, isLeading, isTrailing, maxWait]); return (0, react_1.useMemo)(() => { const wrapped = ((...args) => debouncedState.debounced(...args)); wrapped.cancel = () => { debouncedState.cancel(); }; wrapped.flush = () => { return debouncedState.flush(); }; wrapped.isPending = () => { return debouncedState.isPending(); }; return wrapped; }, [debouncedState]); } //# sourceMappingURL=index.js.map