'use client'; import * as React from 'react'; import { useState } from 'react'; import { Menu, X } from 'lucide-react'; import { Button } from '../../ui/button'; import { LanguageSelector } from '../../brand/language-selector'; import { cn } from '../../shared/utils'; /** * A single navigation link rendered in the navbar. */ export interface MarketingNavLink { label: string; href: string; } /** * A call-to-action button rendered on the right side of the navbar. */ export interface MarketingNavbarCta { label: string; href?: string; onClick?: () => void; } export interface MarketingNavbarProps { /** Logo slot — pass a rendered logo element (e.g. ``). */ logo: React.ReactNode; /** Primary navigation links, shown inline on desktop and stacked on mobile. */ links: MarketingNavLink[]; /** Primary call-to-action, rendered as a solid `Button`. */ cta?: MarketingNavbarCta; /** Secondary call-to-action, rendered as an outline `Button`. */ secondaryCta?: MarketingNavbarCta; /** Shows the design system's language selector. Defaults to `true` — `LanguageSelector` auto-hides itself when only one language is configured. */ showLanguageSelector?: boolean; /** Accessible label for the mobile menu trigger when closed. */ openMenuLabel?: string; /** Accessible label for the mobile menu trigger when open. */ closeMenuLabel?: string; className?: string; } /** * Sticky header for public marketing pages. * * @description * Distinct from the app-shell `Header` (used inside the authenticated product layout): * this navbar is for public-facing marketing sites, with a logo slot, inline nav links, * and up to two CTA buttons. Collapses into a full-width dropdown panel on mobile. * * @ai-rules * 1. Pass the logo as a rendered node via the `logo` prop — do not couple this file to any specific logo component. * 2. Use `cta` for the primary action (solid button) and `secondaryCta` for a lower-emphasis action (outline button). * 3. Each link/CTA needs either `href` (renders an ``) or `onClick` — CTAs support both. */ export function MarketingNavbar({ logo, links, cta, secondaryCta, showLanguageSelector = true, openMenuLabel = 'Open menu', closeMenuLabel = 'Close menu', className, }: MarketingNavbarProps) { const [isOpen, setIsOpen] = useState(false); const closeMenu = () => setIsOpen(false); return (
{/* Mobile dropdown panel */} {isOpen && (
{links.map(link => ( {link.label} ))} {showLanguageSelector && (
)} {(secondaryCta || cta) && (
{secondaryCta && ( )} {cta && ( )}
)}
)}
); }