Gooey Navbar Menu

A spring-animated navbar menu with a gooey SVG-filtered background that connects the active trigger and dropdown panel.

Installation

Pro components require registry authentication. Add your Unlumen UI Pro key as UNLUMEN_LICENSE_KEY in your .env.local file and follow the setup guide.

File Structure

gooey-navbar-menu.tsx

Usage

import {
  GooeyNavbarMenu,
  GooeyNavbarMenuContent,
  GooeyNavbarMenuItem,
  GooeyNavbarMenuLink,
  GooeyNavbarMenuList,
  GooeyNavbarMenuTrigger,
} from "@/components/unlumen-ui/gooey-navbar-menu";

const contentHighlightClassName =
  "bg-primary/10 rounded-lg ring-1 ring-primary/15";

export default function Example() {
  return (
    <GooeyNavbarMenu
      viewportClassName="bg-surface border-none shadow-none"
      gooeyClassName="bg-surface rounded-xl"
      gooeyStrength={12}
    >
      <GooeyNavbarMenuList>
        <GooeyNavbarMenuItem value="products">
          <GooeyNavbarMenuTrigger>Products</GooeyNavbarMenuTrigger>
          <GooeyNavbarMenuContent
            highlightClassName={contentHighlightClassName}
          >
            <div className="grid w-[400px] grid-cols-2 gap-1">
              <GooeyNavbarMenuLink href="/analytics">
                <span className="text-sm font-medium">Analytics</span>
                <span className="text-muted-foreground text-xs">
                  Understand your data flow.
                </span>
              </GooeyNavbarMenuLink>
              <GooeyNavbarMenuLink href="/automation">
                <span className="text-sm font-medium">Automation</span>
                <span className="text-muted-foreground text-xs">
                  Streamline workflows.
                </span>
              </GooeyNavbarMenuLink>
            </div>
          </GooeyNavbarMenuContent>
        </GooeyNavbarMenuItem>

        <GooeyNavbarMenuItem>
          <GooeyNavbarMenuLink
            href="/pricing"
            className="px-4 py-2 text-sm font-medium"
          >
            Pricing
          </GooeyNavbarMenuLink>
        </GooeyNavbarMenuItem>
      </GooeyNavbarMenuList>
    </GooeyNavbarMenu>
  );
}

API Reference

GooeyNavbarMenu

PropTypeDefaultDescription
viewport?booleantrueWhen true, renders content inside the shared morphing viewport. The gooey bridge is only rendered when the shared viewport is enabled.
viewportClassName?string-Additional classes applied to the morphing viewport.
gooey?booleantrueWhen true, renders the SVG-filtered background that connects the active trigger and shared viewport.
gooeyClassName?string-Additional classes applied to the gooey background shapes. Match this to the viewport background for the cleanest merge.
gooeyFilterId?string-Custom SVG filter id used by the gooey background. Useful when you need a stable id.
gooeyStrength?number12Blur strength used by the gooey SVG filter. Higher values create a stronger merge between shapes.
springBounce?number0Bounce used by the spring transition for the viewport, bridge, and content animations.
springStiffness?number350Stiffness used by the spring transition for the viewport, bridge, and content animations.
springDamping?number32Damping used by the spring transition for the viewport, bridge, and content animations.
value?string-Controlled active item value. Use an empty string to close the menu.
onValueChange?(value: string) => void-Callback fired when the active item value changes.
className?string-Additional classes applied to the root element.

GooeyNavbarMenuList

PropTypeDefaultDescription
className?string-Additional classes applied to the list element.
highlightClassName?string-Additional classes applied to the hover highlight rendered behind trigger items.

GooeyNavbarMenuItem

PropTypeDefaultDescription
value?string-Unique identifier for this item. Required when the item has a Trigger + Content pair.
className?string-Additional classes applied to the list item.

GooeyNavbarMenuTrigger

PropTypeDefaultDescription
className?string-Additional classes applied to the trigger button.
children?React.ReactNode-Trigger content.

GooeyNavbarMenuContent

Renders the panel shown when the parent item's trigger is active. Must be placed inside a GooeyNavbarMenuItem that has a value prop. The content is rendered into the morphing container, so its width drives the container and gooey bridge animation.

PropTypeDefaultDescription
className?string-Additional classes applied to the content wrapper.
highlightClassName?string-Additional classes applied to the hover highlight rendered behind links inside the content.
innerClassName?string-Additional classes applied to the inner content container.

GooeyNavbarMenuLink

PropTypeDefaultDescription
href?string-Destination URL for the anchor.
className?string-Additional classes applied to the link.
children?React.ReactNode-Link content.

Notes

  • Gooey bridge: the active trigger and shared viewport are connected by an SVG-filtered background layer. Use gooeyClassName to match the viewport color.
  • Shared viewport: with viewport enabled, open content is rendered inside one morphing viewport that animates width, height, opacity, and scale.
  • Direction-aware transitions: switching between menus slides content horizontally based on whether the new item is to the left or right of the previous one.
  • Controlled mode: pass value and onValueChange to control the active item from outside the component.
  • Overflow clamping: the dropdown automatically stays within its nearest clipping ancestor — no configuration needed when the menu is inside a constrained container like a preview panel or modal.

Credits

Built by leo.

Keep in mind

Most components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.