/**
* use-spinner.ts — Hook for animated braille spinner in Ink.
*
* Returns a frame counter that increments at 120ms intervals when active.
* Use with ProgressView's spinFrame prop to animate the spinner.
*
* Usage:
* const frame = useSpinner(isSpinning);
*
*/
import { useState, useEffect, useRef } from "react";
/** Default spinner interval in milliseconds. */
const SPIN_INTERVAL_MS = 120;
/**
* useSpinner — returns an incrementing frame counter when active.
*
* @param active Whether the spinner should be animating.
* @param intervalMs Interval between frames (default: 120ms).
* @returns The current frame number (starts at 0).
*/
export function useSpinner(active: boolean, intervalMs: number = SPIN_INTERVAL_MS): number {
const [frame, setFrame] = useState(0);
const intervalRef = useRef | null>(null);
useEffect(() => {
if (active) {
intervalRef.current = setInterval(() => {
setFrame((prev) => prev + 1);
}, intervalMs);
} else {
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
}
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
};
}, [active, intervalMs]);
return frame;
}