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
## After
## 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 (