What is Focus Manager?

This is a small Javascript library to help you with focus management for modal dialogs and other content that is opened in the page. How you open or close these dialogs and other content is up to you, this library is just here to help you make your dialogs more accessible for keyboard users.

Examples

Opening a modal dialog

The first example is here to demonstrate the problem. It is all to easy to loose where the focus is without it being properly managed. Try it out.

This example shows how focus can be managed effectively. See for yourself how much nicer it is.

The code

var openedClass = "is-opened";

var openButton = document.querySelector("[data-open-modal-dialog]");
var closeButton = document.querySelectorAll("[data-close-modal-dialog]");
var dialog = document.querySelector("[data-dialog]");

// Listen for clicks on the open button
openButton.addEventListener("click", function (evnt) {
	// How you open the dialog is
	// your own concern
	// for simplicity's sake a class is
	// added in this example
	dialog.classList.add(openedClass);

	// After the dialog gets shown
	// make sure only elements inside
	// the dialog can be focused
	focusManager.capture(dialog);
});

// Listen for clicks on the close button
closeButton.addEventListener("click", function (evnt) {
	// How you close the dialog is
	// your own concern
	// for simplicity's sake a class is
	// removed in this example
	dialog.classList.remove(openedClass);

	// After the dialog gets closed
	// focus should resume to work as
	// normal so the focus capture is released
	// openButton is supplied as an argument
	// so that it will receive focus after
	// the dialog has been closed
	focusManager.release(openButton);
});

Installation

The easiest way to install Focus Manager is npm, execute the following command in your project directory:

npm install --save focus-manager

Alternatively you can download the source manually from GitHub. There is a development build and a minified build.

Documentation

focusManager.focusFirstInElement(element)

If the element is focusable it will be focused. Otherwise the first descendant that is focusable will be focused. If this fails the element itself will be made focusable and will be focused.

focusManager.focusLastInElement(element)

The last descendant that is focusable will be focused. If this fails the element itself will be made focusable and will be focused.

focusManager.capture(modal, focusElement: optional, backgroundElement: optional)

focusManager.capture will only allow modal and it's descendants to be focused. Whenever an element outside modal receives focus, modal or the first focusable descendant inside modal will be focused. Thus helping keyboard users to stay inside the modal until it is dismissed.

Optionally a focusElement can be provided. This element will receive the initial focus instead of the first focusable descendant. If no focusElement is provided focusManager.focusInElement(modal) will be used to determine which element will receive the initial focus.

Optionally a backgroundElement can be provided. It defaults to document. Any time focus gets set inside this element focus gets reset to the modal element. Note, the modal element can be a descendant of the backgroundElement

focusManager.capture will keep listening for focus events until it is released.

This function should be used when opening a modal dialog.

focusManager.release(focusElement: optional)

focusManager.release will release the captured focus and allow elements to be focused as they normally would be.

Optionally a focusElement can be provided. This element will receive focus when this function is executed.

This function should be used when closing a modal dialog.

License

Focus Manager is licensed under the ISC license. See the license file for details.