@gluestack-ui/alert-dialog
Version:
A universal headless alert-dialog component for React Native, Next.js & React
54 lines (53 loc) • 2.79 kB
JSX
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;