// Copyright (c) Meta Platforms, Inc. and affiliates. 'use client'; /** * @file NavHeadingMenuItem.tsx * @input Uses React, StyleX, Icon, Text, NavMenuContext, useLinkComponent * @output Exports NavHeadingMenuItem component and NavHeadingMenuItemProps type * @position Core implementation; consumed by index.ts * * SYNC: When modified, update: * - /packages/core/src/NavMenu/index.ts */ import React, { useCallback, type ReactNode } from 'react'; import * as stylex from "../style-runtime.js"; import { renderIconSlot, type IconType } from "../Icon/index.js"; import { Text } from "../Text/index.js"; import "../theme/tokens.stylex.js"; import { colorVars, spacingVars, typographyVars, typeScaleVars, radiusVars } from "../theme/tokens.stylex.js"; import { mergeProps } from "../utils/index.js"; import type { BaseProps } from "../BaseProps.js"; import { useNavHeadingMenuContext } from "./NavMenuContext.js"; import { useLinkComponent } from "../Link/useLinkComponent.js"; import { themeProps } from "../utils/themeProps.js"; const styles = { root: { kB7OPa: "x9f619", k1xSpc: "x78zum5", kGNEyG: "x6s0dn4", kOIVth: "x1txdalj", kzqmXN: "xh8yej3", kaIpWk: "xh6dtrn", kMv6JI: "x9ynric", kGuDYH: "xcr08ib", kMwMTN: "x1tgivj0", kWkggS: "xjbqb8w x1c52tdz xoevpu5", kkrTdU: "x1ypdohk x16khyan", k9WMMc: "x1yc453h", kI3sdo: "x1a2a7pz", kybGjl: "x1hl2dhg", $$css: true as const }, disabled: { kSiTet: "xbyyjgo", kkrTdU: "xt0e3qv", $$css: true as const } }; const sizeStyles = { sm: { k8WAf4: "xu0wf1k", kg3NbH: "xf314gf", $$css: true as const }, md: { k8WAf4: "xce4md1", kg3NbH: "xf314gf", $$css: true as const }, lg: { k8WAf4: "x8o8v82", kg3NbH: "xrrkdod", $$css: true as const } }; export interface NavHeadingMenuItemProps extends Omit, 'onClick'> { ref?: React.Ref; /** Icon to display before the label. */ icon?: ReactNode | IconType; /** Primary label text. */ label: ReactNode; /** Secondary description text displayed below the label. */ description?: ReactNode; /** URL to navigate to. Renders as an anchor element when provided. */ href?: string; /** Callback when the item is selected. */ onClick?: () => void; /** Whether the item is disabled. @default false */ isDisabled?: boolean; } /** * Menu item for nav heading popovers. * * Reads size from the parent NavHeadingMenu for consistent padding. * Automatically dismisses the menu on click via context. * Renders as a link when `href` is provided. * * @example * ``` * * * * * ``` */ export function NavHeadingMenuItem({ ref, icon, label, description, href, onClick, isDisabled = false, xstyle, className, style, 'data-testid': testId }: NavHeadingMenuItemProps) { const ctx = useNavHeadingMenuContext(); const size = ctx?.size ?? 'md'; const handleClick = useCallback(() => { if (isDisabled) { return; } onClick?.(); ctx?.closeMenu(); }, [isDisabled, onClick, ctx]); const LinkComponent = useLinkComponent(); const Element = href ? LinkComponent : 'div'; return {icon && renderIconSlot(icon, { size: 'sm', color: 'secondary' })} {typeof label === 'string' ? {label} : label} {description && {description} } ; } NavHeadingMenuItem.displayName = 'NavHeadingMenuItem';