Files
supabase/apps/www/components/PrevNextFeatureNav.tsx
Ivan Vasilov 56de26fe22 chore: Migrate the monorepo to use Tailwind v4 (#45318)
This PR migrates the whole monorepo to use Tailwind v4:
- Removed `@tailwindcss/container-queries` plugin since it's included by
default in v4,
- Bump all instances of Tailwind to v4. Made minimal changes to the
shared config to remove non-supported features (`alpha` mentions),
- Migrate all apps to be compatible with v4 configs,
- Fix the `typography.css` import in 3 apps,
- Add missing rules which were included by default in v3,
- Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot
of classes
- Rename all misnamed classes according to
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all
apps.

---------

Co-authored-by: Jordi Enric <jordi.err@gmail.com>
2026-04-30 10:53:24 +00:00

132 lines
4.2 KiB
TypeScript

import { features, type FeatureType } from '~/data/features'
import { ArrowLeft, ArrowRight, List } from 'lucide-react'
import Link, { LinkProps } from 'next/link'
import { useRouter } from 'next/router'
import { PropsWithChildren, useEffect, useState } from 'react'
import {
cn,
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from 'ui'
interface Props {
className?: string
wrapperClassName?: string
currentFeature: FeatureType
prevLink: string
nextLink: string
}
const buttonClassName =
'relative z-10 flex items-center gap-1 px-2 pointer-events-auto overflow-hidden h-[30px]! min-w-[30px]! max-w-[30px]! py-1 justify-center rounded-full border bg-default hover:bg-surface-100 hover:text-foreground hover:border-foreground-lighter transition-all'
const iconClassName = 'className="w-4 h-4 shrink-0'
const PrevNextFeatureNav: React.FC<Props> = ({
className,
wrapperClassName,
currentFeature,
prevLink,
nextLink,
...props
}) => {
const [open, setOpen] = useState(false)
const router = useRouter()
useEffect(() => {
function handleRouteChange() {
setOpen(false)
}
router.events.on('routeChangeComplete', handleRouteChange)
return () => {
router.events.off('routeChangeComplete', handleRouteChange)
}
}, [router.events])
return (
<div
className={cn(
'h-full w-full max-w-2xl absolute mx-auto inset-0 pointer-events-none',
wrapperClassName
)}
{...props}
>
<div
className={cn(
'absolute top-9 w-fit pointer-events-auto flex items-center text-sm gap-1 text-foreground-light right-8 md:right-0',
className
)}
>
<ButtonLink href={prevLink} className="text-right pl-2">
<ArrowLeft className={iconClassName} />
<span className="sr-only">Previous feature</span>
</ButtonLink>
<DropdownMenu open={open} onOpenChange={setOpen}>
<DropdownMenuTrigger className={cn(buttonClassName, 'p-0')}>
<List className={iconClassName} />
</DropdownMenuTrigger>
<DropdownMenuContent align="end" alignOffset={-38} className="pb-0">
<DropdownMenuItem asChild className="text-foreground-lighter p-0">
<Link
href="/features"
as="/features"
className="group/link flex items-center gap-2 px-2 py-1.5 w-full hover:text-foreground"
>
<span className="truncate grow">All Features</span>
</Link>
</DropdownMenuItem>
<DropdownMenuSeparator className="mb-0" />
<DropdownMenuGroup className="max-h-[400px] overflow-y-scroll py-1">
{features
.sort((a, b) => {
if (a['title'] < b['title']) return -1
if (a['title'] > b['title']) return 1
return 0
})
.map((feature) => (
<DropdownMenuItem asChild key={feature.slug} className="p-0">
<Link
href={`/features/${feature.slug}`}
as={`/features/${feature.slug}`}
className="group/link flex items-center gap-2 px-2 py-1.5 w-full hover:text-foreground"
>
<feature.icon className="w-3 h-3 text-foreground-lighter group-hover:text-foreground transition-colors" />
<span className="line-clamp-1 grow">{feature.title}</span>
</Link>
</DropdownMenuItem>
))}
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
<ButtonLink href={nextLink}>
<span className="sr-only">Next feature</span>
<ArrowRight className={iconClassName} />
</ButtonLink>
</div>
</div>
)
}
interface ButtonLinkProps extends LinkProps {
className?: string
}
const ButtonLink: React.FC<PropsWithChildren<ButtonLinkProps>> = ({
href,
className,
children,
}) => {
return (
<Link href={href} className={cn(buttonClassName, className)}>
{children}
</Link>
)
}
export default PrevNextFeatureNav