All files / src/shared/Banner CompactStat.tsx

100% Statements 4/4
85.71% Branches 6/7
100% Functions 1/1
100% Lines 4/4

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                                              22x               22x 22x   22x                                              
import { Stack } from "@mui/material";
import { ReactNode, memo } from "react";
import GiveText from "@shared/Text/GiveText";
import { useAppTheme } from "@theme/v2/Provider";
import { StyledTitle } from "./styles";
 
type Props = {
  /** Pre-formatted value to display (money/percent/count formatting is the caller's job). */
  value: ReactNode;
  label: ReactNode;
  /** Optional label suffix, e.g. " (USD)" / " (%)". */
  suffix?: string;
  align?: "left" | "right";
  titleVariant?: "h5" | "bodyL";
  textColor?: string;
};
 
/**
 * Single stat used by the compact-on-scroll banners (AC004). Presentational
 * only — shared by ProductBannerBase and GiveMerchantBanner so the compact
 * layout lives in one place. Memoized because the banners re-render on every
 * search/filter/tab change while individual stat props stay stable.
 */
const CompactStat = ({
  value,
  label,
  suffix = "",
  align = "left",
  titleVariant = "h5",
  textColor,
}: Props) => {
  const theme = useAppTheme();
  const isLeft = align === "left";
 
  return (
    <Stack
      spacing="2px"
      alignItems={isLeft ? "flex-start" : "flex-end"}
      sx={{ whiteSpace: "nowrap", textAlign: isLeft ? "left" : "right" }}
    >
      <StyledTitle
        theme={theme}
        variant={titleVariant}
        fontWeight="400"
        textColor={textColor as string}
      >
        {value}
      </StyledTitle>
      <GiveText variant="bodyXS" color="secondary">
        {label}
        {suffix}
      </GiveText>
    </Stack>
  );
};
 
export default memo(CompactStat);