Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Continue Create Dropdown Options #946

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0389375
feat: Refactor menu items with { active } to use headlessui highlighting
trillium Jun 22, 2024
0d6b12f
feat: Switch to headerNavLinks import for NavOptions
trillium Jun 22, 2024
402722b
feat: Update object structure to inlcude "children" prop
trillium Jun 22, 2024
a21945a
feat: Create type NavItem for headerNavLinks
trillium Jun 22, 2024
818c645
feat: Import NavItem type into NavOptions
trillium Jun 22, 2024
2424104
feat: Create RenderNavLinks helper function
trillium Jun 22, 2024
fdd1ce8
feat: Use helper function in NavOptions .map()
trillium Jun 22, 2024
478321f
feat: Create NavItemChild type, add to NavItem type
trillium Jun 22, 2024
6af7466
feat: Add NavItemChild import
trillium Jun 22, 2024
fd96713
feat: Add { active } to RenderNavLink, highlighting for dropdown
trillium Jun 22, 2024
bccdbb1
feat: Add { NavOptions } import to Header.tsx
trillium Jun 22, 2024
88a7710
feat: Remove headerNavLinks from Header.tsx
trillium Jun 22, 2024
23a983a
fix: Restore nav links highlighting
trillium Jun 22, 2024
17f0c22
feat: Create RenderMobileNavLink helper func
trillium Jun 22, 2024
b4b89b5
feat: Import types form headerNavLinks
trillium Jun 22, 2024
b301981
feat: Render links with heperFunc
trillium Jun 22, 2024
959bc72
fix: Force href to be '' if no href is supplied in Link
trillium Jun 22, 2024
6cee124
Merge remote-tracking branch 'upstream/main' into ts.continue_feature…
trillium Jun 22, 2024
fd6f4a0
feat: Update NavLinks types
trillium Jun 22, 2024
0789274
feat: Move NavLink type to NavOptions
trillium Jun 23, 2024
792067c
fix: Update RenderMobileNavLinkProps
trillium Jun 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import siteMetadata from '@/data/siteMetadata'
import headerNavLinks from '@/data/headerNavLinks'
import Logo from '@/data/logo.svg'
import Link from './Link'
import MobileNav from './MobileNav'
import ThemeSwitch from './ThemeSwitch'
import SearchButton from './SearchButton'
import { NavOptions } from './NavOptions'

const Header = () => {
return (
Expand All @@ -26,18 +26,7 @@ const Header = () => {
</Link>
</div>
<div className="flex items-center space-x-4 leading-5 sm:space-x-6">
{headerNavLinks
.filter((link) => link.href !== '/')
.map((link) => (
<Link
key={link.title}
href={link.href}
className="hidden font-medium text-gray-900 hover:text-primary-500 dark:text-gray-100 dark:hover:text-primary-400
sm:block"
>
{link.title}
</Link>
))}
<NavOptions />
<SearchButton />
<ThemeSwitch />
<MobileNav />
Expand Down
64 changes: 53 additions & 11 deletions components/MobileNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Dialog, Transition } from '@headlessui/react'
import { Fragment, useState } from 'react'
import Link from './Link'
import headerNavLinks from '@/data/headerNavLinks'
import { NavItem, NavItemChild } from '@/components/NavOptions'

const MobileNav = () => {
const [navShow, setNavShow] = useState(false)
Expand Down Expand Up @@ -63,17 +64,15 @@ const MobileNav = () => {
>
<Dialog.Panel className="fixed left-0 top-0 z-10 h-full w-full bg-white opacity-95 duration-300 dark:bg-gray-950 dark:opacity-[0.98]">
<nav className="fixed mt-8 h-full text-left">
{headerNavLinks.map((link) => (
<div key={link.title} className="px-12 py-4">
<Link
href={link.href}
className="text-2xl font-bold tracking-widest text-gray-900 hover:text-primary-500 dark:text-gray-100 dark:hover:text-primary-400"
onClick={onToggleNav}
>
{link.title}
</Link>
</div>
))}
{headerNavLinks.map((link) => {
return (
<RenderMobileNavLink
navLink={link}
clickFunc={onToggleNav}
key={link.title}
/>
)
})}
</nav>

<div className="flex justify-end">
Expand Down Expand Up @@ -107,3 +106,46 @@ const MobileNav = () => {
}

export default MobileNav

type RenderMobileNavLinkProps = {
clickFunc: () => void
navLink: NavItem
}

const RenderMobileNavLink = ({ navLink, clickFunc }: RenderMobileNavLinkProps) => {
const children: NavItemChild[] = navLink?.children || []

if (children?.length > 0) {
return (
<div key={navLink.title} className="px-12 py-4">
<h3 className="border-b border-gray-500 text-2xl font-bold tracking-widest text-gray-700 dark:border-gray-400 dark:text-gray-300">
{navLink.title}
</h3>
<div className="ml-6 flex flex-col items-start">
{children.map((cLink: NavItemChild) => (
<Link
key={cLink.title}
href={cLink.href}
className="mt-4 text-2xl font-bold tracking-widest text-gray-900 hover:text-primary-500 dark:text-gray-100 dark:hover:text-primary-400"
onClick={clickFunc}
>
{cLink.title}
</Link>
))}
</div>
</div>
)
} else {
return (
<div key={navLink.title} className="px-12 py-4">
<Link
href={navLink.href ?? ''}
className="text-2xl font-bold tracking-widest text-gray-900 hover:text-primary-500 dark:text-gray-100 dark:hover:text-primary-400"
onClick={clickFunc}
>
{navLink.title}
</Link>
</div>
)
}
}
100 changes: 100 additions & 0 deletions components/NavOptions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
'use client'

import { Fragment, useEffect, useState } from 'react'
import { useTheme } from 'next-themes'
import { Menu, RadioGroup, Transition } from '@headlessui/react'
import headerNavLinks from '@/data/headerNavLinks'
import Link from 'next/link'

type NavItemBase = {
title: string
}

type NavItemWithHref = NavItemBase & {
href: string
children?: never
}

type NavItemWithChildren = NavItemBase & {
children: NavItemChild[]
href?: never
}

export type NavItemChild = {
href: string
title: string
}

export type NavItem = NavItemWithHref | NavItemWithChildren

export const NavOptions = () => {
return (
<>
{headerNavLinks
.filter((link) => link.href !== '/')
.map((link) => (
<RenderNavLink navItem={link} key={link.title} />
))}
</>
)
}

const RenderNavLink = ({ navItem }: { navItem: NavItem }) => {
if (!navItem.children) {
return (
<Link
key={navItem.title}
href={navItem.href}
className="hidden font-medium text-gray-900 hover:text-primary-500 dark:text-gray-100 dark:hover:text-primary-400 sm:block"
>
{navItem.title}
</Link>
)
}
return (
<div className="mr-5">
<Menu as="div" className="relative inline-block text-left">
<div>
{navItem.title && (
<Menu.Button
className={
'hidden font-medium text-gray-900 hover:text-primary-500 dark:text-gray-100 dark:hover:text-primary-400 sm:block'
}
>
{navItem.title}
</Menu.Button>
)}
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute right-0 mt-2 w-32 origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-gray-800">
<div className="p-1">
{navItem.children &&
navItem.children.map((link: NavItemChild) => (
<Menu.Item key={link.title}>
{({ active }) => (
<Link
href={link.href}
className={`${
active ? 'bg-primary-600 text-white' : ''
} group flex w-full items-center rounded-md px-2 py-2 text-sm`}
>
{link.title}
</Link>
)}
</Menu.Item>
))}
</div>
</Menu.Items>
</Transition>
</Menu>
</div>
)
}
7 changes: 7 additions & 0 deletions data/headerNavLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ const headerNavLinks = [
{ href: '/tags', title: 'Tags' },
{ href: '/projects', title: 'Projects' },
{ href: '/about', title: 'About' },
trillium marked this conversation as resolved.
Show resolved Hide resolved
{
title: 'Dropdown',
children: [
{ href: '/projects', title: 'Projects' },
{ href: '/about', title: 'About' },
],
},
]

export default headerNavLinks