feat(ui): unify comment assignee selector with icons and fix click flash
Add renderTriggerValue/renderOption to the comment thread's assignee selector so it shows agent icons, matching the new issue dialog. Fix the InlineEntitySelector flash on click by only auto-opening on keyboard focus (not pointer-triggered focus). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import { InlineEntitySelector, type InlineEntityOption } from "./InlineEntitySel
|
||||
import { MarkdownBody } from "./MarkdownBody";
|
||||
import { MarkdownEditor, type MarkdownEditorRef, type MentionOption } from "./MarkdownEditor";
|
||||
import { StatusBadge } from "./StatusBadge";
|
||||
import { AgentIcon } from "./AgentIconPicker";
|
||||
import { formatDateTime } from "../lib/utils";
|
||||
|
||||
interface CommentWithRunMeta extends IssueComment {
|
||||
@@ -385,6 +386,32 @@ export function CommentThread({
|
||||
emptyMessage="No assignees found."
|
||||
onChange={setReassignTarget}
|
||||
className="text-xs h-8"
|
||||
renderTriggerValue={(option) => {
|
||||
if (!option) return <span className="text-muted-foreground">Assignee</span>;
|
||||
const agentId = option.id.startsWith("agent:") ? option.id.slice("agent:".length) : null;
|
||||
const agent = agentId ? agentMap?.get(agentId) : null;
|
||||
return (
|
||||
<>
|
||||
{agent ? (
|
||||
<AgentIcon icon={agent.icon} className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
|
||||
) : null}
|
||||
<span className="truncate">{option.label}</span>
|
||||
</>
|
||||
);
|
||||
}}
|
||||
renderOption={(option) => {
|
||||
if (!option.id) return <span className="truncate">{option.label}</span>;
|
||||
const agentId = option.id.startsWith("agent:") ? option.id.slice("agent:".length) : null;
|
||||
const agent = agentId ? agentMap?.get(agentId) : null;
|
||||
return (
|
||||
<>
|
||||
{agent ? (
|
||||
<AgentIcon icon={agent.icon} className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
|
||||
) : null}
|
||||
<span className="truncate">{option.label}</span>
|
||||
</>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Button size="sm" disabled={!canSubmit} onClick={handleSubmit}>
|
||||
|
||||
@@ -45,6 +45,7 @@ export const InlineEntitySelector = forwardRef<HTMLButtonElement, InlineEntitySe
|
||||
const [highlightedIndex, setHighlightedIndex] = useState(0);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const shouldPreventCloseAutoFocusRef = useRef(false);
|
||||
const isPointerDownRef = useRef(false);
|
||||
|
||||
const allOptions = useMemo<InlineEntityOption[]>(
|
||||
() => [{ id: "", label: noneLabel, searchText: noneLabel }, ...options],
|
||||
@@ -97,7 +98,11 @@ export const InlineEntitySelector = forwardRef<HTMLButtonElement, InlineEntitySe
|
||||
"inline-flex min-w-0 items-center gap-1 rounded-md border border-border bg-muted/40 px-2 py-1 text-sm font-medium text-foreground transition-colors hover:bg-accent/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
||||
className,
|
||||
)}
|
||||
onFocus={() => setOpen(true)}
|
||||
onPointerDown={() => { isPointerDownRef.current = true; }}
|
||||
onFocus={() => {
|
||||
if (!isPointerDownRef.current) setOpen(true);
|
||||
isPointerDownRef.current = false;
|
||||
}}
|
||||
>
|
||||
{renderTriggerValue
|
||||
? renderTriggerValue(currentOption)
|
||||
|
||||
Reference in New Issue
Block a user