chat-sidebar resizing

This commit is contained in:
tusharmagar 2026-01-15 16:00:38 +05:30 committed by Ramnique Singh
parent 74477c772d
commit 35c99cb999
4 changed files with 49 additions and 12 deletions

View file

@ -116,7 +116,7 @@
--sidebar-foreground: var(--text-color, oklch(0.145 0 0));
--sidebar-primary: var(--main-color, oklch(0.205 0 0));
--sidebar-primary-foreground: var(--bg-color, oklch(0.985 0 0));
--sidebar-accent: var(--sub-color, oklch(0.97 0 0));
--sidebar-accent: var(--sub-color, oklch(0.90 0 0));
--sidebar-accent-foreground: var(--text-color, oklch(0.205 0 0));
--sidebar-border: var(--sub-alt-color, oklch(0.922 0 0));
--sidebar-ring: var(--main-color, oklch(0.708 0 0));
@ -150,7 +150,7 @@
--sidebar-foreground: var(--text-color, oklch(0.985 0 0));
--sidebar-primary: var(--main-color, oklch(0.488 0.243 264.376));
--sidebar-primary-foreground: var(--bg-color, oklch(0.985 0 0));
--sidebar-accent: var(--sub-color, oklch(0.269 0 0));
--sidebar-accent: var(--sub-color, oklch(0.35 0 0));
--sidebar-accent-foreground: var(--text-color, oklch(0.985 0 0));
--sidebar-border: var(--sub-alt-color, oklch(1 0 0 / 10%));
--sidebar-ring: var(--main-color, oklch(0.556 0 0));

View file

@ -1124,7 +1124,7 @@ function App() {
{/* Chat sidebar - shown when viewing files/graph */}
{isChatSidebarOpen && (selectedPath || isGraphOpen) && (
<ChatSidebar
width={400}
defaultWidth={400}
onClose={() => setIsChatSidebarOpen(false)}
conversation={conversation}
currentAssistantMessage={currentAssistantMessage}

View file

@ -1,6 +1,8 @@
import { useCallback, useRef, useState } from 'react'
import { X } from 'lucide-react'
import type { ChatStatus, LanguageModelUsage, ToolUIPart } from 'ai'
import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils'
import {
Conversation,
ConversationContent,
@ -105,8 +107,12 @@ const normalizeToolOutput = (output: ToolCall['result'] | undefined, status: Too
return output
}
const MIN_WIDTH = 300
const MAX_WIDTH = 700
const DEFAULT_WIDTH = 400
interface ChatSidebarProps {
width?: number
defaultWidth?: number
onClose: () => void
conversation: ConversationItem[]
currentAssistantMessage: string
@ -121,7 +127,7 @@ interface ChatSidebarProps {
}
export function ChatSidebar({
width = 400,
defaultWidth = DEFAULT_WIDTH,
onClose,
conversation,
currentAssistantMessage,
@ -134,6 +140,33 @@ export function ChatSidebar({
maxTokens,
usedTokens,
}: ChatSidebarProps) {
const [width, setWidth] = useState(defaultWidth)
const [isResizing, setIsResizing] = useState(false)
const startXRef = useRef(0)
const startWidthRef = useRef(0)
const handleMouseDown = useCallback((e: React.MouseEvent) => {
e.preventDefault()
startXRef.current = e.clientX
startWidthRef.current = width
setIsResizing(true)
const handleMouseMove = (e: MouseEvent) => {
// Since sidebar is on right, dragging left increases width
const delta = startXRef.current - e.clientX
const newWidth = Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, startWidthRef.current + delta))
setWidth(newWidth)
}
const handleMouseUp = () => {
setIsResizing(false)
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', handleMouseUp)
}
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', handleMouseUp)
}, [width])
const hasConversation = conversation.length > 0 || currentAssistantMessage || currentReasoning
const submitStatus: ChatStatus = isProcessing ? 'streaming' : 'ready'
const canSubmit = Boolean(message.trim()) && !isProcessing
@ -188,9 +221,19 @@ export function ChatSidebar({
return (
<div
className="flex flex-col border-l border-border bg-background shrink-0"
className="relative flex flex-col border-l border-border bg-background shrink-0"
style={{ width }}
>
{/* Resize handle */}
<div
onMouseDown={handleMouseDown}
className={cn(
"absolute inset-y-0 left-0 z-20 w-4 -translate-x-1/2 cursor-col-resize",
"after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] after:transition-colors",
"hover:after:bg-sidebar-border",
isResizing && "after:bg-primary"
)}
/>
{/* Header */}
<header className="flex h-12 shrink-0 items-center justify-between border-b border-border px-3">
<span className="text-sm font-medium">Chat</span>

View file

@ -7,7 +7,6 @@ import {
HelpCircle,
Plug,
Settings,
Ship,
} from "lucide-react"
import { cn } from "@/lib/utils"
@ -36,11 +35,6 @@ export function SidebarIcon() {
return (
<div className="bg-sidebar border-r border-sidebar-border flex h-svh w-14 flex-col items-center py-2 fixed left-0 top-0 z-50 shrink-0">
{/* Logo */}
<div className="flex h-10 w-10 items-center justify-center rounded-md bg-sidebar-primary text-sidebar-primary-foreground mb-4">
<Ship className="size-5" />
</div>
{/* Main navigation */}
<nav className="flex flex-1 flex-col items-center gap-1">
{navItems.map((item) => (