feat: implement Portal component and refactor modals to use it for improved positioning

This commit is contained in:
hamed
2026-07-04 22:05:27 +03:30
parent ae1e40aeee
commit f3ca6d844f
9 changed files with 168 additions and 9 deletions
@@ -1,5 +1,6 @@
import React from 'react';
import { XMarkIcon, ExclamationTriangleIcon } from '@heroicons/react/24/outline';
import Portal from './Portal';
interface Props {
open: boolean;
@@ -27,6 +28,7 @@ export default function ConfirmDialog({
if (!open) return null;
return (
<Portal>
<div className="overlay" onClick={onCancel}>
<div className="modal" style={{ maxWidth: 420 }} onClick={(e) => e.stopPropagation()}>
<div className="modal-head">
@@ -61,5 +63,6 @@ export default function ConfirmDialog({
</div>
</div>
</div>
</Portal>
);
}
@@ -7,6 +7,7 @@ import { toast } from 'sonner';
import { api } from '../../lib/api';
import type { ApiResponse } from '../../lib/api';
import MobileInput from './MobileInput';
import Portal from './Portal';
import { iranMobileSchema } from '../../lib/utils';
const inviteSchema = z.object({
@@ -39,6 +40,7 @@ export default function InviteDoctorModal({ clinicUuid, onClose, onInvited }: Pr
});
return (
<Portal>
<div className="overlay" onClick={onClose}>
<div className="modal" style={{ maxWidth: 420 }} onClick={e => e.stopPropagation()}>
<div className="modal-head">
@@ -71,5 +73,6 @@ export default function InviteDoctorModal({ clinicUuid, onClose, onInvited }: Pr
</form>
</div>
</div>
</Portal>
);
}
+9
View File
@@ -0,0 +1,9 @@
import React, { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
export default function Portal({ children }: { children: React.ReactNode }) {
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
if (!mounted) return null;
return createPortal(children, document.body);
}