-
Notifications
You must be signed in to change notification settings - Fork 278
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(plugin): add focus tracker plugin
closes #127
- Loading branch information
1 parent
00a3159
commit 467bd28
Showing
6 changed files
with
134 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/** | ||
* Allows users to see what screen readers would see. | ||
*/ | ||
|
||
let Plugin = require("../base"); | ||
|
||
const FOCUS_EVENT = "focusin"; | ||
const BLUR_EVENT = "focusout"; | ||
|
||
// this will let us get a shorter info panel that just | ||
// lets the user know we are tracking their focus | ||
const PANEL_OPTIONS = { | ||
statusPanelView: true | ||
}; | ||
|
||
// we're going to use focusin and focusout because they bubble | ||
const FOCUS_STATES = { | ||
[FOCUS_EVENT]: "tota11y-outlined", | ||
[BLUR_EVENT]: "tota11y-was-focused" | ||
}; | ||
|
||
// we'll use this to make sure we don't apply the was-focused | ||
// indicator to our tota11y panels | ||
const IGNORE_WAS_FOCUSED_CLASS = "tota11y"; | ||
|
||
// convenient method to quickly remove any classes this | ||
// plugin applied | ||
// it is outside of the class because it doesn't really need | ||
// to access this and it lets us now worry about binding | ||
// our event handlers | ||
const removeFocusClasses = (element) => { | ||
element.classList.remove(...Object.values(FOCUS_STATES)); | ||
}; | ||
|
||
require("./style.less"); | ||
|
||
class FocusTracker extends Plugin { | ||
constructor(...args) { | ||
const options = Object.assign({}, args, { panel: PANEL_OPTIONS }); | ||
|
||
super(options); | ||
} | ||
|
||
getTitle() { | ||
return "Focus Tracker"; | ||
} | ||
|
||
getDescription() { | ||
return "Keep track of what's been focused as you tab through the page"; | ||
} | ||
|
||
applyFocusClass(event) { | ||
// get the event target and event name | ||
const { target, type } = event; | ||
|
||
// remove any focused or was-focused indicators on the element | ||
removeFocusClasses(target); | ||
|
||
// choose the class we want to add to this element | ||
// based on whether this is the focusin or focusout event | ||
const classToAdd = FOCUS_STATES[type]; | ||
|
||
// we want to ignore our tota11y toggle and panel because | ||
// the user probably only cares about focusable elements on | ||
// their page getting this visual treatment | ||
if (type === FOCUS_EVENT || target.closest(`.${IGNORE_WAS_FOCUSED_CLASS}`) === null) { | ||
target.classList.add(classToAdd); | ||
} | ||
} | ||
|
||
run() { | ||
// pop up our info panel to let the user know what we're doing | ||
this.summary("Tracking Focus"); | ||
this.panel.render(); | ||
|
||
// dynamically apply our event listeners by looping through | ||
// our defined focus states and adding an event handler | ||
Object.keys(FOCUS_STATES).forEach((key) => { | ||
document.addEventListener(key, this.applyFocusClass); | ||
}); | ||
} | ||
|
||
cleanup() { | ||
// dynamically remove our event listeners by looping through | ||
// our defined focus states and removing the event handler | ||
Object.keys(FOCUS_STATES).forEach((key) => { | ||
document.removeEventListener(key, this.applyFocusClass); | ||
|
||
// we'll also want to clean up all of the classes we added | ||
[...document.querySelectorAll(`.${FOCUS_STATES[key]}`)].forEach((element) => { | ||
removeFocusClasses(element); | ||
}); | ||
}); | ||
} | ||
} | ||
|
||
module.exports = FocusTracker; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
@import "../../less/variables.less"; | ||
|
||
.tota11y-outlined { | ||
outline: 2px solid fadein(@highlightColor, 100%); | ||
} | ||
|
||
.tota11y-was-focused { | ||
outline: 2px dashed fadein(@highlightColor, 80%); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters