From 8fe8c2d6c476d50d4aaed13a924329fabd57a190 Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Tue, 30 Jun 2026 14:46:28 -0500 Subject: [PATCH] style(desktop): bring the install & update overlays onto the design system Align the first-launch install overlay and the in-app update overlay to apps/desktop/DESIGN.md, reusing in-bundle primitives only (no new deps): - install overlay: Loader2 spinners -> Loader (fourier-flow); emerald check / AlertTriangle -> neutral Codicon check + canonical ErrorIcon; de-boxed the failure block; hairline (--stroke-nous) command/code chips; --ui-* tokens; BrandMark header; flat stage rows (only the active step opaque). - update overlay: drop the redundant DialogContent border (base Dialog already supplies shadow-nous + --stroke-nous); de-box the changelog; hairline + primary-flash manual command block; on-brand BrandMark for "all set". --- apps/desktop/src/app/updates-overlay.tsx | 38 +++---- .../components/desktop-install-overlay.tsx | 100 +++++++++--------- apps/desktop/src/components/ui/loader.tsx | 6 +- 3 files changed, 68 insertions(+), 76 deletions(-) diff --git a/apps/desktop/src/app/updates-overlay.tsx b/apps/desktop/src/app/updates-overlay.tsx index 1ed9e327f66..19e649705da 100644 --- a/apps/desktop/src/app/updates-overlay.tsx +++ b/apps/desktop/src/app/updates-overlay.tsx @@ -10,7 +10,7 @@ import { Loader } from '@/components/ui/loader' import type { DesktopUpdateCommit, DesktopUpdateStage, DesktopUpdateStatus } from '@/global' import { useI18n } from '@/i18n' import { buildCommitChangelog, type CommitGroup } from '@/lib/commit-changelog' -import { AlertCircle, Check, CheckCircle2, Copy, Terminal } from '@/lib/icons' +import { AlertCircle, Check, Copy, Terminal } from '@/lib/icons' import { resolveUpdateCopy, type UpdateTarget } from '@/lib/update-copy' import { cn } from '@/lib/utils' import { @@ -94,10 +94,7 @@ export function UpdatesOverlay() { return ( - + {phase === 'applying' && } {phase === 'manual' && ( @@ -204,7 +201,7 @@ function IdleView({ return ( } + icon={} title={u.allSetTitle} /> ) @@ -229,7 +226,7 @@ function IdleView({ {body} -
+
{groups.map(group => (

{group.label}

@@ -304,26 +301,25 @@ function ManualView({ command, message, onDone }: { command: string | null; mess
diff --git a/apps/desktop/src/components/desktop-install-overlay.tsx b/apps/desktop/src/components/desktop-install-overlay.tsx index e11ae6de0e3..c06c9f13441 100644 --- a/apps/desktop/src/components/desktop-install-overlay.tsx +++ b/apps/desktop/src/components/desktop-install-overlay.tsx @@ -1,6 +1,9 @@ import { useEffect, useMemo, useRef, useState } from 'react' +import { BrandMark } from '@/components/brand-mark' import { Button } from '@/components/ui/button' +import { Codicon } from '@/components/ui/codicon' +import { ErrorIcon } from '@/components/ui/error-state' import { Loader } from '@/components/ui/loader' import { LogView } from '@/components/ui/log-view' import type { @@ -11,7 +14,7 @@ import type { DesktopBootstrapState } from '@/global' import { useI18n } from '@/i18n' -import { AlertTriangle, Check, ChevronDown, ChevronRight, iconSize, Loader2 } from '@/lib/icons' +import { ChevronDown, ChevronRight, iconSize } from '@/lib/icons' import { cn } from '@/lib/utils' /** @@ -48,7 +51,6 @@ interface DesktopInstallOverlayProps { interface StageRowProps { descriptor: DesktopBootstrapStageDescriptor result: DesktopBootstrapStageResult | undefined - isCurrent: boolean now: number } @@ -98,7 +100,7 @@ function formatElapsed(ms: number): string { return `${m}:${String(s - m * 60).padStart(2, '0')}` } -function StageRow({ descriptor, result, isCurrent, now }: StageRowProps) { +function StageRow({ descriptor, result, now }: StageRowProps) { const { t } = useI18n() const copy = t.install const state: DesktopBootstrapStageState = result?.state || 'pending' @@ -109,52 +111,48 @@ function StageRow({ descriptor, result, isCurrent, now }: StageRowProps) { const icon = useMemo(() => { switch (state) { case 'running': - return + return case 'succeeded': - return case 'skipped': - return + return case 'failed': - return + return case 'pending': default: - return
+ return
} }, [state]) const reason = result?.json?.reason || result?.error || null return ( -
  • + {state === 'running' && ( +
    {icon}
    )} - > -
    {icon}
    -
    - +
    + {formatStageName(descriptor.name)} - - {state === 'running' - ? elapsed - ? `${copy.stageStates[state]} · ${elapsed}` - : copy.stageStates[state] - : null} - {state === 'succeeded' || state === 'skipped' ? formatDuration(result?.durationMs) : null} - {state === 'failed' ? copy.stageStates[state] : null} - + {state !== 'running' && {icon}}
    {reason && state !== 'pending' &&

    {reason}

    }
    + + {state === 'running' + ? elapsed + ? `${copy.stageStates[state]} · ${elapsed}` + : copy.stageStates[state] + : null} + {state === 'succeeded' || state === 'skipped' ? formatDuration(result?.durationMs) : null} + {state === 'failed' ? copy.stageStates[state] : null} +
  • ) } @@ -245,6 +243,7 @@ function applyEvent(state: DesktopBootstrapState, ev: DesktopBootstrapEvent): De export function DesktopInstallOverlay({ enabled = true }: DesktopInstallOverlayProps) { const { t } = useI18n() const copy = t.install + const [state, setState] = useState(EMPTY_STATE) const [logOpen, setLogOpen] = useState(false) const [copied, setCopied] = useState(false) @@ -353,12 +352,12 @@ export function DesktopInstallOverlay({ enabled = true }: DesktopInstallOverlayP return (
    -

    {copy.oneTimeTitle}

    +

    {copy.oneTimeTitle}

    {copy.unsupportedDesc(platformLabel)}

    {copy.installCommand}
    -
    +            
                   {ups.installCommand}
                 
    @@ -383,9 +382,9 @@ export function DesktopInstallOverlay({ enabled = true }: DesktopInstallOverlayP
    -
    +
    - {copy.installTo} {ups.activeRoot} + {copy.installTo} {ups.activeRoot}
    @@ -540,7 +536,7 @@ export function DesktopInstallOverlay({ enabled = true }: DesktopInstallOverlayP
    {copy.transcriptSaved}{' '} - %LOCALAPPDATA%\hermes\logs\ + %LOCALAPPDATA%\hermes\logs\