// Copyright (c) Meta Platforms, Inc. and affiliates. 'use client'; /** * @file TopNavMegaMenuItem.tsx * @input Uses React, StyleX, theme tokens, navItemStyles, TopNavRenderContext * @output Exports TopNavMegaMenuItem component and props * @position Individual item inside an TopNavMegaMenu — renders itself in both * desktop (popover) and mobile drawer modes. * * SYNC: When modified, update these files to stay in sync: * - /packages/core/src/TopNav/TopNav.doc.mjs * - /packages/core/src/TopNav/index.ts * - /packages/cli/assets/templates/blocks/components/TopNav/ (showcase blocks) */ import React, { type ReactNode } from 'react'; import * as stylex from "../style-runtime.js"; import "../theme/tokens.stylex.js"; import { colorVars, spacingVars, radiusVars, durationVars, easeVars, typeScaleVars, fontWeightVars } from "../theme/tokens.stylex.js"; import { navItemStyles } from "../NavItem/navItemStyles.stylex.js"; import { useLinkComponent } from "../Link/useLinkComponent.js"; import type { LinkComponentType } from "../Link/types.js"; import { useTopNavRenderMode } from "./TopNavRenderContext.js"; import { mergeProps } from "../utils/index.js"; import type { BaseProps } from "../BaseProps.js"; import { useAppShellMobile } from "../AppShell/AppShellMobileContext.js"; import { themeProps } from "../utils/themeProps.js"; import { focusOutlineProps } from "../utils/focusOutline.stylex.js"; import { interactionOverlayStyles } from "../utils/interactionOverlay.stylex.js"; // ============================================================================= // Styles // ============================================================================= const styles = { desktop: { k1xSpc: "x78zum5", kGNEyG: "x1cy8zhl", kOIVth: "xjcht0a", k8WAf4: "x8o8v82", kg3NbH: "xrrkdod", kaIpWk: "xh6dtrn", kybGjl: "x1hl2dhg", kkrTdU: "x1ypdohk x16khyan", k1ekBW: "x15406qy", kIyJzY: "xuedmi6", kAMwcw: "xlr8y92", kMwMTN: "x1heor9g", kMv6JI: "xjb2p0i", k9WMMc: "x1yc453h", kB7OPa: "x9f619", kzqmXN: "xh8yej3", $$css: true as const }, drawerItem: { kZCmMZ: "x31w388", kGNEyG: "x1cy8zhl", kybGjl: "x1hl2dhg", $$css: true as const } }; // ============================================================================= // Types // ============================================================================= export interface TopNavMegaMenuItemProps extends Omit, 'onClick'> { ref?: React.Ref; /** Display title for the menu item. */ title: string; /** Optional description text displayed below the title. */ description?: string; /** Optional icon element displayed to the left. */ icon?: ReactNode; /** URL to navigate to when clicked. */ href?: string; /** Callback when item is clicked. */ onClick?: () => void; /** * Custom component to render instead of `` for link items. * Overrides the provider-level default set by LinkProvider. */ as?: LinkComponentType; } // ============================================================================= // Component // ============================================================================= /** * An individual item inside an TopNavMegaMenu. * * Renders itself in both desktop (popover grid) and mobile drawer modes * using TopNavRenderContext to switch appearance. * * @example * ``` * * } * href="/analytics" * /> * * * } * /> * ``` */ export function TopNavMegaMenuItem({ ref, title, description, icon, href, onClick, as, tabIndex }: TopNavMegaMenuItemProps) { const renderMode = useTopNavRenderMode(); const LinkComponent = useLinkComponent(as); const { closeMobileNav } = useAppShellMobile(); // ========================================================================= // Drawer mode — matches SideNavItem / TopNavMenu drawer appearance // ========================================================================= if (renderMode === 'drawer') { const Element = href ? LinkComponent : 'button'; const elementProps = Element === 'button' ? { type: 'button' as const } : {}; const handleDrawerClick = () => { onClick?.(); closeMobileNav(); }; return {icon &&
{icon}
}
{title} {description && {description} }
; } // ========================================================================= // Default mode — desktop popover item with large icon + description // ========================================================================= const Element = href ? LinkComponent : 'div'; return {icon &&
{icon}
}
{title} {description && {description} }
; } TopNavMegaMenuItem.displayName = 'TopNavMegaMenuItem';