Created
October 13, 2025 19:09
-
-
Save Wigny/b74595a7a4e37e0ece97558e81a41682 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { useEffect, useState } from 'react'; | |
| import { type Duration } from 'dayjs/plugin/duration'; | |
| import { throttle } from 'lodash-es'; | |
| const events: Array<keyof DocumentEventMap> = [ | |
| 'mousemove', | |
| 'keydown', | |
| 'wheel', | |
| 'mousedown', | |
| 'touchstart', | |
| 'touchmove', | |
| 'focus', | |
| 'timeupdate', | |
| ]; | |
| /** | |
| * Detects user inactivity after a specified timeout period. | |
| * | |
| * Returns `true` when the user has been idle for longer than the specified timeout. | |
| */ | |
| export function useIdle(timeout: Duration): boolean { | |
| const [idle, setIdle] = useState(false); | |
| const ms = timeout.asMilliseconds(); | |
| useEffect(() => { | |
| let timeoutId: number; | |
| const setIdleTimer = () => { | |
| setIdle(false); | |
| window.clearTimeout(timeoutId); | |
| timeoutId = window.setTimeout(() => setIdle(true), ms); | |
| }; | |
| const handleEvent = throttle(setIdleTimer, 500, { leading: true, trailing: false }); | |
| const handleVisibilityChange = () => { | |
| if (!document.hidden) handleEvent(); | |
| }; | |
| events.forEach(event => document.addEventListener(event, handleEvent, { capture: true, passive: true })); | |
| document.addEventListener('visibilitychange', handleVisibilityChange); | |
| setIdleTimer(); | |
| return () => { | |
| events.forEach(event => document.removeEventListener(event, handleEvent, { capture: true })); | |
| document.removeEventListener('visibilitychange', handleVisibilityChange); | |
| window.clearTimeout(timeoutId); | |
| }; | |
| }, [ms]); | |
| return idle; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment