Files
memind/src/components/MindSpaceModal.tsx
T
John 2e14873f2d Initial commit: Memind H5 portal with MindSpace, Plaza, and agent jobs.
Track application source and tests; exclude local env, user workspaces, and runtime data via .gitignore.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:04:43 -07:00

70 lines
1.8 KiB
TypeScript

import { useEffect, type ReactNode } from 'react';
import { createPortal } from 'react-dom';
export function MindSpaceModal({
open,
onClose,
title,
eyebrow,
children,
className,
disableClose = false,
}: {
open: boolean;
onClose: () => void;
title: string;
eyebrow?: string;
children: ReactNode;
className?: string;
disableClose?: boolean;
}) {
useEffect(() => {
if (!open) return undefined;
const onKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape' && !disableClose) onClose();
};
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
window.addEventListener('keydown', onKeyDown);
return () => {
document.body.style.overflow = previousOverflow;
window.removeEventListener('keydown', onKeyDown);
};
}, [open, onClose, disableClose]);
if (!open) return null;
return createPortal(
<div
className="mindspace-upload-backdrop"
role="presentation"
onClick={disableClose ? undefined : onClose}
>
<section
className={`mindspace-upload-dialog${className ? ` ${className}` : ''}`}
role="dialog"
aria-modal="true"
aria-labelledby="mindspace-modal-title"
onClick={(event) => event.stopPropagation()}
>
<div className="mindspace-upload-dialog-bar">
<div>
{eyebrow ? <p className="mindspace-eyebrow">{eyebrow}</p> : null}
<h3 id="mindspace-modal-title">{title}</h3>
</div>
<button
type="button"
className="mindspace-upload-dialog-close"
onClick={onClose}
disabled={disableClose}
>
</button>
</div>
{children}
</section>
</div>,
document.body,
);
}