index.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import clsx from "clsx";
  2. import type { ReactNode, ElementType } from "react";
  3. import styles from "./index.module.scss";
  4. import type { Props as CardProps } from "../Card/index.jsx";
  5. import { Card } from "../Card/index.jsx";
  6. type OwnPropsSingle = {
  7. header: ReactNode;
  8. stat: ReactNode;
  9. miniStat?: ReactNode | undefined;
  10. corner?: ReactNode | undefined;
  11. small?: boolean | undefined;
  12. };
  13. type OwnPropsDual = {
  14. header1: ReactNode;
  15. header2: ReactNode;
  16. stat1: ReactNode;
  17. stat2: ReactNode;
  18. miniStat1?: ReactNode | undefined;
  19. miniStat2?: ReactNode | undefined;
  20. };
  21. type Props<T extends ElementType> = Omit<
  22. CardProps<T>,
  23. | keyof OwnPropsSingle
  24. | keyof OwnPropsDual
  25. | "title"
  26. | "toolbar"
  27. | "icon"
  28. | "footer"
  29. > &
  30. (OwnPropsSingle | OwnPropsDual);
  31. export const StatCard = <T extends ElementType>({
  32. className,
  33. children,
  34. ...props
  35. }: Props<T>) => {
  36. const {
  37. /* eslint-disable @typescript-eslint/no-unused-vars */
  38. header,
  39. stat,
  40. miniStat,
  41. corner,
  42. small,
  43. header1,
  44. header2,
  45. stat1,
  46. stat2,
  47. miniStat1,
  48. miniStat2,
  49. /* eslint-enable @typescript-eslint/no-unused-vars */
  50. ...cardProps
  51. } = props;
  52. return (
  53. <Card className={clsx(styles.statCard, className)} {...cardProps}>
  54. <div className={styles.cardContents}>
  55. <div className={styles.top}>
  56. {"header" in props ? (
  57. <>
  58. {props.corner && (
  59. <div className={styles.corner}>{props.corner}</div>
  60. )}
  61. <h2 className={styles.header}>{props.header}</h2>
  62. <div
  63. data-small={props.small ? "" : undefined}
  64. className={styles.stats}
  65. >
  66. <div className={styles.mainStat}>{props.stat}</div>
  67. {props.miniStat && (
  68. <div className={styles.miniStat}>{props.miniStat}</div>
  69. )}
  70. </div>
  71. </>
  72. ) : (
  73. <>
  74. <div className={styles.dualHeader}>
  75. <h2 className={styles.header}>{props.header1}</h2>
  76. <h2 className={styles.header}>{props.header2}</h2>
  77. </div>
  78. <div className={styles.stats}>
  79. <div className={styles.stat}>
  80. <div className={styles.mainStat}>{props.stat1}</div>
  81. {props.miniStat1 && (
  82. <div className={styles.miniStat}>{props.miniStat1}</div>
  83. )}
  84. </div>
  85. <div className={styles.stat}>
  86. {props.miniStat2 && (
  87. <div className={styles.miniStat}>{props.miniStat2}</div>
  88. )}
  89. <div className={styles.mainStat}>{props.stat2}</div>
  90. </div>
  91. </div>
  92. </>
  93. )}
  94. </div>
  95. {children && <div className={styles.bottom}>{children}</div>}
  96. </div>
  97. </Card>
  98. );
  99. };