56 lines
2.0 KiB
JavaScript
56 lines
2.0 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
Object.defineProperty(exports, "applyFocusWithinPolyfill", {
|
|
enumerable: true,
|
|
get: function() {
|
|
return applyFocusWithinPolyfill;
|
|
}
|
|
});
|
|
const _keyborg = require("keyborg");
|
|
const _constants = require("./constants");
|
|
function applyFocusWithinPolyfill(element, win) {
|
|
const keyborg = (0, _keyborg.createKeyborg)(win);
|
|
// When navigation mode changes to mouse, remove the focus-within selector
|
|
keyborg.subscribe((isNavigatingWithKeyboard)=>{
|
|
if (!isNavigatingWithKeyboard) {
|
|
removeFocusWithinClass(element);
|
|
}
|
|
});
|
|
// Keyborg's focusin event is delegated so it's only registered once on the window
|
|
// and contains metadata about the focus event
|
|
const keyborgListener = (e)=>{
|
|
if (keyborg.isNavigatingWithKeyboard() && isHTMLElement(e.target)) {
|
|
// Griffel can't create chained global styles so use the parent element for now
|
|
applyFocusWithinClass(element);
|
|
}
|
|
};
|
|
// Make sure that when focus leaves the scope, the focus within class is removed
|
|
const blurListener = (e)=>{
|
|
if (!e.relatedTarget || isHTMLElement(e.relatedTarget) && !element.contains(e.relatedTarget)) {
|
|
removeFocusWithinClass(element);
|
|
}
|
|
};
|
|
element.addEventListener(_keyborg.KEYBORG_FOCUSIN, keyborgListener);
|
|
element.addEventListener('focusout', blurListener);
|
|
// Return disposer
|
|
return ()=>{
|
|
element.removeEventListener(_keyborg.KEYBORG_FOCUSIN, keyborgListener);
|
|
element.removeEventListener('focusout', blurListener);
|
|
(0, _keyborg.disposeKeyborg)(keyborg);
|
|
};
|
|
}
|
|
function applyFocusWithinClass(el) {
|
|
el.setAttribute(_constants.FOCUS_WITHIN_ATTR, '');
|
|
}
|
|
function removeFocusWithinClass(el) {
|
|
el.removeAttribute(_constants.FOCUS_WITHIN_ATTR);
|
|
}
|
|
function isHTMLElement(target) {
|
|
if (!target) {
|
|
return false;
|
|
}
|
|
return Boolean(target && typeof target === 'object' && 'classList' in target && 'contains' in target);
|
|
}
|