@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.
- package/ai-manifest.json +35 -20
- package/components/composites/dashboard-list-item.tsx +172 -0
- package/components/composites/dashboard-panel.tsx +218 -0
- package/components/content/info-panel-primitives.tsx +9 -8
- package/components/diagrams/diagram-utils.tsx +2 -1
- package/components/hooks/use-dropdown-portal.ts +39 -0
- package/components/hooks/use-modal-behavior.ts +32 -3
- package/components/lib/accent-context.ts +10 -0
- package/components/lib/{ai-tools.tsx → coding-agents.tsx} +23 -8
- package/components/lib/custom-icons.tsx +37 -0
- package/components/lib/git-providers.tsx +39 -0
- package/components/lib/theme-engine.ts +59 -10
- package/components/lib/toolr-brand.tsx +23 -9
- package/components/sections/captured-issues/captured-issues-panel.tsx +17 -8
- package/components/sections/{ai-tools-paths/tools-paths-panel.tsx → coding-agent-paths/agent-paths-panel.tsx} +70 -62
- package/components/sections/coding-agent-paths/index.ts +37 -0
- package/components/sections/{ai-tools-paths → coding-agent-paths}/types.ts +28 -28
- package/components/sections/coding-agent-paths/use-agent-paths.ts +159 -0
- package/components/sections/golden-snapshots/file-diff-viewer.tsx +11 -10
- package/components/sections/golden-snapshots/golden-sync-panel.tsx +12 -3
- package/components/sections/golden-snapshots/snapshot-manager.tsx +9 -7
- package/components/sections/golden-snapshots/status-overview.tsx +8 -8
- package/components/sections/golden-snapshots/version-manager.tsx +6 -6
- package/components/sections/prompt-editor/file-type-tabbed-prompt-editor.tsx +3 -3
- package/components/sections/prompt-editor/index.ts +1 -1
- package/components/sections/prompt-editor/simulator-prompt-editor.tsx +13 -5
- package/components/sections/prompt-editor/tabbed-prompt-editor.tsx +18 -10
- package/components/sections/prompt-editor/types.ts +2 -2
- package/components/sections/report-bug/report-bug-form.tsx +12 -4
- package/components/sections/report-bug/screenshot-uploader.tsx +11 -3
- package/components/sections/snapshot-browser/snapshot-browser-panel.tsx +12 -4
- package/components/sections/snapshot-browser/snapshot-tree.tsx +5 -4
- package/components/sections/snapshot-browser/types.ts +1 -1
- package/components/sections/snippets-editor/snippets-editor.tsx +16 -9
- package/components/settings/SettingsHeader.tsx +2 -2
- package/components/settings/SettingsPanel.tsx +11 -3
- package/components/settings/SettingsTreeNav.tsx +15 -9
- package/components/ui/action-dialog.tsx +37 -35
- package/components/ui/ai-action-button.tsx +12 -11
- package/components/ui/ai-execution-action-buttons.tsx +13 -5
- package/components/ui/badge.tsx +17 -6
- package/components/ui/bottom-panel-header.tsx +9 -5
- package/components/ui/breadcrumb.tsx +14 -6
- package/components/ui/{extension-list-card.tsx → capability-list-card.tsx} +14 -6
- package/components/ui/checkbox.tsx +23 -14
- package/components/ui/collapsible-section.tsx +38 -28
- package/components/ui/confirm-badge.tsx +17 -6
- package/components/ui/cookie-consent.tsx +13 -7
- package/components/ui/detail-section.tsx +24 -16
- package/components/ui/detail-view-wrapper.tsx +30 -22
- package/components/ui/editor-placeholder-card.tsx +28 -24
- package/components/ui/editor-toolbar.tsx +7 -4
- package/components/ui/execution-details-panel.tsx +10 -5
- package/components/ui/file-structure-section.tsx +3 -3
- package/components/ui/file-tree.tsx +7 -5
- package/components/ui/files-panel.tsx +147 -27
- package/components/ui/filter-dropdown.tsx +88 -75
- package/components/ui/form-actions.tsx +21 -11
- package/components/ui/frontmatter-form-header.tsx +10 -2
- package/components/ui/icon-button.tsx +27 -14
- package/components/ui/input.tsx +15 -7
- package/components/ui/label.tsx +9 -5
- package/components/ui/layout-tab-bar.tsx +11 -9
- package/components/ui/modal.tsx +26 -8
- package/components/ui/nav-card.tsx +7 -4
- package/components/ui/navigation-bar.tsx +40 -12
- package/components/ui/number-input.tsx +14 -4
- package/components/ui/project-explorer.tsx +666 -0
- package/components/ui/registry-browser.tsx +12 -1
- package/components/ui/registry-card.tsx +49 -42
- package/components/ui/registry-detail.tsx +34 -11
- package/components/ui/resizable-textarea.tsx +18 -11
- package/components/ui/scope-badge.tsx +18 -11
- package/components/ui/segmented-toggle.tsx +7 -2
- package/components/ui/select.tsx +17 -11
- package/components/ui/selection-grid.tsx +40 -37
- package/components/ui/setting-row.tsx +6 -4
- package/components/ui/settings-card.tsx +12 -5
- package/components/ui/settings-info-box.tsx +9 -6
- package/components/ui/settings-section-title.tsx +14 -2
- package/components/ui/snapshot-card.tsx +10 -2
- package/components/ui/snippets-panel.tsx +4 -2
- package/components/ui/sort-dropdown.tsx +45 -32
- package/components/ui/status-card.tsx +9 -1
- package/components/ui/tab-bar.tsx +26 -13
- package/components/ui/toggle.tsx +31 -17
- package/components/ui/tooltip.tsx +14 -6
- package/dist/content.js +8 -8
- package/dist/diagrams.d.ts +0 -1
- package/dist/index.d.ts +431 -186
- package/dist/index.js +3119 -1724
- package/dist/tokens/primitives.css +28 -6
- package/dist/tokens/semantic.css +15 -15
- package/dist/tokens/theme.css +23 -0
- package/index.ts +25 -11
- package/package.json +9 -1
- package/tokens/primitives.css +28 -6
- package/tokens/semantic.css +15 -15
- package/tokens/theme.css +23 -0
- package/components/sections/ai-tools-paths/index.ts +0 -37
- 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
|
-
|
|
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
|
-
? '
|
|
56
|
-
: '
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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-
|
|
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
|
-
|
|
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[
|
|
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)}
|