shadimage
designali
blockheader-01source: ok · refreshed

Header 01

A simple header section.

npx shadcn add "https://designali.com/r/header-01.json"
free

Where it goes

navbar

Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.

Dependencies

Bundle weight · light

Registry dependencies

buttonnavigation-menutoggle

Files4 · source cached 10/8/2026, 7:41:49 AM

registry/designali/blocks/header/header-01/page.tsx
import { Header } from "@/registry/designali/blocks/header/header-01/components/header"

export default function Header01() {
  return (
    <div className="flex min-h-screen w-full flex-col overflow-hidden">
      <Header />
      <main className="flex-1">
        <section className="flex h-screen items-center justify-center">
          <h1 className="text-4xl font-bold">Hero</h1>
        </section>

        <section className="flex h-screen items-center justify-center">
          <h1 className="text-4xl font-bold">Section</h1>
        </section>
      </main>
    </div>
  )
}
registry/designali/blocks/header/header-01/components/header.tsx
"use client"

import React from "react"
import { Equal, X } from "lucide-react"

import { Menus } from "@/registry/designali/blocks/header/header-01/components/menus"
import { ModeToggle } from "@/registry/designali/blocks/header/header-01/components/theme-switch"
import { cn } from "@workspace/ui/lib/utils"
import { Button } from "@workspace/ui/components/button"
import { Logo } from "@/src/components/logo"

const menuItems = [
  { name: "Components", href: "#" },
  { name: "Pricing", href: "#" },
  { name: "Contact", href: "#" },
]

const Header = () => {
  const [menuState, setMenuState] = React.useState(false)
  const [isScrolled, setIsScrolled] = React.useState(false)

  React.useEffect(() => {
    const handleScroll = () => {
      setIsScrolled(window.scrollY > 4)
    }
    window.addEventListener("scroll", handleScroll)
    return () => window.removeEventListener("scroll", handleScroll)
  }, [])
  return (
    <header>
      <nav
        data-state={menuState && "active"}
        className={cn(
          "fixed z-50 w-full transition-colors duration-300",
          isScrolled ? "border-transparent" : "border-b border-dotted"
        )}
      >
        <div
          className={cn(
            "mx-auto bg-background px-2 transition-all duration-300",
            isScrolled &&
              "max-w-5xl border-b bg-background/50 px-1 backdrop-blur-xl md:mt-2 md:border"
          )}
        >
          <div className="relative flex flex-wrap items-center justify-between gap-3 py-1">
            <div className="flex w-full justify-between md:w-auto">
              <a href="#" aria-label="home" className="flex items-center gap-2">
                <Logo className="ml-3 size-8" />
              </a>
              <div className="flex gap-2">
                <button
                  onClick={() => setMenuState(!menuState)}
                  aria-label={menuState == true ? "Close Menu" : "Open Menu"}
                  className="relative z-20 block cursor-pointer p-2.5 pr-4 md:hidden"
                >
                  <Equal className="m-auto scale-120 duration-200 in-data-[state=active]:scale-0 in-data-[state=active]:rotate-180 in-data-[state=active]:opacity-0" />
                  <X className="absolute inset-0 m-auto size-6 scale-0 -rotate-180 opacity-0 duration-200 in-data-[state=active]:scale-120 in-data-[state=active]:rotate-0 in-data-[state=active]:opacity-100" />
                </button>
              </div>
            </div>

            <div className="absolute inset-0 m-auto hidden size-fit md:block">
              <Menus />
            </div>

            <div className="shadow-3xl hidden w-full flex-wrap items-center justify-end space-y-8 rounded-sm border p-3 shadow-zinc-300/20 backdrop-blur-2xl in-data-[state=active]:block md:m-0 md:flex md:w-fit md:flex-nowrap md:gap-6 md:space-y-0 md:border-transparent md:bg-transparent md:p-0 md:shadow-none md:in-data-[state=active]:flex dark:shadow-none dark:lg:bg-transparent">
              <div className="block p-3 md:hidden">
                <ul className="space-y-6 text-base">
                  {menuItems.map((item, index) => (
                    <li key={index}>
                      <a
                        href={item.href}
                        className="block text-sm text-muted-foreground duration-150 hover:text-primary"
                      >
                        <span>{item.name}</span>
                      </a>
                    </li>
                  ))}
                </ul>
              </div>
              <div className="flex w-full flex-col space-y-3 sm:flex-row sm:gap-2 sm:space-y-0">
                <ModeToggle />
                <Button
                  nativeButton={false}
                  className={cn(isScrolled && "md:hidden")}
                  render={
                    <a target="_blank" href="https://cal.com/designali/30min" />
                  }
                >
                  <span>Book an Intro call</span>
                </Button>
              </div>
            </div>
          </div>
        </div>
      </nav>
    </header>
  )
}

export { Header }
registry/designali/blocks/header/header-01/components/theme-switch.tsx
"use client"

import { Moon, Sun } from "lucide-react"
import { useTheme } from "next-themes"

import { Toggle } from "@workspace/ui/components/toggle"

export function ModeToggle() {
  const { resolvedTheme, setTheme } = useTheme()

  const isDark = resolvedTheme === "dark"

  return (
    <div className="flex flex-col justify-center">
      <Toggle
        className="group size-9 cursor-pointer bg-secondary data-[state=on]:bg-transparent data-[state=on]:hover:bg-muted dark:bg-secondary"
        pressed={isDark}
        onPressedChange={() => setTheme(isDark ? "light" : "dark")}
        aria-label={`Switch to ${isDark ? "light" : "dark"} mode`}
      >
        <Moon
          size={16}
          className="shrink-0 scale-0 opacity-0 transition-all group-data-[state=on]:scale-100 group-data-[state=on]:opacity-100"
          aria-hidden="true"
        />

        <Sun
          size={16}
          className="absolute shrink-0 scale-100 opacity-100 transition-all group-data-[state=on]:scale-0 group-data-[state=on]:opacity-0"
          aria-hidden="true"
        />
      </Toggle>
    </div>
  )
}
registry/designali/blocks/header/header-01/components/menus.tsx
"use client"

import * as React from "react"
import Link from "next/link"

import {
  ArrowUpRightIcon,
  BlocksIcon,
  Code2Icon,
  ComponentIcon,
  SwatchBookIcon,
} from "lucide-react"

import { cn } from "@workspace/ui/lib/utils"

import {
  NavigationMenu,
  NavigationMenuContent,
  NavigationMenuItem,
  NavigationMenuLink,
  NavigationMenuList,
  NavigationMenuTrigger,
  navigationMenuTriggerStyle,
} from "@workspace/ui/components/navigation-menu"

const designResources = [
  {
    title: "UI Components",
    href: "/ui",
    description:
      "Explore reusable and beautifully crafted interface components.",
  },
  {
    title: "Blocks",
    href: "/blocks",
    description:
      "Build complete sections and interfaces with flexible UI blocks.",
  },
  {
    title: "Colors",
    href: "/colors",
    description:
      "Explore accessible colors, gradients, and modern color combinations.",
  },
  {
    title: "Design System",
    href: "/docs",
    description:
      "Learn how Designali approaches scalable design systems.",
  },
]

const developmentResources = [
  {
    title: "Documentation",
    href: "/docs",
    description:
      "Learn how to install, customize, and use Designali components.",
  },
  {
    title: "Components",
    href: "/docs/components",
    description:
      "Browse the component library and explore implementation details.",
  },
  {
    title: "Templates",
    href: "/templates",
    description:
      "Start your next project with production-ready templates.",
  },
  {
    title: "GitHub",
    href: "https://github.com/designali-com",
    description:
      "Explore the source code, components, and projects on GitHub.",
  },
]


export function Menus() {
  return (
    <NavigationMenu>
      <NavigationMenuList>
        {/* Resources */}
        <NavigationMenuItem>
          <NavigationMenuTrigger>Resources</NavigationMenuTrigger>

          <NavigationMenuContent>
            <div className="grid w-[500px] grid-cols-2 gap-2 p-2">
              {designResources.map((item) => (
                <ListItem
                  key={item.title}
                  title={item.title}
                  href={item.href}
                >
                  {item.description}
                </ListItem>
              ))}
            </div>
          </NavigationMenuContent>
        </NavigationMenuItem>

        {/* Development */}
        <NavigationMenuItem>
          <NavigationMenuTrigger>Development</NavigationMenuTrigger>

          <NavigationMenuContent>
            <div className="grid w-[500px] grid-cols-2 gap-2 p-2">
              {developmentResources.map((item) => (
                <ListItem
                  key={item.title}
                  title={item.title}
                  href={item.href}
                  external={item.href.startsWith("http")}
                >
                  {item.description}
                </ListItem>
              ))}
            </div>
          </NavigationMenuContent>
        </NavigationMenuItem>

        {/* Components */}
        <NavigationMenuItem className="hidden md:flex">
          <NavigationMenuTrigger>
            Components
          </NavigationMenuTrigger>

          <NavigationMenuContent>
            <div className="grid w-[500px] grid-cols-2 gap-2 p-2">
              <IconListItem
                href="/ui"
                icon={<ComponentIcon />}
                title="UI Components"
              >
                Reusable components for modern web interfaces.
              </IconListItem>

              <IconListItem
                href="/blocks"
                icon={<BlocksIcon />}
                title="Blocks"
              >
                Complete sections for landing pages and applications.
              </IconListItem>

              <IconListItem
                href="/docs"
                icon={<Code2Icon />}
                title="Developer Docs"
              >
                Component APIs, installation, and implementation guides.
              </IconListItem>

              <IconListItem
                href="/colors"
                icon={<SwatchBookIcon />}
                title="Color System"
              >
                Colors, gradients, and accessible design foundations.
              </IconListItem>
            </div>
          </NavigationMenuContent>
        </NavigationMenuItem>

        {/* Quick Links */}
        <NavigationMenuItem>
          <NavigationMenuLink
            className={navigationMenuTriggerStyle()}
            render={<Link href="/showcase">Showcase</Link>}
          />
        </NavigationMenuItem>

        {/* Contact */}
        <NavigationMenuItem>
          <NavigationMenuLink
            className={navigationMenuTriggerStyle()}
            render={<Link href="/contact">Contact</Link>}
          />
        </NavigationMenuItem>
      </NavigationMenuList>
    </NavigationMenu>
  )
}

function ListItem({
  title,
  children,
  href,
  className,
  external = false,
  ...props
}: React.ComponentPropsWithoutRef<"li"> & {
  title: string
  href: string
  external?: boolean
}) {
  const linkProps = external
    ? {
      target: "_blank",
      rel: "noopener noreferrer",
    }
    : {}

  return (
    <li
      {...props}
      className={cn(
        "list-none",
        className
      )}
    >
      <NavigationMenuLink
      className={"text-start grid"}
        render={
          <Link
            href={href}
            {...linkProps}
            className="group block w-full rounded-lg p-3 text-left no-underline outline-none transition-colors hover:bg-accent focus:bg-accent"
          >
            <div className="flex items-center justify-start gap-2">
              <span className="text-sm font-medium leading-none">
                {title}
              </span>

              {external && (
                <ArrowUpRightIcon className="size-3.5 text-muted-foreground transition-transform group-hover:-translate-y-0.5 group-hover:translate-x-0.5" />
              )}
            </div>

            <p className="mt-1.5 line-clamp-2 text-left text-xs leading-relaxed text-muted-foreground">
              {children}
            </p>
          </Link>
        }
      />
    </li>
  )
}

function IconListItem({
  title,
  children,
  href,
  icon,
  className,
  ...props
}: React.ComponentPropsWithoutRef<"li"> & {
  title: string
  href: string
  icon: React.ReactNode
}) {
  return (
    <li
      {...props}
      className={cn(
        "list-none",
        className
      )}
    >
      <NavigationMenuLink
        render={
          <Link
            href={href}
            className="group flex items-start gap-3 rounded-lg p-3 no-underline outline-none transition-colors hover:bg-accent focus:bg-accent"
          >
            <div className="flex size-9 shrink-0 items-center justify-center rounded-md border bg-background text-muted-foreground transition-colors group-hover:text-foreground">
              {React.isValidElement(icon)
                ? React.cloneElement(
                  icon as React.ReactElement<{
                    className?: string
                  }>,
                  {
                    className: "size-4",
                  }
                )
                : icon}
            </div>

            <div className="min-w-0 flex flex-col">
              <div className="text-sm font-medium leading-none">
                {title}
              </div>

              <p className="mt-1.5 line-clamp-2 text-xs leading-relaxed text-muted-foreground">
                {children}
              </p>
            </div>
          </Link>
        }
      />
    </li>
  )
}

More from designali

Browse all components in this library →