mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-05-30 00:05:33 +08:00
fix(sidebar): keep session rename input visible while editing (#781)
The rename input shares a parent div that uses `group-hover:opacity-100`, so moving the cursor off the row visually hid the input mid-edit. While editing, force the action panel to `opacity-100` and dismiss it via an outside-click listener instead of mouseleave. Also hide the relative-time badge so it does not overlap the input.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { Check, Edit2, Trash2, X } from 'lucide-react';
|
||||
import type { TFunction } from 'i18next';
|
||||
|
||||
@@ -76,7 +77,28 @@ export default function SidebarSessionItem({
|
||||
}: SidebarSessionItemProps) {
|
||||
const sessionView = createSessionViewModel(session, currentTime, t);
|
||||
const isSelected = selectedSession?.id === session.id;
|
||||
const isEditing = editingSession === session.id;
|
||||
const compactSessionAge = formatCompactSessionAge(sessionView.sessionTime, currentTime);
|
||||
const editingContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// The rename panel sits inside a group-hover opacity wrapper, so leaving the row
|
||||
// would visually hide it. While editing, dismiss only when the user clicks outside
|
||||
// the panel (matches Escape / cancel-button behaviour).
|
||||
useEffect(() => {
|
||||
if (!isEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
const handlePointerDown = (event: MouseEvent) => {
|
||||
const container = editingContainerRef.current;
|
||||
if (container && !container.contains(event.target as Node)) {
|
||||
onCancelEditingSession();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('mousedown', handlePointerDown);
|
||||
return () => document.removeEventListener('mousedown', handlePointerDown);
|
||||
}, [isEditing, onCancelEditingSession]);
|
||||
|
||||
// Sessions are owned by a project identified by `projectId` (DB primary key)
|
||||
// after the projectName → projectId migration.
|
||||
@@ -174,7 +196,12 @@ export default function SidebarSessionItem({
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="truncate text-xs font-medium text-foreground">{sessionView.sessionName}</div>
|
||||
{compactSessionAge && (
|
||||
<span className="ml-auto flex-shrink-0 text-[11px] text-muted-foreground transition-opacity duration-200 group-hover:opacity-0">
|
||||
<span
|
||||
className={cn(
|
||||
'ml-auto flex-shrink-0 text-[11px] text-muted-foreground transition-opacity duration-200',
|
||||
isEditing ? 'opacity-0' : 'group-hover:opacity-0',
|
||||
)}
|
||||
>
|
||||
{compactSessionAge}
|
||||
</span>
|
||||
)}
|
||||
@@ -186,8 +213,14 @@ export default function SidebarSessionItem({
|
||||
</div>
|
||||
</Button>
|
||||
|
||||
<div className="absolute right-2 top-1/2 flex -translate-y-1/2 transform items-center gap-1 opacity-0 transition-all duration-200 group-hover:opacity-100">
|
||||
{editingSession === session.id ? (
|
||||
<div
|
||||
ref={editingContainerRef}
|
||||
className={cn(
|
||||
'absolute right-2 top-1/2 flex -translate-y-1/2 transform items-center gap-1 transition-all duration-200',
|
||||
isEditing ? 'opacity-100' : 'opacity-0 group-hover:opacity-100',
|
||||
)}
|
||||
>
|
||||
{isEditing ? (
|
||||
<>
|
||||
<input
|
||||
type="text"
|
||||
|
||||
Reference in New Issue
Block a user