From 119bea1e76f665de8c1671396741e5360bf1e81d Mon Sep 17 00:00:00 2001 From: Yashas Date: Wed, 9 Sep 2026 01:28:37 +0530 Subject: [PATCH] fix(console): centre modals via a portal, not inside a transformed ancestor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The New Lead form opened off-centre and its backdrop covered only part of the screen. Cause: the dialog uses position:fixed, but .shell__main animates transform on entrance, and an element that has animated transform keeps acting as the containing block in Chrome even after the animation finishes. So "fixed" resolved against the 1460px max-width, margin-auto content area — offset by the sidebar — instead of the viewport. Every scrim dialog shared this latent bug. Each now renders through createPortal(…, document.body), so the fixed overlay is always relative to the viewport regardless of any transformed ancestor. New Lead, the conversation and call threads, the full lead file, the agent card, and the reasoning dialog all now centre and dim the whole screen. Co-Authored-By: Claude Opus 5 (1M context) --- src/components/AgentCard.jsx | 5 ++++- src/components/CallTranscript.jsx | 5 ++++- src/components/ClampText.jsx | 6 ++++-- src/components/Conversation.jsx | 5 ++++- src/components/LeadFileDialog.jsx | 5 ++++- src/components/NewLeadDialog.jsx | 5 ++++- 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/components/AgentCard.jsx b/src/components/AgentCard.jsx index cf9ab63..5c41a9f 100644 --- a/src/components/AgentCard.jsx +++ b/src/components/AgentCard.jsx @@ -1,4 +1,5 @@ import { useEffect, useRef } from 'react' +import { createPortal } from 'react-dom' import { AGENTS } from '../api/agents.js' import './AgentCard.css' @@ -38,7 +39,7 @@ export default function AgentCard({ agentKey, onClose }) { if (!a) return null - return ( + return createPortal(
+ , + document.body, ) } diff --git a/src/components/CallTranscript.jsx b/src/components/CallTranscript.jsx index d15b74f..14634fe 100644 --- a/src/components/CallTranscript.jsx +++ b/src/components/CallTranscript.jsx @@ -1,4 +1,5 @@ import { useEffect, useRef } from 'react' +import { createPortal } from 'react-dom' import './Conversation.css' /** @@ -60,7 +61,7 @@ export default function CallTranscript({ text, name, onClose }) { } }, [onClose]) - return ( + return createPortal(
+ , + document.body, ) } diff --git a/src/components/ClampText.jsx b/src/components/ClampText.jsx index 166cf66..36b5388 100644 --- a/src/components/ClampText.jsx +++ b/src/components/ClampText.jsx @@ -1,4 +1,5 @@ import { useEffect, useRef, useState } from 'react' +import { createPortal } from 'react-dom' import './ClampText.css' /** @@ -50,7 +51,7 @@ function ProseDialog({ title, lead, body, onClose }) { } }, [onClose]) - return ( + return createPortal(

{para}

)}
- + , + document.body, ) } diff --git a/src/components/Conversation.jsx b/src/components/Conversation.jsx index ad654bd..d2aa0ec 100644 --- a/src/components/Conversation.jsx +++ b/src/components/Conversation.jsx @@ -1,4 +1,5 @@ import { useEffect, useRef } from 'react' +import { createPortal } from 'react-dom' import { baseFieldId } from '../api/config.js' import './Conversation.css' @@ -88,7 +89,7 @@ export default function Conversation({ rows, name, onClose }) { } }, [onClose]) - return ( + return createPortal(
+ , + document.body, ) } diff --git a/src/components/LeadFileDialog.jsx b/src/components/LeadFileDialog.jsx index d60241e..b744e92 100644 --- a/src/components/LeadFileDialog.jsx +++ b/src/components/LeadFileDialog.jsx @@ -1,4 +1,5 @@ import { useEffect, useMemo, useRef, useState } from 'react' +import { createPortal } from 'react-dom' import ClampText from './ClampText.jsx' import './LeadFileDialog.css' @@ -59,7 +60,7 @@ export default function LeadFileDialog({ groups, labels, label, money, fileHref, const found = shownGroups.reduce((n, [, rows]) => n + rows.length, 0) - return ( + return createPortal(
+ , + document.body, ) } diff --git a/src/components/NewLeadDialog.jsx b/src/components/NewLeadDialog.jsx index ead30a4..fbddf64 100644 --- a/src/components/NewLeadDialog.jsx +++ b/src/components/NewLeadDialog.jsx @@ -1,4 +1,5 @@ import { useEffect, useRef, useState } from 'react' +import { createPortal } from 'react-dom' import { useNavigate } from 'react-router-dom' import ActivityForm from './ActivityForm.jsx' import { ENTRY } from '../api/config.js' @@ -47,7 +48,7 @@ export default function NewLeadDialog({ onClose }) { } }, [onClose]) - return ( + return createPortal(
+ , + document.body, ) }