All files / src/shared/Table GiveTableHeader.tsx

80% Statements 8/10
76.19% Branches 16/21
50% Functions 2/4
77.77% Lines 7/9

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 114              77x                                     77x                     3284x 3284x 3284x   3284x                                                                                                         3284x                                      
import { Box, SxProps, TableCell, TableCellBaseProps } from "@mui/material";
import { CaretDownIcon } from "@phosphor-icons/react";
import GiveText from "@shared/Text/GiveText";
import { useCustomThemeV2 } from "@theme/hooks/useCustomThemeV2";
import { styled, useAppTheme } from "@theme/v2/Provider";
import React, { ElementType } from "react";
 
export const HeaderState = {
  ASCENDING: "asc",
  DESCENDING: "desc",
  NONE: "none",
} as const;
interface Props {
  state?: (typeof HeaderState)[keyof typeof HeaderState];
  onClick?: (event: React.MouseEvent<HTMLElement>) => void;
  children?: React.ReactNode;
  width?: number | string;
  sxProps?: SxProps;
  checkBoxElement?: React.ReactNode;
  backgroundElement?: React.ReactNode;
  sxContentProps?: SxProps;
  component?: ElementType<
    TableCellBaseProps,
    keyof React.JSX.IntrinsicElements
  >;
}
const GiveTableHeader = ({
  children,
  state = "none",
  onClick,
  width,
  sxProps,
  checkBoxElement,
  backgroundElement,
  sxContentProps,
  component,
}: Props) => {
  const { palette } = useAppTheme();
  const { isWideView } = useCustomThemeV2();
  const [hovered, setHovered] = React.useState(false);
 
  return (
    <TableCell
      component={component}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      version="two"
      width={width}
      sx={{
        background: palette.surface?.primary,
        ...sxProps,
      }}
    >
      {backgroundElement}
      <Container
        onClick={onClick}
        sx={{
          cursor: onClick ? "pointer" : "default",
          ...sxContentProps,
        }}
      >
        {checkBoxElement && checkBoxElement}
        <GiveText variant="bodyS" color={hovered ? "primary" : "secondary"}>
          {children}
        </GiveText>
 
        {(onClick || state !== HeaderState.NONE) && (
          <CaretDownIcon
            size={16}
            color={
              hovered && isWideView
                ? palette.icon?.["icon-primary"]
                : palette.icon?.["icon-secondary"]
            }
            style={{
              transform: `rotate(${
                state === HeaderState.ASCENDING ? -180 : 0
              }deg)`,
              transition: "transform 0.1s ease, opacity 0.1s ease",
              flexShrink: 0,
              // Keep the icon's space reserved so toggling its visibility on
              // hover never changes the container width or shifts the header.
              opacity:
                (hovered && isWideView) || state !== HeaderState.NONE ? 1 : 0,
            }}
          />
        )}
      </Container>
    </TableCell>
  );
};
 
export default GiveTableHeader;
 
const Container = styled(Box)(() => ({
  gap: "4px",
  display: "flex",
  alignItems: "center",
  flexDirection: "row",
  width: "fit-content",
  userSelect: "none",
  whiteSpace: "nowrap",
  // increase clickable area without padding
  position: "relative",
  "&::before": {
    content: '""',
    position: "absolute",
    top: "-25%", // 50% of 50% (for top and bottom)
    left: "-12.5%", // 25% of 50% (for left and right)
    width: "125%", // Original width + 25%
    height: "150%", // Original height + 50%
  },
}));