UNPKG

@atlaskit/popup

Version:

A popup displays brief content in an overlay.

59 lines (58 loc) 2.54 kB
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]); };