Skip to content

Commit 1bbc4df

Browse files
committed
feat: Adopt Hashicorp Helios Design system
1 parent dea4ef5 commit 1bbc4df

21 files changed

Lines changed: 662 additions & 924 deletions

frontend/index.html

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>Renovate Bot Dashboard</title>
8-
<link rel="preconnect" href="https://fonts.googleapis.com">
9-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
118
</head>
129
<body>
1310
<div id="root"></div>

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"test:coverage": "vitest run --coverage"
1313
},
1414
"dependencies": {
15+
"@hashicorp/design-system-tokens": "^4.0.1",
1516
"@tanstack/react-query": "^5.95.2",
1617
"class-variance-authority": "^0.7.1",
1718
"clsx": "^2.1.1",

frontend/src/App.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@ import { SocketProvider } from './context/SocketContext';
1414
import { NotificationProvider } from './context/NotificationContext';
1515
import { ScanProvider } from './context/ScanContext';
1616
import { SidebarProvider } from './context/SidebarContext';
17-
import { ThemeProvider } from './context/ThemeContext';
1817

1918
function App() {
2019
return (
21-
<ThemeProvider>
22-
<AuthProvider>
20+
<AuthProvider>
2321
<Routes>
2422
{/* Public routes */}
2523
<Route path="/login" element={<Login />} />
@@ -53,7 +51,6 @@ function App() {
5351
/>
5452
</Routes>
5553
</AuthProvider>
56-
</ThemeProvider>
5754
);
5855
}
5956

frontend/src/components/Avatar.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function Avatar({ src, alt, size = 'md', className }: AvatarProps) {
1919
src={src}
2020
alt={alt}
2121
className={cn(
22-
'rounded-full object-cover border border-gray-200 dark:border-gray-600',
22+
'rounded-full object-cover border border-neutral-200',
2323
sizeClasses[size],
2424
className
2525
)}
@@ -52,13 +52,13 @@ export function AvatarGroup({ contributors, max = 4, size = 'md' }: AvatarGroupP
5252
src={contributor.avatarUrl}
5353
alt={contributor.login}
5454
size={size}
55-
className="ring-2 ring-white hover:ring-primary-500"
55+
className="ring-2 ring-white hover:ring-action-300"
5656
/>
5757
</a>
5858
))}
5959
{remaining > 0 && (
6060
<div className={cn(
61-
'rounded-full bg-gray-100 text-gray-600 font-semibold flex items-center justify-center border border-gray-200 ring-2 ring-white dark:bg-gray-700 dark:text-gray-300 dark:border-gray-600 dark:ring-gray-800',
61+
'rounded-full bg-neutral-100 text-neutral-500 font-semibold flex items-center justify-center border border-neutral-200 ring-2 ring-white',
6262
{
6363
'w-6 h-6 text-xs': size === 'sm',
6464
'w-8 h-8 text-xs': size === 'md',

frontend/src/components/ProtectedRoute.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,19 @@ export function ProtectedRoute({ children }: { children: React.ReactNode }) {
55
const { isAuthenticated, isLoading } = useAuth();
66

77
if (isLoading) {
8-
// Show loading spinner while checking auth
98
return (
10-
<div className="min-h-screen bg-gray-50 dark:bg-slate-950 flex items-center justify-center">
9+
<div className="min-h-screen bg-neutral-50 flex items-center justify-center">
1110
<div className="text-center">
12-
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto"></div>
13-
<p className="mt-4 text-gray-600 dark:text-gray-400">Loading...</p>
11+
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-action-300 mx-auto"></div>
12+
<p className="mt-4 text-neutral-500">Loading...</p>
1413
</div>
1514
</div>
1615
);
1716
}
1817

1918
if (!isAuthenticated) {
20-
// Redirect to login if not authenticated
2119
return <Navigate to="/login" replace />;
2220
}
2321

2422
return <>{children}</>;
2523
}
26-

frontend/src/components/Select.tsx

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export function Select({ options, value, onChange, placeholder, className }: Sel
2222
const selectedOption = options.find(opt => opt.value === value);
2323
const displayLabel = selectedOption?.label || placeholder || 'Select...';
2424

25-
// Close dropdown when clicking outside
2625
useEffect(() => {
2726
function handleClickOutside(event: MouseEvent) {
2827
if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
@@ -43,17 +42,10 @@ export function Select({ options, value, onChange, placeholder, className }: Sel
4342

4443
return (
4544
<div ref={containerRef} className={cn('relative', className)}>
46-
{/* Button */}
4745
<button
4846
onClick={() => setIsOpen(!isOpen)}
49-
className={cn(
50-
'flex h-10 w-full items-center justify-between rounded-md border border-gray-300 bg-white px-3 py-2 text-sm',
51-
'text-gray-900 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent',
52-
'disabled:cursor-not-allowed disabled:opacity-50',
53-
'dark:border-secondary-500/30 dark:bg-slate-800 dark:text-slate-100 dark:placeholder:text-slate-500',
54-
'dark:focus:ring-primary-500 dark:focus:border-primary-500/50 dark:shadow-lg dark:shadow-primary-500/10',
55-
'transition-colors'
56-
)}
47+
className="flex h-10 w-full items-center justify-between rounded-hds-sm bg-white px-3 py-2 text-sm text-neutral-700 transition-colors disabled:cursor-not-allowed disabled:opacity-50"
48+
style={{ border: '1px solid #e2e8f0' }}
5749
>
5850
<span>{displayLabel}</span>
5951
<ChevronDown
@@ -64,13 +56,11 @@ export function Select({ options, value, onChange, placeholder, className }: Sel
6456
/>
6557
</button>
6658

67-
{/* Dropdown */}
6859
{isOpen && (
69-
<div className={cn(
70-
'absolute top-full left-0 right-0 mt-2 z-50',
71-
'rounded-md border border-gray-200 bg-white shadow-lg',
72-
'dark:border-secondary-500/30 dark:bg-slate-800 dark:shadow-lg dark:shadow-secondary-500/10'
73-
)}>
60+
<div
61+
className="absolute top-full left-0 right-0 mt-1 z-50 rounded-hds-md bg-white"
62+
style={{ boxShadow: '0 0 0 1px #e2e8f040, 0 4px 6px 0 #47556920, 0 12px 24px 0 #47556930' }}
63+
>
7464
<ul className="py-1">
7565
{options.map((option) => (
7666
<li key={option.value}>
@@ -79,8 +69,8 @@ export function Select({ options, value, onChange, placeholder, className }: Sel
7969
className={cn(
8070
'w-full text-left px-3 py-2 text-sm transition-colors',
8171
value === option.value
82-
? 'bg-primary-500 text-white dark:bg-primary-600 dark:text-slate-100'
83-
: 'text-gray-900 hover:bg-gray-100 dark:text-slate-100 dark:hover:bg-slate-700'
72+
? 'bg-action-200 text-white'
73+
: 'text-neutral-700 hover:bg-neutral-100'
8474
)}
8575
>
8676
{option.label}

0 commit comments

Comments
 (0)