All files / NavigationBar NavigationBar.tsx

97.87% Statements 46/47
94.11% Branches 32/34
100% Functions 6/6
97.61% Lines 41/42

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                   7x   7x     2x 7x 7x 7x 7x   7x 7x 7x   7x     7x 7x   7x   7x 7x 2x 2x     7x   7x 55x   49x 25x 25x                   24x 12x   42x 36x 36x                 6x 6x                     12x     7x                         2x   2x  
import React from "react";
import {
  NavigationBarProps,
  NavigationBarStyleProps,
} from "./NavigationBar.types";
import styled from "styled-components";
import { useTheme } from "../ThemeProvider/ThemeProvider";
import { NavigationBarGroupProps } from "./NavigationBarGroup/NavigationBarGroup.types";
import { NavigationBarGroupItemProps } from "./NavigationBarGroupItem/NavigationBarGroupItem.types";
import { getColorPalette } from "../../helpers/helpers";
import colorTokens from "../../tokens/colors.json";
 
const StyledNavigationBarCtr = styled.div<NavigationBarStyleProps>`
  display: flex;
  flex-direction: column;
  position: sticky;
  left: 0;
  top: 0;
  height: 100vh;
  width: 15rem;
  overflow: scroll;
  border-right: ${(props) =>
    `1px solid ${props.$colorPalette[props.$color].grayScale[5]}`};
  background-color: ${(props) =>
    props.$colorPalette[props.$color].grayScale[0]};
`;
 
const NavigationBar: React.FC<NavigationBarProps> = ({
  children,
  className,
  style,
  color = colorTokens.default.primary.main,
  // Events
  onChange,
  "data-testid": dataTestId,
  ...props
}) => {
  const [selectedIndex, setSelectedIndex] = React.useState<
    number | undefined
  >();
  const theme = useTheme().theme;
  const colorPalette = getColorPalette(theme, color);
 
  const childrenList = Array.isArray(children) ? children : [children];
 
  const _handleSelectedIndex = (index?: number, value?: string) => {
    if (index === selectedIndex) return;
    setSelectedIndex(index);
    onChange && onChange(value);
  };
 
  let index = 0;
 
  const ChildrenEle = React.Children.map(childrenList, (child) => {
    if (!React.isValidElement(child) || !child.type) return child;
 
    if ((child.type as any).displayName === "NavigationBarItem") {
      index++;
      return React.cloneElement(child, {
        _index: index,
        ...(color && !child.props.color && { color: color }),
        selected: selectedIndex
          ? selectedIndex === index
          : child.props.selected,
        _getSelectedIndex: _handleSelectedIndex,
      } as Partial<NavigationBarGroupProps>);
    }
 
    if ((child.type as any).displayName === "NavigationBarGroup") {
      return React.cloneElement(child, {
        children: React.Children.map(child.props.children, (child) => {
          if (child.type.displayName === "NavigationBarGroupItem") {
            index++;
            return React.cloneElement(child, {
              _index: index,
              _getSelectedIndex: _handleSelectedIndex,
              ...(color && !child.props.color && { color: color }),
              // todo
              selected: selectedIndex
                ? selectedIndex === index
                : (child.props as any).selected,
            } as Partial<NavigationBarGroupItemProps>);
          } else if (child.type.displayName === "NavigationBarHeader") {
            return React.cloneElement(child, {
              ...(color && !child.props.color && { color: color }),
            });
          } else E{
            return child;
          }
        }),
        ...(color && !child.props.color && { color: color }),
      } as Partial<NavigationBarGroupProps>);
    }
 
    return child;
  });
 
  return (
    <StyledNavigationBarCtr
      $color={color}
      $colorPalette={colorPalette}
      className={className}
      style={style}
      data-testid={dataTestId}
      {...props}
    >
      <nav>{ChildrenEle}</nav>
    </StyledNavigationBarCtr>
  );
};
NavigationBar.displayName = "NavigationBar";
 
export default NavigationBar;