fix(web): invite dialog focus trap inside settings modal (#1347)

Portal the invite-teammate dialog into the settings modal and autofocus the email input, matching the delete-org dialog fix. Stacked body-portaled dialogs broke focus so the email field stopped accepting input after the first invite.

Fixes ENG-1110
This commit is contained in:
MaheshtheDev 2026-07-24 03:18:39 +00:00
parent cfc2b49192
commit ea2cf33fd3
2 changed files with 15 additions and 2 deletions

View file

@ -132,7 +132,11 @@ function isPendingInvitation(invitation: {
return new Date(invitation.expiresAt).getTime() > Date.now()
}
export default function Account() {
export default function Account({
dialogPortalContainer,
}: {
dialogPortalContainer?: HTMLElement | null
}) {
const { user, org, refetchActiveOrg, refetchOrganizations } = useAuth()
const autumn = useCustomer()
const { currentPlan, searchesUsed } = useTokenUsage(autumn)
@ -152,6 +156,7 @@ export default function Account() {
const [isEditingOrgName, setIsEditingOrgName] = useState(false)
const [orgNameDraft, setOrgNameDraft] = useState("")
const tagInputRef = useRef<HTMLInputElement>(null)
const inviteEmailInputRef = useRef<HTMLInputElement>(null)
const tagAnchorRef = useRef<HTMLDivElement>(null)
const { allProjects: allContainerTags } = useContainerTags()
@ -877,6 +882,11 @@ export default function Account() {
>
<DialogContent
showCloseButton={false}
portalContainer={dialogPortalContainer}
onOpenAutoFocus={(event) => {
event.preventDefault()
inviteEmailInputRef.current?.focus()
}}
className="sm:max-w-[480px] border-none bg-[#1B1F24] p-0 gap-0 rounded-[22px] overflow-hidden"
>
<div className="flex items-start justify-between gap-3 px-6 pt-6 pb-4">
@ -925,6 +935,7 @@ export default function Account() {
<div className="relative min-w-0">
<Mail className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-[#525D6E]" />
<input
ref={inviteEmailInputRef}
id="team-invite-email"
type="email"
value={inviteEmail}

View file

@ -477,7 +477,9 @@ export function SettingsContent({
</p>
}
>
{activeTab === "account" && <Account />}
{activeTab === "account" && (
<Account dialogPortalContainer={dialogPortalContainer} />
)}
{activeTab === "billing" && <Billing />}
{activeTab === "integrations" && <Integrations />}
{activeTab === "connections" && <ConnectionsMCP />}