feat: 컴포넌트 추가, 스타일 수정

This commit is contained in:
2026-04-10 12:23:48 +09:00
parent a836333512
commit 35f6023f5a
19 changed files with 1263 additions and 56 deletions

View File

@@ -0,0 +1,79 @@
import type { ReactNode } from 'react';
import { useTransition } from 'react';
import { Button } from '../button/Button';
import { ModalBody, ModalFooter, ModalHeader, ModalRoot } from './Modal';
interface ConfirmModalProps {
isOpen?: boolean;
onOpenChange?: (isOpen: boolean) => void;
title?: string;
content?: ReactNode;
confirmText?: string;
cancelText?: string;
onConfirm?: () => Promise<void> | void;
onCancel?: () => void;
}
export const ConfirmModal = (props: ConfirmModalProps) => {
const { isOpen, onOpenChange, title, ...contentProps } = props;
return (
<ModalRoot isOpen={isOpen} onOpenChange={onOpenChange} className="w-75" aria-label={title ?? '확인'}>
{({ close }) => <ConfirmModalContent close={close} title={title} {...contentProps} />}
</ModalRoot>
);
};
function ConfirmModalContent({
close,
title,
content,
confirmText = '확인',
cancelText = '취소',
onConfirm,
onCancel,
}: {
close: () => void;
title?: string;
content?: ReactNode;
confirmText?: string;
cancelText?: string;
onConfirm?: () => Promise<void> | void;
onCancel?: () => void;
}) {
const [isPending, startTransition] = useTransition();
const handleConfirm = () => {
if (onConfirm) {
startTransition(async () => {
await onConfirm();
close();
});
} else {
close();
}
};
const handleCancel = () => {
onCancel?.();
close();
};
return (
<>
{title && <ModalHeader>{title}</ModalHeader>}
<ModalBody className="px-7.5 py-8">
<p className="text-sm text-dabeeo-black-34 font-medium text-center whitespace-pre-wrap">{content}</p>
</ModalBody>
<ModalFooter>
<Button color="gray" size="large" isDisabled={isPending} onClick={handleCancel}>
{cancelText}
</Button>
<Button color="primary" size="large" isPending={isPending} onClick={handleConfirm}>
{confirmText}
</Button>
</ModalFooter>
</>
);
}