This is work in progress
ngx-focus-trap
Trap focus within a DOM node.
There may come a time when you find it important to trap focus within a DOM node — so that when a user hits Tab
or Shift+Tab
or clicks around, they can't escape a certain cycle of focusable elements.
You will definitely face this challenge when you are trying to build accessible modals.
This Angular module is built over focus-trap to help you solve this challenge .
Table of contents
Getting Started
ngx-focus-trap contains a angular directive. You can apply this directive to your div to contain focus inside that div only
Installation instructions
Method 1
Install ngx-focus-trap
from npm
:
npm install ngx-focus-trap --save
Add NgxFocusTrapModule
to NgModule imports:
import { NgxFocusTrapModule } from 'ngx-focus-trap';
@NgModule({
...
imports: [NgxFocusTrapModule,...]
...
})
Add component to your page:
<div class="nested" ngxFocusTrap #ngxFocus="ngxFocusTrap">
<input type="text">
<input type="text">
<input type="text">
<button>Submit</button>
<button (click)="ngxFocus.deactivateFocusTrap()">Disable Focus Trap</button>
</div>
Method 2
TODO: Add support for schematics
Use the Angular CLI ng add command for updating your Angular project
ng add ngx-focus-trap
Add directive to your div:
<div class="nested" ngxFocusTrap #ngxFocus="ngxFocusTrap">
<input type="text">
<input type="text">
<input type="text">
<button>Submit</button>
<button (click)="ngxFocus.deactivateFocusTrap()">Disable Focus Trap</button>
</div>
Browser Support
IE9+
Why? Because this module uses EventTarget.addEventListener()
. And its only dependency, tabbable, uses a couple of IE9+ functions.
Usage & Demo
TODO: Create a demo on stack blitz
API
Inputs
- initActivated {boolean}: By default, when a
ngxFocusTrap
is attached to a element it is automatically activated. You can control this behaviour by passingtrue
orfalse
toinitAcivated
.
<div ngxFocusTrap [initActivated]="false" #focusTrap="ngxFocusTrap"... />
<button (click)="focusTrap.activateFocusTrap()">Enable Focus Trap</button>
- initialFocus {element|string}: By default, when a focus trap is activated the first element in the focus trap's tab order will receive focus. With this option you can specify a different element to receive that initial focus. Can be a DOM node, or a selector string (which will be passed to
document.querySelector()
to find the DOM node), or a function that returns a DOM node. - fallbackFocus {element|string}: By default, an error will be thrown if the focus trap contains no elements in its tab order. With this option you can specify a fallback element to programmatically receive focus if no other tabbable elements are found. For example, you may want a popover's
<div>
to receive focus if the popover's content includes no tabbable elements. Make sure the fallback element has a negativetabindex
so it can be programmatically focused. The option value can be a DOM node, a selector string (which will be passed todocument.querySelector()
to find the DOM node), or a function that returns a DOM node. - escapeDeactivates {boolean}: Default:
true
. Iffalse
, theEscape
key will not trigger deactivation of the focus trap. This can be useful if you want to force the user to make a decision instead of allowing an easy way out. - clickOutsideDeactivates {boolean}: Default:
false
. Iftrue
, a click outside the focus trap will deactivate the focus trap and allow the click event to do its thing. - returnFocusOnDeactivate {boolean}: Default:
true
. Iffalse
, when the trap is deactivated, focus will not return to the element that had focus before activation.
Outputs
activate
Emits event when focus trap is activated.
deactivate
Emits event when focus trap is deactivated.
Methods
activateFocusTrap
call this method to manually activate focus trap.
deactivateFocusTrap
call this method when you want to deactivate focus trap like when you are closing the modal window to which focus trap was applied.
pause
call this method to pause focus trap.
unpause
call this method to un pause focus trap.
How to build lib for development
First time:
-
clone repository
-
npm install
-
npm run build
To update your fork and prepare it for local usage:
-
git pull upstream development
-
rm -rf node_modules
-
npm install
-
npm run build
To run the demo:
npm run demo.serve
// to serve local demo. This is for testing only, without watchers.
For local development run:
-
npm run build.watch
// in first terminal -
ng serve
// in second