blob: 0a55953b81a071babb0fd949dc66b68345049e7f [file]
import { useEffect, useRef, useState } from 'react';
import { createDelayedFlag, type DelayedFlag } from './model-wait-state.js';
/**
* React binding for `createDelayedFlag` (#646): a boolean that turns true only
* after `condition` has held true for `delayMs`, and false immediately when it
* drops. The timing/arm/cancel logic lives in the pure `createDelayedFlag` (unit
* tested with fake timers); this hook only wires it to `window` timers + a
* re-render. `delayMs` is read once at mount — it is a constant in practice.
*/
export function useDelayedFlag(condition: boolean, delayMs: number): boolean {
const [visible, setVisible] = useState(false);
const flagRef = useRef<DelayedFlag | null>(null);
if (flagRef.current === null) {
flagRef.current = createDelayedFlag({
delayMs,
scheduler: {
setTimeout: (handler, ms) => window.setTimeout(handler, ms),
clearTimeout: (handle) => window.clearTimeout(handle as number),
},
onChange: setVisible,
});
}
useEffect(() => {
flagRef.current?.setCondition(condition);
}, [condition]);
useEffect(() => () => flagRef.current?.dispose(), []);
return visible;
}