@prmichaelsen/acp-visualizer 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/acp-visualizer",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "type": "module",
5
5
  "description": "Browser-based dashboard for visualizing ACP progress.yaml data",
6
6
  "bin": {
@@ -1,5 +1,5 @@
1
1
  import { Link, useRouterState } from '@tanstack/react-router'
2
- import { LayoutDashboard, Flag, CheckSquare, Clock, Search, PenTool, Puzzle, FileBarChart, Github, X } from 'lucide-react'
2
+ import { LayoutDashboard, Flag, CheckSquare, Clock, Search, PenTool, Puzzle, FileBarChart, Github, X, ChevronLeft, ChevronRight } from 'lucide-react'
3
3
  import { ProjectSelector } from './ProjectSelector'
4
4
  import { GitHubInput } from './GitHubInput'
5
5
  import { GitHubAuth } from './GitHubAuth'
@@ -22,28 +22,50 @@ interface SidebarProps {
22
22
  onProjectSelect?: (projectId: string) => void
23
23
  onGitHubLoad?: (owner: string, repo: string) => Promise<void>
24
24
  onClose?: () => void
25
+ isCollapsed?: boolean
26
+ onToggleCollapse?: () => void
25
27
  }
26
28
 
27
- export function Sidebar({ projects = [], currentProject = null, onProjectSelect, onGitHubLoad, onClose }: SidebarProps) {
29
+ export function Sidebar({ projects = [], currentProject = null, onProjectSelect, onGitHubLoad, onClose, isCollapsed = false, onToggleCollapse }: SidebarProps) {
28
30
  const location = useRouterState({ select: (s) => s.location })
29
31
 
30
32
  return (
31
- <nav className="w-full lg:w-56 h-auto max-h-[80vh] lg:h-full border-t lg:border-t-0 lg:border-r border-gray-200 dark:border-gray-800 bg-gray-100 dark:bg-gray-950 flex flex-col shrink-0 rounded-t-2xl lg:rounded-none overflow-y-auto">
33
+ <nav className={`w-full h-auto max-h-[80vh] lg:h-full border-t lg:border-t-0 lg:border-r border-gray-200 dark:border-gray-800 bg-gray-100 dark:bg-gray-950 flex flex-col shrink-0 rounded-t-2xl lg:rounded-none overflow-y-auto transition-all duration-300 ${
34
+ isCollapsed ? 'lg:w-16' : 'lg:w-56'
35
+ }`}>
32
36
  <div className="p-4 border-b border-gray-200 dark:border-gray-800 flex items-center justify-between">
33
- <span className="text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide">
34
- ACP Visualizer
35
- </span>
36
- {onClose && (
37
- <button
38
- onClick={onClose}
39
- className="lg:hidden p-1.5 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-800 transition-colors"
40
- aria-label="Close menu"
41
- >
42
- <X className="w-4 h-4 text-gray-700 dark:text-gray-300" />
43
- </button>
37
+ {!isCollapsed && (
38
+ <span className="text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide">
39
+ ACP Visualizer
40
+ </span>
44
41
  )}
42
+ <div className="flex items-center gap-2">
43
+ {onToggleCollapse && (
44
+ <button
45
+ onClick={onToggleCollapse}
46
+ className="hidden lg:block p-1.5 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-800 transition-colors"
47
+ aria-label={isCollapsed ? "Expand sidebar" : "Collapse sidebar"}
48
+ title={isCollapsed ? "Expand sidebar" : "Collapse sidebar"}
49
+ >
50
+ {isCollapsed ? (
51
+ <ChevronRight className="w-4 h-4 text-gray-700 dark:text-gray-300" />
52
+ ) : (
53
+ <ChevronLeft className="w-4 h-4 text-gray-700 dark:text-gray-300" />
54
+ )}
55
+ </button>
56
+ )}
57
+ {onClose && (
58
+ <button
59
+ onClick={onClose}
60
+ className="lg:hidden p-1.5 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-800 transition-colors"
61
+ aria-label="Close menu"
62
+ >
63
+ <X className="w-4 h-4 text-gray-700 dark:text-gray-300" />
64
+ </button>
65
+ )}
66
+ </div>
45
67
  </div>
46
- {projects.length > 1 && onProjectSelect && (
68
+ {projects.length > 1 && onProjectSelect && !isCollapsed && (
47
69
  <div className="px-3 pt-3">
48
70
  <ProjectSelector
49
71
  projects={projects}
@@ -63,34 +85,39 @@ export function Sidebar({ projects = [], currentProject = null, onProjectSelect,
63
85
  <Link
64
86
  key={item.to}
65
87
  to={item.to}
66
- className={`flex items-center gap-3 px-4 py-2 text-sm transition-colors ${
88
+ className={`flex items-center gap-3 py-2 text-sm transition-colors ${
89
+ isCollapsed ? 'px-4 justify-center' : 'px-4'
90
+ } ${
67
91
  isActive
68
92
  ? 'text-gray-900 dark:text-gray-100 bg-gray-200 dark:bg-gray-800/50'
69
93
  : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 hover:bg-gray-200/50 dark:hover:bg-gray-800/30'
70
94
  }`}
71
95
  onClick={onClose}
96
+ title={isCollapsed ? item.label : undefined}
72
97
  >
73
98
  <item.icon className="w-4 h-4" />
74
- {item.label}
99
+ {!isCollapsed && item.label}
75
100
  </Link>
76
101
  )
77
102
  })}
78
103
  </div>
79
- <hr className="border-gray-200 dark:border-gray-800" />
80
- <div className="p-3 space-y-2">
81
- <Link
82
- to="/search"
83
- className="flex items-center gap-2 px-3 py-1.5 text-sm text-gray-600 dark:text-gray-500 bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-800 rounded-md hover:text-gray-900 dark:hover:text-gray-300 hover:border-gray-400 dark:hover:border-gray-600 transition-colors"
84
- onClick={onClose}
85
- >
86
- <Search className="w-4 h-4" />
87
- Search...
88
- </Link>
89
- <GitHubAuth />
90
- {onGitHubLoad && (
91
- <GitHubInput onLoad={onGitHubLoad} />
92
- )}
93
- </div>
104
+ {!isCollapsed && <hr className="border-gray-200 dark:border-gray-800" />}
105
+ {!isCollapsed && (
106
+ <div className="p-3 space-y-2">
107
+ <Link
108
+ to="/search"
109
+ className="flex items-center gap-2 px-3 py-1.5 text-sm text-gray-600 dark:text-gray-500 bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-800 rounded-md hover:text-gray-900 dark:hover:text-gray-300 hover:border-gray-400 dark:hover:border-gray-600 transition-colors"
110
+ onClick={onClose}
111
+ >
112
+ <Search className="w-4 h-4" />
113
+ Search...
114
+ </Link>
115
+ <GitHubAuth />
116
+ {onGitHubLoad && (
117
+ <GitHubInput onLoad={onGitHubLoad} />
118
+ )}
119
+ </div>
120
+ )}
94
121
  </nav>
95
122
  )
96
123
  }
@@ -112,6 +112,7 @@ function RootLayout() {
112
112
  )
113
113
  const [initialLoadDone, setInitialLoadDone] = useState(false)
114
114
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
115
+ const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
115
116
 
116
117
  // On mount, check for ?repo= param and auto-load
117
118
  useEffect(() => {
@@ -196,6 +197,8 @@ function RootLayout() {
196
197
  onProjectSelect={handleProjectSwitch}
197
198
  onGitHubLoad={handleGitHubLoad}
198
199
  onClose={() => setMobileMenuOpen(false)}
200
+ isCollapsed={sidebarCollapsed}
201
+ onToggleCollapse={() => setSidebarCollapsed(!sidebarCollapsed)}
199
202
  />
200
203
  </div>
201
204