@toolr/ui-design 0.1.8 → 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/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 +10 -9
- 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 +24 -30
- package/components/ui/ai-action-button.tsx +10 -7
- package/components/ui/ai-execution-action-buttons.tsx +13 -5
- package/components/ui/badge.tsx +7 -4
- package/components/ui/bottom-panel-header.tsx +9 -5
- package/components/ui/breadcrumb.tsx +9 -1
- package/components/ui/{extension-list-card.tsx → capability-list-card.tsx} +13 -5
- package/components/ui/checkbox.tsx +6 -3
- package/components/ui/collapsible-section.tsx +38 -29
- package/components/ui/confirm-badge.tsx +7 -4
- 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 +3 -1
- package/components/ui/files-panel.tsx +147 -27
- package/components/ui/filter-dropdown.tsx +84 -74
- package/components/ui/form-actions.tsx +14 -6
- package/components/ui/frontmatter-form-header.tsx +10 -2
- package/components/ui/icon-button.tsx +22 -9
- package/components/ui/input.tsx +7 -4
- package/components/ui/label.tsx +5 -5
- package/components/ui/layout-tab-bar.tsx +7 -5
- package/components/ui/modal.tsx +18 -4
- package/components/ui/nav-card.tsx +6 -3
- package/components/ui/navigation-bar.tsx +37 -9
- package/components/ui/number-input.tsx +8 -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 +5 -2
- package/components/ui/select.tsx +12 -9
- package/components/ui/selection-grid.tsx +36 -37
- package/components/ui/setting-row.tsx +2 -2
- package/components/ui/settings-card.tsx +10 -3
- package/components/ui/settings-info-box.tsx +9 -5
- 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 +39 -29
- package/components/ui/status-card.tsx +9 -1
- package/components/ui/tab-bar.tsx +12 -9
- package/components/ui/toggle.tsx +13 -7
- package/components/ui/tooltip.tsx +9 -1
- package/dist/content.js +8 -8
- package/dist/diagrams.d.ts +0 -1
- package/dist/index.d.ts +421 -182
- package/dist/index.js +2984 -1691
- 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 +1 -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
package/components/ui/modal.tsx
CHANGED
|
@@ -5,6 +5,8 @@ import { useModalBehavior } from '../hooks/use-modal-behavior.ts'
|
|
|
5
5
|
import { IconButton, type ActionItem } from './icon-button.tsx'
|
|
6
6
|
import { FormActions } from './form-actions.tsx'
|
|
7
7
|
import type { ReactNode } from 'react'
|
|
8
|
+
import type { FormColor } from '../lib/form-colors.ts'
|
|
9
|
+
import { useAccentColor, AccentColorProvider } from '../lib/accent-context.ts'
|
|
8
10
|
|
|
9
11
|
export type ModalKind = 'info' | 'warning' | 'error' | 'orange' | 'success'
|
|
10
12
|
export type ModalSize = 'sm' | 'md' | 'lg' | 'xl'
|
|
@@ -57,9 +59,9 @@ function Modal({ isOpen, onClose, title, children, kind = 'info', size = 'md', h
|
|
|
57
59
|
aria-modal="true"
|
|
58
60
|
aria-labelledby={titleId}
|
|
59
61
|
data-testid={testId}
|
|
60
|
-
className={`relative bg-neutral-
|
|
62
|
+
className={`relative bg-neutral-980 border border-neutral-700 rounded-lg shadow-lg ${SIZE_CLASSES[size]} w-full mx-4 overflow-hidden`}
|
|
61
63
|
>
|
|
62
|
-
<div className="flex items-center gap-3 px-
|
|
64
|
+
<div className="flex items-center gap-3 px-4 py-4 border-b border-neutral-960">
|
|
63
65
|
{KIND_ICON[kind]}
|
|
64
66
|
<h3 id={titleId} className="text-lg font-semibold text-white flex-1 min-w-0 truncate">{title}</h3>
|
|
65
67
|
{headerActions?.map((a, i) => <IconButton key={i} {...a} />)}
|
|
@@ -68,13 +70,13 @@ function Modal({ isOpen, onClose, title, children, kind = 'info', size = 'md', h
|
|
|
68
70
|
icon="x"
|
|
69
71
|
onClick={onClose}
|
|
70
72
|
size="sm"
|
|
71
|
-
|
|
73
|
+
accentColor="neutral"
|
|
72
74
|
tooltip={{ description: 'Close this modal' }}
|
|
73
75
|
testId="modal-close"
|
|
74
76
|
/>
|
|
75
77
|
)}
|
|
76
78
|
</div>
|
|
77
|
-
<div className="px-
|
|
79
|
+
<div className="px-4 py-4">{children}</div>
|
|
78
80
|
</div>
|
|
79
81
|
</div>,
|
|
80
82
|
document.body,
|
|
@@ -93,6 +95,7 @@ export interface ConfirmModalProps {
|
|
|
93
95
|
confirmColor?: 'red' | 'blue' | 'orange' | 'yellow'
|
|
94
96
|
isLoading?: boolean
|
|
95
97
|
confirmDisabled?: boolean
|
|
98
|
+
accentColor?: FormColor
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
export function ConfirmModal({
|
|
@@ -107,7 +110,10 @@ export function ConfirmModal({
|
|
|
107
110
|
confirmColor = 'blue',
|
|
108
111
|
isLoading = false,
|
|
109
112
|
confirmDisabled = false,
|
|
113
|
+
accentColor: accentColorProp,
|
|
110
114
|
}: ConfirmModalProps) {
|
|
115
|
+
const contextAccent = useAccentColor()
|
|
116
|
+
const effectiveColor = accentColorProp ?? contextAccent ?? 'blue'
|
|
111
117
|
const [isConfirming, setIsConfirming] = useState(false)
|
|
112
118
|
|
|
113
119
|
const isDisabled = isLoading || isConfirming || confirmDisabled
|
|
@@ -126,6 +132,7 @@ export function ConfirmModal({
|
|
|
126
132
|
}
|
|
127
133
|
|
|
128
134
|
return (
|
|
135
|
+
<AccentColorProvider value={effectiveColor}>
|
|
129
136
|
<Modal isOpen={isOpen} onClose={onClose} title={title} kind={kind} hideCloseButton>
|
|
130
137
|
<div className="text-neutral-300 mb-6">
|
|
131
138
|
{message}
|
|
@@ -154,6 +161,7 @@ export function ConfirmModal({
|
|
|
154
161
|
confirmStatus={isInProgress ? 'loading' : undefined}
|
|
155
162
|
/>
|
|
156
163
|
</Modal>
|
|
164
|
+
</AccentColorProvider>
|
|
157
165
|
)
|
|
158
166
|
}
|
|
159
167
|
|
|
@@ -163,6 +171,7 @@ export interface AlertModalProps {
|
|
|
163
171
|
title: string
|
|
164
172
|
message: string
|
|
165
173
|
kind?: ModalKind
|
|
174
|
+
accentColor?: FormColor
|
|
166
175
|
}
|
|
167
176
|
|
|
168
177
|
export function AlertModal({
|
|
@@ -171,8 +180,12 @@ export function AlertModal({
|
|
|
171
180
|
title,
|
|
172
181
|
message,
|
|
173
182
|
kind = 'info',
|
|
183
|
+
accentColor: accentColorProp,
|
|
174
184
|
}: AlertModalProps) {
|
|
185
|
+
const contextAccent = useAccentColor()
|
|
186
|
+
const effectiveColor = accentColorProp ?? contextAccent ?? 'blue'
|
|
175
187
|
return (
|
|
188
|
+
<AccentColorProvider value={effectiveColor}>
|
|
176
189
|
<Modal isOpen={isOpen} onClose={onClose} title={title} kind={kind} hideCloseButton>
|
|
177
190
|
<div className="text-neutral-300 mb-6">{message}</div>
|
|
178
191
|
<FormActions
|
|
@@ -182,5 +195,6 @@ export function AlertModal({
|
|
|
182
195
|
confirmTooltip="Dismiss this alert"
|
|
183
196
|
/>
|
|
184
197
|
</Modal>
|
|
198
|
+
</AccentColorProvider>
|
|
185
199
|
)
|
|
186
200
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { iconMap, type IconName } from './icon-button.tsx'
|
|
4
4
|
import { Label, type LabelColor } from './label.tsx'
|
|
5
5
|
import { cn } from '../lib/cn.ts'
|
|
6
|
+
import type { FormColor } from '../lib/form-colors.ts'
|
|
6
7
|
|
|
7
8
|
export interface NavCardProps {
|
|
8
9
|
title: string
|
|
@@ -11,11 +12,12 @@ export interface NavCardProps {
|
|
|
11
12
|
/** Custom icon component. Takes precedence over icon name. */
|
|
12
13
|
IconComponent?: React.ComponentType<{ className?: string }>
|
|
13
14
|
iconColor?: string
|
|
14
|
-
label?: { text: string; color: LabelColor; tooltip: { description: string } }
|
|
15
|
+
label?: { text: string; color: LabelColor; icon?: IconName; tooltip: { description: string } }
|
|
15
16
|
stats?: string
|
|
16
17
|
onClick?: () => void
|
|
17
18
|
disabled?: boolean
|
|
18
19
|
className?: string
|
|
20
|
+
accentColor?: FormColor
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
export function NavCard({
|
|
@@ -29,6 +31,7 @@ export function NavCard({
|
|
|
29
31
|
onClick,
|
|
30
32
|
disabled = false,
|
|
31
33
|
className,
|
|
34
|
+
accentColor: _accentColor,
|
|
32
35
|
}: NavCardProps) {
|
|
33
36
|
const Icon = IconComponent ?? (icon ? iconMap[icon] : undefined)
|
|
34
37
|
|
|
@@ -38,7 +41,7 @@ export function NavCard({
|
|
|
38
41
|
onClick={disabled ? undefined : onClick}
|
|
39
42
|
disabled={disabled}
|
|
40
43
|
className={cn(
|
|
41
|
-
'relative w-full text-left rounded-lg border border-neutral-700 bg-neutral-
|
|
44
|
+
'relative w-full text-left rounded-lg border border-neutral-700 bg-neutral-960 p-4 transition-all duration-200 cursor-pointer',
|
|
42
45
|
!disabled && 'hover:-translate-y-0.5 hover:border-neutral-600 hover:bg-neutral-700',
|
|
43
46
|
disabled && 'opacity-50 cursor-not-allowed',
|
|
44
47
|
className,
|
|
@@ -46,7 +49,7 @@ export function NavCard({
|
|
|
46
49
|
>
|
|
47
50
|
{label && (
|
|
48
51
|
<span className="absolute top-3 right-3">
|
|
49
|
-
<Label text={label.text}
|
|
52
|
+
<Label text={label.text} accentColor={label.color} icon={label.icon} size="xs" tooltip={label.tooltip} />
|
|
50
53
|
</span>
|
|
51
54
|
)}
|
|
52
55
|
|
|
@@ -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">
|
|
@@ -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,7 +10,7 @@ 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
|
|
@@ -26,7 +27,7 @@ const SIZE_CONFIG = {
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
const VARIANT_CLASSES = {
|
|
29
|
-
filled: 'bg-neutral-
|
|
30
|
+
filled: 'bg-neutral-960',
|
|
30
31
|
outline: 'bg-transparent',
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -37,7 +38,7 @@ export function NumberInput({
|
|
|
37
38
|
max,
|
|
38
39
|
step = 1,
|
|
39
40
|
variant = 'outline',
|
|
40
|
-
|
|
41
|
+
accentColor,
|
|
41
42
|
size = 'sm',
|
|
42
43
|
disabled = false,
|
|
43
44
|
className = '',
|
|
@@ -78,8 +79,11 @@ export function NumberInput({
|
|
|
78
79
|
setFocused(false)
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
const contextAccent = useAccentColor()
|
|
83
|
+
const effectiveColor = accentColor ?? contextAccent ?? 'blue'
|
|
84
|
+
|
|
81
85
|
const sc = SIZE_CONFIG[size]
|
|
82
|
-
const fc = FORM_COLORS[
|
|
86
|
+
const fc = FORM_COLORS[effectiveColor]
|
|
83
87
|
|
|
84
88
|
return (
|
|
85
89
|
<div
|