@prmichaelsen/acp-visualizer 0.9.3 → 0.9.5

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.9.3",
3
+ "version": "0.9.5",
4
4
  "type": "module",
5
5
  "description": "Browser-based dashboard for visualizing ACP progress.yaml data",
6
6
  "bin": {
@@ -39,22 +39,22 @@ export function GitHubInput({ onLoad }: GitHubInputProps) {
39
39
  <div>
40
40
  <div className="flex gap-1">
41
41
  <div className="relative flex-1">
42
- <Github className="absolute left-2 top-[7px] w-3.5 h-3.5 text-gray-500" />
42
+ <Github className="absolute left-2 top-2 w-4 h-4 text-gray-500" />
43
43
  <input
44
44
  type="text"
45
45
  value={value}
46
46
  onChange={(e) => { setValue(e.target.value); setError(null) }}
47
47
  onKeyDown={(e) => e.key === 'Enter' && handleSubmit()}
48
48
  placeholder="owner/repo"
49
- className="w-full bg-gray-900 border border-gray-800 rounded-md pl-7 pr-2 py-1.5 text-xs text-gray-200 placeholder-gray-600 focus:outline-none focus:border-gray-600 transition-colors"
49
+ className="w-full bg-gray-900 border border-gray-800 rounded-md pl-8 pr-2 py-2 text-base text-gray-200 placeholder-gray-600 focus:outline-none focus:border-gray-600 transition-colors"
50
50
  />
51
51
  </div>
52
52
  <button
53
53
  onClick={handleSubmit}
54
54
  disabled={loading || !value.trim()}
55
- className="px-2 py-1.5 bg-gray-800 border border-gray-700 rounded-md text-xs text-gray-300 hover:bg-gray-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
55
+ className="px-3 py-2 bg-gray-800 border border-gray-700 rounded-md text-sm text-gray-300 hover:bg-gray-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
56
56
  >
57
- {loading ? <Loader2 className="w-3 h-3 animate-spin" /> : 'Go'}
57
+ {loading ? <Loader2 className="w-4 h-4 animate-spin" /> : 'Go'}
58
58
  </button>
59
59
  </div>
60
60
  {error && (
@@ -14,7 +14,7 @@ export function Header({ data }: HeaderProps) {
14
14
  if (!data) return null
15
15
 
16
16
  return (
17
- <header className="h-14 border-b border-gray-200 dark:border-gray-800 flex items-center pl-16 lg:pl-6 pr-4 lg:pr-6 gap-2 lg:gap-4 shrink-0 bg-white dark:bg-gray-950">
17
+ <header className="h-14 border-b border-gray-200 dark:border-gray-800 flex items-center px-4 lg:px-6 gap-2 lg:gap-4 shrink-0 bg-white dark:bg-gray-950">
18
18
  <h1 className="text-sm font-medium text-gray-900 dark:text-gray-200 truncate">{data.project.name}</h1>
19
19
  <span className="hidden sm:inline text-xs text-gray-500 dark:text-gray-500 font-mono">v{data.project.version}</span>
20
20
  <div className="hidden sm:block">
@@ -9,13 +9,13 @@ interface SearchInputProps {
9
9
  export function SearchInput({ value, onChange, placeholder = 'Search...' }: SearchInputProps) {
10
10
  return (
11
11
  <div className="relative">
12
- <Search className="absolute left-2.5 top-2 w-4 h-4 text-gray-500" />
12
+ <Search className="absolute left-3 top-2.5 w-4 h-4 text-gray-500" />
13
13
  <input
14
14
  type="text"
15
15
  value={value}
16
16
  onChange={(e) => onChange(e.target.value)}
17
17
  placeholder={placeholder}
18
- className="w-full bg-gray-900 border border-gray-800 rounded-md pl-8 pr-3 py-1.5 text-sm text-gray-200 placeholder-gray-600 focus:outline-none focus:border-gray-600 transition-colors"
18
+ className="w-full bg-gray-900 border border-gray-800 rounded-md pl-10 pr-3 py-2 text-base text-gray-200 placeholder-gray-600 focus:outline-none focus:border-gray-600 transition-colors"
19
19
  />
20
20
  </div>
21
21
  )
@@ -26,7 +26,7 @@ export function Sidebar({ projects = [], currentProject = null, onProjectSelect,
26
26
  const location = useRouterState({ select: (s) => s.location })
27
27
 
28
28
  return (
29
- <nav className="w-56 h-full border-r border-gray-200 dark:border-gray-800 bg-gray-100 dark:bg-gray-950 flex flex-col shrink-0">
29
+ <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-hidden">
30
30
  <div className="p-4 border-b border-gray-200 dark:border-gray-800 flex items-center justify-between">
31
31
  <span className="text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide">
32
32
  ACP Visualizer
@@ -50,7 +50,7 @@ export function Sidebar({ projects = [], currentProject = null, onProjectSelect,
50
50
  />
51
51
  </div>
52
52
  )}
53
- <div className="flex-1 py-2">
53
+ <div className="flex-1 py-2 overflow-y-auto">
54
54
  {navItems.map((item) => {
55
55
  const isActive =
56
56
  item.to === '/'
@@ -66,6 +66,7 @@ export function Sidebar({ projects = [], currentProject = null, onProjectSelect,
66
66
  ? 'text-gray-900 dark:text-gray-100 bg-gray-200 dark:bg-gray-800/50'
67
67
  : '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'
68
68
  }`}
69
+ onClick={onClose}
69
70
  >
70
71
  <item.icon className="w-4 h-4" />
71
72
  {item.label}
@@ -77,6 +78,7 @@ export function Sidebar({ projects = [], currentProject = null, onProjectSelect,
77
78
  <Link
78
79
  to="/search"
79
80
  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"
81
+ onClick={onClose}
80
82
  >
81
83
  <Search className="w-4 h-4" />
82
84
  Search...
@@ -159,13 +159,17 @@ function RootLayout() {
159
159
  <>
160
160
  <AutoRefresh />
161
161
  <div className="flex h-screen bg-white dark:bg-gray-950 text-gray-900 dark:text-gray-100">
162
- {/* Mobile Menu Button */}
162
+ {/* Mobile Menu Button - Bottom Right (Thumb Zone) */}
163
163
  <button
164
- onClick={() => setMobileMenuOpen(true)}
165
- className="lg:hidden fixed top-4 left-4 z-50 p-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-lg"
166
- aria-label="Open menu"
164
+ onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
165
+ className="lg:hidden fixed bottom-6 right-6 z-50 p-3 rounded-full bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-lg transition-transform duration-200"
166
+ aria-label={mobileMenuOpen ? "Close menu" : "Open menu"}
167
167
  >
168
- <Menu className="w-5 h-5 text-gray-900 dark:text-gray-100" />
168
+ {mobileMenuOpen ? (
169
+ <X className="w-6 h-6 text-gray-900 dark:text-gray-100" />
170
+ ) : (
171
+ <Menu className="w-6 h-6 text-gray-900 dark:text-gray-100" />
172
+ )}
169
173
  </button>
170
174
 
171
175
  {/* Mobile Backdrop */}
@@ -176,10 +180,10 @@ function RootLayout() {
176
180
  />
177
181
  )}
178
182
 
179
- {/* Sidebar - Desktop: Always visible | Mobile: Drawer */}
183
+ {/* Sidebar - Desktop: Always visible | Mobile: Bottom Drawer */}
180
184
  <div
181
- className={`fixed lg:relative inset-y-0 left-0 z-50 transition-transform duration-300 lg:translate-x-0 ${
182
- mobileMenuOpen ? 'translate-x-0' : '-translate-x-full'
185
+ className={`fixed lg:relative bottom-0 left-0 right-0 lg:inset-y-0 lg:right-auto z-50 transition-transform duration-300 lg:translate-y-0 ${
186
+ mobileMenuOpen ? 'translate-y-0' : 'translate-y-full'
183
187
  }`}
184
188
  >
185
189
  <Sidebar