All files / src/components/Navbar NavItem.tsx

0% Statements 0/21
0% Branches 0/48
0% Functions 0/5
0% Lines 0/20

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                                                                                                                                                                                   
import React, { ReactElement, useCallback } from 'react';
import Icon from '../Icon/Icon';
import { IconName } from '../Icon/icons';
import './styles.scss';
import { SubNavbarProps } from './SubNavbar';
import theme from '../../theme';
 
export interface NavItemProps {
  label: string | React.ReactNode;
  icon?: IconName;
  iconColor?: string;
  children?: ReactElement<SubNavbarProps>;
  disabled?: boolean;
  selected?: boolean;
  onClick?: (open: boolean | undefined) => void;
  id?: string;
  isFooter?: boolean;
  href?: string; // menu is an anchor tag
}
 
export default function NavItem(props: NavItemProps): JSX.Element {
  const { label, icon, iconColor, children: childrenProps, disabled, selected, onClick, id, isFooter, href } = props;
  const children = href ? null : childrenProps;
 
  const hasChildrenSelected = useCallback(() => {
    if (children && children.props && children.props.children) {
      const subChildren = children.props.children;
      if (Array.isArray(subChildren)) {
        return subChildren.some((subChild) => subChild.props && subChild.props.selected);
      }
 
      return subChildren.props && subChildren.props.selected;
    }
 
    return false;
  }, [children]);
 
  React.useEffect(() => {
    if (hasChildrenSelected()) {
      setOpen(true);
    }
  }, [children, hasChildrenSelected, selected]);
 
  const [open, setOpen] = React.useState(hasChildrenSelected());
 
  const onClickHandler = () => {
    if (!disabled) {
      setOpen(!open || hasChildrenSelected());
      if (onClick) {
        onClick(!open);
      }
    }
  };
 
  const customLabel = typeof label !== 'string';
 
  return (
    <div
      className={`
        nav-item 
        ${selected ? 'nav-item--selected' : ''}
        ${hasChildrenSelected() ? 'nav-item--children-selected' : ''}
        ${isFooter ? 'nav-item--footer' : ''}
        ${children ? 'nav-item--has-children' : ''}
      `}
    >
      <button
        className={`
          ${customLabel ? 'nav-item-custom-content' : 'nav-item-content'}
          ${disabled ? 'nav-item--disabled' : ''}
        `}
        onClick={onClickHandler}
        id={id}
      >
        {icon && (
          <Icon name={icon} className='nav-item--icon' fillColor={iconColor ?? theme.palette.TwClrIcnSecondary} />
        )}
        {!href && <span className='nav-item--label'>{label}</span>}
        {href && (
          <a className='nav-item--label nav-item--anchor' href={href} rel='noopener noreferrer' target='_external'>
            {label}
          </a>
        )}
        {children && <Icon name={open ? 'chevronUp' : 'chevronDown'} className='nav-item--arrow' />}
      </button>
      {children && open && children}
    </div>
  );
}