aboutsummaryrefslogtreecommitdiff
path: root/src/components/metrics/ChangeLabel.tsx
blob: 192f0ff21dd3875b72207d86c831fe4bb2aefe94 (plain) (blame)
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
import { Icon, Row, type RowProps, Text } from '@umami/react-zen';
import type { ReactNode } from 'react';
import { ArrowRight } from '@/components/icons';

const STYLES = {
  positive: {
    color: `var(--success-color)`,
    background: `color-mix(in srgb, var(--success-color), var(--background-color) 95%)`,
  },
  negative: {
    color: `var(--danger-color)`,
    background: `color-mix(in srgb, var(--danger-color), var(--background-color) 95%)`,
  },
  neutral: {
    color: `var(--font-color-muted)`,
    background: `var(--base-color-2)`,
  },
};

export function ChangeLabel({
  value,
  size,
  reverseColors,
  children,
  ...props
}: {
  value: number;
  size?: 'xs' | 'sm' | 'md' | 'lg';
  title?: string;
  reverseColors?: boolean;
  showPercentage?: boolean;
  children?: ReactNode;
} & RowProps) {
  const positive = value >= 0;
  const negative = value < 0;
  const neutral = value === 0 || Number.isNaN(value);
  const good = reverseColors ? negative : positive;

  const style =
    STYLES[good && 'positive'] || STYLES[!good && 'negative'] || STYLES[neutral && 'neutral'];

  return (
    <Row
      {...props}
      style={style}
      alignItems="center"
      alignSelf="flex-start"
      paddingX="2"
      paddingY="1"
      gap="2"
    >
      {!neutral && (
        <Icon rotate={positive ? -90 : 90} size={size}>
          <ArrowRight />
        </Icon>
      )}
      <Text>{children || value}</Text>
    </Row>
  );
}