Skip to content

Commit

Permalink
Add menu links styling
Browse files Browse the repository at this point in the history
  • Loading branch information
cesalberca committed Jul 27, 2024
1 parent 6fe7257 commit 8fcfca4
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 25 deletions.
37 changes: 37 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
},
"dependencies": {
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-slot": "^1.1.0",
"@tailwindcss/typography": "0.5.13",
"@vercel/analytics": "1.3.1",
Expand Down
8 changes: 4 additions & 4 deletions src/app/talks/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Talks } from '../components/talks'
import { Page } from '@/core/components/page/page'

export const metadata = {
title: 'Talks',
description: `Here are all the talks I've given.`,
}

export default function Page() {
export default function TalksPage() {
return (
<section>
<h1 className="font-semibold text-2xl mb-8 tracking-tighter">My Blog</h1>
<Page>
<Talks />
</section>
</Page>
)
}
31 changes: 31 additions & 0 deletions src/components/ui/popover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client'

import * as React from 'react'
import * as PopoverPrimitive from '@radix-ui/react-popover'

import { cn } from '@/lib/utils'

const Popover = PopoverPrimitive.Root

const PopoverTrigger = PopoverPrimitive.Trigger

const PopoverContent = React.forwardRef<
React.ElementRef<typeof PopoverPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className,
)}
{...props}
/>
</PopoverPrimitive.Portal>
))
PopoverContent.displayName = PopoverPrimitive.Content.displayName

export { Popover, PopoverTrigger, PopoverContent }
36 changes: 36 additions & 0 deletions src/core/components/navbar/navbar.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.menu-link::before,
.menu-link::after {
position: absolute;
width: 100%;
height: 0.5px;
background: currentColor;
top: 100%;
left: 0;
pointer-events: none;
}

.menu-link::before {
content: '';
/* show by default */
}

.menu-link::before {
transform-origin: 50% 100%;
transition:
clip-path 0.3s,
transform 0.3s cubic-bezier(0.2, 1, 0.8, 1);
clip-path: polygon(0% 0%, 0% 100%, 0 100%, 0 0, 100% 0, 100% 100%, 0 100%, 0 100%, 100% 100%, 100% 0%);
}

.menu-link:hover::before {
transform: translate3d(0, 2px, 0) scale3d(1.08, 3, 1);
clip-path: polygon(0% 0%, 0% 100%, 50% 100%, 50% 0, 50% 0, 50% 100%, 50% 100%, 0 100%, 100% 100%, 100% 0%);
}

.menu-link span {
transition: transform 0.3s cubic-bezier(0.2, 1, 0.8, 1);
}

.menu-link:hover span {
transform: translate3d(0, -2px, 0);
}
86 changes: 65 additions & 21 deletions src/core/components/navbar/navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,46 @@
import type { FC, SVGProps } from 'react'
import { Link } from '../link/link'
'use client'

import type { FC, PropsWithChildren, SVGProps } from 'react'
import { useTranslations } from 'next-intl'
import { cn } from '@/lib/utils'
import { ThemeToggle } from '@/core/components/theme/theme-toggle'
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
import { Button } from '@/components/ui/button'
import Image from 'next/image'
import { usePathname } from 'next/navigation'
import styles from './navbar.module.css'
import Link from 'next/link'

const MenuLink: FC<
PropsWithChildren<{
to: string
}>
> = ({ to, children }) => {
const currentPath = usePathname()

return (
<Link
href={to}
className={cn(
styles['menu-link'],
'font-medium text-muted-foreground relative',
`${currentPath === to ? 'font-bold text-foreground' : ''}`,
)}
>
<span className="inline-block">{children}</span>
</Link>
)
}

const Links = () => {
const t = useTranslations()
return (
<>
<MenuLink to={'/talks'}>{t('talks.title')}</MenuLink>
<MenuLink to={'/about'}>{t('about.title')}</MenuLink>
</>
)
}

export const Navbar: FC<{
className?: string
Expand All @@ -11,32 +49,38 @@ export const Navbar: FC<{

return (
<header className={cn('flex h-16 w-full items-center justify-between bg-background px-4 md:px-6', className)}>
<Link to={'/'} className="flex items-center gap-2">
<img src="/assets/logo.svg" width={32} height={32} alt={t('common.logo')} className="h-6 w-6" />
<span className="text-lg font-semibold">{t('home.title')}</span>
<Link href={'/'} className="flex items-center gap-2">
<Image src="/assets/logo.svg" width={32} height={32} alt={t('common.logo')} className="h-6 w-6" />
<span className="text-lg">{t('home.title')}</span>
</Link>
<nav className="hidden lg:flex items-center gap-4">
<Link to={'/talks'} className="text-sm font-medium text-muted-foreground hover:text-foreground">
{t('talks.title')}
</Link>
<Link to={'/about'} className="text-sm font-medium text-muted-foreground hover:text-foreground">
{t('about.title')}
</Link>
<nav className="hidden lg:flex items-center justify-end gap-4">
<Links></Links>
</nav>
<div>
<ThemeToggle />
</div>
<div className="ml-auto lg:hidden">
<button>
<MenuIcon className="h-6 w-6" />
<span className="sr-only">{t('common.toggleNavigation')}</span>
</button>
<div className="flex gap-2 items-center">
<div className="ml-auto lg:hidden">
<Popover>
<PopoverTrigger asChild>
<Button variant="outline">
<MenuIcon className="h-6 w-6" />
<span className="sr-only">{t('common.toggleNavigation')}</span>
</Button>
</PopoverTrigger>
<PopoverContent className="w-40">
<div className="flex flex-col">
<Links></Links>
</div>
</PopoverContent>
</Popover>
</div>
<div>
<ThemeToggle />
</div>
</div>
</header>
)
}

function MenuIcon(props: SVGProps<SVGElement>) {
function MenuIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
Expand Down

0 comments on commit 8fcfca4

Please sign in to comment.