by theKashey

theKashey / react-focus-on

🎯 Solution for WAI ARIA compatible modal dialogs or full-screen tasks, you were looking for

160 Stars 8 Forks Last release: 2 months ago (v3.5.0) MIT License 103 Commits 27 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

πŸ‘ React-Focus-On

lock and loaded!
Build status npm downloads bundle size

The final solution for WAI ARIA compatible Modal Dialogs or any full-screen tasks: - locks focus inside using react-focus-lock - disables page scroll and user interactions using react-remove-scroll - hides rest of a page from screen-readers using aria-hidden

Now you could focus on a single task.

This is basically the


Minimal size - no more than 2kb, maximal - no more that 6kb. See sidecar example for details.


Code sandbox example - ```js import {FocusOn} from 'react-focus-on';

<FocusOn onClickOutside={callback} onEscapeKey={callback} shards={[externalRef]}

content you should be "focused" on




- the focus on component -
- controls behaviour

- a list of Refs to be considered as a part of the Lock. A way to properly handle portals or scattered lock.

- you could whitelist locations FocusLock should carry about. Everything outside it will ignore. For example - any modals (see react-focus-lock documentation)

  • [gapMode]
    - the way removed ScrollBar would be compensated - margin(default), or padding. See scroll-locky documentation to find the one you need.
  • [noIsolation]
    - disables aria-hidden isolation
  • [inert]
    - enables pointer-events isolation (☠️ dangerous, use to disable "parent scrollbars", refer to react-remove-scroll documentation)

- enables "pinch-n-zoom" behavior. By default it might be prevented, refer to react-remove-scroll documentation

  • [onActivation]
    - on activation callback

- on deactivation callback

  • [onClickOutside]
    - on click outside of "focus" area. (actually on any event "outside")
  • [onEscapeKey]
    - on Esc key down (and not defaultPrevented)

Additional API

Exposed from React-Focus-Lock

  • AutoFocusInside
    - to mark autofocusable element
  • MoveFocusInside
    - to move focus inside a component on mount
  • InFocusGuard
    - to "guard" a shard node (place an invisible node before and after)

See react-focus-lock documentation for details.

Exposed from React-Remove-Scroll

  • classNames.fullWidth
    - "100%" width (will not change on scrollbar removal)
  • classNames.zeroRight
    - "0" right (will not change on scrollbar removal)

See react-remove-scroll for details.

PS: Version 1 used React-scroll-locky which was replaced by remove-scroll.


- (🧩 full) 5.7kb after compression (excluding tslib).

  • (πŸ‘ UI) 2kb, visual elements only
  • (πŸš— sidecar) 4kb, side effects

Import full

import {FocusOn} from 'react-focus-on';


Import UI only

import {FocusOn} from 'react-focus-on/UI';
import {sidecar} from "use-sidecar";

const FocusOnSidecar = sidecar(
() => import(/* webpackPrefetch: true */ "react-focus-on/sidecar") );


React versions

  • v1 and v2 might work with React 15/16
  • v3 require React 16.8+ (hooks)



We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.