mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs UI refactor. ## What is the current behavior? Framework quickstarts and several other homepage grids used `IconPanel` / `IconPanelWithIconPicker`, which brought redundant tooltips (duplicating the visible title), inconsistent hover treatment, and circular icon tiles that didn't match the intended squarish look. | Before | | --- | | <img width="1744" height="626" alt="CleanShot 2026-07-24 at 14 29 44@2x" src="https://github.com/user-attachments/assets/1e145be2-19c9-4bd0-bf06-17516acbc774" /> | ## What is the new behavior? Introduces a shared `IconLink` used across the docs homepage (and reference index) so icon+label tiles share the same composition and hover: icon tile fill matches the surrounding surface (`surface-100`), with a stronger border on hover, and the row uses `hover:bg-accent`. Framework quickstarts keep the larger tile size; other sections keep the smaller size. Also aligns Explore more GlassPanels with Build your backend by using the same bordered background treatment. | After | | --- | | <img width="2478" height="906" alt="CleanShot 2026-07-24 at 15 09 48@2x" src="https://github.com/user-attachments/assets/dd516845-c162-47e4-8b86-9a7fa0e73290" /> | ## Additional context Removes the unused `IconPanelWithIconPicker` wrapper now that homepage/reference consumers go through `IconLink`. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added reusable `IconLink` UI for consistent docs tiles, including `IconLinkList`, menu icon, and light/dark icon rendering. * Introduced `FrameworkQuickstarts` to generate quickstart links based on feature-flag-enabled SDKs. * **UI / Improvements** * Updated the docs home and API reference pages to use the new list-based icon-link layout. * Refreshed migration guides and “Explore more”/self-hosting sections (including accessibility and updated CTA text). * **Bug Fixes** * Migration guide items now omit entries missing required details. * **Chores / Cleanup** * Removed the older icon panel picker-based UI component and its usage. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
112 lines
2.4 KiB
TypeScript
112 lines
2.4 KiB
TypeScript
import MenuIconPicker from '~/components/Navigation/NavigationMenu/MenuIconPicker'
|
|
import Link from 'next/link'
|
|
import { type ReactNode } from 'react'
|
|
import { cn } from 'ui'
|
|
|
|
const sizeStyles = {
|
|
sm: {
|
|
tile: 'h-10 w-10',
|
|
image: 'w-5',
|
|
},
|
|
lg: {
|
|
tile: 'h-10 w-10 sm:h-16 sm:w-16',
|
|
image: 'w-5 sm:w-8',
|
|
},
|
|
} as const
|
|
|
|
export type IconLinkSize = keyof typeof sizeStyles
|
|
|
|
export type IconLinkItem = {
|
|
title: string
|
|
href: string
|
|
icon: ReactNode
|
|
className?: string
|
|
}
|
|
|
|
export function IconLink({
|
|
href,
|
|
title,
|
|
icon,
|
|
size = 'sm',
|
|
className,
|
|
}: {
|
|
href: string
|
|
title: string
|
|
icon: ReactNode
|
|
size?: IconLinkSize
|
|
className?: string
|
|
}) {
|
|
return (
|
|
<Link
|
|
href={href}
|
|
className={cn(
|
|
'group relative -m-3 flex items-center gap-3 rounded-xl p-3 no-underline transition-colors hover:bg-accent',
|
|
className
|
|
)}
|
|
>
|
|
<div
|
|
className={cn(
|
|
'flex shrink-0 items-center justify-center overflow-hidden rounded-lg border bg-surface-100 transition-colors group-hover:border-strong',
|
|
sizeStyles[size].tile
|
|
)}
|
|
>
|
|
{icon}
|
|
</div>
|
|
<span className="text-base text-foreground">{title}</span>
|
|
</Link>
|
|
)
|
|
}
|
|
|
|
export function IconLinkList({
|
|
items,
|
|
labelledBy,
|
|
className,
|
|
itemClassName = 'col-span-6 md:col-span-4',
|
|
size = 'sm',
|
|
}: {
|
|
items: IconLinkItem[]
|
|
labelledBy?: string
|
|
className?: string
|
|
itemClassName?: string
|
|
size?: IconLinkSize
|
|
}) {
|
|
return (
|
|
<ul className={cn('grid grid-cols-12 gap-6', className)} aria-labelledby={labelledBy}>
|
|
{items.map((item) => (
|
|
<li key={item.href} className={cn(itemClassName, item.className)}>
|
|
<IconLink href={item.href} title={item.title} icon={item.icon} size={size} />
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)
|
|
}
|
|
|
|
export function IconLinkImage({
|
|
path,
|
|
hasLightIcon,
|
|
size = 'sm',
|
|
}: {
|
|
path: string
|
|
hasLightIcon?: boolean
|
|
size?: IconLinkSize
|
|
}) {
|
|
const imgClassName = sizeStyles[size].image
|
|
|
|
return (
|
|
<>
|
|
{hasLightIcon ? (
|
|
<img src={`${path}-light.svg`} alt="" className={cn(imgClassName, 'dark:hidden')} />
|
|
) : null}
|
|
<img
|
|
src={`${path}.svg`}
|
|
alt=""
|
|
className={cn(imgClassName, hasLightIcon && 'hidden dark:block')}
|
|
/>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export function IconLinkMenuIcon({ icon }: { icon: string }) {
|
|
return <MenuIconPicker icon={icon} width={18} height={18} />
|
|
}
|