UNPKG

@gluestack-ui/alert-dialog

Version:

A universal headless alert-dialog component for React Native, Next.js & React

54 lines (53 loc) 2.79 kB
import React, { forwardRef } from 'react'; import { AlertDialogContext } from './Context'; import { Platform, AccessibilityInfo, Keyboard } from 'react-native'; import { FocusScope } from '@react-native-aria/focus'; import { OverlayAnimatePresence } from './OverlayAnimatePresence'; import { useDialog } from '@react-native-aria/dialog'; import { mergeRefs, findNodeHandle } from '@gluestack-ui/utils'; const AlertDialogContent = (StyledAlertDialogContent, AnimatePresence) => forwardRef(({ children, focusScope = true, ...props }, ref) => { const { initialFocusRef, finalFocusRef, handleClose, visible } = React.useContext(AlertDialogContext); const contentRef = React.useRef(null); const mergedRef = mergeRefs([contentRef, ref]); // @ts-ignore const { dialogProps } = useDialog({ ...props }, mergedRef); React.useEffect(() => { if (contentRef) { const reactTag = findNodeHandle(contentRef.current); if (reactTag) { // Issue from react-native side // Hack for now, will fix this later AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); AccessibilityInfo.setAccessibilityFocus(reactTag); } } }, [visible, contentRef]); React.useEffect(() => { if (visible) { Keyboard.dismiss(); if (initialFocusRef && initialFocusRef?.current) { initialFocusRef?.current?.focus(); } } else { if (finalFocusRef && finalFocusRef?.current) { finalFocusRef?.current?.focus(); } } }, [initialFocusRef, finalFocusRef, visible]); const content = (<OverlayAnimatePresence visible={visible} AnimatePresence={AnimatePresence}> <StyledAlertDialogContent {...props} ref={mergedRef} onAccessibilityEscape={handleClose} exit={true} aria-modal="true" role={Platform.OS === 'web' ? 'alertdialog' : undefined} accessibilityViewIsModal tabIndex={Platform.OS === 'web' ? -1 : undefined} {...dialogProps}> {children} </StyledAlertDialogContent> </OverlayAnimatePresence>); return focusScope ? (<FocusScope contain={visible} autoFocus={visible && !initialFocusRef} restoreFocus={visible && !finalFocusRef}> {content} </FocusScope>) : (<>{content}</>); }); export default AlertDialogContent;