/ src / components / GhoBorrowApyRange.tsx
GhoBorrowApyRange.tsx
 1  import {
 2    Box,
 3    Skeleton,
 4    Typography,
 5    TypographyProps,
 6    TypographyPropsVariantOverrides,
 7  } from '@mui/material';
 8  import { Variant } from '@mui/material/styles/createTypography';
 9  import { OverridableStringUnion } from '@mui/types';
10  import React from 'react';
11  import { useAppDataContext } from 'src/hooks/app-data-provider/useAppDataProvider';
12  
13  import { FormattedNumber } from './primitives/FormattedNumber';
14  
15  interface GhoBorrowApyRangeProps extends TypographyProps {
16    minVal?: number;
17    maxVal?: number;
18    percentVariant?: OverridableStringUnion<Variant | 'inherit', TypographyPropsVariantOverrides>;
19    hyphenVariant?: OverridableStringUnion<Variant | 'inherit', TypographyPropsVariantOverrides>;
20  }
21  
22  /**
23   * This component displays two borrow APY values as percentages with two decimal places and a hyphen in between.
24   * This component can take in optional range values and display variants for typography of the percentage values and the hyphen.
25   * If no range values are provided, which would usually be APY values related to different user balances, then the default values are variable borrow APY with no discount as maximum range value and with the max discount as the minimum range value.
26   */
27  const GhoBorrowApyRange: React.FC<GhoBorrowApyRangeProps> = ({
28    minVal,
29    maxVal,
30    percentVariant,
31    hyphenVariant,
32    ...rest
33  }) => {
34    const { ghoLoadingData, ghoReserveData } = useAppDataContext();
35  
36    if (ghoLoadingData) return <Skeleton width={70} height={24} />;
37  
38    // Check precision, could be different by small amount but show same
39    const lowRangeValue = minVal ?? ghoReserveData.ghoBorrowAPYWithMaxDiscount;
40    const highRangeValue = maxVal ?? ghoReserveData.ghoVariableBorrowAPY;
41  
42    // Normalize and compare, round to two decimal places as if they'd be formatted
43    const normalizedLowValue = Number((lowRangeValue * 100).toFixed(2));
44    const normalizedHighValue = Number((highRangeValue * 100).toFixed(2));
45    const isSameDisplayValue = normalizedLowValue === normalizedHighValue;
46  
47    // Just show one value if they are the same display value after being formatted, otherwise, hyphenate and show both values
48    return (
49      <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
50        {isSameDisplayValue ? (
51          <FormattedNumber
52            compact
53            percent
54            value={lowRangeValue} // 50/50 choice
55            visibleDecimals={2}
56            variant={percentVariant ?? 'h3'}
57            data-cy={'apy'}
58            {...rest}
59          />
60        ) : (
61          <>
62            <FormattedNumber
63              compact
64              value={lowRangeValue * 100}
65              visibleDecimals={2}
66              variant={percentVariant ?? 'h3'}
67              data-cy={'apy-gho-from'}
68              {...rest}
69            />
70            <Typography
71              variant={hyphenVariant ?? 'secondary16'}
72              color="text.secondary"
73              sx={{ mx: 0.5 }}
74            >
75              -
76            </Typography>
77            <FormattedNumber
78              compact
79              percent
80              value={highRangeValue}
81              visibleDecimals={2}
82              variant={percentVariant ?? 'h3'}
83              data-cy={'apy-gho-till'}
84              {...rest}
85            />
86          </>
87        )}
88      </Box>
89    );
90  };
91  
92  export default GhoBorrowApyRange;