mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
## Problem The Snowflake destination still uses a neutral text monogram even though its Studio asset is available. Supporting that monogram also leaves a separate rendering path used by no other destination. ## Solution Restore Snowflake through the shared brand-icon registry introduced by #51073. Simplify `DestinationLogo` back to a map of destination marks, removing the monogram type, configuration, and rendering branch. | After | | --- | | <img width="924" height="730" alt="CleanShot 2026-09-30 at 15 14 59@2x" src="https://github.com/user-attachments/assets/7409d483-3371-45ec-bf54-0ddc6ad22857" /> | ## Review instructions 1. Open `/project/<ref>/database/replication` with a Snowflake pipeline. 2. Confirm the Snowflake mark appears in the pipeline list and diagram. 3. Open the pipeline child route and confirm the same mark appears in its header. 4. Confirm the other destination marks remain unchanged in light and dark themes. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Visual Updates** * Snowflake replication destinations now display a themed brand icon instead of the “SF” monogram. Other destinations retain their existing icons. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
65 lines
2.2 KiB
TypeScript
65 lines
2.2 KiB
TypeScript
import { useTheme } from 'next-themes'
|
|
import { cn, StatusIcon } from 'ui'
|
|
|
|
import { DestinationIcon } from './DestinationIcon'
|
|
import type { DestinationType } from './DestinationPanel/DestinationPanel.types'
|
|
import { BRAND_ICONS, resolveThemedIconSrc, type ThemedIconSrc } from '@/lib/brand-icons'
|
|
import { resolveThemeOverrideMode } from '@/lib/theme-overrides'
|
|
|
|
const BRAND_MARK_BY_TYPE: Partial<Record<DestinationType, ThemedIconSrc>> = {
|
|
BigQuery: BRAND_ICONS.bigquery,
|
|
ClickHouse: BRAND_ICONS.clickhouse,
|
|
DuckLake: BRAND_ICONS.ducklake,
|
|
Snowflake: BRAND_ICONS.snowflake,
|
|
}
|
|
|
|
const SIZE_CLASS_NAME = {
|
|
small: { frame: 'h-8 w-8 rounded-md', mark: 'h-4 w-4', icon: 16 },
|
|
large: { frame: 'h-14 w-14 rounded-lg', mark: 'h-8 w-8', icon: 32 },
|
|
} as const
|
|
|
|
interface DestinationLogoProps {
|
|
type: DestinationType
|
|
size?: keyof typeof SIZE_CLASS_NAME
|
|
className?: string
|
|
/** Destructive badge on the bottom-right corner (e.g. table replication errors). */
|
|
hasErrors?: boolean
|
|
}
|
|
|
|
/**
|
|
* A destination's brand mark in a square app-icon frame, used wherever a destination is the
|
|
* subject: the list rows, the pipeline header, and the replication diagram.
|
|
*/
|
|
export const DestinationLogo = ({
|
|
type,
|
|
size = 'small',
|
|
className,
|
|
hasErrors = false,
|
|
}: DestinationLogoProps) => {
|
|
const { resolvedTheme } = useTheme()
|
|
const isDark = resolveThemeOverrideMode(resolvedTheme) === 'dark'
|
|
const sizing = SIZE_CLASS_NAME[size]
|
|
const brandMark = BRAND_MARK_BY_TYPE[type]
|
|
const brandMarkSrc = brandMark === undefined ? undefined : resolveThemedIconSrc(brandMark, isDark)
|
|
|
|
return (
|
|
<span className={cn('relative inline-flex shrink-0', className)}>
|
|
<span className={cn('flex items-center justify-center border bg-surface-100', sizing.frame)}>
|
|
{brandMarkSrc === undefined ? (
|
|
<DestinationIcon type={type} size={sizing.icon} className="text-foreground-light" />
|
|
) : (
|
|
<img src={brandMarkSrc} alt="" aria-hidden className={sizing.mark} />
|
|
)}
|
|
</span>
|
|
{hasErrors && (
|
|
<span
|
|
className="absolute -bottom-1 -right-1 rounded-sm bg-background outline outline-2 outline-background"
|
|
aria-hidden
|
|
>
|
|
<StatusIcon variant="destructive" />
|
|
</span>
|
|
)}
|
|
</span>
|
|
)
|
|
}
|