All files / NavigationBar/NavigationBarItem NavigationBarItem.tsx

100% Statements 49/49
96.96% Branches 32/33
100% Functions 9/9
100% Lines 45/45

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 107 108 109 110 111 112 113 1142x         2x 2x 2x 2x 2x   2x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x   33x 33x 33x 33x   33x   33x 18x   33x 33x   33x 2x 2x 2x   33x 2x 2x 2x 2x       33x                                                 2x 2x   2x                   25x       25x         25x           25x         25x     2x      
import React from "react";
import {
  NavigationBarItemProps,
  NavigationBarItemStyleProps,
} from "./NavigationBarItem.types";
import styled from "styled-components";
import Text from "../../Text/Text";
import { useTheme } from "../../ThemeProvider/ThemeProvider";
import colorTokens from "../../../tokens/colors.json";
import { getColorPalette } from "../../../helpers/helpers";
 
const NavigationBarItem = ({
  _index,
  value,
  children,
  leadingIcon,
  trailingIcon,
  className,
  style,
  size,
  selected = false,
  color = colorTokens.default.primary.main,
  // Events
  _getSelectedIndex,
  onClick,
  "data-testid": dataTestId,
  ...props
}: NavigationBarItemProps) => {
  const [_selected, setSelected] = React.useState(selected);
 
  React.useEffect(() => {
    setSelected(selected);
  }, [selected]);
  const theme = useTheme().theme;
  const colorPalette = getColorPalette(theme, color);
 
  const _onClick = (e: React.MouseEvent) => {
    setSelected(true);
    _getSelectedIndex && _getSelectedIndex(_index, value);
    onClick && onClick(e);
  };
  const _onKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "Enter" || e.key === " ") {
      setSelected(true);
      _getSelectedIndex && _getSelectedIndex(_index, value);
      onClick && onClick(e);
    }
  };
 
  return (
    <StyledNavBarItem
      tabIndex={0}
      $selected={_selected}
      $colorPalette={colorPalette}
      $color={color}
      className={className}
      style={style}
      onClick={_onClick}
      onKeyDown={_onKeyDown}
      data-testid={dataTestId}
      {...props}
    >
      {leadingIcon && <StyledNavBarIcon>{leadingIcon}</StyledNavBarIcon>}
      {typeof children === "string" ? (
        <Text color={color} variant="span" size={size}>
          {children}
        </Text>
      ) : (
        children
      )}
      {trailingIcon && <StyledNavBarIcon>{trailingIcon}</StyledNavBarIcon>}
    </StyledNavBarItem>
  );
};
NavigationBarItem.displayName = "NavigationBarItem";
export default NavigationBarItem;
 
const StyledNavBarItem = styled.li<NavigationBarItemStyleProps>`
  display: flex;
  flex-direction: row;
  gap: 0.5rem;
  align-items: center;
  cursor: pointer;
  border-radius: 0.5rem;
  padding: 0.3rem 0.75rem;
  margin: 0 0.5rem;
  color: ${(props) =>
    props.$selected
      ? props.$colorPalette[props.$color].accentScale[10]
      : props.$colorPalette[props.$color].grayScale[11]};
  background-color: ${(props) =>
    props.$selected
      ? props.$colorPalette[props.$color].accentScale[2]
      : "transparent"};
  &:hover {
    background-color: ${(props) =>
      props.$selected
        ? props.$colorPalette[props.$color].accentScale[3]
        : props.$colorPalette[props.$color].grayScale[1]};
  }
  &:active {
    background-color: ${(props) =>
      props.$selected
        ? props.$colorPalette[props.$color].accentScale[4]
        : props.$colorPalette[props.$color].grayScale[2]};
  }
  &:focus-visible {
    outline: 1px solid ${(props) => props.$colorPalette[props.$color].accentScale[6]};
  }
`;
const StyledNavBarIcon = styled.span`
  margin-left: auto;
`;