UNPKG

@tamagui/react-native-web-lite

Version:
86 lines (85 loc) 3.04 kB
import * as React from "react"; import { StyleSheet, UIManager, canUseDOM } from "@tamagui/react-native-web-internals"; import createElement from "../createElement/index"; import View from "../View"; var FocusBracket = () => createElement("div", { accessibilityRole: "none", tabIndex: 0, style: styles.focusBracket }); function attemptFocus(element) { if (!canUseDOM) return !1; try { element.focus(); } catch { } return document.activeElement === element; } function focusFirstDescendant(element) { for (var i = 0; i < element.childNodes.length; i++) { var child = element.childNodes[i]; if (attemptFocus(child) || focusFirstDescendant(child)) return !0; } return !1; } function focusLastDescendant(element) { for (var i = element.childNodes.length - 1; i >= 0; i--) { var child = element.childNodes[i]; if (attemptFocus(child) || focusLastDescendant(child)) return !0; } return !1; } var ModalFocusTrap = (_ref) => { var active = _ref.active, children = _ref.children, trapElementRef = React.useRef(), focusRef = React.useRef({ trapFocusInProgress: !1, lastFocusedElement: null }); return React.useEffect(() => { if (canUseDOM) { var trapFocus = () => { if (!(trapElementRef.current == null || focusRef.current.trapFocusInProgress || !active)) { try { if (focusRef.current.trapFocusInProgress = !0, document.activeElement instanceof Node && !trapElementRef.current.contains(document.activeElement)) { var hasFocused = focusFirstDescendant(trapElementRef.current); focusRef.current.lastFocusedElement === document.activeElement && (hasFocused = focusLastDescendant(trapElementRef.current)), !hasFocused && trapElementRef.current != null && document.activeElement && UIManager.focus(trapElementRef.current); } } finally { focusRef.current.trapFocusInProgress = !1; } focusRef.current.lastFocusedElement = document.activeElement; } }; return trapFocus(), document.addEventListener("focus", trapFocus, !0), () => document.removeEventListener("focus", trapFocus, !0); } }, [active]), React.useEffect(function() { if (canUseDOM) { var lastFocusedElementOutsideTrap = document.activeElement; return function() { lastFocusedElementOutsideTrap && document.contains(lastFocusedElementOutsideTrap) && UIManager.focus(lastFocusedElementOutsideTrap); }; } }, []), /* @__PURE__ */ React.createElement( React.Fragment, null, /* @__PURE__ */ React.createElement(FocusBracket, null), /* @__PURE__ */ React.createElement( View, { ref: trapElementRef }, children ), /* @__PURE__ */ React.createElement(FocusBracket, null) ); }, ModalFocusTrap_default = ModalFocusTrap, styles = StyleSheet.create({ focusBracket: { outlineStyle: "none" } }); export { ModalFocusTrap_default as default }; //# sourceMappingURL=ModalFocusTrap.js.map