UNPKG

@gluestack-ui/menu

Version:

A universal headless menu component for React Native, Next.js & React

75 lines (74 loc) 3.09 kB
import React, { forwardRef } from 'react'; import { useKeyboardDismissable } from '@gluestack-ui/hooks'; import { usePopover } from './PopoverContext'; import { AccessibilityInfo, View } from 'react-native'; import { mergeRefs, findNodeHandle } from '@gluestack-ui/utils'; import { useOverlayPosition } from '@react-native-aria/overlays'; const PopoverContent = forwardRef(({ children, style, ...props }, ref) => { const { value } = usePopover('PopoverContext'); const { targetRef, onClose, initialFocusRef, finalFocusRef, popoverContentId, placement, shouldOverlapWithTrigger, crossOffset, offset, shouldFlip, isOpen, } = value; const contentRef = React.useRef(null); React.useEffect(() => { if (contentRef) { const reactTag = findNodeHandle(contentRef.current); if (reactTag) { AccessibilityInfo.isScreenReaderEnabled().then((enabled) => { if (enabled) { AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); } }); } } }, [isOpen, contentRef]); React.useEffect(() => { const finalFocusRefCurrentVal = finalFocusRef?.current; if (initialFocusRef && initialFocusRef.current) { initialFocusRef.current.focus(); } return () => { if (finalFocusRefCurrentVal) { finalFocusRefCurrentVal.focus(); } }; }, [finalFocusRef, initialFocusRef]); useKeyboardDismissable({ enabled: true, callback: onClose, }); const overlayRef = React.useRef(null); const { overlayProps } = useOverlayPosition({ placement: placement, targetRef, overlayRef, crossOffset, offset, shouldOverlapWithTrigger, shouldFlip, }); if (Object.keys(overlayProps.style).length === 0) { overlayProps.style = { top: -1000, left: -1000, }; } const mergedRef = mergeRefs([ref, overlayRef, contentRef]); return (<View id={popoverContentId} {...props} ref={mergedRef} collapsable={false} // eslint-disable-next-line react-native/no-inline-styles style={{ position: 'absolute', ...overlayProps?.style, ...style, }} accessible={true}> {children} </View>); }); export { PopoverContent };