From d859176eac24744207fc56f6e7df2d94f9f2dffd Mon Sep 17 00:00:00 2001 From: Jordi Enric <37541088+jordienr@users.noreply.github.com> Date: Wed, 6 May 2026 14:43:07 +0200 Subject: [PATCH] fix(studio): restore readable warning banner and toast close button after Tailwind v4 (#45585) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem Two visual regressions surfaced after the Tailwind v4 migration (#45318): 1. The Postgres upgrade-failed banner used the deprecated `Alert` component, whose `warning` variant relies on custom `amber-1100` / `amber-1200` color tokens that no longer resolve. The title rendered as near-white on the yellow background. 2. The sonner toast close button forced `bg-transparent! hover:bg-transparent!`, letting the library's default translucent circle bleed through against the toast's overlay background on hover. ## Fix - Migrate `ProjectUpgradeFailedBanner` to `Admonition` (the recommended replacement per the deprecation note on `Alert`), which uses semantic `warning-*` tokens defined in the theme. - Drop the transparent-bg overrides on the sonner close button and give it a proper `hover:bg-surface-200` with a fixed `size-6` hit area so the X has a clean hover target. ## Before image ## After CleanShot 2026-05-06 at 11 14 03@2x ## Testing - [ ] Trigger a failed Postgres upgrade state and confirm the banner title/description/actions are all readable on the amber background. - [ ] Fire a toast and hover the close button — the hover should show a subtle square background, not a translucent circle. ## Summary by CodeRabbit * **Bug Fix** * Project upgrade failure banner now only appears when an upgrade has failed and no longer supports dismissing. * **Style** * Replaced the warning banner UI with a streamlined admonition that shows only a “Contact support” action. * Improved toast close-button styling for clearer sizing, color, and interaction states. --- .../ui/ProjectUpgradeFailedBanner.tsx | 58 ++++++------------- .../ui/src/components/shadcn/ui/sonner.tsx | 6 +- 2 files changed, 21 insertions(+), 43 deletions(-) diff --git a/apps/studio/components/ui/ProjectUpgradeFailedBanner.tsx b/apps/studio/components/ui/ProjectUpgradeFailedBanner.tsx index 1306de25e53..af78b93ba15 100644 --- a/apps/studio/components/ui/ProjectUpgradeFailedBanner.tsx +++ b/apps/studio/components/ui/ProjectUpgradeFailedBanner.tsx @@ -2,9 +2,8 @@ import { SupportCategories } from '@supabase/shared-types/out/constants' import { DatabaseUpgradeStatus } from '@supabase/shared-types/out/events' import { useParams } from 'common' import dayjs from 'dayjs' -import { X } from 'lucide-react' -import { useEffect, useState } from 'react' -import { Alert, Button } from 'ui' +import { Button } from 'ui' +import { Admonition } from 'ui-patterns' import { InlineLink } from './InlineLink' import { SupportLink } from '@/components/interfaces/Support/SupportLink' @@ -19,13 +18,6 @@ export const ProjectUpgradeFailedBanner = () => { const { data } = useProjectUpgradingStatusQuery({ projectRef: ref }, { enabled: IS_PLATFORM }) const { status, initiated_at, latest_status_at, error } = data?.databaseUpgradeStatus ?? {} - const key = `supabase-upgrade-${ref}-${initiated_at}` - - const [hasDismissed, setHasDismissed] = useState(false) - useEffect(() => { - setHasDismissed(localStorage?.getItem(key) === 'true') - }, [key]) - const isFailed = status === DatabaseUpgradeStatus.Failed const initiatedAt = dayjs .utc(initiated_at ?? 0) @@ -46,40 +38,26 @@ export const ProjectUpgradeFailedBanner = () => { ) const timestampFilter = `its=${initiatedAtEncoded}&ite=${latestStatusAtEncoded}` - const acknowledgeMessage = () => { - setHasDismissed(true) - localStorage.setItem(key, 'true') - } - - if (!isFailed || hasDismissed) return null + if (!isFailed) return null return (
- - -
+ } >
@@ -93,7 +71,7 @@ export const ProjectUpgradeFailedBanner = () => { .
- + ) } diff --git a/packages/ui/src/components/shadcn/ui/sonner.tsx b/packages/ui/src/components/shadcn/ui/sonner.tsx index 49a91b3065a..87d43b6fee1 100644 --- a/packages/ui/src/components/shadcn/ui/sonner.tsx +++ b/packages/ui/src/components/shadcn/ui/sonner.tsx @@ -53,11 +53,11 @@ const SonnerToaster = ({ toastOptions, ...props }: ToasterProps) => { 'group toast group-[.toaster]:!bg-destructive-200 group-[.toaster]:!border-destructive-500', closeButton: cn( // unset all styles set from sonner - 'absolute right-2 top-2 rounded-md text-foreground/50 opacity-0 transition-opacity', - 'hover:text-foreground focus:opacity-100 focus:outline-hidden focus:ring-2 group-hover:opacity-100', + 'absolute right-2 top-2 size-6 flex items-center justify-center rounded-md text-foreground-light opacity-0 transition', + 'hover:text-foreground hover:bg-surface-200 focus:opacity-100 focus:outline-hidden focus:ring-2 group-hover:opacity-100', 'group-[.destructive]:text-destructive-300 group-[.destructive]:hover:text-destructive-50', 'group-[.destructive]:focus:ring-destructive-400 group-[.destructive]:focus:ring-offset-destructive-600', - 'left-auto transform-none bg-transparent border-0 border-transparent hover:bg-transparent! hover:border-transparent' + 'left-auto transform-none border-0 border-transparent' ), content: 'grow', //group-[.toaster]:bg-overlay group-[.toaster]:text-foreground group-[.toaster]:border group-[.toaster]:border-overlay