import { useCallback, useState } from "react";
import { GlobalModal } from "stream-chat-react";
const Example = () => {
const [open, setOpen] = useState(false);
const closeModal = useCallback(() => setOpen(false), []);
return (
<>
<button onClick={() => setOpen(true)}>Open modal</button>
<GlobalModal onClose={closeModal} open={open}>
<div className="custom-modal-body">Custom content</div>
</GlobalModal>
</>
);
};This is beta documentation for Stream Chat React SDK v14. For the latest stable version, see the latest version (v13)
.
Modal
GlobalModal is the public modal component in the React SDK. It renders through the chat-level modal dialog manager provided by Chat.
Best Practices
- Use
GlobalModalfor app-owned modals rendered inside the chat tree. - Use
WithComponentsto override SDK-owned modal surfaces such as delete dialogs, poll dialogs, or selector dialogs. - Keep modal content lightweight and controlled by a single
openstate. - Use
onCloseAttemptwhen overlay or escape dismissal should be blocked. - Re-check custom CSS if you previously targeted the removed
.str-chat__modal__innerwrapper.
Basic Usage
SDK Modal Overrides
SDK surfaces that open modal content use the shared Modal override from ComponentContext. To change that behavior across a subtree, register a compatible modal component with WithComponents.
import {
Channel,
GlobalModal,
MessageInput,
WithComponents,
} from "stream-chat-react";
import type { ModalProps } from "stream-chat-react";
const CustomModal = (props: ModalProps) => (
<GlobalModal {...props} className="custom-modal-shell" />
);
const App = () => (
<WithComponents overrides={{ Modal: CustomModal }}>
<Channel>
<MessageInput />
</Channel>
</WithComponents>
);Props
| Prop | Description | Type |
|---|---|---|
children | Modal contents. | ReactNode |
className | Additional class name for the modal overlay root. | string |
CloseButtonOnOverlay | Optional close-button component rendered on the overlay layer. | React.ComponentType<ComponentProps<"button">> |
onClose | Called when the modal should close. Your handler should update open. ModalCloseEvent is KeyboardEvent | React.KeyboardEvent | React.MouseEvent<HTMLButtonElement | HTMLDivElement>. | (event: ModalCloseEvent) => void |
onCloseAttempt | Intercepts close attempts. Return false to keep the modal open. ModalCloseSource is "overlay" | "button" | "escape". | (source: ModalCloseSource, event: ModalCloseEvent) => boolean |
open | Controls whether the modal is rendered. Defaults to false. | boolean |
Examples
Intercept close attempts
import { GlobalModal } from "stream-chat-react";
import type { ModalCloseSource, ModalProps } from "stream-chat-react";
const onCloseAttempt = (source: ModalCloseSource) => source !== "overlay";
const ConfirmingModal = (props: ModalProps) => (
<GlobalModal {...props} onCloseAttempt={onCloseAttempt} />
);