fix: improve slash and mention autocomplete (#1309)

Shows loaded skills in slash autocomplete with clear type badges
Stabilizes keyboard navigation across autocomplete menus
Fixes skill link rendering and skill autocomplete scrolling
This commit is contained in:
Bohdan Triapitsyn
2026-05-18 19:11:29 +03:00
parent aede187244
commit 56a2319934
13 changed files with 104 additions and 54 deletions
@@ -44,6 +44,7 @@ export const AgentMentionAutocomplete = React.forwardRef<AgentMentionAutocomplet
const { t } = useI18n();
const containerRef = React.useRef<HTMLDivElement | null>(null);
const [selectedIndex, setSelectedIndex] = React.useState(0);
const selectedIndexRef = React.useRef(0);
const [agents, setAgents] = React.useState<AgentInfo[]>([]);
const itemRefs = React.useRef<(HTMLDivElement | null)[]>([]);
const ignoreTabClickRef = React.useRef(false);
@@ -83,9 +84,12 @@ export const AgentMentionAutocomplete = React.forwardRef<AgentMentionAutocomplet
setSelectedIndex(0);
}, [getVisibleAgents, searchQuery, agentsWithMetadata]);
React.useEffect(() => {
selectedIndexRef.current = selectedIndex;
}, [selectedIndex]);
React.useEffect(() => {
itemRefs.current[selectedIndex]?.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
});
}, [selectedIndex]);
@@ -129,13 +133,14 @@ export const AgentMentionAutocomplete = React.forwardRef<AgentMentionAutocomplet
}
if (key === 'Enter' || key === 'Tab') {
const agent = agents[(selectedIndex + agents.length) % agents.length];
const safeIndex = ((selectedIndexRef.current % agents.length) + agents.length) % agents.length;
const agent = agents[safeIndex];
if (agent) {
onAgentSelect(agent.name);
}
}
},
}), [agents, onAgentSelect, onClose, selectedIndex]);
}), [agents, onAgentSelect, onClose]);
const renderAgent = (agent: AgentInfo, index: number) => {
const isSystem = agent.isBuiltIn;
@@ -150,9 +155,9 @@ export const AgentMentionAutocomplete = React.forwardRef<AgentMentionAutocomplet
className={cn(
'flex items-start gap-2 px-3 py-1.5 cursor-pointer rounded-lg typography-ui-label',
index === selectedIndex && 'bg-interactive-selection'
)}
)}
onClick={() => onAgentSelect(agent.name)}
onMouseEnter={() => setSelectedIndex(index)}
onMouseMove={() => setSelectedIndex(index)}
>
<div className="min-w-0 flex-1">
<div className="flex items-center gap-2">