68 lines
1.6 KiB
TypeScript
68 lines
1.6 KiB
TypeScript
import { Modal, Button, Group, ModalProps, Flex, Box } from "@mantine/core"
|
|
import { ReactNode } from "react"
|
|
|
|
type BaseModalProps = Omit<ModalProps, "opened" | "onClose" | "title">
|
|
|
|
interface CustomModalProps extends BaseModalProps {
|
|
open: boolean
|
|
onCancel: () => void
|
|
onOk?: () => void
|
|
title?: ReactNode
|
|
footer?: ReactNode
|
|
okText?: string
|
|
cancelText?: string
|
|
confirmLoading?: boolean
|
|
width?: string | number
|
|
}
|
|
|
|
const CustomModal = ({
|
|
open,
|
|
onCancel,
|
|
onOk,
|
|
title,
|
|
children,
|
|
footer,
|
|
okText = "确定",
|
|
cancelText = "取消",
|
|
confirmLoading,
|
|
width,
|
|
...props
|
|
}: CustomModalProps) => {
|
|
return (
|
|
<Modal
|
|
opened={open}
|
|
onClose={onCancel}
|
|
title={
|
|
<Flex align="center" gap="xs">
|
|
{/* Preserving potential decorative intent with a Box if needed,
|
|
but for now assuming title text is sufficient or passed as Node.
|
|
If the original had a blue bar, we could add:
|
|
<Box w={4} h={18} bg="blue" style={{ borderRadius: 4 }} />
|
|
*/}
|
|
<Box>{title}</Box>
|
|
</Flex>
|
|
}
|
|
size={width || "md"}
|
|
centered
|
|
{...props}>
|
|
{children}
|
|
{footer === undefined ? (
|
|
<Group justify="flex-end" mt="md">
|
|
<Button variant="default" onClick={onCancel}>
|
|
{cancelText}
|
|
</Button>
|
|
{onOk && (
|
|
<Button onClick={onOk} loading={confirmLoading}>
|
|
{okText}
|
|
</Button>
|
|
)}
|
|
</Group>
|
|
) : (
|
|
footer
|
|
)}
|
|
</Modal>
|
|
)
|
|
}
|
|
|
|
export default CustomModal
|