Skip to content

NavigationRibbon

Component for displaying a navigation ribbon

Code

"use client"

import { CaretDown } from "@phosphor-icons/react"
import * as NavigationMenu from "@radix-ui/react-navigation-menu"
import type { ForwardedRef, ReactNode } from "react"
import { forwardRef } from "react"
import { classNames } from "../../helpers"

const ListItem = forwardRef(
	(
		{
			children,
			hyperlink,
			title,
			...rest
		}: {
			children: ReactNode
			hyperlink: string
			title: string
		},
		forwardedRef: ForwardedRef<HTMLAnchorElement>,
	) => (
		<li>
			<NavigationMenu.Link asChild>
				<a
					className={"block select-none space-y-2 rounded-md p-8 leading-none no-underline outline-none transition-colors cursor-pointer hover:bg-white"}
					ref={forwardedRef}
					{...rest}
					href={hyperlink}
				>
					<span className="block font-bold">{title}</span>
					<span className="block">{children}</span>
				</a>
			</NavigationMenu.Link>
		</li>
	),
)

const ListItemContent = () => (
	<ul className="grid gap-4 py-8 grid-cols-4">
		<ListItem hyperlink="/primitives/docs/overview/introduction" title="Introduction">
			Build high-quality, accessible design systems and web apps.
		</ListItem>
		<ListItem hyperlink="/primitives/docs/overview/getting-started" title="Getting started">
			A quick tutorial to get you up and running with Radix Primitives.
		</ListItem>
		<ListItem hyperlink="/primitives/docs/guides/styling" title="Styling">
			Unstyled and compatible with any styling solution.
		</ListItem>
		<ListItem hyperlink="/primitives/docs/guides/animation" title="Animation">
			Use CSS keyframes or any animation library of your choice.
		</ListItem>
		<ListItem hyperlink="/primitives/docs/overview/accessibility" title="Accessibility">
			Tested in a range of browsers and assistive technologies.
		</ListItem>
		<ListItem hyperlink="/primitives/docs/overview/releases" title="Releases">
			Radix Primitives releases and their changelogs.
		</ListItem>
	</ul>
)

const ListItemTrigger = ({ title }: { title: string }) => {
	return (
		<NavigationMenu.Trigger className="flex items-center justify-start space-x-2 outline-none group">
			<span>{title}</span>
			<CaretDown aria-hidden className="group-data-[state=open]:rotate-180 transition-all duration-300" size={26} />
		</NavigationMenu.Trigger>
	)
}

const NavigationRibbon = ({ className }: { className?: string }) => {
	return (
		<NavigationMenu.Root className={classNames("relative", className)}>
			<NavigationMenu.List className="container flex justify-start items-center py-6 list-none gap-6 overflow-x-auto">
				<NavigationMenu.Item>
					<ListItemTrigger title={"Producten"} />
					<NavigationMenu.Content className="w-full duration-300 ease-in">
						<ul className="grid gap-4 py-8 grid-cols-3">
							<li className="row-span-2">
								<NavigationMenu.Link asChild>
									<a className="flex h-full w-full select-none flex-col justify-end rounded-md p-6 no-underline outline-none bg-black text-white" href="/">
										<div className="mb-4 text-lg">Core</div>
										<p className="text-md leading-tight">Beautifully designed components built with Radix UI and Tailwind CSS.</p>
									</a>
								</NavigationMenu.Link>
							</li>
							<ListItem hyperlink="/docs" title="Introduction">
								Re-usable components built using Radix UI and Tailwind CSS.
							</ListItem>
							<ListItem hyperlink="/docs/installation" title="Installation">
								How to install dependencies and structure your app.
							</ListItem>
							<ListItem hyperlink="/docs/primitives/typography" title="Typography">
								Styles for headings, paragraphs, lists...etc
							</ListItem>
						</ul>
					</NavigationMenu.Content>
				</NavigationMenu.Item>
				<NavigationMenu.Item>
					<ListItemTrigger title={"Ruimten"} />
					<NavigationMenu.Content className="w-full duration-300 ease-in">
						<ListItemContent />
					</NavigationMenu.Content>
				</NavigationMenu.Item>
				<NavigationMenu.Item>
					<ListItemTrigger title={"Inspiratie"} />
					<NavigationMenu.Content className="w-full duration-300 ease-in">
						<ListItemContent />
					</NavigationMenu.Content>
				</NavigationMenu.Item>
				<NavigationMenu.Item>
					<ListItemTrigger title={"Nieuw"} />
					<NavigationMenu.Content className="w-full duration-300 ease-in">
						<ListItemContent />
					</NavigationMenu.Content>
				</NavigationMenu.Item>
				<NavigationMenu.Item>
					<ListItemTrigger title={"Outlet"} />
					<NavigationMenu.Content className="w-full duration-300 ease-in">
						<ListItemContent />
					</NavigationMenu.Content>
				</NavigationMenu.Item>
				<NavigationMenu.Indicator className="">
					<div className="" />
				</NavigationMenu.Indicator>
			</NavigationMenu.List>
			<div className="w-full bg-[#FFEB35]">
				<div className="w-full bg-gray-800/5">
					<NavigationMenu.Viewport className="container rounded origin-top" />
				</div>
			</div>
		</NavigationMenu.Root>
	)
}

export default NavigationRibbon