scoreBar.tsx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import styled from '@emotion/styled';
  2. import theme from 'sentry/utils/theme';
  3. type Props = {
  4. score: number;
  5. className?: string;
  6. palette?: Readonly<string[]>;
  7. paletteClassNames?: string[];
  8. radius?: number;
  9. size?: number;
  10. thickness?: number;
  11. vertical?: boolean;
  12. };
  13. const BaseScoreBar = ({
  14. score,
  15. className,
  16. vertical,
  17. size = 40,
  18. thickness = 4,
  19. radius = 3,
  20. palette = theme.similarity.colors,
  21. ...props
  22. }: Props) => {
  23. const maxScore = palette.length;
  24. // Make sure score is between 0 and maxScore
  25. const scoreInBounds = score >= maxScore ? maxScore : score <= 0 ? 0 : score;
  26. // Make sure paletteIndex is 0 based
  27. const paletteIndex = scoreInBounds - 1;
  28. // Size of bar, depends on orientation, although we could just apply a transformation via css
  29. const barProps = {
  30. vertical,
  31. thickness,
  32. size,
  33. radius,
  34. };
  35. return (
  36. <div className={className} {...props}>
  37. {[...Array(scoreInBounds)].map((_j, i) => (
  38. <Bar {...barProps} key={i} color={palette[paletteIndex]} />
  39. ))}
  40. {[...Array(maxScore - scoreInBounds)].map((_j, i) => (
  41. <Bar key={`empty-${i}`} {...barProps} empty />
  42. ))}
  43. </div>
  44. );
  45. };
  46. const ScoreBar = styled(BaseScoreBar)`
  47. display: flex;
  48. ${p =>
  49. p.vertical
  50. ? `flex-direction: column-reverse;
  51. justify-content: flex-end;`
  52. : 'min-width: 80px;'};
  53. `;
  54. type BarProps = {
  55. radius: number;
  56. size: number;
  57. thickness: number;
  58. color?: string;
  59. empty?: boolean;
  60. vertical?: boolean;
  61. };
  62. const Bar = styled('div')<BarProps>`
  63. border-radius: ${p => p.radius}px;
  64. margin: 2px;
  65. ${p => p.empty && `background-color: ${p.theme.similarity.empty};`};
  66. ${p => p.color && `background-color: ${p.color};`};
  67. width: ${p => (!p.vertical ? p.thickness : p.size)}px;
  68. height: ${p => (!p.vertical ? p.size : p.thickness)}px;
  69. `;
  70. export default ScoreBar;