70 lines
2.1 KiB
TypeScript
70 lines
2.1 KiB
TypeScript
// ---------------------------------------------------------------------------
|
|
// Shared modal wrapper — handles overlay, centering, dialog role, aria
|
|
// ---------------------------------------------------------------------------
|
|
|
|
import type { ReactNode } from 'react'
|
|
|
|
interface ModalProps {
|
|
ariaLabelledBy: string
|
|
children: ReactNode
|
|
}
|
|
|
|
export default function Modal({ ariaLabelledBy, children }: ModalProps) {
|
|
return (
|
|
<div
|
|
className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm"
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-labelledby={ariaLabelledBy}
|
|
>
|
|
<div className="bg-black-900 border border-white/20 rounded-2xl p-6 max-w-md w-full mx-4 space-y-4">
|
|
{children}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Shared modal footer with two buttons
|
|
// ---------------------------------------------------------------------------
|
|
|
|
interface ModalActionsProps {
|
|
cancelLabel: string
|
|
confirmLabel: string
|
|
onCancel: () => void
|
|
onConfirm: () => void
|
|
/** Tailwind classes for the confirm button (default: white bg) */
|
|
confirmClassName?: string
|
|
disabled?: boolean
|
|
}
|
|
|
|
export function ModalActions({
|
|
cancelLabel,
|
|
confirmLabel,
|
|
onCancel,
|
|
onConfirm,
|
|
confirmClassName = 'bg-white text-[#000000] hover:bg-gray-200',
|
|
disabled = false,
|
|
}: ModalActionsProps) {
|
|
return (
|
|
<div className="flex gap-3">
|
|
<button
|
|
onClick={onCancel}
|
|
disabled={disabled}
|
|
className="flex-1 bg-black-700 text-gray-300 font-medium text-sm
|
|
py-2.5 px-4 rounded-xl border border-white/10 transition-colors duration-150 disabled:opacity-50 disabled:cursor-not-allowed
|
|
hover:bg-black-600"
|
|
>
|
|
{cancelLabel}
|
|
</button>
|
|
<button
|
|
onClick={onConfirm}
|
|
disabled={disabled}
|
|
className={`flex-1 font-medium text-sm py-2.5 px-4 rounded-xl transition-colors duration-150 disabled:opacity-50 disabled:cursor-not-allowed ${confirmClassName}`}
|
|
>
|
|
{confirmLabel}
|
|
</button>
|
|
</div>
|
|
)
|
|
}
|