Skip to content

Commit 3d44337

Browse files
authored
fix(ui): polish UI according to vercel.com/design/guidelines/install (#9)
1 parent d26963b commit 3d44337

File tree

6 files changed

+48
-20
lines changed

6 files changed

+48
-20
lines changed

website/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1" />
66
</head>
77
<body class="bg-background text-foreground">
8+
<a href="#main-content" class="sr-only focus:not-sr-only focus:fixed focus:left-4 focus:top-4 focus:z-50 focus:rounded-md focus:bg-background focus:px-4 focus:py-2 focus:outline-none focus:ring-2 focus:ring-cyan-400">
9+
Skip to content
10+
</a>
811
<div id="root"></div>
912
</body>
1013
</html>

website/src/App.tsx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,11 @@ export default function App() {
187187

188188
return (
189189
<div className="min-h-screen bg-transparent px-4 py-12 text-foreground sm:px-8">
190-
<div className="mx-auto flex w-full max-w-6xl flex-col gap-10">
190+
<div
191+
id="main-content"
192+
tabIndex={-1}
193+
className="mx-auto flex w-full max-w-6xl flex-col gap-10 outline-none"
194+
>
191195
<header className="flex flex-col gap-6 sm:flex-row sm:items-center sm:justify-between">
192196
<div className="space-y-4">
193197
<div className="inline-flex items-center gap-3 rounded-lg border border-white/10 bg-white/5 px-4 py-1.5 text-[11px] font-semibold uppercase tracking-[0.2em] text-white/90">
@@ -210,6 +214,8 @@ export default function App() {
210214
<img
211215
src="https://assets.rspack.rs/rspack/rspack-logo.svg"
212216
alt="Rspack logo"
217+
width="40"
218+
height="40"
213219
className="relative h-10 w-10 drop-shadow-[0_4px_18px_rgba(34,211,238,0.75)]"
214220
/>
215221
</span>
@@ -224,7 +230,7 @@ export default function App() {
224230
href={GITHUB_REPO_URL}
225231
target="_blank"
226232
rel="noreferrer"
227-
className="inline-flex h-9 w-9 items-center justify-center rounded-full border border-border/40 bg-white/5 text-white/80 transition hover:bg-white/10 hover:text-white"
233+
className="inline-flex h-9 w-9 items-center justify-center rounded-full border border-border/40 bg-white/5 text-white/80 transition-[background-color,color] hover:bg-white/10 hover:text-white"
228234
aria-label="Open GitHub repository"
229235
>
230236
<span className="sr-only">GitHub</span>
@@ -243,7 +249,7 @@ export default function App() {
243249
<div className="relative" ref={repoMenuRef}>
244250
<button
245251
type="button"
246-
className="inline-flex items-center gap-1 rounded-full border border-border/40 bg-white/5 px-3 py-1.5 text-xs font-semibold uppercase tracking-[0.18em] text-white/80 transition hover:bg-white/10 hover:text-white"
252+
className="inline-flex items-center gap-1 rounded-full border border-border/40 bg-white/5 px-3 py-1.5 text-xs font-semibold uppercase tracking-[0.18em] text-white/80 transition-[background-color,color] hover:bg-white/10 hover:text-white"
247253
aria-haspopup="menu"
248254
aria-expanded={isRepoMenuOpen}
249255
onClick={() => setIsRepoMenuOpen((open) => !open)}
@@ -252,7 +258,7 @@ export default function App() {
252258
<svg
253259
aria-hidden="true"
254260
viewBox="0 0 12 12"
255-
className={`h-3 w-3 transition-transform ${isRepoMenuOpen ? 'rotate-180' : ''}`}
261+
className={`h-3 w-3 transition-transform motion-safe:duration-200 ${isRepoMenuOpen ? 'rotate-180' : ''}`}
256262
fill="none"
257263
role="img"
258264
>
@@ -275,7 +281,7 @@ export default function App() {
275281
href={repo.url}
276282
target="_blank"
277283
rel="noreferrer"
278-
className="block rounded-md px-2.5 py-1.5 text-sm text-foreground/85 transition hover:bg-white/10 hover:text-white"
284+
className="block rounded-md px-2.5 py-1.5 text-sm text-foreground/85 transition-[background-color,color] hover:bg-white/10 hover:text-white"
279285
onClick={() => setIsRepoMenuOpen(false)}
280286
>
281287
{repo.label}
@@ -424,7 +430,7 @@ function StackStatusCard({
424430
{statuses.map((stack) => {
425431
const isActive = stack.id === activeStack;
426432
const baseClasses =
427-
'flex items-center justify-between rounded-lg border border-white/10 bg-white/[0.04] px-3 py-3 transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-400/70 focus-visible:ring-offset-2 focus-visible:ring-offset-black/30';
433+
'flex items-center justify-between rounded-lg border border-white/10 bg-white/[0.04] px-3 py-3 transition-[background-color,border-color] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-400/70 focus-visible:ring-offset-2 focus-visible:ring-offset-black/30';
428434
return (
429435
<button
430436
type="button"
@@ -442,7 +448,7 @@ function StackStatusCard({
442448
{stack.label}
443449
</span>
444450
<span
445-
className={`inline-flex h-3.5 w-3.5 shrink-0 rounded-full ${STACK_STATUS_CLASS[stack.status]}`}
451+
className={`inline-flex h-3.5 w-3.5 shrink-0 rounded-full motion-safe:animate-[glow-pulse_2s_ease-in-out_infinite] ${STACK_STATUS_CLASS[stack.status]}`}
446452
aria-hidden="true"
447453
/>
448454
</button>

website/src/components/timeline.tsx

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export function Timeline({
137137
value={externalSelectedStack}
138138
onValueChange={(value) => onStackChange?.(value)}
139139
>
140-
<SelectTrigger className="w-52">
140+
<SelectTrigger className="w-52" aria-label="Select stack">
141141
<div className="flex flex-1 items-center justify-between gap-2">
142142
<span className="truncate font-medium text-foreground/90">
143143
{selectedStackMeta?.label ?? 'Select stack'}
@@ -152,7 +152,7 @@ export function Timeline({
152152
</Badge>
153153
) : null}
154154
</div>
155-
<SelectValue className="sr-only" placeholder="Select stack" />
155+
<SelectValue className="sr-only" placeholder="Select stack" />
156156
</SelectTrigger>
157157
<SelectContent>
158158
{stacks?.map((stack) => (
@@ -181,7 +181,7 @@ export function Timeline({
181181
</label>
182182
<Select value={selectedSuite} onValueChange={setSelectedSuite}>
183183
<SelectTrigger id="suite-filter" className="w-64">
184-
<SelectValue placeholder="Select suite">
184+
<SelectValue placeholder="Select suite">
185185
{selectedSuite === 'all' ? 'All suites' : selectedSuite}
186186
</SelectValue>
187187
</SelectTrigger>
@@ -214,6 +214,8 @@ export function Timeline({
214214
<img
215215
src={netlifyLogomark}
216216
alt=""
217+
width="14"
218+
height="14"
217219
className="h-3.5 w-3.5 mr-1"
218220
loading="lazy"
219221
/>
@@ -228,7 +230,10 @@ export function Timeline({
228230
) : null}
229231

230232
{filteredEntries.length > 0 ? (
231-
<div className="grid gap-3">
233+
<div
234+
className="grid gap-3"
235+
style={{ contentVisibility: 'auto', containIntrinsicSize: '1000px' }}
236+
>
232237
{filteredEntries.map((entry, index) => {
233238
const commitStyles =
234239
commitStatusStyles[entry.overallStatus] ??
@@ -273,7 +278,7 @@ export function Timeline({
273278
>
274279
<span
275280
className={cn(
276-
'h-3.5 w-3.5 rounded-full',
281+
'h-3.5 w-3.5 rounded-full motion-safe:animate-[glow-pulse_2s_ease-in-out_infinite]',
277282
commitStyles.dotCore,
278283
)}
279284
/>
@@ -295,6 +300,8 @@ export function Timeline({
295300
<img
296301
src={avatarUrl}
297302
alt={entry.author?.name ?? 'Author'}
303+
width="32"
304+
height="32"
298305
className={cn(
299306
'h-8 w-8 flex-none border-2 border-border/40 bg-black/40',
300307
isRenovateBot ? 'rounded-[6px]' : 'rounded-full',
@@ -309,7 +316,7 @@ export function Timeline({
309316
href={commitUrl}
310317
target="_blank"
311318
rel="noreferrer"
312-
className="inline-flex items-center gap-2 text-foreground transition hover:text-foreground/70"
319+
className="inline-flex items-center gap-2 text-foreground transition-[color] hover:text-foreground/70"
313320
>
314321
<span className="truncate">
315322
{entry.commitMessage}
@@ -321,7 +328,7 @@ export function Timeline({
321328
</CardTitle>
322329
<div className="flex flex-wrap items-center gap-2 text-xs font-medium text-muted-foreground">
323330
<a
324-
className="inline-flex items-center gap-1 rounded border border-border/50 bg-black/40 px-2 py-0.5 font-mono tracking-tight text-foreground/85 transition hover:border-border hover:text-foreground"
331+
className="inline-flex items-center gap-1 rounded border border-border/50 bg-black/40 px-2 py-0.5 font-mono tracking-tight text-foreground/85 transition-[border-color,color] hover:border-border hover:text-foreground"
325332
href={commitUrl}
326333
target="_blank"
327334
rel="noreferrer"
@@ -370,7 +377,7 @@ export function Timeline({
370377
</Badge>
371378
<a
372379
href={entry.workflowRunUrl}
373-
className="text-[11px] text-muted-foreground transition hover:text-foreground/90"
380+
className="text-[11px] text-muted-foreground transition-[color] hover:text-foreground/90"
374381
target="_blank"
375382
rel="noreferrer"
376383
>
@@ -400,7 +407,7 @@ export function Timeline({
400407
target="_blank"
401408
rel="noreferrer"
402409
className={cn(
403-
'flex w-full items-center justify-between gap-3 rounded-lg border px-3 py-2 text-xs font-medium transition hover:border-border hover:bg-black/15',
410+
'flex w-full items-center justify-between gap-3 rounded-lg border px-3 py-2 text-xs font-medium transition-[background-color,border-color] hover:border-border hover:bg-black/15',
404411
suiteStyles.container,
405412
)}
406413
>

website/src/components/ui/button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
1111
}
1212

1313
const baseClasses =
14-
'inline-flex items-center justify-center rounded-xl text-sm font-medium transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20 disabled:pointer-events-none disabled:opacity-50';
14+
'inline-flex items-center justify-center rounded-xl text-sm font-medium transition-[background-color,color,box-shadow] motion-safe:duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20 disabled:pointer-events-none disabled:opacity-50';
1515

1616
const variants = {
1717
default: 'bg-foreground text-background hover:bg-foreground/90',

website/src/components/ui/select.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const SelectTrigger = forwardRef<
1818
<SelectPrimitive.Trigger
1919
ref={ref}
2020
className={cn(
21-
'inline-flex h-11 w-full items-center justify-between rounded-xl border border-border/60 bg-transparent px-4 py-2 text-sm text-foreground shadow-sm transition hover:border-border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20 disabled:cursor-not-allowed disabled:opacity-50',
21+
'inline-flex h-11 w-full items-center justify-between rounded-xl border border-border/60 bg-transparent px-4 py-2 text-sm text-foreground shadow-sm transition-[background-color,border-color,color,box-shadow] motion-safe:duration-200 hover:border-border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20 disabled:cursor-not-allowed disabled:opacity-50',
2222
className,
2323
)}
2424
{...props}
@@ -39,7 +39,7 @@ const SelectContent = forwardRef<
3939
<SelectPrimitive.Content
4040
ref={ref}
4141
className={cn(
42-
'z-50 min-w-[14rem] overflow-hidden rounded-2xl border border-border/40 bg-popover/95 shadow-xl backdrop-blur-xl animate-in fade-in-0 zoom-in-95',
42+
'z-50 min-w-[14rem] overflow-hidden rounded-2xl border border-border/40 bg-popover/95 shadow-xl backdrop-blur-xl motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-95',
4343
position === 'popper' && 'translate-y-2',
4444
className,
4545
)}
@@ -73,7 +73,7 @@ const SelectItem = forwardRef<
7373
<SelectPrimitive.Item
7474
ref={ref}
7575
className={cn(
76-
'relative flex w-full cursor-pointer select-none items-center rounded-xl border border-transparent px-3 py-2 text-sm outline-none transition focus:bg-accent/60 focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[state=checked]:border-border data-[state=checked]:bg-accent/80 data-[state=checked]:text-foreground',
76+
'relative flex w-full cursor-pointer select-none items-center rounded-xl border border-transparent px-3 py-2 text-sm outline-none transition-[background-color,color,border-color] motion-safe:duration-200 focus:bg-accent/60 focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[state=checked]:border-border data-[state=checked]:bg-accent/80 data-[state=checked]:text-foreground',
7777
className,
7878
)}
7979
{...props}

website/src/index.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@ body {
1313
background: #000;
1414
font-family: "JetBrains Mono", "Geist Mono", "SF Mono", "Consolas", monospace;
1515
color: #f5f5f5;
16+
touch-action: manipulation;
17+
}
18+
19+
@media (prefers-reduced-motion: reduce) {
20+
*,
21+
::before,
22+
::after {
23+
animation-duration: 0.01ms !important;
24+
animation-iteration-count: 1 !important;
25+
transition-duration: 0.01ms !important;
26+
scroll-behavior: auto !important;
27+
}
1628
}
1729

1830
.glass-panel {

0 commit comments

Comments
 (0)