From 606dac4176c58d37ff29150fad200fcf434b0f09 Mon Sep 17 00:00:00 2001 From: Kris Baumgartner Date: Sun, 12 Apr 2026 13:06:58 -0400 Subject: [PATCH 01/13] Tweak the nav modal --- components/gallery/NavPill.tsx | 184 ++++++++++++++++----------------- 1 file changed, 89 insertions(+), 95 deletions(-) diff --git a/components/gallery/NavPill.tsx b/components/gallery/NavPill.tsx index c097c4fc0..b12a8b556 100644 --- a/components/gallery/NavPill.tsx +++ b/components/gallery/NavPill.tsx @@ -3,14 +3,17 @@ import Link from '@/components/Link' import SearchButton from '@/components/SearchButton' import { Discord, Github, Twitter } from '@/components/social-icons/icons' -import ThemeSwitch from '@/components/ThemeSwitch' -import { PillButton } from '@/components/gallery/PillButton' import headerNavLinks from '@/data/headerNavLinks' import Logo from '@/data/logo.svg' import siteMetadata from '@/data/siteMetadata' -import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/react' +import { Popover, PopoverButton, PopoverPanel } from '@headlessui/react' import { useTheme } from 'next-themes' import { usePathname } from 'next/navigation' +import { useRef } from 'react' + +// Compact spring curve (~tension:300 friction:20), good for small UI like popovers +const SPRING = + 'linear(0.00, 0.0183, 0.0587, 0.116, 0.184, 0.264, 0.349, 0.436, 0.524, 0.610, 0.691, 0.768, 0.837, 0.900, 0.955, 1.00, 1.04, 1.07, 1.10, 1.12, 1.13, 1.14, 1.14, 1.14, 1.14, 1.13, 1.12, 1.11, 1.10, 1.08, 1.07, 1.06, 1.05, 1.04, 1.03, 1.02, 1.01, 1.00, 0.996, 0.991, 0.987, 0.984, 0.982, 0.980, 0.980, 0.980, 0.980, 0.981, 0.982, 0.984, 0.986, 0.987, 0.989, 0.991, 0.992, 0.994, 0.996, 0.997, 0.998, 0.999, 1.00)' const NAV_LINKS = headerNavLinks.filter((l) => l.href !== '/') @@ -49,106 +52,97 @@ export function NavPill() { ))} - - -
- - - - - - - - - {iconLinks.map(({ href, Icon, label }) => - href ? ( - - - - ) : null - )} -
- - + ) } -function MobileMoreMenu() { +function MoreMenu() { + const searchRef = useRef(null) + return ( - - - - - - - - - - -
- {/* Search — whole row triggers the nested SearchButton */} - - - {/* Theme — inline buttons to avoid nested Headless UI Menu */} - - -
- - {iconLinks.map(({ href, Icon, label }) => - href ? ( - - ( + - -
+ Search + + + + + + + + + )} + + + )} + ) } @@ -158,7 +152,7 @@ const themeOptions = [ { value: 'system', label: 'Auto' }, ] as const -function MobileThemeRow() { +function ThemeRow() { const { theme, setTheme } = useTheme() return (
From 3f8c69de5212513d12fbdf2e103baab1437bb6c1 Mon Sep 17 00:00:00 2001 From: Kris Baumgartner Date: Tue, 14 Apr 2026 19:18:36 -0400 Subject: [PATCH 02/13] Refactor NavPill and theme --- app/layout.tsx | 2 +- .../NavPill.tsx => nav-pill/MoreMenu.tsx} | 75 +------------------ components/nav-pill/NavPill.tsx | 45 +++++++++++ components/nav-pill/ThemeRow.tsx | 73 ++++++++++++++++++ components/nav-pill/index.ts | 1 + 5 files changed, 122 insertions(+), 74 deletions(-) rename components/{gallery/NavPill.tsx => nav-pill/MoreMenu.tsx} (63%) create mode 100644 components/nav-pill/NavPill.tsx create mode 100644 components/nav-pill/ThemeRow.tsx create mode 100644 components/nav-pill/index.ts diff --git a/app/layout.tsx b/app/layout.tsx index 07a1b8fa3..6d533cd8a 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,7 +2,7 @@ import 'css/tailwind.css' import 'pliny/search/algolia.css' import 'remark-github-blockquote-alert/alert.css' -import { NavPill } from '@/components/gallery/NavPill' +import { NavPill } from '@/components/nav-pill' import siteMetadata from '@/data/siteMetadata' import { Metadata } from 'next' import { Inter } from 'next/font/google' diff --git a/components/gallery/NavPill.tsx b/components/nav-pill/MoreMenu.tsx similarity index 63% rename from components/gallery/NavPill.tsx rename to components/nav-pill/MoreMenu.tsx index b12a8b556..e674a240c 100644 --- a/components/gallery/NavPill.tsx +++ b/components/nav-pill/MoreMenu.tsx @@ -1,64 +1,23 @@ 'use client' -import Link from '@/components/Link' import SearchButton from '@/components/SearchButton' import { Discord, Github, Twitter } from '@/components/social-icons/icons' -import headerNavLinks from '@/data/headerNavLinks' -import Logo from '@/data/logo.svg' import siteMetadata from '@/data/siteMetadata' import { Popover, PopoverButton, PopoverPanel } from '@headlessui/react' -import { useTheme } from 'next-themes' -import { usePathname } from 'next/navigation' import { useRef } from 'react' +import { ThemeRow } from './ThemeRow' // Compact spring curve (~tension:300 friction:20), good for small UI like popovers const SPRING = 'linear(0.00, 0.0183, 0.0587, 0.116, 0.184, 0.264, 0.349, 0.436, 0.524, 0.610, 0.691, 0.768, 0.837, 0.900, 0.955, 1.00, 1.04, 1.07, 1.10, 1.12, 1.13, 1.14, 1.14, 1.14, 1.14, 1.13, 1.12, 1.11, 1.10, 1.08, 1.07, 1.06, 1.05, 1.04, 1.03, 1.02, 1.01, 1.00, 0.996, 0.991, 0.987, 0.984, 0.982, 0.980, 0.980, 0.980, 0.980, 0.981, 0.982, 0.984, 0.986, 0.987, 0.989, 0.991, 0.992, 0.994, 0.996, 0.997, 0.998, 0.999, 1.00)' -const NAV_LINKS = headerNavLinks.filter((l) => l.href !== '/') - const iconLinks = [ { href: siteMetadata.github, Icon: Github, label: 'GitHub' }, { href: siteMetadata.discord, Icon: Discord, label: 'Discord' }, { href: siteMetadata.x, Icon: Twitter, label: 'Twitter / X' }, ] as const -export function NavPill() { - const isHome = usePathname() === '/' - - return ( - <> - {!isHome && ( - - - - )} - - - - ) -} - -function MoreMenu() { +export function MoreMenu() { const searchRef = useRef(null) return ( @@ -145,33 +104,3 @@ function MoreMenu() { ) } - -const themeOptions = [ - { value: 'light', label: 'Light' }, - { value: 'dark', label: 'Dark' }, - { value: 'system', label: 'Auto' }, -] as const - -function ThemeRow() { - const { theme, setTheme } = useTheme() - return ( -
- Theme -
- {themeOptions.map((opt) => ( - - ))} -
-
- ) -} diff --git a/components/nav-pill/NavPill.tsx b/components/nav-pill/NavPill.tsx new file mode 100644 index 000000000..f08213a2d --- /dev/null +++ b/components/nav-pill/NavPill.tsx @@ -0,0 +1,45 @@ +'use client' + +import Link from '@/components/Link' +import headerNavLinks from '@/data/headerNavLinks' +import Logo from '@/data/logo.svg' +import siteMetadata from '@/data/siteMetadata' +import { usePathname } from 'next/navigation' +import { MoreMenu } from './MoreMenu' + +const NAV_LINKS = headerNavLinks.filter((l) => l.href !== '/') + +export function NavPill() { + const isHome = usePathname() === '/' + + return ( + <> + {!isHome && ( + + + + )} + + + + ) +} diff --git a/components/nav-pill/ThemeRow.tsx b/components/nav-pill/ThemeRow.tsx new file mode 100644 index 000000000..2ff9e1a62 --- /dev/null +++ b/components/nav-pill/ThemeRow.tsx @@ -0,0 +1,73 @@ +'use client' + +import { useTheme } from 'next-themes' +import { useEffect, useState } from 'react' + +function SunIcon() { + return ( + + + + + + + + + + + + ) +} + +function MoonIcon() { + return ( + + + + ) +} + +function SystemIcon() { + return ( + + + + + + ) +} + +const themeOptions = [ + { value: 'light', label: 'Light', Icon: SunIcon }, + { value: 'dark', label: 'Dark', Icon: MoonIcon }, + { value: 'system', label: 'Auto', Icon: SystemIcon }, +] as const + +export function ThemeRow() { + const { theme, setTheme } = useTheme() + const [mounted, setMounted] = useState(false) + + useEffect(() => setMounted(true), []) + + return ( +
+ Theme +
+ {themeOptions.map(({ value, label, Icon }) => ( + + ))} +
+
+ ) +} diff --git a/components/nav-pill/index.ts b/components/nav-pill/index.ts new file mode 100644 index 000000000..811746318 --- /dev/null +++ b/components/nav-pill/index.ts @@ -0,0 +1 @@ +export { NavPill } from './NavPill' From 9b5fbe41a7bd6c58544fa93a2080612033dcc4c4 Mon Sep 17 00:00:00 2001 From: Kris Baumgartner Date: Wed, 15 Apr 2026 10:00:34 -0400 Subject: [PATCH 03/13] Add standin example actions --- components/nav-pill/ExampleActions.tsx | 49 +++++++++++++++ components/nav-pill/NavPill.tsx | 82 +++++++++++++++++++++----- 2 files changed, 116 insertions(+), 15 deletions(-) create mode 100644 components/nav-pill/ExampleActions.tsx diff --git a/components/nav-pill/ExampleActions.tsx b/components/nav-pill/ExampleActions.tsx new file mode 100644 index 000000000..b986b544b --- /dev/null +++ b/components/nav-pill/ExampleActions.tsx @@ -0,0 +1,49 @@ +'use client' + +const actions = [ + { + label: 'Bookmark', + icon: ( + + + + ), + }, + { + label: 'Share', + icon: ( + + + + + + + + ), + }, + { + label: 'Settings', + icon: ( + + + + + ), + }, +] as const + +export function ExampleActions() { + return ( + <> + {actions.map(({ label, icon }) => ( + + ))} + + ) +} diff --git a/components/nav-pill/NavPill.tsx b/components/nav-pill/NavPill.tsx index f08213a2d..1b4a97fcd 100644 --- a/components/nav-pill/NavPill.tsx +++ b/components/nav-pill/NavPill.tsx @@ -5,15 +5,48 @@ import headerNavLinks from '@/data/headerNavLinks' import Logo from '@/data/logo.svg' import siteMetadata from '@/data/siteMetadata' import { usePathname } from 'next/navigation' +import { useEffect, useState } from 'react' +import { ExampleActions } from './ExampleActions' import { MoreMenu } from './MoreMenu' const NAV_LINKS = headerNavLinks.filter((l) => l.href !== '/') +const pillSurface = + 'flex items-center gap-px rounded-full bg-white p-1.5 shadow-[0_1px_6px_rgb(0_0_0/0.08)] ring-1 ring-black/5 dark:bg-[#1a1a1a] dark:shadow-[0_1px_6px_rgb(0_0_0/0.3)] dark:ring-white/10' + export function NavPill() { const isHome = usePathname() === '/' + const [mounted, setMounted] = useState(isHome) + const [exiting, setExiting] = useState(false) + + useEffect(() => { + if (isHome) { + setExiting(false) + setMounted(true) + } else if (mounted) { + setExiting(true) + } + }, [isHome]) return ( <> + + {!isHome && ( )} - + {mounted && ( +
{ + if (exiting) { + setMounted(false) + setExiting(false) + } + }} + > +
+ +
+
+ )} +
) } From f226172455e1378bd8366509b967720d026eefae Mon Sep 17 00:00:00 2001 From: Kris Baumgartner Date: Wed, 15 Apr 2026 10:13:50 -0400 Subject: [PATCH 04/13] Refactor nav --- app/layout.tsx | 4 ++-- components/nav-pill/index.ts | 1 - components/{nav-pill => nav}/ExampleActions.tsx | 0 components/{nav-pill => nav}/MoreMenu.tsx | 0 components/{nav-pill/NavPill.tsx => nav/Nav.tsx} | 2 +- components/{nav-pill => nav}/ThemeRow.tsx | 0 components/nav/index.ts | 1 + 7 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 components/nav-pill/index.ts rename components/{nav-pill => nav}/ExampleActions.tsx (100%) rename components/{nav-pill => nav}/MoreMenu.tsx (100%) rename components/{nav-pill/NavPill.tsx => nav/Nav.tsx} (99%) rename components/{nav-pill => nav}/ThemeRow.tsx (100%) create mode 100644 components/nav/index.ts diff --git a/app/layout.tsx b/app/layout.tsx index 6d533cd8a..b08e78535 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,7 +2,7 @@ import 'css/tailwind.css' import 'pliny/search/algolia.css' import 'remark-github-blockquote-alert/alert.css' -import { NavPill } from '@/components/nav-pill' +import { Nav } from '@/components/nav' import siteMetadata from '@/data/siteMetadata' import { Metadata } from 'next' import { Inter } from 'next/font/google' @@ -94,7 +94,7 @@ export default function RootLayout({ children }: { children: React.ReactNode }) - +