UNPKG

@trail-ui/react

Version:
57 lines (55 loc) 1.51 kB
// src/number-input/use-spinner.ts import { useInterval } from "@trail-ui/hooks"; import { useCallback, useEffect, useRef, useState } from "react"; var CONTINUOUS_CHANGE_INTERVAL = 50; var CONTINUOUS_CHANGE_DELAY = 300; function useSpinner(increment, decrement) { const [isSpinning, setIsSpinning] = useState(false); const [action, setAction] = useState(null); const [runOnce, setRunOnce] = useState(true); const timeoutRef = useRef(null); const removeTimeout = () => clearTimeout(timeoutRef.current); useInterval( () => { if (action === "increment") { increment(); } if (action === "decrement") { decrement(); } }, isSpinning ? CONTINUOUS_CHANGE_INTERVAL : null ); const up = useCallback(() => { if (runOnce) { increment(); } timeoutRef.current = setTimeout(() => { setRunOnce(false); setIsSpinning(true); setAction("increment"); }, CONTINUOUS_CHANGE_DELAY); }, [increment, runOnce]); const down = useCallback(() => { if (runOnce) { decrement(); } timeoutRef.current = setTimeout(() => { setRunOnce(false); setIsSpinning(true); setAction("decrement"); }, CONTINUOUS_CHANGE_DELAY); }, [decrement, runOnce]); const stop = useCallback(() => { setRunOnce(true); setIsSpinning(false); removeTimeout(); }, []); useEffect(() => { return () => removeTimeout(); }, []); return { up, down, stop, isSpinning }; } export { useSpinner };