From 6007b3ce4f0f85628de8a3bf4c8a37b7aa6eaafa Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Mon, 28 Sep 2026 11:35:24 -0500 Subject: [PATCH] refactor(desktop): export DialogCloseButton for the boot-failure overlay The overlay carried a byte-for-byte copy of DialogContent's close button. --- .../src/components/boot-failure-overlay.tsx | 36 ++--------------- apps/desktop/src/components/ui/dialog.tsx | 40 +++++++++++-------- 2 files changed, 28 insertions(+), 48 deletions(-) diff --git a/apps/desktop/src/components/boot-failure-overlay.tsx b/apps/desktop/src/components/boot-failure-overlay.tsx index 673c914a90..eb04ba27fb 100644 --- a/apps/desktop/src/components/boot-failure-overlay.tsx +++ b/apps/desktop/src/components/boot-failure-overlay.tsx @@ -3,6 +3,7 @@ import { Dialog as DialogPrimitive } from 'radix-ui' import { type ComponentProps, lazy, type ReactNode, Suspense, useEffect, useState } from 'react' import { Button } from '@/components/ui/button' +import { DialogCloseButton } from '@/components/ui/dialog' import { DialogPortalContainerContext } from '@/components/ui/dialog-portal-context' import { ErrorIcon } from '@/components/ui/error-state' import { Loader } from '@/components/ui/loader' @@ -12,17 +13,7 @@ import { useI18n } from '@/i18n' import { reestablishCloudAgentSession } from '@/lib/cloud-agent-session' import { DESKTOP_DOCS_URL } from '@/lib/docs' import { openExternalLink } from '@/lib/external-link' -import { - ChevronLeft, - ExternalLink, - FileText, - Loader2, - LogIn, - RefreshCw, - SlidersHorizontal, - Wrench, - X -} from '@/lib/icons' +import { ChevronLeft, ExternalLink, FileText, Loader2, LogIn, RefreshCw, SlidersHorizontal, Wrench } from '@/lib/icons' import { $desktopBoot } from '@/store/boot' import { notify, notifyError } from '@/store/notifications' import { $desktopOnboarding } from '@/store/onboarding' @@ -54,25 +45,6 @@ type RecoveryView = 'connect' | 'recovery' // re-establish the remote session. The detection + copy helpers live in // ./boot-failure-reauth so they're unit-testable without a React render. -// Radix Close routes through the modal's onOpenChange, same path as Escape. -function DismissControl() { - const { t } = useI18n() - - return ( - - - - ) -} - // Recovery surface for a hard boot failure (gateway never came up, backend // exited during startup, bootstrap latched, …). Without this the app shell // renders dead — "gateway offline", no composer, only a toast — with no way @@ -504,7 +476,7 @@ export function BootFailureOverlay() { return (
- + {/* Subtle back affordance (projects/overlay idiom): muted → foreground on hover, no divider. */} + + ) +} + function DialogContent({ className, bodyClassName, @@ -105,8 +126,6 @@ function DialogContent({ banner?: React.ReactNode bannerTone?: DialogBannerTone }) { - const { t } = useI18n() - const widthClass = fitContent ? 'w-auto max-w-[92vw]' : 'w-full max-w-lg' // Publish the dialog's content node so popovers (Select / Popover / @@ -133,20 +152,8 @@ function DialogContent({ // an input) is what most dialogs want. Dialogs with no input should pass // `onOpenAutoFocus={preventCloseButtonAutoFocus}` explicitly instead. - // No tip on the X — the glyph is the label. Keep aria-label / sr-only for a11y. - const closeButton = showCloseButton ? ( - - - - ) : null + // No tip on the X — the glyph is the label (DialogCloseButton keeps aria-label / sr-only). + const closeButton = showCloseButton ? : null // With a banner, the border can't live on the scroll/clip box (it would draw a // line around the banner too). The white body keeps its own bottom radius and @@ -314,6 +321,7 @@ function DialogDescription({ className, ...props }: React.ComponentProps