mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 14:35:41 +00:00
exp(orbit): iterative refinements
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,10 +7,15 @@ interface ConfirmModalProps {
|
||||
title: string;
|
||||
message: string;
|
||||
confirmLabel: string;
|
||||
cancelLabel: string;
|
||||
/**
|
||||
* Cancel button label. Omit (together with `onCancel`) to render the
|
||||
* modal as a single-button info dialog — Esc / outside-click / X then
|
||||
* also resolve via `onConfirm`.
|
||||
*/
|
||||
cancelLabel?: string;
|
||||
danger?: boolean;
|
||||
onConfirm: () => void;
|
||||
onCancel: () => void;
|
||||
onCancel?: () => void;
|
||||
}
|
||||
|
||||
export default function ConfirmModal({
|
||||
@@ -23,15 +28,17 @@ export default function ConfirmModal({
|
||||
onConfirm,
|
||||
onCancel,
|
||||
}: ConfirmModalProps) {
|
||||
const dismiss = onCancel ?? onConfirm;
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') onCancel();
|
||||
if (e.key === 'Escape') dismiss();
|
||||
else if (e.key === 'Enter') onConfirm();
|
||||
};
|
||||
window.addEventListener('keydown', onKey);
|
||||
return () => window.removeEventListener('keydown', onKey);
|
||||
}, [open, onCancel, onConfirm]);
|
||||
}, [open, dismiss, onConfirm]);
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
@@ -42,7 +49,7 @@ export default function ConfirmModal({
|
||||
return createPortal(
|
||||
<div
|
||||
className="modal-overlay"
|
||||
onClick={onCancel}
|
||||
onClick={dismiss}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
style={{ alignItems: 'center', paddingTop: 0 }}
|
||||
@@ -52,7 +59,7 @@ export default function ConfirmModal({
|
||||
onClick={e => e.stopPropagation()}
|
||||
style={{ maxWidth: '380px' }}
|
||||
>
|
||||
<button className="modal-close" onClick={onCancel} aria-label={cancelLabel}>
|
||||
<button className="modal-close" onClick={dismiss} aria-label={cancelLabel ?? confirmLabel}>
|
||||
<X size={18} />
|
||||
</button>
|
||||
<h3 style={{ marginBottom: '0.5rem', fontFamily: 'var(--font-display)' }}>{title}</h3>
|
||||
@@ -60,10 +67,12 @@ export default function ConfirmModal({
|
||||
{message}
|
||||
</p>
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: '8px' }}>
|
||||
<button className="btn btn-ghost" onClick={onCancel} autoFocus>
|
||||
{cancelLabel}
|
||||
</button>
|
||||
<button className="btn btn-primary" style={confirmStyle} onClick={onConfirm}>
|
||||
{cancelLabel && onCancel && (
|
||||
<button className="btn btn-ghost" onClick={onCancel} autoFocus>
|
||||
{cancelLabel}
|
||||
</button>
|
||||
)}
|
||||
<button className="btn btn-primary" style={confirmStyle} onClick={onConfirm} autoFocus={!cancelLabel}>
|
||||
{confirmLabel}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user