Skip to content

new conf design — navbar #7

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

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 5 additions & 7 deletions src/app/conf/2025/components/hero/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,16 @@ export function Hero() {

function DateAndLocation() {
return (
<div className="flex flex-col gap-4 md:flex-row md:gap-6">
<div className="flex flex-col gap-4 typography-body-md md:flex-row md:gap-6">
<div className="flex items-center gap-2">
<CalendarIcon className="size-6" />
<CalendarIcon className="size-5 sm:size-6" />
<time dateTime="2025-09-08">September 08</time>
<span>-</span>
<time dateTime="2025-09-10">10, 2025</time>
</div>
<div className="flex items-center gap-2">
<PinIcon className="size-6" />
<address className="not-italic typography-body-md">
Amsterdam, Netherlands
</address>
<PinIcon className="size-5 sm:size-6" />
<address className="not-italic">Amsterdam, Netherlands</address>
</div>
</div>
)
Expand Down Expand Up @@ -95,7 +93,7 @@ function Stripes() {
}}
>
<div
className="absolute inset-0 bg-[linear-gradient(180deg,hsl(var(--color-pri-light))_0%,hsl(319deg_100%_90%_/_0.4)_100%)] dark:bg-[linear-gradient(180deg,hsl(var(--color-pri-dark))_0%,hsl(319_100%_20%_/_1)_100%)]"
className="absolute inset-0 bg-[linear-gradient(180deg,hsl(var(--color-pri-light))_0%,hsl(319deg_100%_90%_/_0.2)_100%)] dark:bg-[linear-gradient(180deg,hsl(var(--color-pri-dark))_0%,hsl(319_100%_20%_/_1)_100%)]"
style={{
maskImage: maskEven,
WebkitMaskImage: maskEven,
Expand Down
167 changes: 167 additions & 0 deletions src/app/conf/2025/components/navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
"use client"

import {
ReactElement,
ReactNode,
useCallback,
useEffect,
useState,
} from "react"
import NextLink from "next/link"
import { clsx } from "clsx"
import { usePathname } from "next/navigation"

import { HamburgerIcon, CrossIcon } from "@/icons"

import { Badge } from "../../_components/badge"

export interface NavbarProps {
links: { href: string; children: React.ReactNode; "aria-disabled"?: true }[]
year: number
}

export function Navbar({ links, year }: NavbarProps): ReactElement {
const pathname = usePathname()
const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false)

const handleDrawerClick = useCallback(() => {
setMobileDrawerOpen(prev => !prev)
}, [])

useEffect(() => {
setMobileDrawerOpen(false)
}, [pathname])

const navbarHeight = "70px"

return (
<>
<div
/* pink background "prelude" */ className={clsx(
"top-0 w-full scale-y-105 bg-pri-base dark:bg-pri-darker",
mobileDrawerOpen ? "static" : "absolute",
)}
style={{
height: navbarHeight,
}}
/>
<header
// todo: not white, but ALWAYS contrasting color, either white or black depending on background
className={clsx(
"top-0 z-10 w-full bg-white/20 font-mono text-white antialiased",
mobileDrawerOpen ? "fixed" : "sticky",
)}
style={
{
"--navbar-h": navbarHeight,
} as {}
}
>
<BackdropBlur />
<div className="container flex h-[var(--navbar-h)] items-center justify-between gap-5">
<div className="flex items-center gap-2 text-xl/none uppercase">
<NextLink href="/">
<GraphQLLogo className="h-6" />
</NextLink>
<span>/ GraphQLConf {year}</span>
</div>

{mobileDrawerOpen && (
<div
onClick={handleDrawerClick}
className="fixed inset-0 top-[calc(var(--navbar-h)+1px)] z-10 bg-neu-0/40 backdrop-blur-[6.4px]"
/>
)}

<nav
className={clsx(
"inset-0 z-20 flex gap-7 typography-menu max-lg:fixed max-lg:mt-[calc(var(--navbar-h)+1px)] max-lg:flex-col max-md:min-w-[50%] sm:max-lg:p-4 lg:items-end",
mobileDrawerOpen
? "translate-x-0 text-neu-900"
: "text-white max-lg:translate-x-full",
)}
>
<div className="flex w-full flex-col lg:mt-0 lg:block">
{links.map(
({ "aria-disabled": isDisabled, children, ...link }) => (
<NextLink
aria-disabled={isDisabled}
key={link.href}
{...link}
// if external link, open in new tab
{...(link.href.startsWith("https") && {
target: "_blank",
rel: "noopener noreferrer",
})}
className={clsx(
"p-5 underline-offset-4 hover:underline aria-disabled:pointer-events-none max-lg:text-base",
pathname === link.href && "underline",
)}
>
{children}
{isDisabled && (
<sup className="ml-2">
<Badge className="text-white">Soon</Badge>
</sup>
)}
</NextLink>
),
)}
</div>
</nav>

<button
className="z-40 ml-auto size-6 text-white lg:hidden"
onClick={handleDrawerClick}
>
{mobileDrawerOpen ? <CrossIcon /> : <HamburgerIcon />}
</button>
</div>
</header>
</>
)
}

function GraphQLLogo(props: React.SVGProps<SVGSVGElement>) {
return (
<svg viewBox="0 0 100 100" fill="currentColor" {...props}>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M50 6.90308L87.323 28.4515V71.5484L50 93.0968L12.677 71.5484V28.4515L50 6.90308ZM16.8647 30.8693V62.5251L44.2795 15.0414L16.8647 30.8693ZM50 13.5086L18.3975 68.2457H81.6025L50 13.5086ZM77.4148 72.4334H22.5852L50 88.2613L77.4148 72.4334ZM83.1353 62.5251L55.7205 15.0414L83.1353 30.8693V62.5251Z"
/>
<circle cx="50" cy="9.3209" r="8.82" />
<circle cx="85.2292" cy="29.6605" r="8.82" />
<circle cx="85.2292" cy="70.3396" r="8.82" />
<circle cx="50" cy="90.6791" r="8.82" />
<circle cx="14.7659" cy="70.3396" r="8.82" />
<circle cx="14.7659" cy="29.6605" r="8.82" />
</svg>
)
}

function BackdropBlur() {
const mask = "linear-gradient(to bottom, #000 0% 50%, transparent 50% 100%)"
const edgeMask =
"linear-gradient(to bottom, black 0, black 1.1px, transparent 1.1px)"
return (
<>
<div
// note: we can't use the background trick to reduce flickering, because we have many section
// background colors and big images, so we'd have to change the --bg var with javascript
className="pointer-events-none absolute inset-0 -z-10 h-[200%] backdrop-blur-[6.4px]"
style={{
maskImage: mask,
WebkitMaskImage: mask,
}}
/>
<div
className="pointer-events-none absolute inset-0 -z-10 h-full translate-y-full bg-white/50 backdrop-blur-sm backdrop-brightness-200 backdrop-grayscale-[50%]"
style={{
maskImage: edgeMask,
WebkitMaskImage: edgeMask,
}}
/>
</>
)
}
17 changes: 4 additions & 13 deletions src/app/conf/2025/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ReactElement, ReactNode } from "react"
import { Metadata } from "next"
import { Header } from "../_components/header"
import { Footer } from "../_components/footer"
import { GraphQLConf, HostedByGraphQLFoundation } from "@/icons"
import NextLink from "next/link"
import { NewFontsStyleTag } from "../../fonts"
import "../../colors.css"
import { Navbar } from "./components/navbar"

// @ts-expect-error: we want to import the same version as Nextra for the main page
import { ThemeProvider } from "next-themes"
Expand Down Expand Up @@ -36,16 +36,8 @@ export default function Layout({
return (
<>
<NewFontsStyleTag />
<Header
logo={
<NextLink
href="/conf/2025"
className="nextra-logo flex items-center gap-2 text-white"
>
<GraphQLConf className="h-6" />
<span className="select-none text-xl/none">2025</span>
</NextLink>
}
<Navbar
year={2025}
links={[
{ children: "Sponsor", href: "/conf/2025/#sponsors" },
{ children: "Submit to Speak", href: "/conf/2025/#speakers" },
Expand All @@ -54,10 +46,9 @@ export default function Layout({
{ children: "Resources", href: "/conf/2025/resources" },
{ children: "FAQ", href: "/conf/2025/#faq" },
]}
is2025
/>
<ThemeProvider attribute="class">
<div className="bg-neu-0 text-neu-900">{children}</div>
<div className="bg-neu-0 text-neu-900 antialiased">{children}</div>
</ThemeProvider>
<Footer
logo={
Expand Down
2 changes: 1 addition & 1 deletion src/app/conf/_components/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function Button({
return disabled ? (
<span
className={clsx(
"inline-flex w-fit cursor-default whitespace-nowrap rounded border-0 px-6 py-2 text-center text-sm no-underline transition ease-in-out sm:text-base",
"inline-flex w-fit cursor-default whitespace-nowrap rounded border-0 px-6 py-2 text-center text-sm no-underline subpixel-antialiased transition ease-in-out sm:text-base",
"bg-gray-400 font-medium text-white",
className,
)}
Expand Down
1 change: 0 additions & 1 deletion tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ const config: Config = {
},
".typography-body-md": {
fontSize: "14px",
fontWeight: "300",
"@screen md": {
fontSize: "16px",
},
Expand Down
Loading