React focus management library that provides robust focus trapping functionality for modal dialogs and accessibility compliance
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Core React components for implementing focus trapping, including the main FocusLock component and helper components for specific focus behaviors like auto-focusing and free focus movement.
The main focus lock component that traps focus within its children, preventing tab navigation outside the component boundary.
/**
* Main focus lock component that traps focus within its children
* @param props - Configuration options for focus behavior
* @returns React component that wraps children with focus trapping
*/
declare const FocusLock: FC<ReactFocusLockProps>;
interface ReactFocusLockProps {
/** Enable or disable the focus lock */
disabled?: boolean;
/** Return focus to previous position on unmount */
returnFocus?: boolean | FocusOptions | ((returnTo: Element) => boolean | FocusOptions);
/**
* @deprecated Can lead to wrong user experience. Use only if you know what you are doing.
* Controls behavior of returning focus back to the lock
*/
focusOptions?: FocusOptions;
/** @deprecated Use persistentFocus=false instead */
allowTextSelection?: boolean;
/** Require persistent focus, disables text selection */
persistentFocus?: boolean;
/** Enable cross-iframe focus handling */
crossFrame?: boolean;
/** Auto-focus on activation */
autoFocus?: boolean;
/** Disable focus guards */
noFocusGuards?: boolean | "tail";
/** Handle positive tab indices */
hasPositiveIndices?: boolean;
/** Named group for scattered locks */
group?: string;
/** CSS class name */
className?: string;
/** Callback on lock activation */
onActivation?(node: HTMLElement): void;
/** Callback on lock deactivation */
onDeactivation?(node: HTMLElement): void;
/** Component element type, defaults to 'div' */
as?: string | ElementType<LockProps & { children: ReactNode }>;
/** Additional props for wrapper element */
lockProps?: LockProps;
/** React ref */
ref?: Ref<HTMLElement>;
/** Focus whitelist function */
whiteList?: (activeElement: HTMLElement) => boolean;
/** Scattered lock elements */
shards?: Array<RefObject<any> | HTMLElement>;
/** Child components */
children?: ReactNode;
}Usage Examples:
import React from "react";
import FocusLock from "react-focus-lock";
// Basic focus lock
function BasicModal({ children, onClose }) {
return (
<FocusLock>
<div className="modal">
{children}
<button onClick={onClose}>Close</button>
</div>
</FocusLock>
);
}
// Advanced configuration
function AdvancedModal({ children, onClose }) {
return (
<FocusLock
returnFocus={true}
autoFocus={true}
persistentFocus={false}
onActivation={(node) => console.log("Focus lock activated", node)}
onDeactivation={(node) => console.log("Focus lock deactivated", node)}
>
<div className="modal">
{children}
<button onClick={onClose}>Close</button>
</div>
</FocusLock>
);
}
// Scattered focus with shards
function ScatteredModal({ children, headerRef, footerRef }) {
return (
<FocusLock shards={[headerRef, footerRef]}>
<div className="modal-content">
{children}
</div>
</FocusLock>
);
}Automatically focuses children on lock activation.
/**
* Automatically focuses children on lock activation
* @param props - Component configuration
* @returns React component that triggers autofocus
*/
declare class AutoFocusInside extends Component<AutoFocusProps> {}
interface AutoFocusProps {
/** Child components */
children: ReactNode;
/** Disable autofocus behavior */
disabled?: boolean;
/** CSS class name */
className?: string;
}Usage Example:
import { AutoFocusInside } from "react-focus-lock";
function FormModal() {
return (
<FocusLock>
<div className="modal">
<AutoFocusInside>
<input placeholder="This will be auto-focused" />
</AutoFocusInside>
<button>Other button</button>
</div>
</FocusLock>
);
}Immediately moves focus inside children on mount.
/**
* Immediately moves focus inside children on mount
* @param props - Component configuration
* @returns React component that moves focus on mount
*/
declare class MoveFocusInside extends Component<AutoFocusProps> {}Usage Example:
import { MoveFocusInside } from "react-focus-lock";
function DialogWithForcedFocus() {
return (
<div className="dialog">
<MoveFocusInside>
<div>
<input placeholder="Focus will move here immediately" />
<button>Button</button>
</div>
</MoveFocusInside>
</div>
);
}Allows free focus movement inside children, hiding them from FocusLock.
/**
* Allows free focus movement inside children, hiding from FocusLock
* @param props - Component configuration
* @returns React component that allows free focus
*/
declare class FreeFocusInside extends Component<FreeFocusProps> {}
interface FreeFocusProps {
/** Child components */
children: ReactNode;
/** CSS class name */
className?: string;
}Usage Example:
import FocusLock, { FreeFocusInside } from "react-focus-lock";
function ModalWithFreeArea() {
return (
<FocusLock>
<div className="modal">
<input placeholder="Locked input" />
<FreeFocusInside>
<div className="free-area">
<input placeholder="Free focus input" />
<button>Free focus button</button>
</div>
</FreeFocusInside>
<button>Locked button</button>
</div>
</FocusLock>
);
}Secures the focus around the node, providing invisible focus guards.
/**
* Secures the focus around the node with invisible guards
* @param props - Component configuration
* @returns React component that provides focus guards
*/
declare class InFocusGuard extends Component<InFocusGuardProps> {}
interface InFocusGuardProps {
/** Child components */
children?: ReactNode;
}Usage Example:
import { InFocusGuard } from "react-focus-lock";
function GuardedContent() {
return (
<InFocusGuard>
<div>
<input placeholder="Guarded input" />
<button>Guarded button</button>
</div>
</InFocusGuard>
);
}UI-only version of FocusLock that requires a separate sidecar for the focus trap logic.
/**
* UI-only version of FocusLock requiring external sidecar
* @param props - Configuration including sidecar
* @returns React component with UI logic only
*/
declare const FocusLockUI: FC<ReactFocusLockProps & { sideCar: FC<any> }>;Usage Example:
import { FocusLockUI } from "react-focus-lock/UI";
import sidecar from "react-focus-lock/sidecar";
function CustomFocusLock({ children }) {
return (
<FocusLockUI sideCar={sidecar}>
{children}
</FocusLockUI>
);
}Install with Tessl CLI
npx tessl i tessl/npm-react-focus-lock