@atlaskit/popup
Version:
A popup displays brief content in an overlay.
59 lines (58 loc) • 2.54 kB
JavaScript
import { useEffect } from 'react';
import createFocusTrap from 'focus-trap';
import noop from '@atlaskit/ds-lib/noop';
import { useLayering } from '@atlaskit/layering';
import { fg } from '@atlaskit/platform-feature-flags';
import { useAnimationFrame } from './utils/use-animation-frame';
export var useFocusManager = function useFocusManager(_ref) {
var initialFocusRef = _ref.initialFocusRef,
popupRef = _ref.popupRef,
triggerRef = _ref.triggerRef,
autoFocus = _ref.autoFocus,
shouldCloseOnTab = _ref.shouldCloseOnTab,
shouldDisableFocusTrap = _ref.shouldDisableFocusTrap,
shouldReturnFocus = _ref.shouldReturnFocus,
shouldRenderToParent = _ref.shouldRenderToParent;
var _useAnimationFrame = useAnimationFrame(),
requestFrame = _useAnimationFrame.requestFrame,
cancelAllFrames = _useAnimationFrame.cancelAllFrames;
var _useLayering = useLayering(),
currentLevel = _useLayering.currentLevel;
useEffect(function () {
if (!popupRef || shouldCloseOnTab) {
return noop;
}
if (shouldDisableFocusTrap && fg('platform_dst_popup-disable-focuslock')) {
var isDropdown = popupRef.matches('[id^=ds--dropdown--]');
var popups = document.querySelectorAll("[data-ds--level=\"".concat(currentLevel - 1, "\"]"));
if (!(popups[popups.length - 1] && !shouldRenderToParent && isDropdown)) {
// Plucking trigger & popup content container from the tab order so that
// when we Shift+Tab, the focus moves to the element before trigger
requestFrame(function () {
triggerRef === null || triggerRef === void 0 || triggerRef.setAttribute('tabindex', '-1');
if (popupRef && autoFocus) {
popupRef.setAttribute('tabindex', '-1');
}
(initialFocusRef || popupRef).focus();
});
return noop;
}
}
var trapConfig = {
clickOutsideDeactivates: true,
escapeDeactivates: true,
initialFocus: initialFocusRef || popupRef,
fallbackFocus: popupRef,
returnFocusOnDeactivate: shouldReturnFocus
};
var focusTrap = createFocusTrap(popupRef, trapConfig);
// Wait for the popup to reposition itself before we focus
requestFrame(function () {
focusTrap.activate();
});
return function () {
cancelAllFrames();
focusTrap.deactivate();
};
}, [popupRef, triggerRef, autoFocus, initialFocusRef, shouldCloseOnTab, shouldDisableFocusTrap, requestFrame, cancelAllFrames, shouldReturnFocus, shouldRenderToParent, currentLevel]);
};