@material-ui/core
Version:
React components that implement Google's Material Design.
62 lines (53 loc) • 2.14 kB
JavaScript
import warning from 'warning';
import ownerDocument from '../utils/ownerDocument';
const internal = {
focusKeyPressed: false,
keyUpEventTimeout: -1
};
function findActiveElement(doc) {
let activeElement = doc.activeElement;
while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement) {
activeElement = activeElement.shadowRoot.activeElement;
}
return activeElement;
}
export function detectFocusVisible(instance, element, callback, attempt = 1) {
process.env.NODE_ENV !== "production" ? warning(instance.focusVisibleCheckTime, 'Material-UI: missing instance.focusVisibleCheckTime.') : void 0;
process.env.NODE_ENV !== "production" ? warning(instance.focusVisibleMaxCheckTimes, 'Material-UI: missing instance.focusVisibleMaxCheckTimes.') : void 0;
instance.focusVisibleTimeout = setTimeout(() => {
const doc = ownerDocument(element);
const activeElement = findActiveElement(doc);
if (internal.focusKeyPressed && (activeElement === element || element.contains(activeElement))) {
callback();
} else if (attempt < instance.focusVisibleMaxCheckTimes) {
detectFocusVisible(instance, element, callback, attempt + 1);
}
}, instance.focusVisibleCheckTime);
}
const FOCUS_KEYS = [9, // 'Tab',
13, // 'Enter',
27, // 'Escape',
32, // ' ',
37, // 'ArrowLeft',
38, // 'ArrowUp',
39, // 'ArrowRight',
40];
function isFocusKey(event) {
// Use event.keyCode to support IE 11
return FOCUS_KEYS.indexOf(event.keyCode) > -1;
}
const handleKeyUpEvent = event => {
if (isFocusKey(event)) {
internal.focusKeyPressed = true; // Let's consider that the user is using a keyboard during a window frame of 500ms.
clearTimeout(internal.keyUpEventTimeout);
internal.keyUpEventTimeout = setTimeout(() => {
internal.focusKeyPressed = false;
}, 500);
}
};
export function listenForFocusKeys(win) {
// The event listener will only be added once per window.
// Duplicate event listeners will be ignored by addEventListener.
// Also, this logic is client side only, we don't need a teardown.
win.addEventListener('keyup', handleKeyUpEvent);
}