@afex-dapps/idle-timer
v1.1.4
Published
Idle Timer library for detecting user inactivity and managing session timeouts
Maintainers
Readme
@afex-dapps/idle-timer
A React library for detecting user inactivity and managing session timeouts with customizable UI components.
Features
- 🕐 Configurable inactivity detection
- ⚠️ Customizable timeout warning prompts
- 🔄 Cross-tab synchronization
- 🎨 Bring your own UI components
- 📱 TypeScript support
- 🪝 React hooks API
- ⏱️ Built-in countdown timer functionality
- 🎯 Modal/prompt management utilities
Installation
npm install @afex-dapps/idle-timer
# or
yarn add @afex-dapps/idle-timer
# or
pnpm add @afex-dapps/idle-timerNote: This library requires
reactandreact-domas a peer dependency.
Quick Start
Basic Usage with useIdleTimeout Hook
import { useState } from "react";
import { IdleTimerProvider, useIdleTimeout } from "@afex-dapps/idle-timer";
function MyComponent() {
const [isLoggedIn, setIsLoggedIn] = useState(true);
const { remainingTime, continueUserSession, showIdleTimerPrompt } =
useIdleTimeout({
timeout: 5 * 60 * 1000, // 5 minutes
promptBeforeIdle: 1 * 60 * 1000, // 1 minute warning
onIdle: () => {
setIsLoggedIn(false);
console.log("User logged out due to inactivity");
},
disabled: !isLoggedIn, // Only run when logged in
});
return (
<IdleTimerProvider>
<div>
<h1>{isLoggedIn ? "Welcome!" : "Please log in"}</h1>
{showIdleTimerPrompt && (
<div className="warning-modal">
<p>Session expires in {remainingTime} seconds</p>
<button onClick={continueUserSession}>Continue Session</button>
</div>
)}
</div>
</IdleTimerProvider>
);
}Advanced Usage with Custom Modal
import { useState } from "react";
import {
IdleTimerProvider,
useIdleTimeout,
formatTime,
} from "@afex-dapps/idle-timer";
// Custom prompt component
const SessionTimeoutModal = ({
isOpen,
remainingTime,
onContinue,
onLogout,
}) => {
if (!isOpen) return null;
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white p-6 rounded-lg max-w-md">
<h2 className="text-xl font-bold mb-4">⚠️ Session Timeout Warning</h2>
<p className="mb-4">
Your session will expire in{" "}
<span className="font-mono text-2xl text-red-600">
{formatTime(remainingTime)}
</span>
</p>
<div className="flex gap-3">
<button
onClick={onContinue}
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
>
Continue Session
</button>
<button
onClick={onLogout}
className="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600"
>
Logout Now
</button>
</div>
</div>
</div>
);
};
function App() {
const [isAuthenticated, setIsAuthenticated] = useState(true);
const handleLogout = () => {
setIsAuthenticated(false);
// Your logout logic here
console.log("Logging out...");
};
const { remainingTime, continueUserSession, showIdleTimerPrompt } =
useIdleTimeout({
timeout: 300000, // 5 minutes
promptBeforeIdle: 60000, // 1 minute
crossTab: true,
leaderElection: true,
onIdle: handleLogout,
disabled: !isAuthenticated,
});
return (
<IdleTimerProvider>
<div>
<h1>{isAuthenticated ? "Dashboard" : "Login Required"}</h1>
<SessionTimeoutModal
isOpen={showIdleTimerPrompt}
remainingTime={remainingTime}
onContinue={continueUserSession}
onLogout={handleLogout}
/>
</div>
</IdleTimerProvider>
);
}Using Hooks Directly
import { useIdleTimeout } from "@afex-dapps/idle-timer";
function MyComponent() {
const { remainingTime, continueUserSession, showIdleTimerPrompt, idleTimer } =
useIdleTimeout({
timeout: 300000, // 5 minutes
promptBeforeIdle: 60000, // 1 minute
onIdle: () => console.log("User is idle"),
onPrompt: () => console.log("Showing prompt"),
});
if (showIdleTimerPrompt) {
return (
<div>
<p>You'll be logged out in {remainingTime} seconds</p>
<button onClick={continueUserSession}>Stay Active</button>
</div>
);
}
return <div>Your content here</div>;
}API Reference
useIdleTimeout Hook
The main hook that provides idle timeout functionality.
Parameters:
config: IIdleTimerProps- Configuration object from react-idle-timer
Returns:
{
remainingTime: number; // Time remaining in seconds
continueUserSession: () => void; // Function to reset timer and continue session
showIdleTimerPrompt: boolean; // Whether to show the timeout prompt
idleTimer: IIdleTimer; // The underlying idle timer instance
}IdleTimerProvider
Provider component from react-idle-timer. Wrap your app with this component.
import { IdleTimerProvider } from "@afex-dapps/idle-timer";
<IdleTimerProvider>
<YourApp />
</IdleTimerProvider>;Configuration Options
All configuration options are passed directly to react-idle-timer. Common options include:
| Property | Type | Default | Description |
| ------------------ | ---------- | ---------------- | --------------------------------- |
| timeout | number | 300000 (5 min) | Time in ms before user is idle |
| promptBeforeIdle | number | 60000 (1 min) | Time in ms to show warning |
| crossTab | boolean | true | Sync across browser tabs |
| leaderElection | boolean | true | Use leader election for cross-tab |
| syncTimers | number | 500 | Sync interval in ms |
| disabled | boolean | false | Disable the timer |
| onIdle | function | - | Callback when user becomes idle |
| onPrompt | function | - | Callback when prompt is shown |
| onAction | function | - | Callback when user is active |
For a complete list of options, see the react-idle-timer documentation.
Utility Functions
formatTime(ms: number): string- Format time as MM:SSmillisecondsToSeconds(ms: number): number- Convert ms to secondssecondsToMilliseconds(seconds: number): number- Convert seconds to ms
Debug Hook
import { useIdleTimerDebug } from "@afex-dapps/idle-timer";
function MyComponent() {
const { idleTimer } = useIdleTimeout({
/* config */
});
// Enable debug logging (logs timer state every second)
useIdleTimerDebug(idleTimer, true);
return <div>Your component</div>;
}Migration from Original Code
If you're migrating from the original InactivityProvider code, here's how to adapt it:
// Before (original code)
function InacitivityProvider({ children }) {
const { asPath } = useRouter();
const [opened, disclosure] = useDisclosure(false);
const logout = useLogout();
const disabled = asPath === "/" || asPath.startsWith("/auth");
const handleContinueSession = () => {
disclosure.close();
interval.stop();
timer.reset();
};
// ... rest of original code
}
// After (using this library)
function InactivityProvider({ children }) {
const { asPath } = useRouter();
const logout = useLogout();
const disabled = asPath === "/" || asPath.startsWith("/auth");
const { remainingTime, continueUserSession, showIdleTimerPrompt } =
useIdleTimeout({
timeout: 1000 * 60 * 5, // 5 minutes
promptBeforeIdle: 1000 * 60, // 1 minute
onIdle: logout,
disabled,
});
return (
<IdleTimerProvider>
{children}
<YourCustomModal
opened={showIdleTimerPrompt}
remainingTime={remainingTime}
onContinue={continueUserSession}
onLogout={logout}
/>
</IdleTimerProvider>
);
}Constants
The library exports several useful constants:
import {
DEFAULT_INACTIVITY_TIME, // 300000ms (5 minutes)
DEFAULT_PROMPT_TIME, // 60000ms (1 minute)
DEFAULT_DISCLOSURE_TIME, // 59 seconds
} from "@afex-dapps/idle-timer";TypeScript Support
The library is fully typed. Key types include:
import type {
UseIdleTimer, // Return type of useIdleTimeout
IdleTimerHandler, // Event handler type
IdleTimerCountdownCallback, // Countdown callback type
UseIdleTimerCountdown, // Countdown hook return type
} from "@afex-dapps/idle-timer";Best Practices
Always wrap your app with IdleTimerProvider:
import { IdleTimerProvider } from "@afex-dapps/idle-timer"; function App() { return ( <IdleTimerProvider> <YourApp /> </IdleTimerProvider> ); }Use the disabled prop for auth pages:
const disabled = !isAuthenticated || isOnAuthPage; useIdleTimeout({ disabled, ...config });Handle the continueUserSession properly:
const handleContinue = () => { // This automatically: // - Closes the prompt // - Stops the countdown // - Resets the idle timer continueUserSession(); };Customize timeout values for your use case:
// For development (shorter timeouts) const config = { timeout: 30 * 1000, // 30 seconds promptBeforeIdle: 10 * 1000, // 10 seconds }; // For production (longer timeouts) const config = { timeout: 15 * 60 * 1000, // 15 minutes promptBeforeIdle: 2 * 60 * 1000, // 2 minutes };
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Dependencies
This library depends on:
react-idle-timer- The core idle timer functionalityreact&react-dom- React framework (peer dependencies)
