@toolr/ui-design 0.1.5 → 0.1.6
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/agent-rules.json +91 -0
- package/ai-manifest.json +190 -0
- package/components/content/info-panel-primitives.tsx +14 -14
- package/components/lib/ai-tools.tsx +1 -1
- package/components/sections/ai-tools-paths/tools-paths-panel.tsx +7 -7
- package/components/sections/captured-issues/captured-issues-panel.tsx +11 -11
- package/components/sections/golden-snapshots/file-diff-viewer.tsx +13 -13
- package/components/sections/golden-snapshots/golden-sync-panel.tsx +5 -5
- package/components/sections/golden-snapshots/snapshot-manager.tsx +11 -11
- package/components/sections/golden-snapshots/status-overview.tsx +20 -20
- package/components/sections/golden-snapshots/version-manager.tsx +8 -8
- package/components/sections/prompt-editor/file-type-tabbed-prompt-editor.tsx +4 -4
- package/components/sections/prompt-editor/simulator-prompt-editor.tsx +5 -5
- package/components/sections/prompt-editor/tabbed-prompt-editor.tsx +7 -7
- package/components/sections/report-bug/report-bug-form.tsx +14 -14
- package/components/sections/report-bug/screenshot-uploader.tsx +6 -6
- package/components/sections/snapshot-browser/snapshot-browser-panel.tsx +3 -3
- package/components/sections/snapshot-browser/snapshot-tree.tsx +8 -8
- package/components/sections/snippets-editor/snippets-editor.tsx +81 -22
- package/components/settings/SettingsHeader.tsx +1 -1
- package/components/settings/SettingsTreeNav.tsx +22 -4
- package/components/ui/action-dialog.tsx +5 -5
- package/components/ui/badge.tsx +4 -4
- package/components/ui/bottom-panel-header.tsx +4 -4
- package/components/ui/breadcrumb.tsx +2 -2
- package/components/ui/collapsible-section.tsx +1 -1
- package/components/ui/cookie-consent.tsx +5 -5
- package/components/ui/detail-section.tsx +3 -3
- package/components/ui/editor-placeholder-card.tsx +7 -7
- package/components/ui/editor-toolbar.tsx +12 -0
- package/components/ui/execution-details-panel.tsx +6 -6
- package/components/ui/extension-list-card.tsx +3 -3
- package/components/ui/file-structure-section.tsx +17 -17
- package/components/ui/file-tree.tsx +3 -1
- package/components/ui/files-panel.tsx +27 -9
- package/components/ui/filter-dropdown.tsx +5 -5
- package/components/ui/form-actions.tsx +1 -1
- package/components/ui/frontmatter-form-header.tsx +4 -4
- package/components/ui/icon-button.tsx +1 -1
- package/components/ui/input.tsx +5 -5
- package/components/ui/label.tsx +4 -4
- package/components/ui/layout-tab-bar.tsx +4 -4
- package/components/ui/modal.tsx +2 -2
- package/components/ui/nav-card.tsx +3 -3
- package/components/ui/navigation-bar.tsx +5 -5
- package/components/ui/number-input.tsx +4 -4
- package/components/ui/registry-browser.tsx +4 -4
- package/components/ui/registry-card.tsx +13 -13
- package/components/ui/registry-detail.tsx +6 -6
- package/components/ui/segmented-toggle.tsx +4 -4
- package/components/ui/select.tsx +5 -5
- package/components/ui/selection-grid.tsx +4 -4
- package/components/ui/setting-row.tsx +1 -1
- package/components/ui/settings-card.tsx +3 -3
- package/components/ui/settings-info-box.tsx +1 -1
- package/components/ui/settings-section-title.tsx +1 -1
- package/components/ui/snapshot-card.tsx +7 -7
- package/components/ui/snippets-panel.tsx +10 -10
- package/components/ui/sort-dropdown.tsx +2 -2
- package/components/ui/status-card.tsx +4 -4
- package/components/ui/tab-bar.tsx +2 -2
- package/components/ui/tooltip.tsx +3 -3
- package/dist/content.js +14 -14
- package/dist/index.d.ts +11 -4
- package/dist/index.js +428 -336
- package/dist/tokens/primitives.css +9 -2
- package/package.json +13 -3
- package/tokens/primitives.css +9 -2
package/components/ui/label.tsx
CHANGED
|
@@ -87,10 +87,10 @@ const progressFillColors: Record<LabelColor, string> = {
|
|
|
87
87
|
|
|
88
88
|
const sizeConfig = {
|
|
89
89
|
xss: { height: 14, padding: 'px-1', text: 'text-xss', iconSize: 'w-2 h-2', gap: 'gap-0.5' },
|
|
90
|
-
xs: { height: 16, padding: 'px-1.5', text: 'text-
|
|
91
|
-
sm: { height: 18, padding: 'px-1.5', text: 'text-
|
|
92
|
-
md: { height: 20, padding: 'px-1.5', text: 'text-
|
|
93
|
-
lg: { height: 22, padding: 'px-2', text: 'text-
|
|
90
|
+
xs: { height: 16, padding: 'px-1.5', text: 'text-xs', iconSize: 'w-2.5 h-2.5', gap: 'gap-1' },
|
|
91
|
+
sm: { height: 18, padding: 'px-1.5', text: 'text-xs', iconSize: 'w-2.5 h-2.5', gap: 'gap-1.5' },
|
|
92
|
+
md: { height: 20, padding: 'px-1.5', text: 'text-xs', iconSize: 'w-3 h-3', gap: 'gap-1' },
|
|
93
|
+
lg: { height: 22, padding: 'px-2', text: 'text-sm', iconSize: 'w-3 h-3', gap: 'gap-1' },
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
/** Smart capitalize: capitalizes first letter of each word separated by spaces or dashes */
|
|
@@ -220,14 +220,14 @@ export function LayoutTabBar({ tabs, activeId, onSelect, onClose, onReorder, cla
|
|
|
220
220
|
{/* Line 1: Icon + Title */}
|
|
221
221
|
<div className="flex items-center gap-1.5 w-full transition-[padding] duration-150 group-hover:pr-5">
|
|
222
222
|
{tab.icon && <span className={cn('shrink-0 inline-flex', isActive ? iconC : 'text-neutral-400')} style={{ width: 14, height: 14 }}>{tab.icon}</span>}
|
|
223
|
-
<span className={cn('truncate text-
|
|
223
|
+
<span className={cn('truncate text-md font-medium', isActive ? titleC : 'text-neutral-300')}>{tab.title}</span>
|
|
224
224
|
</div>
|
|
225
225
|
|
|
226
226
|
{/* Line 2: Subtitle with optional icon */}
|
|
227
227
|
{tab.subtitle && (
|
|
228
228
|
<div className="flex items-center gap-1 w-full">
|
|
229
229
|
{tab.subtitleIcon && <span className={cn('shrink-0 inline-flex', isActive ? subIconC : 'text-neutral-500')} style={{ width: 10, height: 10 }}>{tab.subtitleIcon}</span>}
|
|
230
|
-
<span className={cn('truncate text-
|
|
230
|
+
<span className={cn('truncate text-sm', isActive ? subC : 'text-neutral-500')}>{tab.subtitle}</span>
|
|
231
231
|
</div>
|
|
232
232
|
)}
|
|
233
233
|
|
|
@@ -272,12 +272,12 @@ export function LayoutTabBar({ tabs, activeId, onSelect, onClose, onReorder, cla
|
|
|
272
272
|
<div className={cn('flex flex-col gap-0.5 px-2.5 py-1.5 rounded-t-lg border-t-2 shadow-xl bg-neutral-800', ghostBorder)}>
|
|
273
273
|
<div className="flex items-center gap-1.5">
|
|
274
274
|
{t.icon && <span className={cn('shrink-0 inline-flex', ghostIconC)} style={{ width: 14, height: 14 }}>{t.icon}</span>}
|
|
275
|
-
<span className={cn('text-
|
|
275
|
+
<span className={cn('text-md font-medium', ghostTitleC)}>{t.title}</span>
|
|
276
276
|
</div>
|
|
277
277
|
{t.subtitle && (
|
|
278
278
|
<div className="flex items-center gap-1">
|
|
279
279
|
{t.subtitleIcon && <span className={cn('shrink-0 inline-flex', ghostSubIconC)} style={{ width: 10, height: 10 }}>{t.subtitleIcon}</span>}
|
|
280
|
-
<span className={cn('text-
|
|
280
|
+
<span className={cn('text-sm', ghostSubC)}>{t.subtitle}</span>
|
|
281
281
|
</div>
|
|
282
282
|
)}
|
|
283
283
|
</div>
|
package/components/ui/modal.tsx
CHANGED
|
@@ -139,11 +139,11 @@ export function ConfirmModal({
|
|
|
139
139
|
{message}
|
|
140
140
|
{warning && (
|
|
141
141
|
<div className="mt-3 p-3 bg-amber-500/10 border border-amber-500/30 rounded-lg">
|
|
142
|
-
<p className="text-amber-300 text-
|
|
142
|
+
<p className="text-amber-300 text-md font-medium">{warning}</p>
|
|
143
143
|
{warningItems && warningItems.length > 0 && (
|
|
144
144
|
<ul className="mt-2 space-y-1">
|
|
145
145
|
{warningItems.map((item, i) => (
|
|
146
|
-
<li key={i} className="text-amber-300/80 text-
|
|
146
|
+
<li key={i} className="text-amber-300/80 text-md ml-4 list-disc">{item}</li>
|
|
147
147
|
))}
|
|
148
148
|
</ul>
|
|
149
149
|
)}
|
|
@@ -74,14 +74,14 @@ export function NavCard({
|
|
|
74
74
|
</div>
|
|
75
75
|
)}
|
|
76
76
|
|
|
77
|
-
<h3 className="text-
|
|
77
|
+
<h3 className="text-md font-medium text-neutral-200">{title}</h3>
|
|
78
78
|
|
|
79
79
|
{description && (
|
|
80
|
-
<p className="mt-1 text-
|
|
80
|
+
<p className="mt-1 text-sm text-neutral-500 leading-relaxed line-clamp-2">{description}</p>
|
|
81
81
|
)}
|
|
82
82
|
|
|
83
83
|
{stats && (
|
|
84
|
-
<p className="mt-2 text-
|
|
84
|
+
<p className="mt-2 text-sm text-neutral-600">{stats}</p>
|
|
85
85
|
)}
|
|
86
86
|
</button>
|
|
87
87
|
)
|
|
@@ -70,8 +70,8 @@ export interface NavigationBarProps {
|
|
|
70
70
|
|
|
71
71
|
const sizeConfig = {
|
|
72
72
|
xss: { text: 'text-xss', segIcon: 'w-2.5 h-2.5', navIcon: 'w-2.5 h-2.5', navBtn: 'w-[18px] h-[18px] rounded-[3px]', px: 'px-1', py: 'py-0.5', sep: 'w-2 h-2', divH: 'h-3' },
|
|
73
|
-
xs: { text: 'text-
|
|
74
|
-
sm: { text: 'text-
|
|
73
|
+
xs: { text: 'text-sm', segIcon: 'w-3 h-3', navIcon: 'w-3 h-3', navBtn: 'w-6 h-6 rounded-[5px]', px: 'px-1.5', py: 'py-0.5', sep: 'w-2.5 h-2.5', divH: 'h-3.5' },
|
|
74
|
+
sm: { text: 'text-md', segIcon: 'w-3.5 h-3.5', navIcon: 'w-3.5 h-3.5', navBtn: 'w-7 h-7 rounded-md', px: 'px-2', py: 'py-1', sep: 'w-3 h-3', divH: 'h-4' },
|
|
75
75
|
md: { text: 'text-base', segIcon: 'w-4 h-4', navIcon: 'w-4 h-4', navBtn: 'w-8 h-8 rounded-md', px: 'px-2.5', py: 'py-1', sep: 'w-3.5 h-3.5', divH: 'h-5' },
|
|
76
76
|
lg: { text: 'text-lg', segIcon: 'w-5 h-5', navIcon: 'w-5 h-5', navBtn: 'w-9 h-9 rounded-md', px: 'px-3', py: 'py-1.5', sep: 'w-4 h-4', divH: 'h-6' },
|
|
77
77
|
}
|
|
@@ -202,7 +202,7 @@ export function NavigationBar({
|
|
|
202
202
|
{historyOpen && hasHistoryEntries && (
|
|
203
203
|
<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">
|
|
204
204
|
<div className="px-3 py-1.5 border-b border-neutral-700/50">
|
|
205
|
-
<p className="text-
|
|
205
|
+
<p className="text-sm font-medium text-neutral-500">History</p>
|
|
206
206
|
</div>
|
|
207
207
|
<div className="max-h-[300px] overflow-y-auto py-1">
|
|
208
208
|
{historyEntries.map((entry, i) => (
|
|
@@ -220,7 +220,7 @@ export function NavigationBar({
|
|
|
220
220
|
{segIdx > 0 && <ChevronRight className="w-2.5 h-2.5 text-neutral-600 flex-shrink-0" />}
|
|
221
221
|
{seg.icon && <SegmentIcon icon={seg.icon} color={seg.color} size="xs" />}
|
|
222
222
|
<span className={cn(
|
|
223
|
-
'text-
|
|
223
|
+
'text-sm truncate',
|
|
224
224
|
seg.color && colorMap[seg.color] ? colorMap[seg.color].text : 'text-neutral-300',
|
|
225
225
|
)}>
|
|
226
226
|
{seg.label}
|
|
@@ -231,7 +231,7 @@ export function NavigationBar({
|
|
|
231
231
|
))}
|
|
232
232
|
</div>
|
|
233
233
|
<div className="px-3 py-1.5 border-t border-neutral-700/50">
|
|
234
|
-
<p className="text-
|
|
234
|
+
<p className="text-sm text-neutral-600">Click to navigate</p>
|
|
235
235
|
</div>
|
|
236
236
|
</div>
|
|
237
237
|
)}
|
|
@@ -17,10 +17,10 @@ export interface NumberInputProps {
|
|
|
17
17
|
|
|
18
18
|
const SIZE_CONFIG = {
|
|
19
19
|
xss: { wrapper: 'h-[18px]', input: 'px-1 text-xss', chevron: 'w-2.5 h-2.5', stepperW: 'w-4' },
|
|
20
|
-
xs: { wrapper: 'h-6', input: 'px-1.5 text-
|
|
21
|
-
sm: { wrapper: 'h-7', input: 'px-2 text-
|
|
22
|
-
md: { wrapper: 'h-8', input: 'px-3 text-
|
|
23
|
-
lg: { wrapper: 'h-9', input: 'px-3 text-
|
|
20
|
+
xs: { wrapper: 'h-6', input: 'px-1.5 text-sm', chevron: 'w-2.5 h-2.5', stepperW: 'w-5' },
|
|
21
|
+
sm: { wrapper: 'h-7', input: 'px-2 text-sm', chevron: 'w-3 h-3', stepperW: 'w-5' },
|
|
22
|
+
md: { wrapper: 'h-8', input: 'px-3 text-md', chevron: 'w-3 h-3', stepperW: 'w-6' },
|
|
23
|
+
lg: { wrapper: 'h-9', input: 'px-3 text-md', chevron: 'w-3.5 h-3.5', stepperW: 'w-7' },
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
const VARIANT_CLASSES = {
|
|
@@ -231,18 +231,18 @@ export function RegistryBrowser({
|
|
|
231
231
|
) : error ? (
|
|
232
232
|
<div className="flex flex-col items-center justify-center py-12 text-neutral-500">
|
|
233
233
|
<AlertTriangle className="w-6 h-6 text-amber-400 mb-2" />
|
|
234
|
-
<p className="text-
|
|
234
|
+
<p className="text-md">{error}</p>
|
|
235
235
|
{onRetry && (
|
|
236
|
-
<button onClick={onRetry} className="mt-2 text-
|
|
236
|
+
<button onClick={onRetry} className="mt-2 text-sm text-blue-400 hover:underline cursor-pointer">
|
|
237
237
|
Try again
|
|
238
238
|
</button>
|
|
239
239
|
)}
|
|
240
240
|
</div>
|
|
241
241
|
) : isEmpty ? (
|
|
242
242
|
<div className="flex flex-col items-center justify-center py-12 text-neutral-500">
|
|
243
|
-
<p className="text-
|
|
243
|
+
<p className="text-md">{emptyMessage}</p>
|
|
244
244
|
{hasActiveFilters && onResetFilters && (
|
|
245
|
-
<button onClick={onResetFilters} className="mt-2 text-
|
|
245
|
+
<button onClick={onResetFilters} className="mt-2 text-sm text-blue-400 hover:underline cursor-pointer">
|
|
246
246
|
Reset filters
|
|
247
247
|
</button>
|
|
248
248
|
)}
|
|
@@ -412,7 +412,7 @@ export function RegistryCard(props: RegistryCardProps) {
|
|
|
412
412
|
<Tooltip key={`pkg-${key}`} content={{ description: `${count} ${count === 1 ? label : labelPlural}` }} position="top">
|
|
413
413
|
<span className="flex items-center gap-0.5">
|
|
414
414
|
<Icon className={`w-3 h-3 ${color}`} />
|
|
415
|
-
<span className="text-
|
|
415
|
+
<span className="text-xs text-neutral-500">{count}</span>
|
|
416
416
|
</span>
|
|
417
417
|
</Tooltip>
|
|
418
418
|
)]
|
|
@@ -469,7 +469,7 @@ export function RegistryCard(props: RegistryCardProps) {
|
|
|
469
469
|
...(props.stars != null && props.stars > 0 ? [(
|
|
470
470
|
<CardClickable key="stars" onClick={() => props.onSortBy?.('stars')}>
|
|
471
471
|
<Tooltip content={{ description: `${props.stars.toLocaleString()} stars \u00b7 Click to sort` }} position="top">
|
|
472
|
-
<span className="flex items-center gap-1 text-
|
|
472
|
+
<span className="flex items-center gap-1 text-xs text-amber-400/80">
|
|
473
473
|
<Star className="w-3 h-3" />
|
|
474
474
|
{formatCount(props.stars)}
|
|
475
475
|
</span>
|
|
@@ -479,7 +479,7 @@ export function RegistryCard(props: RegistryCardProps) {
|
|
|
479
479
|
...(props.downloads != null && props.downloads > 0 ? [(
|
|
480
480
|
<CardClickable key="downloads" onClick={() => props.onSortBy?.('downloads')}>
|
|
481
481
|
<Tooltip content={{ description: `${props.downloads.toLocaleString()} downloads \u00b7 Click to sort` }} position="top">
|
|
482
|
-
<span className="flex items-center gap-1 text-
|
|
482
|
+
<span className="flex items-center gap-1 text-xs text-emerald-400/80">
|
|
483
483
|
<Download className="w-3 h-3" />
|
|
484
484
|
{formatCount(props.downloads)}
|
|
485
485
|
</span>
|
|
@@ -581,7 +581,7 @@ export function RegistryCard(props: RegistryCardProps) {
|
|
|
581
581
|
if (props.installs != null && props.installs > 0) {
|
|
582
582
|
bottomStats = [(
|
|
583
583
|
<Tooltip key="installs" content={{ description: `${props.installs.toLocaleString()} installs` }} position="top">
|
|
584
|
-
<span className="flex items-center gap-1 text-
|
|
584
|
+
<span className="flex items-center gap-1 text-xs text-neutral-500">
|
|
585
585
|
<Download className="w-3 h-3" />
|
|
586
586
|
{props.installs.toLocaleString()}
|
|
587
587
|
</span>
|
|
@@ -632,17 +632,17 @@ export function RegistryCard(props: RegistryCardProps) {
|
|
|
632
632
|
</div>
|
|
633
633
|
|
|
634
634
|
{/* Name */}
|
|
635
|
-
<h3 className="text-
|
|
635
|
+
<h3 className="text-md font-medium text-white">{name}</h3>
|
|
636
636
|
|
|
637
637
|
{/* Subtitle */}
|
|
638
|
-
{subtitle && <div className="text-
|
|
638
|
+
{subtitle && <div className="text-sm text-neutral-400 mb-1.5">{subtitle}</div>}
|
|
639
639
|
|
|
640
640
|
{/* Description */}
|
|
641
|
-
{description && <p className="text-
|
|
641
|
+
{description && <p className="text-sm text-neutral-500 mb-3 flex-grow line-clamp-2">{description}</p>}
|
|
642
642
|
|
|
643
643
|
{/* Error/warning message */}
|
|
644
644
|
{errorMessage && (
|
|
645
|
-
<p className={`text-
|
|
645
|
+
<p className={`text-xs mb-2 break-all ${flash === 'warning' ? 'text-amber-400' : 'text-red-400'}`}>{errorMessage}</p>
|
|
646
646
|
)}
|
|
647
647
|
|
|
648
648
|
{/* Bottom row */}
|
|
@@ -650,7 +650,7 @@ export function RegistryCard(props: RegistryCardProps) {
|
|
|
650
650
|
const dateNode = updatedAt ? (
|
|
651
651
|
<Tooltip content={{ description: onDateClick ? `Last updated ${formatFullDate(updatedAt)} \u00b7 Click to sort by date` : `Last updated ${formatFullDate(updatedAt)}` }} position="top">
|
|
652
652
|
<span
|
|
653
|
-
className={`flex items-center gap-1 text-
|
|
653
|
+
className={`flex items-center gap-1 text-xs text-neutral-500 whitespace-nowrap${onDateClick ? ' cursor-pointer hover:brightness-125 transition-all' : ''}`}
|
|
654
654
|
onClick={onDateClick ? (e: MouseEvent) => { e.stopPropagation(); onDateClick() } : undefined}
|
|
655
655
|
>
|
|
656
656
|
<Clock className="w-3 h-3" />
|
|
@@ -692,13 +692,13 @@ export function RegistryCard(props: RegistryCardProps) {
|
|
|
692
692
|
<div onClick={(e) => e.stopPropagation()}>
|
|
693
693
|
<div className="fixed inset-0 bg-[var(--background)]/50 z-50 flex items-center justify-center" onClick={() => setShowScopeConfirm(false)}>
|
|
694
694
|
<div className="bg-neutral-800 border border-neutral-700 rounded-lg p-4 max-w-sm" onClick={(e) => e.stopPropagation()}>
|
|
695
|
-
<h3 className="text-
|
|
696
|
-
<p className="text-
|
|
695
|
+
<h3 className="text-md font-medium text-neutral-200 mb-2">{ALREADY_AT_USER}</h3>
|
|
696
|
+
<p className="text-sm text-neutral-400 mb-4">
|
|
697
697
|
<strong className="text-neutral-300">{name}</strong> is already installed at user level and available to all projects. Do you also want to install it at project level?
|
|
698
698
|
</p>
|
|
699
699
|
<div className="flex justify-end gap-2">
|
|
700
|
-
<button type="button" onClick={() => setShowScopeConfirm(false)} className="px-3 py-1.5 text-
|
|
701
|
-
<button type="button" onClick={() => { setShowScopeConfirm(false); props.onInstall() }} className="px-3 py-1.5 text-
|
|
700
|
+
<button type="button" onClick={() => setShowScopeConfirm(false)} className="px-3 py-1.5 text-sm text-neutral-400 hover:text-neutral-200 transition-colors cursor-pointer">Cancel</button>
|
|
701
|
+
<button type="button" onClick={() => { setShowScopeConfirm(false); props.onInstall() }} className="px-3 py-1.5 text-sm bg-blue-600 text-white rounded hover:bg-blue-500 transition-colors cursor-pointer">Install to project</button>
|
|
702
702
|
</div>
|
|
703
703
|
</div>
|
|
704
704
|
</div>
|
|
@@ -42,7 +42,7 @@ export interface RegistryDetailProps {
|
|
|
42
42
|
children?: ReactNode
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const MARKDOWN_CLASSES = 'text-
|
|
45
|
+
const MARKDOWN_CLASSES = 'text-md text-neutral-400 leading-relaxed [&_strong]:text-neutral-200 [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:rounded [&_code]:bg-neutral-700/40 [&_code]:border [&_code]:border-neutral-500/40 [&_code]:text-neutral-200 [&_code]:font-mono [&_code]:text-sm [&_h1]:text-lg [&_h1]:font-semibold [&_h1]:text-neutral-200 [&_h1]:mb-2 [&_h2]:text-base [&_h2]:font-semibold [&_h2]:text-neutral-200 [&_h2]:mb-2 [&_h3]:text-md [&_h3]:font-medium [&_h3]:text-neutral-200 [&_h3]:mb-1 [&_ul]:list-disc [&_ul]:pl-4 [&_ol]:list-decimal [&_ol]:pl-4 [&_li]:mb-1 [&_p]:mb-2 [&_pre]:bg-neutral-900 [&_pre]:rounded [&_pre]:p-3 [&_pre]:overflow-x-auto [&_pre]:text-sm'
|
|
46
46
|
|
|
47
47
|
// ── CollapsibleSection ────────────────────────────────────────────────────────
|
|
48
48
|
|
|
@@ -78,7 +78,7 @@ function CollapsibleTextSection({ children, header }: { children: string; header
|
|
|
78
78
|
{(header || overflows) && (
|
|
79
79
|
<div className="flex items-center justify-between mb-2">
|
|
80
80
|
{header && (
|
|
81
|
-
<h3 className="text-
|
|
81
|
+
<h3 className="text-sm font-medium text-neutral-500 uppercase tracking-wider">{header}</h3>
|
|
82
82
|
)}
|
|
83
83
|
{overflows && (
|
|
84
84
|
<IconButton
|
|
@@ -117,12 +117,12 @@ function CompatibleWithSection({ tools }: { tools: string[] }) {
|
|
|
117
117
|
|
|
118
118
|
return (
|
|
119
119
|
<div>
|
|
120
|
-
<h3 className="text-
|
|
120
|
+
<h3 className="text-sm font-medium text-neutral-500 uppercase tracking-wider mb-3">Compatible with</h3>
|
|
121
121
|
<div className="flex items-start gap-3">
|
|
122
122
|
{tools.map((tool) => (
|
|
123
123
|
<div key={tool} className="flex flex-col items-center gap-1">
|
|
124
124
|
<AiToolIcon tool={tool} size={18} />
|
|
125
|
-
<span className="text-
|
|
125
|
+
<span className="text-xs text-neutral-400">{AI_TOOL_NAMES[tool as AiToolKey] ?? tool}</span>
|
|
126
126
|
</div>
|
|
127
127
|
))}
|
|
128
128
|
</div>
|
|
@@ -181,8 +181,8 @@ export function RegistryDetail({
|
|
|
181
181
|
{/* Description */}
|
|
182
182
|
{description && (
|
|
183
183
|
<div>
|
|
184
|
-
<h3 className="text-
|
|
185
|
-
<p className="text-
|
|
184
|
+
<h3 className="text-sm font-medium text-neutral-500 uppercase tracking-wider mb-2">Description</h3>
|
|
185
|
+
<p className="text-md text-neutral-400 leading-relaxed">{description}</p>
|
|
186
186
|
</div>
|
|
187
187
|
)}
|
|
188
188
|
|
|
@@ -35,10 +35,10 @@ const ICON_SIZE_CLASSES = {
|
|
|
35
35
|
/** Text label button sizes — horizontal padding instead of fixed width */
|
|
36
36
|
const TEXT_SIZE_CLASSES = {
|
|
37
37
|
xss: 'h-[18px] px-1.5 text-xss',
|
|
38
|
-
xs: 'h-6 px-2 text-
|
|
39
|
-
sm: 'h-7 px-2.5 text-
|
|
40
|
-
md: 'h-8 px-3 text-
|
|
41
|
-
lg: 'h-9 px-3.5 text-
|
|
38
|
+
xs: 'h-6 px-2 text-xs',
|
|
39
|
+
sm: 'h-7 px-2.5 text-sm',
|
|
40
|
+
md: 'h-8 px-3 text-sm',
|
|
41
|
+
lg: 'h-9 px-3.5 text-md',
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const ROUNDING_CLASSES = {
|
package/components/ui/select.tsx
CHANGED
|
@@ -30,10 +30,10 @@ const VARIANT_CLASSES = {
|
|
|
30
30
|
|
|
31
31
|
const SIZE_CLASSES = {
|
|
32
32
|
xss: 'h-[18px] px-1.5 text-xss',
|
|
33
|
-
xs: 'h-6 px-2 text-
|
|
34
|
-
sm: 'h-7 px-2 text-
|
|
35
|
-
md: 'h-8 px-3 text-
|
|
36
|
-
lg: 'h-9 px-3 text-
|
|
33
|
+
xs: 'h-6 px-2 text-sm',
|
|
34
|
+
sm: 'h-7 px-2 text-sm',
|
|
35
|
+
md: 'h-8 px-3 text-md',
|
|
36
|
+
lg: 'h-9 px-3 text-md',
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export function Select<T extends string | number = string>({
|
|
@@ -152,7 +152,7 @@ export function Select<T extends string | number = string>({
|
|
|
152
152
|
data-idx={idx}
|
|
153
153
|
onClick={() => { onChange(opt.value); close() }}
|
|
154
154
|
onPointerEnter={() => setHighlightIdx(idx)}
|
|
155
|
-
className={`w-full flex items-center gap-2 px-3 py-1.5 text-
|
|
155
|
+
className={`w-full flex items-center gap-2 px-3 py-1.5 text-sm text-left transition-colors cursor-pointer ${
|
|
156
156
|
isHighlighted
|
|
157
157
|
? `${FORM_COLORS[color].selectedBg} text-neutral-200`
|
|
158
158
|
: isSelected ? `${FORM_COLORS[color].selectedBg} text-neutral-200` : `text-neutral-400 ${v.hoverBg}`
|
|
@@ -251,10 +251,10 @@ function GridCard({ item, selected, onClick }: CardProps) {
|
|
|
251
251
|
/>
|
|
252
252
|
)}
|
|
253
253
|
|
|
254
|
-
<span className="text-
|
|
254
|
+
<span className="text-sm font-medium text-neutral-200 block">{item.name}</span>
|
|
255
255
|
|
|
256
256
|
{item.description && (
|
|
257
|
-
<span className="text-
|
|
257
|
+
<span className="text-sm text-neutral-500 block mt-0.5">{item.description}</span>
|
|
258
258
|
)}
|
|
259
259
|
</button>
|
|
260
260
|
)
|
|
@@ -291,9 +291,9 @@ function ListCard({ item, selected, onClick }: CardProps) {
|
|
|
291
291
|
)}
|
|
292
292
|
|
|
293
293
|
<div className="min-w-0">
|
|
294
|
-
<span className="text-
|
|
294
|
+
<span className="text-sm font-medium text-neutral-200 block">{item.name}</span>
|
|
295
295
|
{item.description && (
|
|
296
|
-
<span className="text-
|
|
296
|
+
<span className="text-sm text-neutral-500 block mt-0.5">{item.description}</span>
|
|
297
297
|
)}
|
|
298
298
|
</div>
|
|
299
299
|
</button>
|
|
@@ -58,7 +58,7 @@ export function SettingRow(props: SettingRowProps) {
|
|
|
58
58
|
<div className={`flex items-start justify-between gap-4 ${className}`}>
|
|
59
59
|
<div>
|
|
60
60
|
<label className="text-neutral-200 leading-7">{label}</label>
|
|
61
|
-
{description && <p className="text-
|
|
61
|
+
{description && <p className="text-md text-neutral-500">{description}</p>}
|
|
62
62
|
</div>
|
|
63
63
|
{props.type === 'toggle' && (
|
|
64
64
|
<Toggle
|
|
@@ -16,11 +16,11 @@ export function SettingsCard({ children, className, title, description, testId }
|
|
|
16
16
|
>
|
|
17
17
|
{title && (
|
|
18
18
|
<div>
|
|
19
|
-
<h3 className="text-
|
|
20
|
-
{description && <p className="text-
|
|
19
|
+
<h3 className="text-md font-medium text-neutral-200">{title}</h3>
|
|
20
|
+
{description && <p className="text-md text-neutral-500 mt-1">{description}</p>}
|
|
21
21
|
</div>
|
|
22
22
|
)}
|
|
23
|
-
{!title && description && <p className="text-
|
|
23
|
+
{!title && description && <p className="text-md text-neutral-500">{description}</p>}
|
|
24
24
|
{children}
|
|
25
25
|
</div>
|
|
26
26
|
)
|
|
@@ -74,7 +74,7 @@ export function SettingsInfoBox({ children, color = 'neutral', className, testId
|
|
|
74
74
|
data-testid={testId}
|
|
75
75
|
>
|
|
76
76
|
<Icon className={cn('w-4 h-4 mt-0.5 shrink-0', iconColorMap[color])} />
|
|
77
|
-
<div className="text-
|
|
77
|
+
<div className="text-md text-neutral-500">{children}</div>
|
|
78
78
|
</div>
|
|
79
79
|
)
|
|
80
80
|
}
|
|
@@ -15,7 +15,7 @@ export interface SettingsSectionTitleProps {
|
|
|
15
15
|
export function SettingsSectionTitle({ children, className = '', testId }: SettingsSectionTitleProps) {
|
|
16
16
|
return (
|
|
17
17
|
<h3
|
|
18
|
-
className={`text-
|
|
18
|
+
className={`text-sm font-medium text-neutral-400 uppercase tracking-wider ${className}`}
|
|
19
19
|
data-testid={testId}
|
|
20
20
|
>
|
|
21
21
|
{children}
|
|
@@ -48,7 +48,7 @@ export function SnapshotCard({
|
|
|
48
48
|
|
|
49
49
|
<div className="p-4">
|
|
50
50
|
<div className="flex items-start justify-between gap-2">
|
|
51
|
-
<h3 className="text-
|
|
51
|
+
<h3 className="text-md font-medium text-neutral-200 truncate">{title}</h3>
|
|
52
52
|
<Label
|
|
53
53
|
text={statusLabelConfig[status].text}
|
|
54
54
|
color={statusLabelConfig[status].color}
|
|
@@ -59,19 +59,19 @@ export function SnapshotCard({
|
|
|
59
59
|
</div>
|
|
60
60
|
|
|
61
61
|
{timestamp && (
|
|
62
|
-
<p className="mt-1 text-
|
|
62
|
+
<p className="mt-1 text-xs text-neutral-500">{timestamp}</p>
|
|
63
63
|
)}
|
|
64
64
|
|
|
65
65
|
{description && (
|
|
66
|
-
<p className="mt-2 text-
|
|
66
|
+
<p className="mt-2 text-sm text-neutral-500 leading-relaxed line-clamp-2">{description}</p>
|
|
67
67
|
)}
|
|
68
68
|
|
|
69
69
|
{stats && stats.length > 0 && (
|
|
70
70
|
<div className="mt-3 grid grid-cols-2 gap-x-4 gap-y-2">
|
|
71
71
|
{stats.map((stat) => (
|
|
72
72
|
<div key={stat.label}>
|
|
73
|
-
<p className="text-
|
|
74
|
-
<p className="text-
|
|
73
|
+
<p className="text-xs text-neutral-500">{stat.label}</p>
|
|
74
|
+
<p className="text-sm font-medium text-neutral-200">{stat.value}</p>
|
|
75
75
|
</div>
|
|
76
76
|
))}
|
|
77
77
|
</div>
|
|
@@ -83,7 +83,7 @@ export function SnapshotCard({
|
|
|
83
83
|
<button
|
|
84
84
|
type="button"
|
|
85
85
|
onClick={onSync}
|
|
86
|
-
className="flex items-center gap-1.5 px-2.5 py-1 text-
|
|
86
|
+
className="flex items-center gap-1.5 px-2.5 py-1 text-sm font-medium rounded-md bg-blue-400/15 text-blue-400 hover:bg-blue-400/25 transition-colors cursor-pointer"
|
|
87
87
|
>
|
|
88
88
|
<RefreshCw className={cn('w-3 h-3', status === 'pending' && 'animate-spin')} />
|
|
89
89
|
Sync
|
|
@@ -93,7 +93,7 @@ export function SnapshotCard({
|
|
|
93
93
|
<button
|
|
94
94
|
type="button"
|
|
95
95
|
onClick={onView}
|
|
96
|
-
className="flex items-center gap-1.5 px-2.5 py-1 text-
|
|
96
|
+
className="flex items-center gap-1.5 px-2.5 py-1 text-sm font-medium rounded-md text-neutral-400 hover:bg-neutral-700 transition-colors cursor-pointer"
|
|
97
97
|
>
|
|
98
98
|
<Eye className="w-3 h-3" />
|
|
99
99
|
View
|
|
@@ -63,19 +63,19 @@ export function SnippetsPanel({
|
|
|
63
63
|
return (
|
|
64
64
|
<div className={cn('flex flex-col bg-neutral-800 rounded-lg overflow-hidden', className)}>
|
|
65
65
|
<div className="flex items-center justify-between px-3 py-2 border-b border-neutral-700">
|
|
66
|
-
<span className="text-
|
|
67
|
-
<span className="text-
|
|
66
|
+
<span className="text-xs font-semibold uppercase tracking-wider text-neutral-500">Snippets</span>
|
|
67
|
+
<span className="text-xs text-neutral-500">{snippets.length} snippets</span>
|
|
68
68
|
</div>
|
|
69
69
|
{showSearch && (
|
|
70
70
|
<div className="px-2 py-2 border-b border-neutral-700">
|
|
71
|
-
<div className="flex items-center gap-1.5 px-2 py-1 bg-[var(--background)] border border-neutral-700 rounded text-
|
|
71
|
+
<div className="flex items-center gap-1.5 px-2 py-1 bg-[var(--background)] border border-neutral-700 rounded text-sm">
|
|
72
72
|
<Search className="w-3 h-3 text-neutral-500 shrink-0" />
|
|
73
73
|
<input
|
|
74
74
|
type="text"
|
|
75
75
|
placeholder="Search snippets..."
|
|
76
76
|
value={searchQuery}
|
|
77
77
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
78
|
-
className="flex-1 bg-transparent text-neutral-200 placeholder-neutral-500 outline-none text-
|
|
78
|
+
className="flex-1 bg-transparent text-neutral-200 placeholder-neutral-500 outline-none text-sm"
|
|
79
79
|
/>
|
|
80
80
|
</div>
|
|
81
81
|
</div>
|
|
@@ -90,7 +90,7 @@ export function SnippetsPanel({
|
|
|
90
90
|
/>
|
|
91
91
|
))}
|
|
92
92
|
{filteredSnippets.length === 0 && (
|
|
93
|
-
<p className="text-
|
|
93
|
+
<p className="text-xs text-neutral-500 text-center py-4">No snippets found</p>
|
|
94
94
|
)}
|
|
95
95
|
</div>
|
|
96
96
|
</div>
|
|
@@ -110,10 +110,10 @@ function SnippetCard({ snippet, onInsert, onCopy }: SnippetCardProps) {
|
|
|
110
110
|
<div className="rounded-md border border-neutral-700 bg-neutral-900 hover:border-neutral-600 transition-colors">
|
|
111
111
|
<div className="flex items-center justify-between gap-2 px-2.5 py-1.5">
|
|
112
112
|
<div className="flex items-center gap-2 min-w-0">
|
|
113
|
-
<span className="text-
|
|
113
|
+
<span className="text-sm font-medium text-neutral-200 truncate">{snippet.label}</span>
|
|
114
114
|
{snippet.language && (
|
|
115
115
|
<span
|
|
116
|
-
className="px-1.5 py-0.5 text-
|
|
116
|
+
className="px-1.5 py-0.5 text-xs font-medium rounded shrink-0"
|
|
117
117
|
style={{ color: langColor, backgroundColor: `${langColor}20` }}
|
|
118
118
|
>
|
|
119
119
|
{snippet.language}
|
|
@@ -140,17 +140,17 @@ function SnippetCard({ snippet, onInsert, onCopy }: SnippetCardProps) {
|
|
|
140
140
|
</div>
|
|
141
141
|
</div>
|
|
142
142
|
{snippet.description && (
|
|
143
|
-
<p className="px-2.5 pb-1.5 text-
|
|
143
|
+
<p className="px-2.5 pb-1.5 text-xs text-neutral-400 leading-relaxed">{snippet.description}</p>
|
|
144
144
|
)}
|
|
145
145
|
<div className="mx-2.5 mb-2 rounded bg-[var(--background)] border border-neutral-700 overflow-hidden">
|
|
146
|
-
<pre className="p-2 text-
|
|
146
|
+
<pre className="p-2 text-xs text-neutral-400 leading-relaxed overflow-x-auto max-h-24">
|
|
147
147
|
<code>{snippet.code}</code>
|
|
148
148
|
</pre>
|
|
149
149
|
</div>
|
|
150
150
|
{snippet.tags && snippet.tags.length > 0 && (
|
|
151
151
|
<div className="flex flex-wrap gap-1 px-2.5 pb-2">
|
|
152
152
|
{snippet.tags.map((tag) => (
|
|
153
|
-
<span key={tag} className="px-1.5 py-0.5 text-
|
|
153
|
+
<span key={tag} className="px-1.5 py-0.5 text-xs rounded bg-neutral-700 text-neutral-500">
|
|
154
154
|
{tag}
|
|
155
155
|
</span>
|
|
156
156
|
))}
|
|
@@ -74,7 +74,7 @@ export function SortDropdown({
|
|
|
74
74
|
<div className="relative flex items-center" ref={ref} onKeyDown={handleKeyDown}>
|
|
75
75
|
<button
|
|
76
76
|
onClick={() => setIsOpen(!isOpen)}
|
|
77
|
-
className={`flex items-center gap-1.5 h-7 px-2 rounded-md border ${v.bg} text-
|
|
77
|
+
className={`flex items-center gap-1.5 h-7 px-2 rounded-md border ${v.bg} text-sm transition-colors cursor-pointer ${FORM_COLORS[color].border} text-neutral-200 ${FORM_COLORS[color].hover}`}
|
|
78
78
|
>
|
|
79
79
|
<span
|
|
80
80
|
className={`${FORM_COLORS[color].accent} hover:brightness-125 transition-colors`}
|
|
@@ -94,7 +94,7 @@ export function SortDropdown({
|
|
|
94
94
|
key={f.value}
|
|
95
95
|
onClick={() => { onFieldChange(f.value); setIsOpen(false) }}
|
|
96
96
|
onPointerEnter={() => setHighlightIdx(idx)}
|
|
97
|
-
className={`w-full flex items-center gap-2 px-3 py-1.5 text-
|
|
97
|
+
className={`w-full flex items-center gap-2 px-3 py-1.5 text-sm text-left transition-colors cursor-pointer ${
|
|
98
98
|
idx === highlightIdx ? `${FORM_COLORS[color].selectedBg} text-neutral-200` : field === f.value ? `${FORM_COLORS[color].selectedBg} text-neutral-200` : `text-neutral-400 ${v.hoverBg}`
|
|
99
99
|
}`}
|
|
100
100
|
>
|
|
@@ -63,15 +63,15 @@ export function StatusCard({
|
|
|
63
63
|
{Icon && (
|
|
64
64
|
<Icon className="w-4 h-4 shrink-0" style={{ color: iconColor }} />
|
|
65
65
|
)}
|
|
66
|
-
<h3 className="text-
|
|
66
|
+
<h3 className="text-md font-medium text-neutral-200">{title}</h3>
|
|
67
67
|
</div>
|
|
68
68
|
|
|
69
69
|
<div className="divide-y divide-neutral-700/60">
|
|
70
70
|
{items.map((item) => (
|
|
71
71
|
<div key={item.label} className="flex items-center justify-between px-4 py-2.5">
|
|
72
|
-
<span className="text-
|
|
72
|
+
<span className="text-sm text-neutral-400">{item.label}</span>
|
|
73
73
|
<div className="flex items-center gap-2">
|
|
74
|
-
<span className={cn('text-
|
|
74
|
+
<span className={cn('text-sm font-medium', statusValueColor[item.status])}>
|
|
75
75
|
{item.value}
|
|
76
76
|
</span>
|
|
77
77
|
<span className={cn('w-2 h-2 rounded-full shrink-0', statusDotColor[item.status])} />
|
|
@@ -85,7 +85,7 @@ export function StatusCard({
|
|
|
85
85
|
<button
|
|
86
86
|
type="button"
|
|
87
87
|
onClick={action.onClick}
|
|
88
|
-
className="text-
|
|
88
|
+
className="text-sm text-blue-400 hover:text-blue-300 transition-colors cursor-pointer"
|
|
89
89
|
>
|
|
90
90
|
{action.label}
|
|
91
91
|
</button>
|
|
@@ -55,8 +55,8 @@ export interface TabBarProps {
|
|
|
55
55
|
|
|
56
56
|
const sizeConfig = {
|
|
57
57
|
xss: { text: 'text-xss', icon: 'w-2.5 h-2.5', px: 'px-1.5', py: 'py-1', close: 'w-2.5 h-2.5', badgeSize: 'xss' as const, gap: 'gap-1' },
|
|
58
|
-
xs: { text: 'text-
|
|
59
|
-
sm: { text: 'text-
|
|
58
|
+
xs: { text: 'text-sm', icon: 'w-3 h-3', px: 'px-2', py: 'py-1', close: 'w-3 h-3', badgeSize: 'xs' as const, gap: 'gap-1' },
|
|
59
|
+
sm: { text: 'text-md', icon: 'w-3.5 h-3.5', px: 'px-3', py: 'py-1.5', close: 'w-3 h-3', badgeSize: 'sm' as const, gap: 'gap-1.5' },
|
|
60
60
|
md: { text: 'text-base', icon: 'w-4 h-4', px: 'px-4', py: 'py-2', close: 'w-3.5 h-3.5', badgeSize: 'md' as const, gap: 'gap-2' },
|
|
61
61
|
lg: { text: 'text-lg', icon: 'w-5 h-5', px: 'px-5', py: 'py-2.5', close: 'w-4 h-4', badgeSize: 'lg' as const, gap: 'gap-2' },
|
|
62
62
|
}
|
|
@@ -271,9 +271,9 @@ export function Tooltip({
|
|
|
271
271
|
onMouseEnter={interactive && trigger !== 'click' ? show : undefined}
|
|
272
272
|
onMouseLeave={interactive && trigger !== 'click' ? hide : undefined}
|
|
273
273
|
>
|
|
274
|
-
{content.title && <p className="text-
|
|
275
|
-
<div className={`text-
|
|
276
|
-
{content.extra && <p className="text-
|
|
274
|
+
{content.title && <p className="text-md text-neutral-200 font-medium">{content.title}</p>}
|
|
275
|
+
<div className={`text-sm text-neutral-400 ${content.title ? 'mt-0.5' : ''}`}>{content.description}</div>
|
|
276
|
+
{content.extra && <p className="text-sm text-orange-400/70 mt-0.5">{content.extra}</p>}
|
|
277
277
|
<div className={arrowClasses} />
|
|
278
278
|
</div>
|
|
279
279
|
)
|