shadimage
designali
blockheader-02source: ok · hit

Header 02

A simple header section.

npx shadcn add "https://designali.com/r/header-02.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
next-themes

Registry dependencies

buttoncommandnavigation-menutoggleaccordionsheet

Files4 · source cached 10/8/2026, 5:57:37 PM

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

export default function Header02() {
  return (
    <div className="flex min-h-screen w-full flex-col">
      <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-02/components/header.tsx
"use client"

import { useState } from "react"
import { ArrowRight, Equal } from "lucide-react"

import { Search } from "@/registry/designali/blocks/header/header-02/components/search"
import { ModeToggle } from "@/registry/designali/blocks/header/header-02/components/theme-switch"

import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@workspace/ui/components/accordion"

import { Button } from "@workspace/ui/components/button"

import {
  Sheet,
  SheetContent,
  SheetTrigger,
} from "@workspace/ui/components/sheet"

import { Logo } from "@/src/components/logo"

export function Header() {
  const [mobileOpen, setMobileOpen] = useState(false)

  const navItems = [
    {
      label: "Overview",
      href: "#",
      active: true,
    },
    {
      label: "Design Systems",
      href: "#",
    },
    {
      label: "UI Kits",
      href: "#",
    },
    {
      label: "Brand Assets",
      href: "#",
    },
    {
      label: "Templates",
      href: "#",
    },
    {
      label: "Workshops",
      href: "#",
    },
    {
      label: "Design Labs",
      href: "#",
    },
    {
      label: "Case Studies",
      href: "#",
    },
    {
      label: "Resources",
      href: "#",
    },
  ]

  const properties = [
    {
      location: "Design Hub – India",
      venues: [
        {
          name: "Creative Studio",
          href: "#",
        },
      ],
    },
    {
      location: "Design Hub – Global",
      venues: [
        {
          name: "UI/UX Studio",
          href: "#",
        },
        {
          name: "Branding Lab",
          href: "#",
        },
      ],
    },
  ]

  return (
    <header className="sticky top-0 z-50 border-b bg-background">
      <div className="mx-auto px-4">
        {/* Main Header */}
        <div className="flex h-16 items-center justify-between">
          {/* Logo */}
          <a
            href="/"
            aria-label="Designali home"
            className="flex items-center gap-2 whitespace-nowrap"
          >
            <Logo className="ml-3 size-8" />

            <span className="text-lg font-medium">designali</span>
          </a>

          {/* Search */}
          <Search />

          {/* Actions */}
          <div className="flex items-center gap-2">
            <ModeToggle />

            {/* Desktop CTA */}
            <Button className="hidden items-center gap-2 md:flex">
              <span>Start Designing</span>
              <ArrowRight className="h-4 w-4" />
            </Button>

            {/* Mobile Menu */}
            <Sheet open={mobileOpen} onOpenChange={setMobileOpen}>
              <SheetTrigger
                render={
                  <Button variant="ghost" size="icon" className="lg:hidden" />
                }
              >
                <Equal className="h-6 w-6" />
                <span className="sr-only">Open menu</span>
              </SheetTrigger>

              <SheetContent
                side="right"
                className="w-full overflow-y-auto sm:w-[400px]"
              >
                <div className="m-6 mt-14">
                  {/* Mobile Navigation */}
                  <Accordion className="mb-8">
                    <AccordionItem value="navigation" className="border-none">
                      <AccordionTrigger className="rounded-lg bg-accent px-4 hover:bg-accent/80 hover:no-underline">
                        <div className="text-left">
                          <div className="font-medium">Design Hub</div>

                          <div className="text-sm text-muted-foreground">
                            / Overview
                          </div>
                        </div>
                      </AccordionTrigger>

                      <AccordionContent className="pt-2">
                        <div className="overflow-hidden rounded-lg border">
                          {navItems.map((item) => (
                            <a
                              key={item.label}
                              href={item.href}
                              className={`block border-b px-4 py-3 text-sm transition-colors last:border-b-0 hover:bg-accent ${
                                item.active ? "bg-accent font-medium" : ""
                              }`}
                              onClick={() => setMobileOpen(false)}
                            >
                              {item.label}
                            </a>
                          ))}
                        </div>
                      </AccordionContent>
                    </AccordionItem>
                  </Accordion>

                  {/* Properties */}
                  <div className="space-y-6">
                    {properties.map((property) => (
                      <div key={property.location}>
                        <p className="mb-2 text-xs tracking-wider text-muted-foreground uppercase">
                          {property.location}
                        </p>

                        <ul className="space-y-2">
                          {property.venues.map((venue) => (
                            <li
                              key={venue.name}
                              className="border-t border-border"
                            >
                              <a
                                href={venue.href}
                                className="block py-3 text-lg font-medium transition-colors hover:text-muted-foreground"
                                onClick={() => setMobileOpen(false)}
                              >
                                {venue.name}
                              </a>
                            </li>
                          ))}
                        </ul>
                      </div>
                    ))}
                  </div>
                </div>
              </SheetContent>
            </Sheet>
          </div>
        </div>

        {/* Desktop Secondary Navigation */}
        <nav className="hidden border-t lg:block">
          <ul className="-mx-2 flex items-center justify-center">
            {navItems.map((item) => (
              <li key={item.label}>
                <a
                  href={item.href}
                  className={`block px-4 py-3 text-xs transition-colors ${
                    item.active
                      ? "border-b-2 border-primary font-semibold"
                      : "text-muted-foreground hover:bg-primary/20"
                  }`}
                >
                  {item.label}
                </a>
              </li>
            ))}
          </ul>
        </nav>
      </div>
    </header>
  )
}
registry/designali/blocks/header/header-02/components/theme-switch.tsx
"use client"

import * as React from "react"
import { useEffect, useState } from "react"
import { Moon, Sun } from "lucide-react"
import { useTheme } from "next-themes"

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

export function ModeToggle() {
  const { theme, setTheme } = useTheme()
  const [mounted, setMounted] = useState(false)

  useEffect(() => {
    setMounted(true)
  }, [])

  if (!mounted) return null

  return (
    <div className="flex flex-col justify-center">
      <div>
        <Toggle
          className="group size-9 cursor-pointer bg-secondary data-[state=on]:bg-transparent data-[state=on]:hover:bg-muted dark:bg-secondary"
          pressed={theme === "dark"}
          onPressedChange={() => setTheme(theme === "dark" ? "light" : "dark")}
          aria-label={`Switch to ${theme === "dark" ? "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>
    </div>
  )
}
registry/designali/blocks/header/header-02/components/search.tsx
"use client"

import * as React from "react"
import {
  ArrowUpRightIcon,
  FilePlus2Icon,
  LayoutTemplateIcon,
  PaletteIcon,
  PenToolIcon,
  SearchIcon,
} from "lucide-react"

import {
  Command,
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
  CommandShortcut,
} from "@workspace/ui/components/command"

export function Search() {
  const [open, setOpen] = React.useState(false)

  React.useEffect(() => {
    const down = (e: KeyboardEvent) => {
      if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
        e.preventDefault()
        setOpen((open) => !open)
      }
    }

    document.addEventListener("keydown", down)

    return () => {
      document.removeEventListener("keydown", down)
    }
  }, [])

  return (
    <div className="absolute left-1/2 -translate-x-1/2">
      <button
        type="button"
        onClick={() => setOpen(true)}
        className="hidden h-9 w-full max-w-sm items-center border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 lg:inline-flex"
      >
        <span className="flex grow items-center">
          <SearchIcon
            className="-ms-1 me-3 text-muted-foreground/80"
            size={16}
            aria-hidden="true"
          />

          <span className="font-normal text-muted-foreground/70">
            Search design tools...
          </span>
        </span>

        <kbd className="ms-12 -me-1 inline-flex h-5 items-center border bg-background px-1 font-[inherit] text-[0.625rem] font-medium text-muted-foreground/70">
          ⌘K
        </kbd>
      </button>

      {/* Command Dialog */}
      <CommandDialog open={open} onOpenChange={setOpen}>
        <Command>
          <CommandInput placeholder="Type to search components, assets, or docs..." />

          <CommandList>
            <CommandEmpty>No matches found.</CommandEmpty>

            {/* Create */}
            <CommandGroup heading="Create">
              <CommandItem>
                <FilePlus2Icon
                  size={16}
                  className="opacity-60"
                  aria-hidden="true"
                />

                <span>New project</span>

                <CommandShortcut>⌘N</CommandShortcut>
              </CommandItem>

              <CommandItem>
                <LayoutTemplateIcon
                  size={16}
                  className="opacity-60"
                  aria-hidden="true"
                />

                <span>New template</span>

                <CommandShortcut>⌘T</CommandShortcut>
              </CommandItem>

              <CommandItem>
                <PenToolIcon
                  size={16}
                  className="opacity-60"
                  aria-hidden="true"
                />

                <span>Start design</span>

                <CommandShortcut>⌘S</CommandShortcut>
              </CommandItem>
            </CommandGroup>

            <CommandSeparator />

            {/* Navigate */}
            <CommandGroup heading="Navigate">
              <CommandItem>
                <ArrowUpRightIcon
                  size={16}
                  className="opacity-60"
                  aria-hidden="true"
                />

                <span>Go to workspace</span>
              </CommandItem>

              <CommandItem>
                <ArrowUpRightIcon
                  size={16}
                  className="opacity-60"
                  aria-hidden="true"
                />

                <span>Go to templates</span>
              </CommandItem>

              <CommandItem>
                <ArrowUpRightIcon
                  size={16}
                  className="opacity-60"
                  aria-hidden="true"
                />

                <span>Go to documentation</span>
              </CommandItem>

              <CommandItem>
                <ArrowUpRightIcon
                  size={16}
                  className="opacity-60"
                  aria-hidden="true"
                />

                <span>Go to blocks</span>
              </CommandItem>

              <CommandItem>
                <ArrowUpRightIcon
                  size={16}
                  className="opacity-60"
                  aria-hidden="true"
                />

                <span>Go to icons</span>
              </CommandItem>
            </CommandGroup>

            <CommandSeparator />

            {/* Themes */}
            <CommandGroup heading="Themes">
              <CommandItem>
                <PaletteIcon
                  size={16}
                  className="opacity-60"
                  aria-hidden="true"
                />

                <span>Switch theme</span>

                <CommandShortcut>⌘⇧T</CommandShortcut>
              </CommandItem>
            </CommandGroup>
          </CommandList>
        </Command>
      </CommandDialog>
    </div>
  )
}

More from designali

Browse all components in this library →