feat: resizable sidebar, branch hover preview, Fork Point label fix
- Sidebar: click-and-drag resize handle (200-500px range), accent highlight on drag, cursor changes to col-resize - BranchNode: hover/active expands to show context_summary (tried, result), status_reason, and step count with smooth animation - ForkCard: "Fork Point" label changed from text-muted to text-accent-text for visibility against bg-card Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* Renders all branching components with mock data — no API calls.
|
||||
* Use this to validate visual design before wiring into FlowPilotSessionPage.
|
||||
*/
|
||||
import { useState } from 'react'
|
||||
import { useState, useCallback, useEffect, useRef } from 'react'
|
||||
import { BranchMap } from '@/components/session/BranchMap'
|
||||
import { ForkCard } from '@/components/session/ForkCard'
|
||||
import { BranchTransitionBar } from '@/components/session/BranchTransitionBar'
|
||||
@@ -421,6 +421,8 @@ export default function DevBranchingPage() {
|
||||
const [showHandoff, setShowHandoff] = useState(false)
|
||||
const [previousBranchId, setPreviousBranchId] = useState<string | null>(null)
|
||||
const [showTransition, setShowTransition] = useState(false)
|
||||
const [sidebarWidth, setSidebarWidth] = useState(280)
|
||||
const [isResizing, setIsResizing] = useState(false)
|
||||
|
||||
const activeBranch = MOCK_BRANCHES.find(b => b.id === activeBranchId)!
|
||||
const previousBranch = previousBranchId ? MOCK_BRANCHES.find(b => b.id === previousBranchId) ?? null : null
|
||||
@@ -436,15 +438,61 @@ export default function DevBranchingPage() {
|
||||
}
|
||||
}
|
||||
|
||||
// ── Resizable sidebar ──
|
||||
const sidebarRef = useRef<HTMLDivElement>(null)
|
||||
const isResizingRef = useRef(false)
|
||||
|
||||
const handleMouseDown = useCallback((e: React.MouseEvent) => {
|
||||
e.preventDefault()
|
||||
isResizingRef.current = true
|
||||
setIsResizing(true)
|
||||
document.body.style.cursor = 'col-resize'
|
||||
document.body.style.userSelect = 'none'
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
function handleMouseMove(e: MouseEvent) {
|
||||
if (!isResizingRef.current) return
|
||||
const newWidth = Math.min(Math.max(e.clientX, 200), 500)
|
||||
setSidebarWidth(newWidth)
|
||||
}
|
||||
function handleMouseUp() {
|
||||
if (!isResizingRef.current) return
|
||||
isResizingRef.current = false
|
||||
setIsResizing(false)
|
||||
document.body.style.cursor = ''
|
||||
document.body.style.userSelect = ''
|
||||
}
|
||||
document.addEventListener('mousemove', handleMouseMove)
|
||||
document.addEventListener('mouseup', handleMouseUp)
|
||||
return () => {
|
||||
document.removeEventListener('mousemove', handleMouseMove)
|
||||
document.removeEventListener('mouseup', handleMouseUp)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex h-full">
|
||||
{/* Branch Map Sidebar */}
|
||||
<aside className="w-[260px] shrink-0 border-r border-default bg-sidebar p-3 overflow-y-auto">
|
||||
<aside
|
||||
ref={sidebarRef}
|
||||
style={{ width: sidebarWidth }}
|
||||
className="shrink-0 border-r border-default bg-sidebar p-3 overflow-y-auto relative"
|
||||
>
|
||||
<BranchMap
|
||||
branches={MOCK_BRANCHES}
|
||||
activeBranchId={activeBranchId}
|
||||
onSelectBranch={handleSwitchBranch}
|
||||
/>
|
||||
{/* Resize handle */}
|
||||
<div
|
||||
onMouseDown={handleMouseDown}
|
||||
className={cn(
|
||||
'absolute top-0 right-0 w-1 h-full cursor-col-resize transition-colors',
|
||||
'hover:bg-accent/40',
|
||||
isResizing ? 'bg-accent/60' : 'bg-transparent'
|
||||
)}
|
||||
/>
|
||||
</aside>
|
||||
|
||||
{/* Main Content */}
|
||||
|
||||
Reference in New Issue
Block a user