// Copyright (c) Meta Platforms, Inc. and affiliates. 'use client'; /** * @file TopNavMegaMenuFeaturedCard.tsx * @input Uses React, StyleX, theme tokens * @output Exports TopNavMegaMenuFeaturedCard component * @position Standard featured card for the TopNavMegaMenu featured slot. * * Provides a consistent appearance for promotional/featured content in mega menus. * The `featured` slot on TopNavMegaMenu is still open ReactNode — this component * is the standard card, but consumers can pass anything. * * 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, typeScaleVars, fontWeightVars } from "../theme/tokens.stylex.js"; import { mergeProps } from "../utils/index.js"; import type { BaseProps } from "../BaseProps.js"; import { useLinkComponent } from "../Link/useLinkComponent.js"; import { themeProps } from "../utils/themeProps.js"; // ============================================================================= // Styles // ============================================================================= const styles = { root: { k1xSpc: "x78zum5", kXwgrk: "xdt5ytf", $$css: true as const } }; // ============================================================================= // Types // ============================================================================= export interface TopNavMegaMenuFeaturedCardProps extends BaseProps { ref?: React.Ref; /** Card title. */ title: string; /** Description text below the title. */ description?: string; /** Optional image URL displayed above the body. */ image?: string; /** * Alt text for the image. * * When omitted, the image is explicitly decorative (`alt=""` + * `role="presentation"` + `aria-hidden`, matching Avatar) and hidden from * assistive technology. Since the card already has a visible `title`, a * decorative image is usually correct; pass `imageAlt` only when the image * conveys information beyond the title and description. */ imageAlt?: string; /** CTA link text. */ linkLabel?: string; /** CTA link URL. */ linkHref?: string; /** Custom content rendered below the standard body. */ children?: ReactNode; } // ============================================================================= // Component // ============================================================================= /** * Standard featured card for the TopNavMegaMenu `featured` slot. * * Provides a consistent card with optional image, title, description, * and CTA link. For fully custom content, pass any ReactNode directly * to the `featured` slot instead. * * @example * ``` * * } * /> * ``` */ export function TopNavMegaMenuFeaturedCard({ ref, title, description, image, imageAlt, linkLabel, linkHref, children, xstyle, className, style, ...rest }: TopNavMegaMenuFeaturedCardProps) { const LinkComponent = useLinkComponent(); return
{image && // Without `imageAlt`, the image is explicitly decorative rather than // silently empty-alt, matching Avatar's handling of unnamed images. // Usually correct here: the card already has a visible title. {imageAlt}
{title} {description && {description}} {linkLabel && linkHref && {linkLabel} → } {children}
; } TopNavMegaMenuFeaturedCard.displayName = 'TopNavMegaMenuFeaturedCard';