첫 커밋
This commit is contained in:
29
src/shared/ui/dialogs/dialog-buttons.tsx
Normal file
29
src/shared/ui/dialogs/dialog-buttons.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
export interface DialogButtonsProps {
|
||||
buttonLabel: string[];
|
||||
onConfirm: () => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
export const DialogButtons = ({ buttonLabel, onConfirm, onCancel }: DialogButtonsProps) => {
|
||||
if (buttonLabel.length === 1) {
|
||||
return (
|
||||
<button className="btn-40 btn-darkgray" onClick={onConfirm}>
|
||||
{buttonLabel[0]}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="popup-btn-group">
|
||||
{buttonLabel[0] && (
|
||||
<button className="btn-40 btn-darkgray" onClick={onCancel}>
|
||||
{buttonLabel[0]}
|
||||
</button>
|
||||
)}
|
||||
{buttonLabel[1] && (
|
||||
<button className="btn-40 btn-blue" onClick={onConfirm}>
|
||||
{buttonLabel[1]}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
95
src/shared/ui/dialogs/dialog.tsx
Normal file
95
src/shared/ui/dialogs/dialog.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
|
||||
import { Description, Dialog as _Dialog, DialogPanel, DialogTitle, Transition } from '@headlessui/react';
|
||||
import { useBlocker } from '@/shared/lib/hooks/use-blocker';
|
||||
import { useBridge } from '@webview-bridge/react';
|
||||
import { Fragment, ReactNode, useCallback } from 'react';
|
||||
import { DialogButtons } from '@/shared/ui/dialogs/dialog-buttons';
|
||||
import { bridge } from '@/bridge';
|
||||
|
||||
export interface DialogProps {
|
||||
open: boolean;
|
||||
onConfirmClick?: () => void | Promise<void>;
|
||||
onCancelClick?: () => void | Promise<void>;
|
||||
children?: ReactNode;
|
||||
title?: string | ReactNode;
|
||||
message?: string | ReactNode;
|
||||
shouldCloseOnBackdropClick?: boolean;
|
||||
buttonLabel?: string[];
|
||||
onClose: () => void;
|
||||
fullScreenMode?: boolean;
|
||||
afterLeave: () => void;
|
||||
}
|
||||
|
||||
export const Dialog = ({
|
||||
open = false,
|
||||
onConfirmClick,
|
||||
onCancelClick,
|
||||
children,
|
||||
title,
|
||||
message,
|
||||
shouldCloseOnBackdropClick = false,
|
||||
buttonLabel = ['확인'],
|
||||
onClose,
|
||||
afterLeave,
|
||||
fullScreenMode = false,
|
||||
}: DialogProps) => {
|
||||
const { nativeDialog, resetNativeDialog } = useBridge(bridge.store, (state) => state);
|
||||
|
||||
const whenToBlock = useCallback(() => open, [open]);
|
||||
// 다이얼로그가 열려있을때 뒤로가기 방지
|
||||
const blocker = useBlocker(whenToBlock);
|
||||
const nativeMessage = nativeDialog?.message;
|
||||
const displayMessage = nativeMessage || message;
|
||||
const handleClose = useCallback(() => {
|
||||
resetNativeDialog?.();
|
||||
onClose();
|
||||
}, []);
|
||||
const handleConfirm = useCallback(() => {
|
||||
blocker?.proceed?.();
|
||||
onConfirmClick?.();
|
||||
handleClose();
|
||||
}, []);
|
||||
const handleCancel = useCallback(() => {
|
||||
blocker?.reset?.();
|
||||
onCancelClick?.();
|
||||
handleClose();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Transition
|
||||
afterLeave={afterLeave}
|
||||
show={open}
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="ease-in duration-100"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<_Dialog onClose={shouldCloseOnBackdropClick ? onClose : () => null} static={!shouldCloseOnBackdropClick}>
|
||||
{/* The backdrop, rendered as a fixed sibling to the panel container */}
|
||||
<div
|
||||
id="cancelConfirmPopup"
|
||||
className="popup-overlay"
|
||||
>
|
||||
<div className="popup-bg-dim"></div>
|
||||
<DialogPanel
|
||||
as="div"
|
||||
className="popup-container"
|
||||
>
|
||||
{displayMessage && (
|
||||
<Description as="div" className={'popup-title'}>
|
||||
<p>{displayMessage}</p>
|
||||
</Description>
|
||||
)}
|
||||
{/* render buttonLabel */}
|
||||
{!fullScreenMode && (
|
||||
<DialogButtons buttonLabel={buttonLabel} onCancel={handleCancel} onConfirm={handleConfirm} />
|
||||
)}
|
||||
</DialogPanel>
|
||||
</div>
|
||||
</_Dialog>
|
||||
</Transition>
|
||||
);
|
||||
};
|
||||
9
src/shared/ui/dialogs/index.ts
Normal file
9
src/shared/ui/dialogs/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { overlay } from 'overlay-kit';
|
||||
import { delay } from '~/shared/lib/delay';
|
||||
|
||||
export const DIALOG_LEAVE_ANIMATION_DURATION = 100;
|
||||
|
||||
export const closeDialog = (callback: () => void) => {
|
||||
overlay.closeAll();
|
||||
delay(DIALOG_LEAVE_ANIMATION_DURATION).then(callback);
|
||||
};
|
||||
Reference in New Issue
Block a user