Skip to content

Commit 3a21e71

Browse files
committed
fix(ui): prevent accidental hover selections in context menu
Add logic to temporarily disable hover-based selection when context menu items change, preventing unintended selections during dynamic updates. Also introduce stable empty array references- Previously, the empty arrays were causing the props to change, causing a continuous render loop while the @ContextMenu.tsx was open Fixes: #2104
1 parent d7462b8 commit 3a21e71

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

.changeset/dirty-plants-sort.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"kilo-code": patch
3+
---
4+
5+
Now items in the Chat context menu will not be auto selected if your cursor is already on the row when the items change

webview-ui/src/components/chat/ContextMenu.tsx

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ interface ContextMenuProps {
3232
commands?: Command[]
3333
}
3434

35+
const EMPTY_COMMANDS: Command[] = [] // kilocode_change - maintain stable references for React props
36+
const EMPTY_SEARCH_RESULTS: SearchResult[] = [] // kilocode_change - maintain stable references for React props
37+
3538
const ContextMenu: React.FC<ContextMenuProps> = ({
3639
onSelect,
3740
searchQuery,
@@ -41,8 +44,8 @@ const ContextMenu: React.FC<ContextMenuProps> = ({
4144
selectedType,
4245
queryItems,
4346
modes,
44-
dynamicSearchResults = [],
45-
commands = [],
47+
dynamicSearchResults = EMPTY_SEARCH_RESULTS, // kilocode_change
48+
commands = EMPTY_COMMANDS, // kilocode_change
4649
}) => {
4750
const [materialIconsBaseUri, setMaterialIconsBaseUri] = useState("")
4851
const menuRef = useRef<HTMLDivElement>(null)
@@ -51,6 +54,21 @@ const ContextMenu: React.FC<ContextMenuProps> = ({
5154
return getContextMenuOptions(searchQuery, selectedType, queryItems, dynamicSearchResults, modes, commands)
5255
}, [searchQuery, selectedType, queryItems, dynamicSearchResults, modes, commands])
5356

57+
// kilocode_change start - disable hover selection briefly when items change to prevent accidental selections
58+
const [allowEvents, setAllowEvents] = useState(false)
59+
const prevOptionsRef = useRef<ContextMenuQueryItem[] | null>(null)
60+
61+
useEffect(() => {
62+
if (prevOptionsRef.current === null || filteredOptions !== prevOptionsRef.current) {
63+
setAllowEvents(false)
64+
setTimeout(() => {
65+
setAllowEvents(true)
66+
}, 100)
67+
}
68+
prevOptionsRef.current = filteredOptions
69+
}, [filteredOptions])
70+
// kilocode_change end - disable hover selection briefly when items change
71+
5472
useEffect(() => {
5573
if (menuRef.current) {
5674
const selectedElement = menuRef.current.children[selectedIndex] as HTMLElement
@@ -373,7 +391,13 @@ const ContextMenu: React.FC<ContextMenuProps> = ({
373391
}
374392
: {}),
375393
}}
376-
onMouseEnter={() => isOptionSelectable(option) && setSelectedIndex(index)}>
394+
onMouseEnter={() => {
395+
// kilocode_change start - add allowEvents check
396+
if (allowEvents && isOptionSelectable(option)) {
397+
setSelectedIndex(index)
398+
}
399+
// kilocode_change end - add allowEvents check
400+
}}>
377401
<div
378402
style={{
379403
display: "flex",

0 commit comments

Comments
 (0)