UNPKG

stream-chat-react

Version:

React components to create chat conversations or livestream style chat

58 lines (57 loc) 2.57 kB
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))))); };