UNPKG

@shopify/polaris

Version:

Shopify’s product component library

77 lines (64 loc) 2.8 kB
import { Key } from '../../types.js'; import React$1, { useState, useRef, useEffect } from 'react'; import { EventListener as EventListener$1 } from '../EventListener/EventListener.js'; import { useFocusManager } from '../../utilities/focus-manager/hooks.js'; import { focusFirstFocusableNode, findFirstKeyboardFocusableNode, findLastKeyboardFocusableNode, focusFirstKeyboardFocusableNode, focusLastKeyboardFocusableNode } from '../../utilities/focus.js'; import { KeypressListener as KeypressListener$1 } from '../KeypressListener/KeypressListener.js'; import { Focus as Focus$1 } from '../Focus/Focus.js'; function TrapFocus({ trapping = true, children }) { var [shouldFocusSelf, setFocusSelf] = useState(undefined); var { canSafelyFocus } = useFocusManager(); var focusTrapWrapper = useRef(null); useEffect(() => { setFocusSelf(!(canSafelyFocus && focusTrapWrapper.current && focusTrapWrapper.current.contains(document.activeElement))); }, [canSafelyFocus]); var shouldDisableFirstElementFocus = () => { if (shouldFocusSelf === undefined || !canSafelyFocus) { return true; } return shouldFocusSelf ? !trapping : !shouldFocusSelf; }; var handleFocusIn = event => { var containerContentsHaveFocus = focusTrapWrapper.current && focusTrapWrapper.current.contains(document.activeElement); if (trapping === false || !focusTrapWrapper.current || containerContentsHaveFocus) { return; } if (canSafelyFocus && event.target instanceof HTMLElement && focusTrapWrapper.current !== event.target && !focusTrapWrapper.current.contains(event.target)) { focusFirstFocusableNode(focusTrapWrapper.current); } }; var handleTab = event => { if (trapping === false || !focusTrapWrapper.current) { return; } var firstFocusableNode = findFirstKeyboardFocusableNode(focusTrapWrapper.current); var lastFocusableNode = findLastKeyboardFocusableNode(focusTrapWrapper.current); if (event.target === lastFocusableNode && !event.shiftKey) { event.preventDefault(); focusFirstKeyboardFocusableNode(focusTrapWrapper.current); } if (event.target === firstFocusableNode && event.shiftKey) { event.preventDefault(); focusLastKeyboardFocusableNode(focusTrapWrapper.current); } }; return /*#__PURE__*/React$1.createElement(Focus$1, { disabled: shouldDisableFirstElementFocus(), root: focusTrapWrapper.current }, /*#__PURE__*/React$1.createElement("div", { ref: focusTrapWrapper }, /*#__PURE__*/React$1.createElement(EventListener$1, { event: "focusin", handler: handleFocusIn }), /*#__PURE__*/React$1.createElement(KeypressListener$1, { keyCode: Key.Tab, keyEvent: "keydown", handler: handleTab }), children)); } export { TrapFocus };