Fluid Navbar

An expanding navigation bar with image-backed dropdown panels, responsive sizing, and hover or click interactions.

Installation

  1. 1

    Install the component:

    npx shadcn@latest add https://ui.amines.fun/r/fluid-navbar.json
  2. 2

    Usage:

    jsx

    app/page.jsx

    import Link from "next/link";import ALogo from "@/assets/ALogo";import FluidNavbar from "@/registry/blocks/FluidNavbar";const AMINES_NAV_MENU = {  Components: [    {      label: "Buttons",      href: "/components/button",      description:        "Tactile micro-interactive button variants with spring physics",      image: "/demo/button.png",      tag: "Micro-interaction",    },    {      label: "Split Stack",      href: "/components/split-stack",      description: "Interactive layered card stack with fluid drag physics",      image: "/bg.jpg",      tag: "Interactive Cards",    },    {      label: "Split Stack Photo",      href: "/components/split-stack-photo",      description: "Smooth photographic stack with 3D tilt & swipe controls",      image: "/bg2.jpg",      tag: "Gallery Showcase",    },    {      label: "Split Stack Particles",      href: "/components/split-stack-particles",      description: "Dynamic particle-infused cards with reactive velocity",      image: "/bg3.jpg",      tag: "Particle FX",    },  ],  Illustrations: [    {      label: "Mechanical Keyboard",      href: "/illustrations/keyboard-illustration",      description:        "Physical mechanical keyboard with keycap clicks & trigger states",      image: "/demo/keyboard.png",      tag: "Hardware Motion",    },    {      label: "Note Folder",      href: "/illustrations/note-folder",      description: "Tactile interactive folder with draggable document sheets",      image: "/demo/notesfolder.png",      tag: "Tactile Documents",    },    {      label: "Amines Showcase",      href: "/illustrations",      description:        "Handcrafted dynamic vector motion illustrations and scenes",      image: "/demo/amines.png",      tag: "Creative Motion",    },  ],  Blocks: [    {      label: "Fluid Navbar",      href: "/blocks/fluid-navbar",      description:        "Expanding glass pill with direction-aware slide & image preview",      image: "/demo/amines.png",      tag: "Navigation Bar",    },    {      label: "Pricing Section",      href: "/blocks/pricing-block",      description:        "Conversion-optimized pricing with text morphing & step glitter",      image: "/bg.jpg",      tag: "Marketing Section",    },    {      label: "Logo Cloud",      href: "/blocks/logo-cloud",      description:        "Infinite marquee carousel with cursor-centered photo reveals",      image: "/bg4.jpg",      tag: "Social Proof",    },  ],  Pricing: "/#pricing",};export default function Page() {  return (    <FluidNavbar      position="fixed"      offset={100}      logo={        <Link          href="/"          className="group flex items-center gap-2 outline-none"          aria-label="Amines homepage"        >          <ALogo            size={24}            className="text-white transition-transform duration-300 group-hover:scale-110"          />          <span className="shrink-0 text-[14px] font-semibold tracking-tight text-white/95">            Amines UI          </span>        </Link>      }      menu={AMINES_NAV_MENU}      cta={{        label: "Get Lifetime",        href: "/#pricing",      }}      expandedWidth={780}      panelHeight={350}      backdrop={true}    />  );}

Props

PropTypeDefaultDescription
menuRecord<string, string | Array<string | { label: string; href?: string; description?: string; image?: string; imageAlt?: string; tag?: string; external?: boolean }>>—Simple navigation configuration. A string value creates a direct link; an array creates a dropdown whose links can include descriptions, images, tags, and custom destinations.
itemsArray<{ id?: string; label: string; href?: string; heading?: string; image?: string; imageAlt?: string; caption?: string; footer?: { label: string; href: string }; links?: Array<{ label: string; href: string; description?: string; image?: string; imageAlt?: string; tag?: string; external?: boolean }> }>—Advanced full-control navigation data. When provided, these items are used instead of menu.
ctafalse | string | { label: string; href?: string; onClick?: () => void; icon?: ReactNode }Contact link to /contact when omittedCTA configuration. A string sets its destination; false hides the CTA; an object supports a custom label, destination, callback, and icon.
ctaLabelstring"Contact"Label used for string or default CTA values.
logoReactNode—Optional content displayed at the start of the navigation bar.
trigger"hover" | "click""hover"How dropdown panels are opened.
openDelaynumber0Hover delay before opening a dropdown, in milliseconds.
closeDelaynumber180Hover delay before closing a dropdown, in milliseconds.
activeIdstring | null—Controlled active navigation item ID. Pair with onActiveChange.
defaultActiveIdstring | nullnullInitially active navigation item ID when the active state is uncontrolled.
onActiveChange(activeId: string | null) => void—Called when the active navigation item changes.
closeOnEscapebooleantrueClose an open dropdown when Escape is pressed.
closeOnOutsideClickbooleantrueClose an open dropdown when the user clicks outside the navigation.
closeOnNavigatebooleantrueClose an open dropdown after a panel link is activated.
position"fixed" | "absolute" | "static""fixed"Positioning mode for the navigation bar.
offsetnumber24Distance from the top edge in pixels for fixed and absolute positioning.
barHeightnumber56Collapsed navigation bar height in pixels.
expandedWidthnumber760Expanded navigation panel width in pixels, capped to the viewport width.
panelHeight"auto" | number"auto"Dropdown panel height. A number forces a pixel height and enables internal scrolling when needed.
minPanelHeightnumber300Minimum dropdown panel height in pixels.
maxPanelHeightnumber—Maximum dropdown panel height in pixels. Defaults to the available viewport height.
zIndexnumber50Stacking order for the navigation and its backdrop.
imagePropsPartial<NextImageProps>{}Additional props forwarded to next/image for panel preview images.
imageSizesstring"380px"Sizes hint passed to next/image for panel preview images.
preloadLimitnumber16Maximum number of distinct panel preview images kept mounted for quick switching.
transitionFramerMotionTransition—Spring or duration transition settings for the navigation layout.
staggernumber0.045Stagger interval in seconds for dropdown content entrance.
animateOnMountbooleantrueAnimate the navigation bar into place when it first mounts.
magneticCtabooleantrueEnable the pointer-following magnetic effect on the CTA.
imageParallaxbooleantrueEnable pointer-driven parallax on dropdown preview images.
showIndicesbooleanfalseShow numbered indices beside dropdown links.
backdropbooleanfalseShow a dimmed page backdrop while a dropdown is open.
showCloseButtonbooleantrueShow the dropdown panel close button.
closeButtonPlacement"center" | "right""center"Position of the dropdown close button.
closeButtonSizenumber48Close button size in pixels.
closeButtonOffsetnumber-8Pixel offset used to position the dropdown close button.
theme{ background?: string; foreground?: string; muted?: string; hover?: string; border?: string; ctaBackground?: string; ctaForeground?: string; closeBackground?: string; shadow?: string }—Override navigation, panel, CTA, close button, and shadow colors.
classNamestring—Additional class names applied to the outer positioning container.
classNamesPartial<Record<"container" | "bar" | "item" | "panel" | "heading" | "link" | "linkLabel" | "linkDescription" | "imageWrap" | "image" | "caption" | "footer" | "cta" | "closeButton", string>>{}Optional class names for the navigation container, bar, links, dropdown content, images, footer, CTA, and close button.
renderPanel({ item, close }: { item: NavigationItem; close: () => void }) => ReactNode—Custom dropdown panel renderer. Receives the active item and a callback to close the panel.
ariaLabelstring"Main navigation"Accessible name for the navigation landmark.