From e447525ceb2c98ee02451deaafc7188468e33952 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 10:39:02 -0700 Subject: [PATCH 1/2] fix(sidebar): fix rename input losing its selection on open Radix's FocusScope defers close-time focus teardown to a setTimeout(0), which can occasionally run after the rename input's own focus()/select() and clobber the selection. Focus the input from onCloseAutoFocus instead, which runs inside that same deferred teardown and always wins the race. Affects workflow, folder, and workspace rename (all route through the shared sidebar ContextMenu component). --- .../components/context-menu/context-menu.tsx | 19 ++++++++++++++++++- .../components/folder-item/folder-item.tsx | 1 + .../workflow-item/workflow-item.tsx | 1 + .../workspace-header/workspace-header.tsx | 3 +++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx index ac6cd52bac0..9c8af667cda 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx @@ -34,6 +34,15 @@ interface ContextMenuProps { onMarkAsUnread?: () => void onTogglePin?: () => void onRename?: () => void + /** + * Ref to the rename input rendered by the "Rename" action, if any. Radix's + * FocusScope defers its close-time focus teardown to a `setTimeout(0)`, which + * can run after the rename input's own mount-time `focus()`/`select()` and + * clobber the selection (the "rename deselects the text" bug). Focusing from + * `onCloseAutoFocus` runs synchronously inside that same deferred teardown, so + * it always wins the race regardless of scheduler timing. + */ + renameInputRef?: React.RefObject onCreate?: () => void onCreateFolder?: () => void onDuplicate?: () => void @@ -84,6 +93,7 @@ export function ContextMenu({ onMarkAsUnread, onTogglePin, onRename, + renameInputRef, onCreate, onCreateFolder, onDuplicate, @@ -152,7 +162,14 @@ export function ContextMenu({ side='bottom' sideOffset={4} className='max-h-[var(--radix-dropdown-menu-content-available-height,400px)]' - onCloseAutoFocus={(e) => e.preventDefault()} + onCloseAutoFocus={(e) => { + e.preventDefault() + const input = renameInputRef?.current + if (input) { + input.focus() + input.select() + } + }} > {showOpenInNewTab && onOpenInNewTab && ( (null) const [isMounted, setIsMounted] = useState(false) useEffect(() => { @@ -408,6 +409,7 @@ function WorkspaceHeaderImpl({ )} { + renameInputRef.current = el if (el && !hasInputFocusedRef.current) { hasInputFocusedRef.current = true el.focus() @@ -643,6 +645,7 @@ function WorkspaceHeaderImpl({ menuRef={contextMenuRef} onClose={closeContextMenu} onRename={handleRenameAction} + renameInputRef={renameInputRef} onDelete={handleDeleteAction} onLeave={handleLeaveAction} onUploadLogo={handleUploadLogoAction} From 26f4482e7c9477b760e0a47c91db645de66c60d9 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 10 Jul 2026 10:47:38 -0700 Subject: [PATCH 2/2] fix(sidebar): only refocus the rename input when Rename triggered the close onCloseAutoFocus fires on every menu close, not just after selecting Rename. Gate the refocus behind a ref set only when the Rename item was selected, so closing the menu for an unrelated action (Delete, Duplicate, ...) while an earlier rename is still live doesn't steal focus back into it and delay its blur-save. --- .../components/context-menu/context-menu.tsx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx index 9c8af667cda..13e4dc6ab16 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx @@ -1,5 +1,6 @@ 'use client' +import { useRef } from 'react' import { DropdownMenu, DropdownMenuContent, @@ -40,7 +41,10 @@ interface ContextMenuProps { * can run after the rename input's own mount-time `focus()`/`select()` and * clobber the selection (the "rename deselects the text" bug). Focusing from * `onCloseAutoFocus` runs synchronously inside that same deferred teardown, so - * it always wins the race regardless of scheduler timing. + * it always wins the race regardless of scheduler timing. Only applied when + * this specific close was caused by selecting "Rename" (see + * `justSelectedRenameRef`) — an unrelated action closing the menu while an + * earlier rename is still live must not steal focus back into it. */ renameInputRef?: React.RefObject onCreate?: () => void @@ -142,6 +146,13 @@ export function ContextMenu({ (showUploadLogo && onUploadLogo) const hasCopySection = (showDuplicate && onDuplicate) || (showExport && onExport) + /** + * Only the "Rename" item should trigger the `onCloseAutoFocus` refocus below — + * an unrelated action (Delete, Duplicate, ...) closing this menu while a rename + * from an earlier interaction is still live must not steal focus back into it. + */ + const justSelectedRenameRef = useRef(false) + return ( !open && onClose()} modal={false}> @@ -164,7 +175,9 @@ export function ContextMenu({ className='max-h-[var(--radix-dropdown-menu-content-available-height,400px)]' onCloseAutoFocus={(e) => { e.preventDefault() - const input = renameInputRef?.current + const shouldFocusRenameInput = justSelectedRenameRef.current + justSelectedRenameRef.current = false + const input = shouldFocusRenameInput ? renameInputRef?.current : null if (input) { input.focus() input.select() @@ -227,6 +240,7 @@ export function ContextMenu({ { + justSelectedRenameRef.current = true onRename() onClose() }}