useIdleDetection
Location: src/hooks/useIdleDetection.js
Overview
Tracks user activity (mouse movement, clicks, key presses, touch, scroll, wheel) and sets an isIdle flag after a configurable period of inactivity. Activity handlers are throttled to fire at most once per second to avoid excessive state updates.
Used to support features like auto-locking, session management, and privacy-related behaviors aligned with the platform's "Privacy Is Infrastructure" invariant.
Signature
function useIdleDetection(
timeoutMinutes?: number,
enabled?: boolean
): {
isIdle: boolean,
resetIdle: () => void,
lastActivity: number
}
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
timeoutMinutes | number | No | 5 | Minutes of inactivity before the user is considered idle. |
enabled | boolean | No | true | Whether idle detection is active. When false, isIdle is always false and no listeners are attached. |
Return Value
| Property | Type | Description |
|---|---|---|
isIdle | boolean | true when the user has been inactive for longer than the configured timeout. Resets to false on any user activity. |
resetIdle | () => void | Manually reset the idle state and activity timestamp. |
lastActivity | number | Timestamp (from Date.now()) of the most recent detected user activity. |
Tracked Events
The hook listens for the following events on the window object (with { passive: true }):
mousemovemousedownkeydowntouchstartscrollwheel
All events are throttled to a maximum of one update per second.
Usage
function AutoLockWrapper({ children }) {
const { isIdle } = useIdleDetection(10); // 10 minutes
if (isIdle) {
return <LockScreen />;
}
return children;
}
With custom timeout and manual reset
function SessionManager() {
const { isIdle, resetIdle, lastActivity } = useIdleDetection(15, true);
useEffect(() => {
if (isIdle) {
showIdleWarning();
}
}, [isIdle]);
return (
<div>
<p>Last activity: {new Date(lastActivity).toLocaleTimeString()}</p>
{isIdle && (
<div>
<p>You appear to be away.</p>
<button onClick={resetIdle}>I am here</button>
</div>
)}
</div>
);
}
Last updated: 2026-02-07