All files / src/app/layout/sidebar NavItem.tsx

83.96% Statements 89/106
100% Branches 5/5
50% Functions 1/2
83.96% Lines 89/106

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 1071x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x                                   11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x  
/**
 * @file NavItem.tsx
 * @module app/layout/sidebar/NavItem
 *
 * @summary
 * Individual navigation list item with route matching and disabled state support.
 * Highlights current route and supports feature flag-based disabling.
 *
 * @enterprise
 * - Route matching with active state highlighting
 * - Disabled state with tooltips for feature flags
 * - MUI ListItemButton integration with routing
 * - Full TypeDoc coverage for navigation state and user feedback
 */
 
import {
  ListItemButton,
  ListItemIcon,
  ListItemText,
  Tooltip,
} from '@mui/material';
import { Link, useLocation } from 'react-router-dom';
 
interface NavItemProps {
  /** Route path to navigate to */
  to: string;
 
  /** MUI Icon component to display */
  icon: React.ElementType;
 
  /** Navigation label (translated) */
  label: string | undefined;
 
  /** Whether navigation item is disabled */
  disabled?: boolean;
 
  /** Tooltip text when disabled */
  tooltip?: string;
}
 
/**
 * Navigation item component with route matching and disabled state support.
 *
 * Highlights when current route matches navigation item's route.
 * Shows tooltip when disabled via feature flag.
 *
 * @param props - Navigation item configuration
 * @returns JSX element rendering navigation item or wrapped tooltip
 *
 * @example
 * ```tsx
 * <NavItem
 *   to="/dashboard"
 *   icon={DashboardIcon}
 *   label="Dashboard"
 *   disabled={false}
 * />
 * ```
 */
export default function NavItem({
  to,
  icon: Icon,
  label,
  disabled,
  tooltip,
}: NavItemProps) {
  const location = useLocation();
  const selected = location.pathname === to || (to !== '/' && location.pathname.startsWith(to));
 
  const handleClick = (event: React.MouseEvent) => {
    if (disabled) {
      event.preventDefault();
      event.stopPropagation();
      return;
    }

    try {
      if (localStorage.getItem('debugRouting') === '1') {
        // eslint-disable-next-line no-console
        console.debug('[nav] click -> navigate', to, '| from', window.location.pathname);
      }
    } catch {
      // ignore
    }

    // Let React Router's <Link> handle the navigation.
  };
 
  const button = (
    <ListItemButton
      component={Link}
      to={to}
      onClick={handleClick}
      selected={selected}
      sx={{ borderRadius: 1, mx: 1 }}
      disabled={disabled}
    >
      <ListItemIcon sx={{ minWidth: 36 }}>
        <Icon />
      </ListItemIcon>
      <ListItemText primary={label} />
    </ListItemButton>
  );
 
  return tooltip ? <Tooltip title={tooltip}>{button}</Tooltip> : button;
}