refactor: enhance chat tab management by implementing fallback navigation and preventing race conditions during deletion for improved user experience

This commit is contained in:
Anish Sarkar 2026-03-29 22:12:55 +05:30
parent b54aa517a8
commit 69b8eef5ce
7 changed files with 65 additions and 93 deletions

View file

@ -1,7 +1,7 @@
"use client";
import { useAtomValue, useSetAtom } from "jotai";
import { FileText, MessageSquare, Plus, X } from "lucide-react";
import { Plus, X } from "lucide-react";
import { useCallback, useEffect, useRef } from "react";
import {
activeTabIdAtom,
@ -65,7 +65,6 @@ export function TabBar({ onTabSwitch, onNewChat, className }: TabBarProps) {
>
{tabs.map((tab) => {
const isActive = tab.id === activeTabId;
const Icon = tab.type === "document" ? FileText : MessageSquare;
return (
<button
@ -74,15 +73,16 @@ export function TabBar({ onTabSwitch, onNewChat, className }: TabBarProps) {
data-tab-id={tab.id}
onClick={() => handleTabClick(tab)}
className={cn(
"group relative flex h-full items-center self-stretch gap-1.5 px-3 min-w-0 max-w-[200px] text-xs font-medium border-r transition-colors shrink-0",
"group relative flex h-full w-[170px] items-center self-stretch px-3 min-w-0 overflow-hidden text-sm font-medium border-r transition-colors shrink-0",
isActive
? "bg-muted/40 text-foreground"
: "bg-transparent text-muted-foreground hover:bg-muted/25 hover:text-foreground"
)}
>
{isActive && <span className="absolute bottom-0 left-0 right-0 h-[2px] bg-primary" />}
<Icon className="size-3.5 shrink-0" />
<span className="truncate">{tab.title}</span>
<span className="block min-w-0 flex-1 truncate text-left transition-[padding-right] duration-150 group-hover:pr-5 group-focus-within:pr-5">
{tab.title}
</span>
{/* biome-ignore lint/a11y/useSemanticElements: cannot nest button inside button */}
<span
role="button"
@ -95,10 +95,10 @@ export function TabBar({ onTabSwitch, onNewChat, className }: TabBarProps) {
}
}}
className={cn(
"ml-auto shrink-0 rounded-sm p-0.5 transition-colors",
"absolute right-2 top-1/2 -translate-y-1/2 shrink-0 rounded-sm p-0.5 transition-colors",
isActive
? "opacity-60 hover:opacity-100 hover:bg-muted"
: "opacity-0 group-hover:opacity-60 hover:opacity-100! hover:bg-muted"
? "opacity-0 group-hover:opacity-70 group-focus-within:opacity-70 hover:opacity-100 hover:bg-muted"
: "opacity-0 group-hover:opacity-60 group-focus-within:opacity-60 hover:opacity-100! hover:bg-muted"
)}
>
<X className="size-3" />