All files / src/components/charts/StackedSingleBar StackedSingleBar.tsx

0% Statements 0/14
0% Branches 0/4
0% Functions 0/7
0% Lines 0/13

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                                                                                                                                                                                                                                   
import { memo } from "react";
import { Box, Stack, styled } from "@mui/material";
import { palette } from "@palette";
import { Text } from "@common/Text";
import { parseAmount } from "@utils/index";
 
export type TData = { label: string; value: number; isAmount?: boolean }[];
 
interface StackedSingleBarProps {
  data: TData;
  title: string;
}
 
const StackedSingleBar = ({ data, title }: StackedSingleBarProps) => {
  const slicedData = data.slice(0, 4);
  const total = slicedData.reduce((acc, v) => {
    return acc + v.value;
  }, 0);
  const colors = Object.values(palette.charts);
 
  return (
    <Stack flexGrow={1} direction="column" gap="24px" alignItems="stretch">
      <Text
        color={palette.black[100]}
        fontSize="18px"
        fontWeight="book"
        lineHeight="21.6px"
        letterSpacing="-0.18px"
      >
        {title}
      </Text>
      <StackedBar data={slicedData} total={total} colors={colors} />
      {slicedData.map(({ label, value, isAmount }, index) => {
        return (
          <Label
            key={label}
            label={label}
            value={value}
            color={colors[index]}
            isAmount={isAmount || false}
          />
        );
      })}
    </Stack>
  );
};
 
const StackedBar = ({
  data,
  total,
  colors,
}: {
  data: TData;
  total: number;
  colors: string[];
}) => {
  return (
    <StyledBar>
      {data.map((dataEntry, idx) => {
        return (
          <Box
            key={dataEntry.label}
            sx={{
              backgroundColor: colors[idx],
              width: `${Math.round((dataEntry.value * 100) / total)}%`,
            }}
          />
        );
      })}
    </StyledBar>
  );
};
 
const Label = ({
  label,
  value,
  color,
  isAmount,
}: {
  label: string;
  value: number;
  color: string;
  isAmount: boolean;
}) => {
  return (
    <Stack direction="row" justifyContent="space-between" alignItems="center">
      <Stack direction="row" gap="8px" alignItems="center">
        <Box
          width="20px"
          height="20px"
          sx={{ borderRadius: "4px", backgroundColor: color }}
        />
        <Text color={palette.black[100]} fontWeight="book" lineHeight="16.8px">
          {label}
        </Text>
      </Stack>
      <Text color={palette.black[300]} lineHeight="16.8px">
        {isAmount ? parseAmount(value) : value}
      </Text>
    </Stack>
  );
};
 
const StyledBar = styled(Stack)(() => ({
  flexDirection: "row",
  alignItems: "stretch",
  height: "27px",
  borderRadius: "8px",
  flexGrow: 1,
  overflow: "hidden",
}));
 
export default memo(StackedSingleBar);