@toolr/ui-design 0.1.7 → 0.1.9

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.
Files changed (101) hide show
  1. package/ai-manifest.json +35 -20
  2. package/components/composites/dashboard-list-item.tsx +172 -0
  3. package/components/composites/dashboard-panel.tsx +218 -0
  4. package/components/content/info-panel-primitives.tsx +9 -8
  5. package/components/diagrams/diagram-utils.tsx +2 -1
  6. package/components/hooks/use-dropdown-portal.ts +39 -0
  7. package/components/hooks/use-modal-behavior.ts +32 -3
  8. package/components/lib/accent-context.ts +10 -0
  9. package/components/lib/{ai-tools.tsx → coding-agents.tsx} +23 -8
  10. package/components/lib/custom-icons.tsx +37 -0
  11. package/components/lib/git-providers.tsx +39 -0
  12. package/components/lib/theme-engine.ts +59 -10
  13. package/components/lib/toolr-brand.tsx +23 -9
  14. package/components/sections/captured-issues/captured-issues-panel.tsx +17 -8
  15. package/components/sections/{ai-tools-paths/tools-paths-panel.tsx → coding-agent-paths/agent-paths-panel.tsx} +70 -62
  16. package/components/sections/coding-agent-paths/index.ts +37 -0
  17. package/components/sections/{ai-tools-paths → coding-agent-paths}/types.ts +28 -28
  18. package/components/sections/coding-agent-paths/use-agent-paths.ts +159 -0
  19. package/components/sections/golden-snapshots/file-diff-viewer.tsx +11 -10
  20. package/components/sections/golden-snapshots/golden-sync-panel.tsx +12 -3
  21. package/components/sections/golden-snapshots/snapshot-manager.tsx +9 -7
  22. package/components/sections/golden-snapshots/status-overview.tsx +8 -8
  23. package/components/sections/golden-snapshots/version-manager.tsx +6 -6
  24. package/components/sections/prompt-editor/file-type-tabbed-prompt-editor.tsx +3 -3
  25. package/components/sections/prompt-editor/index.ts +1 -1
  26. package/components/sections/prompt-editor/simulator-prompt-editor.tsx +13 -5
  27. package/components/sections/prompt-editor/tabbed-prompt-editor.tsx +18 -10
  28. package/components/sections/prompt-editor/types.ts +2 -2
  29. package/components/sections/report-bug/report-bug-form.tsx +12 -4
  30. package/components/sections/report-bug/screenshot-uploader.tsx +11 -3
  31. package/components/sections/snapshot-browser/snapshot-browser-panel.tsx +12 -4
  32. package/components/sections/snapshot-browser/snapshot-tree.tsx +5 -4
  33. package/components/sections/snapshot-browser/types.ts +1 -1
  34. package/components/sections/snippets-editor/snippets-editor.tsx +16 -9
  35. package/components/settings/SettingsHeader.tsx +2 -2
  36. package/components/settings/SettingsPanel.tsx +11 -3
  37. package/components/settings/SettingsTreeNav.tsx +15 -9
  38. package/components/ui/action-dialog.tsx +37 -35
  39. package/components/ui/ai-action-button.tsx +12 -11
  40. package/components/ui/ai-execution-action-buttons.tsx +13 -5
  41. package/components/ui/badge.tsx +17 -6
  42. package/components/ui/bottom-panel-header.tsx +9 -5
  43. package/components/ui/breadcrumb.tsx +14 -6
  44. package/components/ui/{extension-list-card.tsx → capability-list-card.tsx} +14 -6
  45. package/components/ui/checkbox.tsx +23 -14
  46. package/components/ui/collapsible-section.tsx +38 -28
  47. package/components/ui/confirm-badge.tsx +17 -6
  48. package/components/ui/cookie-consent.tsx +13 -7
  49. package/components/ui/detail-section.tsx +24 -16
  50. package/components/ui/detail-view-wrapper.tsx +30 -22
  51. package/components/ui/editor-placeholder-card.tsx +28 -24
  52. package/components/ui/editor-toolbar.tsx +7 -4
  53. package/components/ui/execution-details-panel.tsx +10 -5
  54. package/components/ui/file-structure-section.tsx +3 -3
  55. package/components/ui/file-tree.tsx +7 -5
  56. package/components/ui/files-panel.tsx +147 -27
  57. package/components/ui/filter-dropdown.tsx +88 -75
  58. package/components/ui/form-actions.tsx +21 -11
  59. package/components/ui/frontmatter-form-header.tsx +10 -2
  60. package/components/ui/icon-button.tsx +27 -14
  61. package/components/ui/input.tsx +15 -7
  62. package/components/ui/label.tsx +9 -5
  63. package/components/ui/layout-tab-bar.tsx +11 -9
  64. package/components/ui/modal.tsx +26 -8
  65. package/components/ui/nav-card.tsx +7 -4
  66. package/components/ui/navigation-bar.tsx +40 -12
  67. package/components/ui/number-input.tsx +14 -4
  68. package/components/ui/project-explorer.tsx +666 -0
  69. package/components/ui/registry-browser.tsx +12 -1
  70. package/components/ui/registry-card.tsx +49 -42
  71. package/components/ui/registry-detail.tsx +34 -11
  72. package/components/ui/resizable-textarea.tsx +18 -11
  73. package/components/ui/scope-badge.tsx +18 -11
  74. package/components/ui/segmented-toggle.tsx +7 -2
  75. package/components/ui/select.tsx +17 -11
  76. package/components/ui/selection-grid.tsx +40 -37
  77. package/components/ui/setting-row.tsx +6 -4
  78. package/components/ui/settings-card.tsx +12 -5
  79. package/components/ui/settings-info-box.tsx +9 -6
  80. package/components/ui/settings-section-title.tsx +14 -2
  81. package/components/ui/snapshot-card.tsx +10 -2
  82. package/components/ui/snippets-panel.tsx +4 -2
  83. package/components/ui/sort-dropdown.tsx +45 -32
  84. package/components/ui/status-card.tsx +9 -1
  85. package/components/ui/tab-bar.tsx +26 -13
  86. package/components/ui/toggle.tsx +31 -17
  87. package/components/ui/tooltip.tsx +14 -6
  88. package/dist/content.js +8 -8
  89. package/dist/diagrams.d.ts +0 -1
  90. package/dist/index.d.ts +431 -186
  91. package/dist/index.js +3119 -1724
  92. package/dist/tokens/primitives.css +28 -6
  93. package/dist/tokens/semantic.css +15 -15
  94. package/dist/tokens/theme.css +23 -0
  95. package/index.ts +25 -11
  96. package/package.json +9 -1
  97. package/tokens/primitives.css +28 -6
  98. package/tokens/semantic.css +15 -15
  99. package/tokens/theme.css +23 -0
  100. package/components/sections/ai-tools-paths/index.ts +0 -37
  101. package/components/sections/ai-tools-paths/use-tools-paths.ts +0 -159
@@ -6,6 +6,7 @@ import type { LucideIcon } from 'lucide-react'
6
6
  import { iconMap, type IconName } from './icon-button.tsx'
7
7
  import type { BreadcrumbSegment } from './breadcrumb.tsx'
8
8
  import { ACCENT_NAV, type AccentColor } from '../lib/form-colors.ts'
9
+ import { useAccentColor } from '../lib/accent-context.ts'
9
10
  import { cn } from '../lib/cn.ts'
10
11
  import { useClickOutside } from '../hooks/use-click-outside.ts'
11
12
 
@@ -21,6 +22,7 @@ export interface NavigationBarProps {
21
22
  leadingAction?: { icon: IconName; onClick?: () => void }
22
23
  separator?: 'chevron' | 'slash' | 'dot'
23
24
  size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg'
25
+ accentColor?: AccentColor
24
26
  className?: string
25
27
  }
26
28
 
@@ -33,12 +35,32 @@ const sizeConfig = {
33
35
  }
34
36
 
35
37
 
36
- function NavButton({ icon: Icon, onClick, disabled, size, active }: {
38
+ // Accent color classes for NavButton same pattern as IconButton's colorClasses
39
+ const navColorClasses: Record<AccentColor, { text: string; border: string; hover: string; active: string }> = {
40
+ green: { text: 'text-green-400', border: 'border-green-500/30', hover: 'hover:bg-green-500/20 hover:border-green-500/40 hover:text-green-300', active: 'bg-green-500/20 text-green-300 border-green-500/40' },
41
+ red: { text: 'text-red-400', border: 'border-red-500/30', hover: 'hover:bg-red-500/20 hover:border-red-500/40 hover:text-red-300', active: 'bg-red-500/20 text-red-300 border-red-500/40' },
42
+ blue: { text: 'text-blue-400', border: 'border-blue-500/30', hover: 'hover:bg-blue-500/20 hover:border-blue-500/40 hover:text-blue-300', active: 'bg-blue-500/20 text-blue-300 border-blue-500/40' },
43
+ orange: { text: 'text-orange-400', border: 'border-orange-500/30', hover: 'hover:bg-orange-500/20 hover:border-orange-500/40 hover:text-orange-300', active: 'bg-orange-500/20 text-orange-300 border-orange-500/40' },
44
+ cyan: { text: 'text-cyan-400', border: 'border-cyan-500/30', hover: 'hover:bg-cyan-500/20 hover:border-cyan-500/40 hover:text-cyan-300', active: 'bg-cyan-500/20 text-cyan-300 border-cyan-500/40' },
45
+ yellow: { text: 'text-yellow-400', border: 'border-yellow-500/30', hover: 'hover:bg-yellow-500/20 hover:border-yellow-500/40 hover:text-yellow-300', active: 'bg-yellow-500/20 text-yellow-300 border-yellow-500/40' },
46
+ purple: { text: 'text-purple-400', border: 'border-purple-500/30', hover: 'hover:bg-purple-500/20 hover:border-purple-500/40 hover:text-purple-300', active: 'bg-purple-500/20 text-purple-300 border-purple-500/40' },
47
+ indigo: { text: 'text-indigo-400', border: 'border-indigo-500/30', hover: 'hover:bg-indigo-500/20 hover:border-indigo-500/40 hover:text-indigo-300', active: 'bg-indigo-500/20 text-indigo-300 border-indigo-500/40' },
48
+ emerald: { text: 'text-emerald-400', border: 'border-emerald-500/30', hover: 'hover:bg-emerald-500/20 hover:border-emerald-500/40 hover:text-emerald-300', active: 'bg-emerald-500/20 text-emerald-300 border-emerald-500/40' },
49
+ amber: { text: 'text-amber-400', border: 'border-amber-500/30', hover: 'hover:bg-amber-500/20 hover:border-amber-500/40 hover:text-amber-300', active: 'bg-amber-500/20 text-amber-300 border-amber-500/40' },
50
+ violet: { text: 'text-violet-400', border: 'border-violet-500/30', hover: 'hover:bg-violet-500/20 hover:border-violet-500/40 hover:text-violet-300', active: 'bg-violet-500/20 text-violet-300 border-violet-500/40' },
51
+ neutral: { text: 'text-neutral-400', border: 'border-neutral-500/30', hover: 'hover:bg-neutral-500/20 hover:border-neutral-500/40 hover:text-neutral-300', active: 'bg-neutral-500/20 text-neutral-300 border-neutral-500/40' },
52
+ sky: { text: 'text-sky-400', border: 'border-sky-500/30', hover: 'hover:bg-sky-500/20 hover:border-sky-500/40 hover:text-sky-300', active: 'bg-sky-500/20 text-sky-300 border-sky-500/40' },
53
+ pink: { text: 'text-pink-400', border: 'border-pink-500/30', hover: 'hover:bg-pink-500/20 hover:border-pink-500/40 hover:text-pink-300', active: 'bg-pink-500/20 text-pink-300 border-pink-500/40' },
54
+ teal: { text: 'text-teal-400', border: 'border-teal-500/30', hover: 'hover:bg-teal-500/20 hover:border-teal-500/40 hover:text-teal-300', active: 'bg-teal-500/20 text-teal-300 border-teal-500/40' },
55
+ }
56
+
57
+ function NavButton({ icon: Icon, onClick, disabled, size, active, colorStyle }: {
37
58
  icon: LucideIcon
38
59
  onClick?: () => void
39
60
  disabled?: boolean
40
61
  size: keyof typeof sizeConfig
41
62
  active?: boolean
63
+ colorStyle: typeof navColorClasses[AccentColor]
42
64
  }) {
43
65
  const s = sizeConfig[size]
44
66
  return (
@@ -52,8 +74,8 @@ function NavButton({ icon: Icon, onClick, disabled, size, active }: {
52
74
  disabled
53
75
  ? 'text-neutral-600 cursor-not-allowed'
54
76
  : active
55
- ? 'text-white bg-neutral-700/50 border border-neutral-600 cursor-pointer'
56
- : 'text-neutral-400 border border-neutral-700/50 hover:text-white hover:bg-neutral-700/50 cursor-pointer',
77
+ ? cn('border cursor-pointer', colorStyle.active)
78
+ : cn('border cursor-pointer', colorStyle.text, colorStyle.border, colorStyle.hover),
57
79
  )}
58
80
  >
59
81
  <Icon className={s.navIcon} />
@@ -95,8 +117,13 @@ export function NavigationBar({
95
117
  leadingAction,
96
118
  separator = 'chevron',
97
119
  size = 'sm',
120
+ accentColor,
98
121
  className,
99
122
  }: NavigationBarProps) {
123
+ const contextAccentColor = useAccentColor()
124
+ const effectiveColor = accentColor ?? contextAccentColor ?? 'neutral'
125
+ const colorStyle = navColorClasses[effectiveColor]
126
+
100
127
  const s = sizeConfig[size]
101
128
  const hasNav = !!(onBack || onForward)
102
129
  const LeadIcon = leadingAction ? iconMap[leadingAction.icon] : null
@@ -110,10 +137,10 @@ export function NavigationBar({
110
137
 
111
138
  return (
112
139
  <nav className={cn('flex items-center', className)}>
113
- <div className={cn('flex items-center gap-1', s.px, s.py, 'bg-neutral-800/50 border border-neutral-700/50 rounded-lg')}>
140
+ <div className={cn('flex items-center gap-1', s.px, s.py, 'bg-neutral-960/50 border rounded-lg', colorStyle.border)}>
114
141
  {leadingAction && LeadIcon && (
115
142
  <>
116
- <NavButton icon={LeadIcon} onClick={leadingAction.onClick} size={size} />
143
+ <NavButton icon={LeadIcon} onClick={leadingAction.onClick} size={size} colorStyle={colorStyle} />
117
144
  <Divider size={size} />
118
145
  </>
119
146
  )}
@@ -121,8 +148,8 @@ export function NavigationBar({
121
148
  {hasNav && (
122
149
  <>
123
150
  <div className="flex items-center gap-0.5">
124
- <NavButton icon={ChevronLeft} onClick={onBack} disabled={!canGoBack} size={size} />
125
- <NavButton icon={ChevronRight} onClick={onForward} disabled={!canGoForward} size={size} />
151
+ <NavButton icon={ChevronLeft} onClick={onBack} disabled={!canGoBack} size={size} colorStyle={colorStyle} />
152
+ <NavButton icon={ChevronRight} onClick={onForward} disabled={!canGoForward} size={size} colorStyle={colorStyle} />
126
153
  </div>
127
154
  <Divider size={size} />
128
155
  </>
@@ -137,9 +164,10 @@ export function NavigationBar({
137
164
  disabled={!hasHistoryEntries}
138
165
  size={size}
139
166
  active={historyOpen}
167
+ colorStyle={colorStyle}
140
168
  />
141
169
  {historyOpen && hasHistoryEntries && (
142
- <div className="absolute left-0 top-full mt-1 w-max min-w-[200px] max-w-[420px] bg-neutral-800 border border-neutral-700 rounded-lg shadow-xl z-50">
170
+ <div className="absolute left-0 top-full mt-1 w-max min-w-[200px] max-w-[420px] bg-neutral-960 border border-neutral-700 rounded-lg shadow-lg z-50">
143
171
  <div className="px-3 py-1.5 border-b border-neutral-700/50">
144
172
  <p className="text-sm font-medium text-neutral-500">History</p>
145
173
  </div>
@@ -152,7 +180,7 @@ export function NavigationBar({
152
180
  onHistorySelect?.(i)
153
181
  setHistoryOpen(false)
154
182
  }}
155
- className="w-full px-3 py-1.5 flex items-center gap-1 text-left hover:bg-neutral-800 transition-colors cursor-pointer"
183
+ className="w-full px-3 py-1.5 flex items-center gap-1 text-left hover:bg-neutral-960 transition-colors cursor-pointer"
156
184
  >
157
185
  {entry.map((seg, segIdx) => (
158
186
  <span key={seg.id} className="flex items-center gap-1 min-w-0">
@@ -185,14 +213,14 @@ export function NavigationBar({
185
213
  const colors = segment.color && ACCENT_NAV[segment.color as AccentColor] ? ACCENT_NAV[segment.color as AccentColor] : null
186
214
 
187
215
  return (
188
- <div key={segment.id} className="flex items-center gap-1">
216
+ <div key={segment.id} className="flex items-center gap-1 min-w-0">
189
217
  {index > 0 && <SegmentSeparator type={separator} size={size} />}
190
218
  {isClickable ? (
191
219
  <button
192
220
  type="button"
193
221
  onClick={segment.onClick}
194
222
  className={cn(
195
- 'flex items-center gap-1.5 px-2 py-0.5 rounded-md transition-colors cursor-pointer',
223
+ 'flex items-center gap-1.5 px-2 py-0.5 rounded-md transition-colors cursor-pointer min-w-0',
196
224
  s.text,
197
225
  'font-medium hover:text-white',
198
226
  colors ? [colors.text, `hover:${colors.bg}`] : ['text-neutral-300', 'hover:bg-neutral-700/50'],
@@ -204,7 +232,7 @@ export function NavigationBar({
204
232
  ) : (
205
233
  <div
206
234
  className={cn(
207
- 'flex items-center gap-1.5 px-2 py-0.5 rounded-md',
235
+ 'flex items-center gap-1.5 px-2 py-0.5 rounded-md min-w-0',
208
236
  s.text,
209
237
  isLast
210
238
  ? ['font-medium bg-neutral-700/50', colors ? colors.text : 'text-white']
@@ -1,6 +1,7 @@
1
1
  import { useState, useRef, useCallback, type KeyboardEvent } from 'react'
2
2
  import { ChevronUp, ChevronDown } from 'lucide-react'
3
3
  import { FORM_COLORS, type FormColor } from '../lib/form-colors.ts'
4
+ import { useAccentColor } from '../lib/accent-context.ts'
4
5
 
5
6
  export interface NumberInputProps {
6
7
  value: number
@@ -9,10 +10,12 @@ export interface NumberInputProps {
9
10
  max?: number
10
11
  step?: number
11
12
  variant?: 'filled' | 'outline'
12
- color?: FormColor
13
+ accentColor?: FormColor
13
14
  size?: 'xss' | 'xs' | 'sm' | 'md' | 'lg'
14
15
  disabled?: boolean
15
16
  className?: string
17
+ /** Accessible label — required for screen readers */
18
+ 'aria-label'?: string
16
19
  }
17
20
 
18
21
  const SIZE_CONFIG = {
@@ -24,7 +27,7 @@ const SIZE_CONFIG = {
24
27
  }
25
28
 
26
29
  const VARIANT_CLASSES = {
27
- filled: 'bg-neutral-800',
30
+ filled: 'bg-neutral-960',
28
31
  outline: 'bg-transparent',
29
32
  }
30
33
 
@@ -35,10 +38,11 @@ export function NumberInput({
35
38
  max,
36
39
  step = 1,
37
40
  variant = 'outline',
38
- color = 'blue',
41
+ accentColor,
39
42
  size = 'sm',
40
43
  disabled = false,
41
44
  className = '',
45
+ 'aria-label': ariaLabel,
42
46
  }: NumberInputProps) {
43
47
  const [focused, setFocused] = useState(false)
44
48
  const [editText, setEditText] = useState<string | null>(null)
@@ -75,8 +79,11 @@ export function NumberInput({
75
79
  setFocused(false)
76
80
  }
77
81
 
82
+ const contextAccent = useAccentColor()
83
+ const effectiveColor = accentColor ?? contextAccent ?? 'blue'
84
+
78
85
  const sc = SIZE_CONFIG[size]
79
- const fc = FORM_COLORS[color]
86
+ const fc = FORM_COLORS[effectiveColor]
80
87
 
81
88
  return (
82
89
  <div
@@ -92,6 +99,7 @@ export function NumberInput({
92
99
  ref={inputRef}
93
100
  type="text"
94
101
  inputMode="numeric"
102
+ aria-label={ariaLabel}
95
103
  value={editText ?? value}
96
104
  onChange={(e) => setEditText(e.target.value)}
97
105
  onFocus={() => {
@@ -128,6 +136,7 @@ export function NumberInput({
128
136
  >
129
137
  <button
130
138
  type="button"
139
+ aria-label="Increase value"
131
140
  tabIndex={-1}
132
141
  onMouseDown={(e) => e.preventDefault()}
133
142
  onClick={() => nudge(1)}
@@ -145,6 +154,7 @@ export function NumberInput({
145
154
  <div className={`border-t ${fc.border}`} />
146
155
  <button
147
156
  type="button"
157
+ aria-label="Decrease value"
148
158
  tabIndex={-1}
149
159
  onMouseDown={(e) => e.preventDefault()}
150
160
  onClick={() => nudge(-1)}