NapCatQQ/napcat.webui/src/components/modal.tsx
时瑾 2185a884b4 refactor: 优化eslint配置,提升代码质量 (#1341)
* feat: 统一并标准化eslint

* lint: napcat.webui

* lint: napcat.webui

* lint: napcat.core

* build: fix

* lint: napcat.webui

* refactor: 重构eslint

* Update README.md
2025-11-03 16:30:45 +08:00

98 lines
2.2 KiB
TypeScript

import { Button } from '@heroui/button';
import {
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
Modal as NextUIModal,
useDisclosure,
} from '@heroui/modal';
import React from 'react';
export interface ModalProps {
content: React.ReactNode
title?: React.ReactNode
size?: React.ComponentProps<typeof NextUIModal>['size']
scrollBehavior?: React.ComponentProps<typeof NextUIModal>['scrollBehavior']
onClose?: () => void
onConfirm?: () => void
onCancel?: () => void
backdrop?: 'opaque' | 'blur' | 'transparent'
showCancel?: boolean
dismissible?: boolean
confirmText?: string
cancelText?: string
}
const Modal: React.FC<ModalProps> = React.memo((props) => {
const {
backdrop = 'blur',
title,
content,
showCancel = true,
dismissible,
confirmText = '确定',
cancelText = '取消',
onClose,
onConfirm,
onCancel,
...rest
} = props;
const { onClose: onNativeClose } = useDisclosure();
return (
<NextUIModal
defaultOpen
backdrop={backdrop}
isDismissable={dismissible}
onClose={() => {
onClose?.();
onNativeClose();
}}
classNames={{
backdrop: 'z-[99]',
wrapper: 'z-[99]',
}}
{...rest}
>
<ModalContent>
{(nativeClose) => (
<>
{title && (
<ModalHeader className='flex flex-col gap-1'>{title}</ModalHeader>
)}
<ModalBody className='break-all'>{content}</ModalBody>
<ModalFooter>
{showCancel && (
<Button
color='primary'
variant='light'
onPress={() => {
onCancel?.();
nativeClose();
}}
>
{cancelText}
</Button>
)}
<Button
color='primary'
onPress={() => {
onConfirm?.();
nativeClose();
}}
>
{confirmText}
</Button>
</ModalFooter>
</>
)}
</ModalContent>
</NextUIModal>
);
});
Modal.displayName = 'Modal';
export default Modal;