upstream #1
| @@ -98,13 +98,11 @@ export default function RootLayout({ children }: { children: React.ReactNode }) | ||||
|         <ThemeProviders> | ||||
|           <Analytics analyticsConfig={siteMetadata.analytics as AnalyticsConfig} /> | ||||
|           <SectionContainer> | ||||
|             <div className="flex h-screen flex-col justify-between font-sans"> | ||||
|               <SearchProvider searchConfig={siteMetadata.search as SearchConfig}> | ||||
|                 <Header /> | ||||
|                 <main className="mb-auto">{children}</main> | ||||
|               </SearchProvider> | ||||
|               <Footer /> | ||||
|             </div> | ||||
|             <SearchProvider searchConfig={siteMetadata.search as SearchConfig}> | ||||
|               <Header /> | ||||
|               <main className="mb-auto">{children}</main> | ||||
|             </SearchProvider> | ||||
|             <Footer /> | ||||
|           </SectionContainer> | ||||
|         </ThemeProviders> | ||||
|       </body> | ||||
|   | ||||
| @@ -7,37 +7,41 @@ import ThemeSwitch from './ThemeSwitch' | ||||
| import SearchButton from './SearchButton' | ||||
|  | ||||
| const Header = () => { | ||||
|   let headerClass = 'flex items-center w-full bg-white dark:bg-gray-950 justify-between py-10' | ||||
|   if (siteMetadata.stickyNav) { | ||||
|     headerClass += ' sticky top-0 z-50' | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     <header className="flex items-center justify-between py-10"> | ||||
|       <div> | ||||
|         <Link href="/" aria-label={siteMetadata.headerTitle}> | ||||
|           <div className="flex items-center justify-between"> | ||||
|             <div className="mr-3"> | ||||
|               <Logo /> | ||||
|             </div> | ||||
|             {typeof siteMetadata.headerTitle === 'string' ? ( | ||||
|               <div className="hidden h-6 text-2xl font-semibold sm:block"> | ||||
|                 {siteMetadata.headerTitle} | ||||
|               </div> | ||||
|             ) : ( | ||||
|               siteMetadata.headerTitle | ||||
|             )} | ||||
|     <header className={headerClass}> | ||||
|       <Link href="/" aria-label={siteMetadata.headerTitle}> | ||||
|         <div className="flex items-center justify-between"> | ||||
|           <div className="mr-3"> | ||||
|             <Logo /> | ||||
|           </div> | ||||
|         </Link> | ||||
|       </div> | ||||
|           {typeof siteMetadata.headerTitle === 'string' ? ( | ||||
|             <div className="hidden h-6 text-2xl font-semibold sm:block"> | ||||
|               {siteMetadata.headerTitle} | ||||
|             </div> | ||||
|           ) : ( | ||||
|             siteMetadata.headerTitle | ||||
|           )} | ||||
|         </div> | ||||
|       </Link> | ||||
|       <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> | ||||
|           ))} | ||||
|         <div className="no-scrollbar hidden max-w-40 items-center space-x-4 overflow-x-auto sm:flex sm:space-x-6 md:max-w-72 lg:max-w-96"> | ||||
|           {headerNavLinks | ||||
|             .filter((link) => link.href !== '/') | ||||
|             .map((link) => ( | ||||
|               <Link | ||||
|                 key={link.title} | ||||
|                 href={link.href} | ||||
|                 className="block font-medium text-gray-900 hover:text-primary-500 dark:text-gray-100 dark:hover:text-primary-400" | ||||
|               > | ||||
|                 {link.title} | ||||
|               </Link> | ||||
|             ))} | ||||
|         </div> | ||||
|         <SearchButton /> | ||||
|         <ThemeSwitch /> | ||||
|         <MobileNav /> | ||||
|   | ||||
| @@ -1,25 +1,31 @@ | ||||
| 'use client' | ||||
|  | ||||
| import { Dialog, Transition } from '@headlessui/react' | ||||
| import { Fragment, useState } from 'react' | ||||
| import { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock' | ||||
| import { Fragment, useState, useEffect, useRef } from 'react' | ||||
| import Link from './Link' | ||||
| import headerNavLinks from '@/data/headerNavLinks' | ||||
|  | ||||
| const MobileNav = () => { | ||||
|   const [navShow, setNavShow] = useState(false) | ||||
|   const navRef = useRef(null) | ||||
|  | ||||
|   const onToggleNav = () => { | ||||
|     setNavShow((status) => { | ||||
|       if (status) { | ||||
|         document.body.style.overflow = 'auto' | ||||
|         enableBodyScroll(navRef.current) | ||||
|       } else { | ||||
|         // Prevent scrolling | ||||
|         document.body.style.overflow = 'hidden' | ||||
|         disableBodyScroll(navRef.current) | ||||
|       } | ||||
|       return !status | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   useEffect(() => { | ||||
|     return clearAllBodyScrollLocks | ||||
|   }) | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <button aria-label="Toggle Menu" onClick={onToggleNav} className="sm:hidden"> | ||||
| @@ -36,8 +42,8 @@ const MobileNav = () => { | ||||
|           /> | ||||
|         </svg> | ||||
|       </button> | ||||
|       <Transition appear show={navShow} as={Fragment}> | ||||
|         <Dialog as="div" className="relative z-10" onClose={onToggleNav}> | ||||
|       <Transition appear show={navShow} as={Fragment} unmount={false}> | ||||
|         <Dialog as="div" onClose={onToggleNav} unmount={false}> | ||||
|           <Transition.Child | ||||
|             as={Fragment} | ||||
|             enter="ease-out duration-300" | ||||
| @@ -46,60 +52,53 @@ const MobileNav = () => { | ||||
|             leave="ease-in duration-200" | ||||
|             leaveFrom="opacity-100" | ||||
|             leaveTo="opacity-0" | ||||
|             unmount={false} | ||||
|           > | ||||
|             <div className="fixed inset-0 bg-black/25" /> | ||||
|             <div className="fixed inset-0 z-60 bg-black/25" /> | ||||
|           </Transition.Child> | ||||
|  | ||||
|           <div className="fixed inset-0 overflow-y-auto"> | ||||
|             <div className="flex min-h-full items-center justify-center p-4 text-center"> | ||||
|               <Transition.Child | ||||
|                 as={Fragment} | ||||
|                 enter="transition ease-in-out duration-300 transform" | ||||
|                 enterFrom="translate-x-full opacity-0" | ||||
|                 enterTo="translate-x-0 opacity-95" | ||||
|                 leave="transition ease-in duration-200 transform" | ||||
|                 leaveFrom="translate-x-0 opacity-95" | ||||
|                 leaveTo="translate-x-full opacity-0" | ||||
|           <Transition.Child | ||||
|             as={Fragment} | ||||
|             enter="transition ease-in-out duration-300 transform" | ||||
|             enterFrom="translate-x-full opacity-0" | ||||
|             enterTo="translate-x-0 opacity-95" | ||||
|             leave="transition ease-in duration-200 transform" | ||||
|             leaveFrom="translate-x-0 opacity-95" | ||||
|             leaveTo="translate-x-full opacity-0" | ||||
|             unmount={false} | ||||
|           > | ||||
|             <Dialog.Panel className="fixed left-0 top-0 z-70 h-full w-full bg-white opacity-95 duration-300 dark:bg-gray-950 dark:opacity-[0.98]"> | ||||
|               <nav | ||||
|                 ref={navRef} | ||||
|                 className="mt-8 flex h-full basis-0 flex-col items-start overflow-y-auto pl-12 pt-2 text-left" | ||||
|               > | ||||
|                 <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> | ||||
|                     ))} | ||||
|                   </nav> | ||||
|                 {headerNavLinks.map((link) => ( | ||||
|                   <Link | ||||
|                     key={link.title} | ||||
|                     href={link.href} | ||||
|                     className="mb-4 py-2 pr-4 text-2xl font-bold tracking-widest text-gray-900 outline outline-0 hover:text-primary-500 dark:text-gray-100 dark:hover:text-primary-400" | ||||
|                     onClick={onToggleNav} | ||||
|                   > | ||||
|                     {link.title} | ||||
|                   </Link> | ||||
|                 ))} | ||||
|               </nav> | ||||
|  | ||||
|                   <div className="flex justify-end"> | ||||
|                     <button | ||||
|                       className="mr-8 mt-11 h-8 w-8" | ||||
|                       aria-label="Toggle Menu" | ||||
|                       onClick={onToggleNav} | ||||
|                     > | ||||
|                       <svg | ||||
|                         xmlns="http://www.w3.org/2000/svg" | ||||
|                         viewBox="0 0 20 20" | ||||
|                         fill="currentColor" | ||||
|                         className="text-gray-900 hover:text-primary-500 dark:text-gray-100 dark:hover:text-primary-400" | ||||
|                       > | ||||
|                         <path | ||||
|                           fillRule="evenodd" | ||||
|                           d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" | ||||
|                           clipRule="evenodd" | ||||
|                         /> | ||||
|                       </svg> | ||||
|                     </button> | ||||
|                   </div> | ||||
|                 </Dialog.Panel> | ||||
|               </Transition.Child> | ||||
|             </div> | ||||
|           </div> | ||||
|               <button | ||||
|                 className="fixed right-4 top-7 z-80 h-16 w-16 p-4 text-gray-900 hover:text-primary-500 dark:text-gray-100 dark:hover:text-primary-400" | ||||
|                 aria-label="Toggle Menu" | ||||
|                 onClick={onToggleNav} | ||||
|               > | ||||
|                 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"> | ||||
|                   <path | ||||
|                     fillRule="evenodd" | ||||
|                     d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" | ||||
|                     clipRule="evenodd" | ||||
|                   /> | ||||
|                 </svg> | ||||
|               </button> | ||||
|             </Dialog.Panel> | ||||
|           </Transition.Child> | ||||
|         </Dialog> | ||||
|       </Transition> | ||||
|     </> | ||||
|   | ||||
| @@ -22,6 +22,15 @@ | ||||
|   @apply my-5; | ||||
| } | ||||
|  | ||||
| .no-scrollbar::-webkit-scrollbar { | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| .no-scrollbar { | ||||
|   -ms-overflow-style: none; /* IE and Edge */ | ||||
|   scrollbar-width: none; /* Firefox */ | ||||
| } | ||||
|  | ||||
| /* https://stackoverflow.com/questions/61083813/how-to-avoid-internal-autofill-selected-style-to-be-applied */ | ||||
| input:-webkit-autofill, | ||||
| input:-webkit-autofill:focus { | ||||
|   | ||||
| @@ -21,6 +21,8 @@ const siteMetadata = { | ||||
|   threads: 'https://www.threads.net', | ||||
|   instagram: 'https://www.instagram.com', | ||||
|   locale: 'en-US', | ||||
|   // set to true if you want a navbar fixed to the top | ||||
|   stickyNav: false, | ||||
|   analytics: { | ||||
|     // If you want to use an analytics provider you have to add it to the | ||||
|     // content security policy in the `next.config.js` file. | ||||
| @@ -34,7 +36,7 @@ const siteMetadata = { | ||||
|     }, | ||||
|     // plausibleAnalytics: { | ||||
|     //   plausibleDataDomain: '', // e.g. tailwind-nextjs-starter-blog.vercel.app | ||||
|          // If you are hosting your own Plausible. | ||||
|     // If you are hosting your own Plausible. | ||||
|     //   src: '', // e.g. https://plausible.my-domain.com/js/script.js | ||||
|     // }, | ||||
|     // simpleAnalytics: {}, | ||||
|   | ||||
| @@ -17,6 +17,7 @@ | ||||
|     "@tailwindcss/forms": "^0.5.7", | ||||
|     "@tailwindcss/typography": "^0.5.12", | ||||
|     "autoprefixer": "^10.4.13", | ||||
|     "body-scroll-lock": "^4.0.0-beta.0", | ||||
|     "contentlayer2": "0.4.6", | ||||
|     "esbuild": "0.20.2", | ||||
|     "github-slugger": "^2.0.0", | ||||
|   | ||||
| @@ -28,6 +28,11 @@ module.exports = { | ||||
|         primary: colors.pink, | ||||
|         gray: colors.gray, | ||||
|       }, | ||||
|       zIndex: { | ||||
|         60: '60', | ||||
|         70: '70', | ||||
|         80: '80', | ||||
|       }, | ||||
|       typography: ({ theme }) => ({ | ||||
|         DEFAULT: { | ||||
|           css: { | ||||
|   | ||||
| @@ -4002,6 +4002,13 @@ __metadata: | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
| 
 | ||||
| "body-scroll-lock@npm:^4.0.0-beta.0": | ||||
|   version: 4.0.0-beta.0 | ||||
|   resolution: "body-scroll-lock@npm:4.0.0-beta.0" | ||||
|   checksum: 61d40007fddf64ecc69e9e02ed9d96bb895f88d7da65cea7651081110225de48efa44ffc4acd376ed004788e242a9af12059fec728c096774b49365524ea6f46 | ||||
|   languageName: node | ||||
|   linkType: hard | ||||
| 
 | ||||
| "boolbase@npm:^1.0.0": | ||||
|   version: 1.0.0 | ||||
|   resolution: "boolbase@npm:1.0.0" | ||||
| @@ -10908,6 +10915,7 @@ __metadata: | ||||
|     "@typescript-eslint/eslint-plugin": ^6.1.0 | ||||
|     "@typescript-eslint/parser": ^6.1.0 | ||||
|     autoprefixer: ^10.4.13 | ||||
|     body-scroll-lock: ^4.0.0-beta.0 | ||||
|     contentlayer2: 0.4.6 | ||||
|     cross-env: ^7.0.3 | ||||
|     esbuild: 0.20.2 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user