"use client"; /** * Figma: "Utility / Menu Item" (see registry) */ import { memo } from "react"; import MenuItemView from "./MenuItem.view"; import type { MenuItemProps } from "./MenuItem.types"; const MenuItemContainer = memo( ({ href = "#", buttonOnClick, children, state: stateProp, mode: modeProp, icon: _icon = false, size: sizeProp = "X Small", className = "", disabled = false, reducedPadding = false, ariaLabel, ...props }) => { const state = stateProp ?? "default"; const mode = modeProp ?? "default"; const size = sizeProp ?? "X Small"; // Size styles based on Figma specifications const sizeStyles: Record< "X Small" | "Small" | "Medium" | "Large" | "X Large", string > = { "X Small": reducedPadding ? "px-[var(--space-100)] py-[var(--space-050)]" : "px-[var(--space-100)] py-[var(--space-050)]", Small: "px-[var(--space-100)] py-[var(--space-050)]", Medium: reducedPadding ? "px-[var(--space-050)] py-[var(--space-200)] h-[32px]" : "px-[var(--space-200)] py-[var(--space-200)] h-[32px]", Large: "px-[var(--space-400)] py-[var(--space-400)] h-[44px]", "X Large": "px-[var(--space-400)] py-[var(--space-400)] h-[44px]", }; // Text styles based on Figma specifications const textStyles: Record< "X Small" | "Small" | "Medium" | "Large" | "X Large", string > = { "X Small": "text-xx-small-label", Small: "text-x-small-label", Medium: "text-x-small-label", Large: "text-medium-label", "X Large": "text-x-large-label", }; // State styles for Default mode (yellow text on dark background) const defaultModeStyles: Record<"default" | "hover" | "selected", string> = { default: "bg-transparent text-[var(--color-content-default-brand-primary)] hover:bg-[var(--color-gray-800)] hover:text-[var(--color-content-default-brand-primary)]", hover: "bg-[var(--color-gray-800)] text-[var(--color-content-default-brand-primary)]", selected: "border border-[var(--color-border-default-brand-primary)] text-[var(--color-content-default-brand-primary)] bg-transparent hover:bg-[var(--color-gray-800)]", }; // State styles for Inverse mode (black text on yellow HeaderTab / inverse surfaces) const inverseModeStyles: Record<"default" | "hover" | "selected", string> = { default: "bg-transparent text-[var(--color-content-invert-primary)] hover:bg-[var(--color-surface-invert-brand-secondary)] hover:text-[var(--color-content-invert-primary)]", hover: "bg-[var(--color-surface-invert-brand-secondary)] text-[var(--color-content-invert-primary)]", selected: "border border-[var(--color-border-default-primary)] text-[var(--color-content-invert-primary)] bg-transparent hover:bg-[var(--color-surface-invert-brand-secondary)]", }; // Get state styles based on mode const stateStyles = mode === "inverse" ? inverseModeStyles : defaultModeStyles; // Base styles const baseStyles = `inline-flex items-center whitespace-nowrap ${sizeStyles[size]} ${textStyles[size]} rounded-[var(--radius-full)] transition-all duration-200 ease-in-out cursor-pointer`; // Interactive styles const interactiveStyles = "active:scale-[0.98] disabled:opacity-50 disabled:cursor-not-allowed disabled:active:scale-100"; // Disabled styles const disabledStyles = disabled ? "bg-[var(--color-surface-default-tertiary)] text-[var(--color-content-default-tertiary)]" : ""; // Combine all styles const combinedStyles = `${baseStyles} ${stateStyles[state]} ${interactiveStyles} ${disabledStyles} ${className}`; const accessibilityProps = { ...(ariaLabel && { "aria-label": ariaLabel }), ...(disabled && { "aria-disabled": true }), ...(state === "selected" && { "aria-current": "page" as const }), role: "menuitem" as const, tabIndex: disabled ? -1 : 0, ...props, }; return ( {children} ); }, ); MenuItemContainer.displayName = "MenuItem"; export default MenuItemContainer;