modal.tsx
Overview
modal.tsx defines a versatile and customizable Modal React component built on top of the @radix-ui/react-dialog primitive. It provides a rich set of features such as configurable size, header title, footer with customizable buttons or content, mask closability, loading states, and support for full-width display. It also integrates internationalization support through react-i18next and uses a portal-based modal management system for global control.
This file's core purpose is to provide an accessible, reusable modal dialog UI element that can be easily integrated into a React application with flexible control over its behavior and appearance.
Exports
Modal: The main modal component with props and static methods
showandhidefor programmatic control.
Interfaces
ModalProps
Defines the properties accepted by the Modal component.
Property | Type | Description | Optional | Default |
|---|---|---|---|---|
|
| Controls whether the modal is open or closed. | No | |
| Callback fired when the open state changes (e.g., user closes or opens the modal). | Yes | ||
|
| Optional title content displayed in the modal header. | Yes | |
| Additional CSS classes for the title container. | Yes | ||
|
| The main content of the modal. | No | |
|
| Custom footer content. If not provided, default footer with cancel/ok buttons is rendered. | Yes | |
|
| Additional CSS classes for the footer container. | Yes | |
|
| Whether to show the footer section. If false, footer is hidden. | Yes |
|
|
| Additional CSS classes for the modal content container. | Yes |
|
| `'small' | 'default' | 'large'` | Modal size, controlling max width. |
|
| Whether the modal can be closed via the close button. | Yes |
|
|
| Custom close icon element. | Yes |
|
|
| Whether clicking on the overlay mask closes the modal. | Yes |
|
|
| Whether to unmount modal children when closed. | Yes |
|
|
| Whether the modal should use full width ( | Yes |
|
|
| Shows a loading spinner on the OK button to indicate a pending action. | Yes | |
| `ReactNode | string` | Text or node for the cancel button label. | Yes |
| `ReactNode | string` | Text or node for the OK button label. | Yes |
|
| Callback fired when OK button is clicked. | Yes | |
|
| Callback fired when cancel action is triggered (close, cancel button). | Yes |
Component: Modal
A functional React component implementing a modal dialog with the above props.
Usage Example
import { Modal } from '@/components/ui/modal';
import { useState } from 'react';
function Example() {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(true)}>Open Modal</button>
<Modal
open={open}
onOpenChange={setOpen}
title="Example Modal"
onOk={() => alert('Confirmed')}
onCancel={() => alert('Cancelled')}
confirmLoading={false}
>
<p>This is some modal content</p>
</Modal>
</>
);
}
Props Explanation and Behavior
open / onOpenChange: Control modal visibility via controlled component pattern.
title: Optional header text or element.
closable: Enables a close button in the header (top-right) with customizable icon.
maskClosable: Clicking outside modal content (overlay) closes the modal.
destroyOnClose: Unmounts children when modal is closed to optimize performance or reset state.
size: Controls modal width using TailwindCSS max-width classes (
max-w-md,max-w-2xl,max-w-4xl).full: Overrides size and sets modal to full width (
max-w-full).footer / showfooter: Custom footer content or default buttons; can be hidden.
confirmLoading: Shows a spinner in the OK button to indicate loading or submission.
cancelText / okText: Localized button labels, defaulting to i18n translations.
onOk / onCancel: Callbacks for button actions or modal close events.
Internal Implementation Details
Uses Radix UI's Dialog primitives for accessibility and portal rendering.
Listens to
Escapekeypress to close modal ifmaskClosableis enabled.The modal overlay blocks background scrolling and applies a blurred, semi-transparent background.
Footer buttons handle
onOkandonCancelwith callbacks and modal state changes.The modal prevents click propagation on content to avoid mask closing.
Uses
useMemoto memoize footer rendering for performance.Uses
useCallbackfor stable function references passed to buttons.Supports internationalization via
react-i18nextto translate button labels.Provides static methods
Modal.showandModal.hideto programmatically control modal instances via an importedcreatePortalModalutility (likely managing a singleton modal instance or portal).
Methods
Modal.show
Type:
() => voidDescription: Static method to programmatically show the modal via portal instance.
Usage:
Modal.show();
Modal.hide
Type:
() => voidDescription: Static method to programmatically hide the modal.
Usage:
Modal.hide();
These methods delegate to an instance created by createPortalModal() imported from ./modal-manage. This allows external code to open or close the modal without embedding the component in JSX.
Interaction with Other System Parts
@radix-ui/react-dialog: Provides the foundational accessible dialog primitives, including focus management, aria attributes, and portal rendering.lucide-react: Supplies SVG icon components such as the Close (X) icon and the Loader spinner.react-i18next: Enables translation of default button texts (cancelTextandokText).@/lib/utils: Provides thecnutility function for conditional classNames concatenation../modal-manage: Provides thecreatePortalModalutility, enabling global modal instance management outside React component tree.
Visual Diagram: Component Structure and Workflow
componentDiagram
component Modal {
+open: boolean
+onOpenChange(open: boolean): void
+title: ReactNode
+footer: ReactNode
+showfooter: boolean
+size: 'small' | 'default' | 'large'
+closable: boolean
+closeIcon: ReactNode
+maskClosable: boolean
+destroyOnClose: boolean
+full: boolean
+confirmLoading: boolean
+cancelText: ReactNode | string
+okText: ReactNode | string
+onOk(): void
+onCancel(): void
+show(): void
+hide(): void
}
component RadixDialogPrimitive {
+Root
+Portal
+Overlay
+Content
+Title
+Close
}
component ModalManage {
+createPortalModal(): { show(), hide() }
}
Modal --> RadixDialogPrimitive : uses
Modal --> ModalManage : uses for show/hide static methods
Modal --> lucide-react : uses icons (X, Loader)
Modal --> react-i18next : uses for translations
Summary
modal.tsx provides a fully featured modal dialog React component with fine-grained control over appearance and behavior, leveraging Radix UI primitives for accessibility and portals for rendering. It supports internationalization, customizable buttons, dynamic loading states, and programmatic control through static methods. The component is designed to be flexible and composable, suitable for use across a React application’s UI.
If you have questions about integration or extending the modal, or need examples for specific usage scenarios, feel free to ask!