stream-chat-react
Version:
React components to create chat conversations or livestream style chat
58 lines (57 loc) • 2.57 kB
JavaScript
import clsx from 'clsx';
import { useCallback } from 'react';
import React, { useEffect, useRef } from 'react';
import { FocusScope } from '@react-aria/focus';
import { CloseIconRound } from './icons';
import { useTranslationContext } from '../../context';
import { DialogPortalEntry, modalDialogId, useModalDialog, useModalDialogIsOpen, } from '../Dialog';
export const GlobalModal = ({ children, className, onClose, onCloseAttempt, open, }) => {
const { t } = useTranslationContext('Modal');
const dialog = useModalDialog();
const isOpen = useModalDialogIsOpen();
const innerRef = useRef(null);
const closeButtonRef = useRef(null);
const maybeClose = useCallback((source, event) => {
const allow = onCloseAttempt?.(source, event);
if (allow !== false) {
onClose?.(event);
dialog.close();
}
}, [dialog, onClose, onCloseAttempt]);
const handleClick = (event) => {
const target = event.target;
if (!innerRef.current || !closeButtonRef.current)
return;
if (innerRef.current?.contains(target))
return;
if (closeButtonRef.current.contains(target)) {
maybeClose('button', event);
}
else if (!innerRef.current.contains(target)) {
maybeClose('overlay', event);
}
};
useEffect(() => {
if (!isOpen)
return;
const handleKeyDown = (event) => {
if (event.key === 'Escape')
maybeClose('escape', event);
};
document.addEventListener('keydown', handleKeyDown);
return () => document.removeEventListener('keydown', handleKeyDown);
}, [isOpen, maybeClose]);
useEffect(() => {
if (open && !dialog.isOpen) {
dialog.open();
}
}, [dialog, open]);
if (!open || !isOpen)
return null;
return (React.createElement(DialogPortalEntry, { dialogId: modalDialogId },
React.createElement("div", { className: clsx('str-chat str-chat__modal str-chat-react__modal str-chat__modal--open', className), onClick: handleClick },
React.createElement(FocusScope, { autoFocus: true, contain: true },
React.createElement("button", { className: 'str-chat__modal__close-button', ref: closeButtonRef, title: t('Close'), type: 'button' },
React.createElement(CloseIconRound, null)),
React.createElement("div", { className: 'str-chat__modal__inner str-chat-react__modal__inner', ref: innerRef }, children)))));
};