Skip to content

Commit

Permalink
feat:navigation bar
Browse files Browse the repository at this point in the history
  • Loading branch information
heydoyouknowme0 committed Sep 27, 2024
1 parent ebc4068 commit ab9d27f
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 26 deletions.
84 changes: 62 additions & 22 deletions app/[locale]/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import MaybeLink from '~/components/maybe-link';
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuCustomListItem,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from '~/components/ui';
import { getTranslations } from '~/i18n/translations';
import { cn } from '~/lib/utils';
Expand All @@ -37,7 +39,45 @@ export default async function Header({ locale }: { locale: string }) {
{ label: text.alumni, href: 'alumni' },
{ label: text.activities, href: 'student-activities' },
];

const components: { title: string; href: string; description: string }[] = [
{
title: 'Alert Dialog',
href: '/docs/primitives/alert-dialog',
description:
'A modal dialog that interrupts the user with important content and expects a response.',
},
{
title: 'Hover Card',
href: '/docs/primitives/hover-card',
description:
'For sighted users to preview content available behind a link.',
},
{
title: 'Progress',
href: '/docs/primitives/progress',
description:
'Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.',
},
{
title: 'Scroll-area',
href: '/docs/primitives/scroll-area',
description: 'Visually or semantically separates content.',
},
{
title: 'Tabs',
href: '/docs/primitives/tabs',
description:
'A set of layered sections of content—known as tab panels—that are displayed one at a time.',
},
{
title: 'Tooltip',
href: '/docs/primitives/tooltip',
description:
'A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.',
},
];
const itemss = 3;
const componentsCount = itemss >= 4 ? 4 : itemss;
return (
<header className="header-sticky-ness sticky top-0 z-nav min-w-full bg-background">
<nav
Expand All @@ -56,28 +96,28 @@ export default async function Header({ locale }: { locale: string }) {
src="assets/nitlogo.png"
/>
</Link>

<ol className={cn('hidden grow lg:flex', 'gap-4 xl:gap-5 2xl:gap-6')}>
{items.map(({ label, href }, index) => (
<li className="my-auto min-h-fit" key={index}>
<Link href={`/${locale}/${href}`} prefetch>
{label}
<NavigationMenu>
<NavigationMenuList
className={cn('hidden grow lg:flex', 'gap-4 xl:gap-5 2xl:gap-6')}
>
<NavigationMenuCustomListItem
triggerName={items[0].label}
imageDetails={{
src: 'https://s3-alpha-sig.figma.com/img/054e/19b7/43c945f2ee30e43f797f944b1c02fe2e?Expires=1728259200&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=TjH6LvDVUoTwEvUvc02-8DAwccrJ9YRqDqTy5h-0O0cYSVWG03it8-zr5OSBcjGVuu5TMnV7ZlnEiM3CIHQ3mQAy7Z3~Bv2sbCL8plMbE0GDxzmjpaVkKPAfgbMpuyofWABnyQjH4cda6qWEzeBuGEw~KQfFxVuAA-wHYTA6GL~B776fRbfdfzNxtSqucrIEqfGG1nUMFEdxvTLMPCqXTjErPikIs2rDXtAZ3K3U4suPFFqLRyBQ9H0B3DAGDzxZ64CIVLkAaE~ALCRy1BBUDyXrU24E1~BeTobiCoR0q1WcnBOPMKpnUb0c2qTyaDz8BxMe9hMMI9vGnv4fxdqGBA__',
alt: items[0].label,
href: items[0].href,
}}
listItems={components}
/>
<NavigationMenuItem>
<Link href="/docs" legacyBehavior passHref>
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
Documentation
</NavigationMenuLink>
</Link>
</li>
))}
<li>
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>Item One</NavigationMenuTrigger>
<NavigationMenuContent>
<NavigationMenuLink>Link</NavigationMenuLink>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
</li>
</ol>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>

<ol className="inline-flex h-10 gap-2">
<li className="flex h-full rounded-xl border border-neutral-500 bg-neutral-50">
Expand Down
87 changes: 83 additions & 4 deletions components/ui/navigation-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as React from 'react';
import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
import { cva } from 'class-variance-authority';
import { RxChevronDown } from 'react-icons/rx';
import Link from 'next/link';
import Image from 'next/image';

import { cn } from '~/lib/utils';

Expand Down Expand Up @@ -41,13 +43,13 @@ NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
const NavigationMenuItem = NavigationMenuPrimitive.Item;

const navigationMenuTriggerStyle = cva(
'hover:text-gray-900 focus:bg-gray-100 focus:text-gray-900 group flex max-w-fit rounded-md bg-background transition-colors hover:bg-neutral-100 focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-neutral-100/50 data-[state=open]:bg-neutral-100/50'
'hover:text-gray-900 focus:bg-gray-100 focus:text-gray-900 group flex max-w-fit rounded-md bg-background transition-colors hover:bg-neutral-100 focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-neutral-100/50 data-[state=open]:bg-neutral-100/50 lg:text-lg'
);

const NavigationMenuTrigger = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>
>(({ className, children, title, ...props }, ref) => (
>(({ className, children, ...props }, ref) => (
<NavigationMenuPrimitive.Trigger
ref={ref}
className={cn(navigationMenuTriggerStyle(), 'group', className)}
Expand Down Expand Up @@ -86,7 +88,7 @@ const NavigationMenuViewport = React.forwardRef<
<div className={cn('absolute left-0 top-full flex justify-center')}>
<NavigationMenuPrimitive.Viewport
className={cn(
'origin-top-center border-gray-200 bg-white text-gray-950 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]',
'origin-top-center text-neutral-950 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-xl border border-neutral-200 bg-shade-light shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]',
className
)}
ref={ref}
Expand All @@ -109,17 +111,94 @@ const NavigationMenuIndicator = React.forwardRef<
)}
{...props}
>
<div className="bg-gray-200 relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" />
<div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-neutral-200 shadow-md" />
</NavigationMenuPrimitive.Indicator>
));
NavigationMenuIndicator.displayName =
NavigationMenuPrimitive.Indicator.displayName;

const NavigationMenuCustomListItem = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Item> & {
imageDetails?: {
src: string;
alt: string;
href: string;
};
listItems: {
title: string;
description: string;
href: string;
}[];
triggerName: string;
}
>(({ imageDetails, listItems, triggerName, ...props }, ref) => {
const imageHeight = listItems.length > 4 ? 4 : listItems.length;
return (
<NavigationMenuItem {...props} ref={ref}>
<NavigationMenuTrigger>{triggerName}</NavigationMenuTrigger>
<NavigationMenuContent className="flex gap-4 p-6 xl:gap-6 2xl:gap-8">
{imageDetails && (
<Link href={imageDetails.href} passHref legacyBehavior>
<NavigationMenuLink
className="group relative flex select-none flex-col justify-end overflow-hidden rounded-xl no-underline outline-none"
style={{ minWidth: `${70 * imageHeight}px` }}
>
<Image
className="absolute inset-0 z-0 h-full w-full object-cover transition-transform duration-500 ease-in-out group-hover:scale-125"
alt=""
src={imageDetails.src}
width={0}
height={0}
/>
<section className="relative z-30 flex h-3/4 w-full flex-col justify-end bg-gradient-to-b from-primary-500/25 to-primary-500 p-2 focus:shadow-md">
<h5 className="!mb-0 origin-bottom-left text-shade-light transition-transform duration-500 ease-in-out group-hover:scale-150">
{imageDetails.alt + '→'}
</h5>
</section>
</NavigationMenuLink>
</Link>
)}
<ul
className={cn(
'grid grid-flow-col auto-rows-max gap-4 xl:gap-6 2xl:gap-8'
)}
style={{
gridTemplateRows: `repeat(${imageHeight}, minmax(0, 1fr))`,
}}
>
{listItems.map(({ title, description, href }, index) => (
<li key={index}>
<NavigationMenuLink asChild>
<Link
className={cn(
'group block min-w-[12rem] select-none space-y-1 rounded-xl p-3 leading-none no-underline outline-none transition-colors transition-transform duration-500 ease-in-out hover:scale-110 hover:bg-neutral-50 focus:bg-neutral-50'
)}
href={href}
>
<h6 className="font-sans font-semibold leading-none text-shade-dark group-hover:text-primary-500 group-focus:text-primary-500">
{title}
</h6>
<p className="line-clamp-3 text-sm leading-snug text-neutral-700 group-hover:text-primary-500 group-focus:text-primary-500">
{description}
</p>
</Link>
</NavigationMenuLink>
</li>
))}
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
);
});
NavigationMenuCustomListItem.displayName = 'NavigationMenuCustomListItem';

export {
navigationMenuTriggerStyle,
NavigationMenu,
NavigationMenuList,
NavigationMenuItem,
NavigationMenuCustomListItem,
NavigationMenuContent,
NavigationMenuTrigger,
NavigationMenuLink,
Expand Down

0 comments on commit ab9d27f

Please sign in to comment.