@bundle-stats/ui 4.23.0-beta.3 → 4.23.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/lib/app/app.module.css +4 -2
  2. package/lib/app/header/header.module.css +1 -3
  3. package/lib/chart-colors.json +56 -56
  4. package/lib/components/asset-name/asset-name.js +8 -7
  5. package/lib/components/asset-name/asset-name.js.map +1 -1
  6. package/lib/components/asset-name/asset-name.module.css +20 -10
  7. package/lib/components/bundle-assets/bundle-assets.js +4 -2
  8. package/lib/components/bundle-assets/bundle-assets.js.map +1 -1
  9. package/lib/components/bundle-assets/bundle-assets.module.css +0 -12
  10. package/lib/components/bundle-assets-totals/bundle-assets-totals.js +4 -2
  11. package/lib/components/bundle-assets-totals/bundle-assets-totals.js.map +1 -1
  12. package/lib/components/bundle-modules/bundle-modules.js +4 -2
  13. package/lib/components/bundle-modules/bundle-modules.js.map +1 -1
  14. package/lib/components/bundle-modules/bundle-modules.module.css +8 -16
  15. package/lib/components/bundle-packages/bundle-packages.js +4 -2
  16. package/lib/components/bundle-packages/bundle-packages.js.map +1 -1
  17. package/lib/components/bundle-packages/bundle-packages.module.css +21 -22
  18. package/lib/components/entry-info/entry-info.module.css +0 -1
  19. package/lib/components/metric-run-info/metric-run-info.js +3 -2
  20. package/lib/components/metric-run-info/metric-run-info.js.map +1 -1
  21. package/lib/components/metrics-display-selector/metrics-display-selector.module.css +0 -2
  22. package/lib/components/metrics-table/metrics-table.js +31 -20
  23. package/lib/components/metrics-table/metrics-table.js.map +1 -1
  24. package/lib/components/metrics-table/metrics-table.module.css +4 -12
  25. package/lib/components/metrics-table-options/metrics-table-options.js +4 -4
  26. package/lib/components/metrics-table-options/metrics-table-options.js.map +1 -1
  27. package/lib/components/metrics-table-row-count/index.js +18 -0
  28. package/lib/components/metrics-table-row-count/index.js.map +1 -0
  29. package/lib/components/metrics-table-row-count/metrics-table-row-count.js +17 -0
  30. package/lib/components/metrics-table-row-count/metrics-table-row-count.js.map +1 -0
  31. package/lib/components/metrics-table-row-count/metrics-table-row-count.module.css +5 -0
  32. package/lib/components/sort-button/sort-button.module.css +0 -2
  33. package/lib/components/summary/summary.module.css +10 -3
  34. package/lib/css/default.css +7 -4
  35. package/lib/css/variables.css +21 -17
  36. package/lib/layout/flex-stack/flex-stack.js +2 -2
  37. package/lib/layout/flex-stack/flex-stack.js.map +1 -1
  38. package/lib/layout/flex-stack/flex-stack.module.css +65 -10
  39. package/lib/ui/button/button.js +1 -0
  40. package/lib/ui/button/button.js.map +1 -1
  41. package/lib/ui/button/button.module.css +28 -28
  42. package/lib/ui/copy-to-clipboard/copy-to-clipboard.module.css +2 -2
  43. package/lib/ui/dropdown/dropdown.module.css +4 -2
  44. package/lib/ui/filters/filters.js +6 -5
  45. package/lib/ui/filters/filters.js.map +1 -1
  46. package/lib/ui/filters/filters.module.css +3 -5
  47. package/lib/ui/hover-card/hover-card.module.css +4 -5
  48. package/lib/ui/input/input.module.css +2 -2
  49. package/lib/ui/table/table.module.css +12 -5
  50. package/lib/ui/tabs/tabs.module.css +13 -9
  51. package/lib/ui/tag/tag.module.css +0 -2
  52. package/lib/ui/textarea/textarea.module.css +2 -2
  53. package/lib-esm/app/app.module.css +4 -2
  54. package/lib-esm/app/header/header.module.css +1 -3
  55. package/lib-esm/chart-colors.json +56 -56
  56. package/lib-esm/components/asset-name/asset-name.js +8 -7
  57. package/lib-esm/components/asset-name/asset-name.js.map +1 -1
  58. package/lib-esm/components/asset-name/asset-name.module.css +20 -10
  59. package/lib-esm/components/bundle-assets/bundle-assets.js +4 -2
  60. package/lib-esm/components/bundle-assets/bundle-assets.js.map +1 -1
  61. package/lib-esm/components/bundle-assets/bundle-assets.module.css +0 -12
  62. package/lib-esm/components/bundle-assets-totals/bundle-assets-totals.js +4 -2
  63. package/lib-esm/components/bundle-assets-totals/bundle-assets-totals.js.map +1 -1
  64. package/lib-esm/components/bundle-modules/bundle-modules.js +4 -2
  65. package/lib-esm/components/bundle-modules/bundle-modules.js.map +1 -1
  66. package/lib-esm/components/bundle-modules/bundle-modules.module.css +8 -16
  67. package/lib-esm/components/bundle-packages/bundle-packages.js +4 -2
  68. package/lib-esm/components/bundle-packages/bundle-packages.js.map +1 -1
  69. package/lib-esm/components/bundle-packages/bundle-packages.module.css +21 -22
  70. package/lib-esm/components/entry-info/entry-info.module.css +0 -1
  71. package/lib-esm/components/metric-run-info/metric-run-info.js +3 -2
  72. package/lib-esm/components/metric-run-info/metric-run-info.js.map +1 -1
  73. package/lib-esm/components/metrics-display-selector/metrics-display-selector.module.css +0 -2
  74. package/lib-esm/components/metrics-table/metrics-table.js +32 -20
  75. package/lib-esm/components/metrics-table/metrics-table.js.map +1 -1
  76. package/lib-esm/components/metrics-table/metrics-table.module.css +4 -12
  77. package/lib-esm/components/metrics-table-options/metrics-table-options.js +4 -4
  78. package/lib-esm/components/metrics-table-options/metrics-table-options.js.map +1 -1
  79. package/lib-esm/components/metrics-table-row-count/index.js +2 -0
  80. package/lib-esm/components/metrics-table-row-count/index.js.map +1 -0
  81. package/lib-esm/components/metrics-table-row-count/metrics-table-row-count.js +10 -0
  82. package/lib-esm/components/metrics-table-row-count/metrics-table-row-count.js.map +1 -0
  83. package/lib-esm/components/metrics-table-row-count/metrics-table-row-count.module.css +5 -0
  84. package/lib-esm/components/sort-button/sort-button.module.css +0 -2
  85. package/lib-esm/components/summary/summary.module.css +10 -3
  86. package/lib-esm/css/default.css +7 -4
  87. package/lib-esm/css/variables.css +21 -17
  88. package/lib-esm/layout/flex-stack/flex-stack.js +3 -2
  89. package/lib-esm/layout/flex-stack/flex-stack.js.map +1 -1
  90. package/lib-esm/layout/flex-stack/flex-stack.module.css +65 -10
  91. package/lib-esm/ui/button/button.js +1 -0
  92. package/lib-esm/ui/button/button.js.map +1 -1
  93. package/lib-esm/ui/button/button.module.css +28 -28
  94. package/lib-esm/ui/copy-to-clipboard/copy-to-clipboard.module.css +2 -2
  95. package/lib-esm/ui/dropdown/dropdown.module.css +4 -2
  96. package/lib-esm/ui/filters/filters.js +6 -5
  97. package/lib-esm/ui/filters/filters.js.map +1 -1
  98. package/lib-esm/ui/filters/filters.module.css +3 -5
  99. package/lib-esm/ui/hover-card/hover-card.module.css +4 -5
  100. package/lib-esm/ui/input/input.module.css +2 -2
  101. package/lib-esm/ui/table/table.module.css +12 -5
  102. package/lib-esm/ui/tabs/tabs.module.css +13 -9
  103. package/lib-esm/ui/tag/tag.module.css +0 -2
  104. package/lib-esm/ui/textarea/textarea.module.css +2 -2
  105. package/package.json +3 -3
  106. package/src/app/app.module.css +4 -2
  107. package/src/app/header/header.module.css +1 -3
  108. package/src/chart-colors.json +56 -56
  109. package/src/components/asset-name/asset-name.module.css +20 -10
  110. package/src/components/asset-name/asset-name.tsx +8 -12
  111. package/src/components/bundle-assets/bundle-assets.module.css +0 -12
  112. package/src/components/bundle-assets/bundle-assets.tsx +8 -1
  113. package/src/components/bundle-assets-totals/bundle-assets-totals.jsx +6 -4
  114. package/src/components/bundle-modules/bundle-modules.module.css +8 -16
  115. package/src/components/bundle-modules/bundle-modules.tsx +8 -1
  116. package/src/components/bundle-packages/bundle-packages.jsx +5 -1
  117. package/src/components/bundle-packages/bundle-packages.module.css +21 -22
  118. package/src/components/entry-info/entry-info.module.css +0 -1
  119. package/src/components/metric-run-info/metric-run-info.stories.tsx +9 -0
  120. package/src/components/metric-run-info/metric-run-info.tsx +9 -2
  121. package/src/components/metrics-display-selector/metrics-display-selector.module.css +0 -2
  122. package/src/components/metrics-table/metrics-table.module.css +4 -12
  123. package/src/components/metrics-table/metrics-table.tsx +70 -39
  124. package/src/components/metrics-table-options/metrics-table-options.tsx +12 -12
  125. package/src/components/metrics-table-row-count/index.ts +1 -0
  126. package/src/components/metrics-table-row-count/metrics-table-row-count.module.css +5 -0
  127. package/src/components/metrics-table-row-count/metrics-table-row-count.tsx +21 -0
  128. package/src/components/sort-button/sort-button.module.css +0 -2
  129. package/src/components/summary/summary.module.css +10 -3
  130. package/src/css/default.css +7 -4
  131. package/src/css/variables.css +21 -17
  132. package/src/layout/flex-stack/flex-stack.module.css +65 -10
  133. package/src/layout/flex-stack/flex-stack.stories.tsx +68 -9
  134. package/src/layout/flex-stack/flex-stack.tsx +24 -4
  135. package/src/ui/button/button.module.css +28 -28
  136. package/src/ui/button/button.tsx +1 -0
  137. package/src/ui/copy-to-clipboard/copy-to-clipboard.module.css +2 -2
  138. package/src/ui/dropdown/dropdown.module.css +4 -2
  139. package/src/ui/dropdown/dropdown.stories.tsx +6 -0
  140. package/src/ui/filters/filters.module.css +3 -5
  141. package/src/ui/filters/filters.tsx +21 -16
  142. package/src/ui/hover-card/hover-card.module.css +4 -5
  143. package/src/ui/input/input.module.css +2 -2
  144. package/src/ui/table/table.module.css +12 -5
  145. package/src/ui/tabs/tabs.module.css +13 -9
  146. package/src/ui/tag/tag.module.css +0 -2
  147. package/src/ui/textarea/textarea.module.css +2 -2
  148. package/types/components/metric-run-info/metric-run-info.d.ts +1 -1
  149. package/types/components/metrics-table/metrics-table.d.ts +2 -1
  150. package/types/components/metrics-table-row-count/index.d.ts +1 -0
  151. package/types/components/metrics-table-row-count/metrics-table-row-count.d.ts +7 -0
  152. package/types/layout/flex-stack/flex-stack.d.ts +6 -2
  153. package/types/ui/button/button.d.ts +1 -0
@@ -12,8 +12,23 @@
12
12
  }
13
13
 
14
14
  .packageName {
15
- display: inline-block;
15
+ display: inline-flex;
16
+ align-items: center;
17
+ gap: var(--space-xxxsmall);
16
18
  color: var(--color-text-light);
19
+ text-decoration: none;
20
+ }
21
+
22
+ .packageNameTagDuplicate {
23
+ flex: 0 0 auto;
24
+ }
25
+
26
+ .packageNameTagDuplicate::before {
27
+ content: 'd';
28
+ }
29
+
30
+ .packageNameLabel {
31
+ flex: 1 1 auto;
17
32
  }
18
33
 
19
34
  .packageName:last-child {
@@ -25,29 +40,13 @@
25
40
  margin: 0 var(--space-xxxsmall);
26
41
  content: '/';
27
42
  color: var(--color-text-ultra-light);
43
+ text-decoration: none;
28
44
  }
29
45
 
30
- .packageNameTagDuplicate {
31
- margin-right: var(--space-xxxsmall);
32
- vertical-align: middle;
33
- }
34
-
35
- .packageNameLabel {
36
- vertical-align: middle;
37
- }
38
-
39
- .packageNameTagDuplicate::before {
40
- content: 'd';
41
- }
42
-
43
- .root .packageName:hover,
44
- .root .packageName:active,
45
- .root .packageName:focus {
46
- text-decoration: none;
46
+ .packageName:hover {
47
+ text-decoration: none !important;
47
48
  }
48
49
 
49
- .root .packageName:hover .packageNameLabel,
50
- .root .packageName:active .packageNameLabel,
51
- .root .packageName:focus .packageNameLabel {
52
- text-decoration: underline;
50
+ .packageName:hover .packageNameLabel {
51
+ text-decoration: underline !important;
53
52
  }
@@ -107,7 +107,6 @@
107
107
  line-height: var(--line-height-heading);
108
108
  border-radius: var(--radius-small);
109
109
  background: var(--color-highlight);
110
- transition: var(--transition-out);
111
110
 
112
111
  text-decoration: none;
113
112
  text-transform: none;
@@ -28,6 +28,15 @@ export const NoBaseline: Story = {
28
28
  },
29
29
  };
30
30
 
31
+ export const ShowDeltaAbsoluteValue: Story = {
32
+ args: {
33
+ metricId: 'webpack.totalSizeByTypeALL',
34
+ current: 120 * 1024,
35
+ baseline: 100 * 1024,
36
+ showDeltaAbsoluteValue: true,
37
+ },
38
+ };
39
+
31
40
  export const NoDelta: Story = {
32
41
  args: {
33
42
  ...NoBaseline.args,
@@ -56,7 +56,12 @@ export type MetricRunInfoProps = {
56
56
  baseline?: number;
57
57
  showMetricDescription?: boolean;
58
58
  titleWrapper?: ElementType;
59
- showDeltaValue?: boolean;
59
+ /**
60
+ * Show the delta absolute value alongside the percentage value.
61
+ * Only applies when `showDelta` is `true`.
62
+ * @default false
63
+ */
64
+ showDeltaAbsoluteValue?: boolean;
60
65
  } & Pick<RunInfoProps, 'showDelta' | 'showBaseline' | 'size' | 'loading'>;
61
66
 
62
67
  export const MetricRunInfo = (props: MetricRunInfoProps & React.ComponentProps<'div'>) => {
@@ -67,6 +72,7 @@ export const MetricRunInfo = (props: MetricRunInfoProps & React.ComponentProps<'
67
72
  showDelta = true,
68
73
  showMetricDescription = true,
69
74
  showBaseline = true,
75
+ showDeltaAbsoluteValue = false,
70
76
  titleWrapper: CustomTitleWrapper = React.Fragment,
71
77
  ...restProps
72
78
  } = props;
@@ -118,8 +124,9 @@ export const MetricRunInfo = (props: MetricRunInfoProps & React.ComponentProps<'
118
124
  showDelta: true,
119
125
  deltaType: metricRunInfo.deltaType,
120
126
  deltaPercentage: metricRunInfo.displayDeltaPercentage,
127
+ ...(showDeltaAbsoluteValue && { delta: metricRunInfo.displayDelta }),
121
128
  };
122
- }, [metric, metricRunInfo, showDelta]);
129
+ }, [metric, metricRunInfo, showDelta, showDeltaAbsoluteValue]);
123
130
 
124
131
  return (
125
132
  <RunInfo
@@ -1,6 +1,5 @@
1
1
  .dropdownGroup {
2
2
  border: 1px solid var(--color-outline);
3
- transition: var(--transition-out);
4
3
  }
5
4
 
6
5
  .dropdownGroupButton {
@@ -9,7 +8,6 @@
9
8
 
10
9
  .dropdownGroup:hover {
11
10
  border-color: var(--color-outline-dark);
12
- transition: var(--transition-in);
13
11
  }
14
12
 
15
13
  .itemActive {
@@ -1,21 +1,13 @@
1
- .root a {
2
- color: inherit;
3
- text-decoration: none;
4
- }
5
-
6
- .root a:hover,
7
- .root a:active,
8
- .root a:focus {
9
- color: var(--color-primary);
10
- text-decoration: underline;
11
- }
12
-
13
1
  .root .value,
14
2
  .root .delta {
15
3
  text-align: right;
16
4
  }
17
5
 
18
6
  /** rows */
7
+ .clickable {
8
+ cursor: default;
9
+ }
10
+
19
11
  .multipleRuns .unchanged th,
20
12
  .multipleRuns .unchanged td {
21
13
  color: var(--color-text-light);
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useCallback } from 'react';
2
2
  import cx from 'classnames';
3
3
  import isEmpty from 'lodash/isEmpty';
4
4
  import type { ReportMetricRow } from '@bundle-stats/utils';
@@ -20,51 +20,75 @@ const CURRENT_COLUMN_SPAN = 3;
20
20
  interface RowProps extends React.ComponentProps<typeof Table.Tr> {
21
21
  item: ReportMetricRow;
22
22
  renderHeader: (item: ReportMetricRow) => React.ReactNode;
23
+ onRowClick?: (item: ReportMetricRow) => void;
23
24
  }
24
25
 
25
- const Row = ({ className = '', item, renderHeader, ...restProps }: RowProps) => (
26
- <Table.Tr className={cx(!item.changed && css.unchanged, className)} {...restProps}>
27
- <Table.Th className={css.metricName}>{renderHeader(item)}</Table.Th>
26
+ const Row = ({ className = '', item, renderHeader, onRowClick, ...restProps }: RowProps) => {
27
+ const handleClick = useCallback(
28
+ (event: React.MouseEvent<HTMLTableRowElement>) => {
29
+ // Skip clicks on interactive elements (eg: links, buttons)
30
+ if ((event.target as HTMLElement).closest('a, button')) {
31
+ return;
32
+ }
33
+
34
+ // Skip when the user is selecting text
35
+ if (window.getSelection()?.toString()) {
36
+ return;
37
+ }
28
38
 
29
- {item.runs.map((run, index) => {
30
- const isBaseline = index === item.runs.length - 1;
31
- const valueClassName = cx(css.value, !isBaseline && css.current);
39
+ onRowClick?.(item);
40
+ },
41
+ [onRowClick, item],
42
+ );
43
+
44
+ return (
45
+ <Table.Tr
46
+ className={cx(!item.changed && css.unchanged, onRowClick && css.clickable, className)}
47
+ onClick={onRowClick ? handleClick : undefined}
48
+ {...restProps}
49
+ >
50
+ <Table.Th className={css.metricName}>{renderHeader(item)}</Table.Th>
51
+
52
+ {item.runs.map((run, index) => {
53
+ const isBaseline = index === item.runs.length - 1;
54
+ const valueClassName = cx(css.value, !isBaseline && css.current);
55
+
56
+ // Empty cells if no value
57
+ if (!run || typeof run.value === 'undefined') {
58
+ return (
59
+ <>
60
+ <Table.Td className={valueClassName}>-</Table.Td>
61
+ {!isBaseline && <Table.Td className={css.delta} />}
62
+ {!isBaseline && <Table.Td className={cx(css.delta, css.deltaPercentage)} />}
63
+ </>
64
+ );
65
+ }
32
66
 
33
- // Empty cells if no value
34
- if (!run || typeof run.value === 'undefined') {
35
67
  return (
36
68
  <>
37
- <Table.Td className={valueClassName}>-</Table.Td>
38
- {!isBaseline && <Table.Td className={css.delta} />}
39
- {!isBaseline && <Table.Td className={cx(css.delta, css.deltaPercentage)} />}
69
+ <Table.Td className={valueClassName}>
70
+ <Metric value={run.displayValue} />
71
+ </Table.Td>
72
+ {!isBaseline && (
73
+ <>
74
+ <Table.Td className={css.delta}>
75
+ {'delta' in run && (
76
+ <Delta displayValue={run.displayDelta} deltaType={run.deltaType} />
77
+ )}
78
+ </Table.Td>
79
+ <Table.Td className={cx(css.delta, css.deltaPercentage)}>
80
+ {'delta' in run && (
81
+ <Delta displayValue={run.displayDeltaPercentage} deltaType={run.deltaType} />
82
+ )}
83
+ </Table.Td>
84
+ </>
85
+ )}
40
86
  </>
41
87
  );
42
- }
43
-
44
- return (
45
- <>
46
- <Table.Td className={valueClassName}>
47
- <Metric value={run.displayValue} />
48
- </Table.Td>
49
- {!isBaseline && (
50
- <>
51
- <Table.Td className={css.delta}>
52
- {'delta' in run && (
53
- <Delta displayValue={run.displayDelta} deltaType={run.deltaType} />
54
- )}
55
- </Table.Td>
56
- <Table.Td className={cx(css.delta, css.deltaPercentage)}>
57
- {'delta' in run && (
58
- <Delta displayValue={run.displayDeltaPercentage} deltaType={run.deltaType} />
59
- )}
60
- </Table.Td>
61
- </>
62
- )}
63
- </>
64
- );
65
- })}
66
- </Table.Tr>
67
- );
88
+ })}
89
+ </Table.Tr>
90
+ );
91
+ };
68
92
 
69
93
  interface MetricsTableProps extends Omit<React.ComponentProps<typeof Table>, 'title'> {
70
94
  runs: Array<{
@@ -77,6 +101,7 @@ interface MetricsTableProps extends Omit<React.ComponentProps<typeof Table>, 'ti
77
101
  sort?: MetricsTableHeaderProps['sort'];
78
102
  updateSort?: MetricsTableHeaderProps['updateSort'];
79
103
  renderRowHeader?: (item: ReportMetricRow) => React.ReactNode;
104
+ onRowClick?: (item: ReportMetricRow) => void;
80
105
  emptyMessage?: React.ReactNode;
81
106
  showAllItems: boolean;
82
107
  setShowAllItems: (value: boolean) => void;
@@ -91,6 +116,7 @@ export const MetricsTable = ({
91
116
  sort,
92
117
  updateSort,
93
118
  renderRowHeader = (item: any) => item.label,
119
+ onRowClick,
94
120
  emptyMessage = I18N.EMPTY_MESSAGE,
95
121
  showAllItems,
96
122
  setShowAllItems,
@@ -132,7 +158,12 @@ export const MetricsTable = ({
132
158
  {showItems && (
133
159
  <>
134
160
  {visibleItems.map((item) => (
135
- <Row key={item.key} item={item} renderHeader={renderRowHeader} />
161
+ <Row
162
+ key={item.key}
163
+ item={item}
164
+ renderHeader={renderRowHeader}
165
+ onRowClick={onRowClick}
166
+ />
136
167
  ))}
137
168
 
138
169
  {hasHiddenItems && (
@@ -15,18 +15,18 @@ export const MetricsTableOptions = (props: MetricsTableOptionsProps) => {
15
15
 
16
16
  return (
17
17
  <Dropdown glyph="more-vertical" placement="bottom-end" {...restProps}>
18
- <DropdownGroup>
19
- {onResetClick && <DropdownItem onClick={onResetClick}>{I18N.RESET_FILTERS}</DropdownItem>}
20
- {onViewAllClick && <DropdownItem onClick={onViewAllClick}>{I18N.VIEW_ALL}</DropdownItem>}
21
- </DropdownGroup>
22
- <DropdownGroup>
23
- {onExportClick && (
24
- <>
25
- <DropdownItem onClick={() => onExportClick('csv')}>{I18N.EXPORT_CSV}</DropdownItem>
26
- <DropdownItem onClick={() => onExportClick('json')}>{I18N.EXPORT_JSON}</DropdownItem>
27
- </>
28
- )}
29
- </DropdownGroup>
18
+ {(onResetClick || onViewAllClick) && (
19
+ <DropdownGroup>
20
+ {onResetClick && <DropdownItem onClick={onResetClick}>{I18N.RESET_FILTERS}</DropdownItem>}
21
+ {onViewAllClick && <DropdownItem onClick={onViewAllClick}>{I18N.VIEW_ALL}</DropdownItem>}
22
+ </DropdownGroup>
23
+ )}
24
+ {onExportClick && (
25
+ <DropdownGroup>
26
+ <DropdownItem onClick={() => onExportClick('csv')}>{I18N.EXPORT_CSV}</DropdownItem>
27
+ <DropdownItem onClick={() => onExportClick('json')}>{I18N.EXPORT_JSON}</DropdownItem>
28
+ </DropdownGroup>
29
+ )}
30
30
  </Dropdown>
31
31
  );
32
32
  };
@@ -0,0 +1 @@
1
+ export * from './metrics-table-row-count';
@@ -0,0 +1,5 @@
1
+ .root {
2
+ display: inline-flex;
3
+ align-items: baseline;
4
+ gap: 2px;
5
+ }
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+
3
+ import { FlexStack } from '../../layout';
4
+ import { FlexStackProps } from '../../layout/flex-stack';
5
+
6
+ export type MetricsTableRowCountProps = {
7
+ count: number;
8
+ total: number;
9
+ } & FlexStackProps<'span'>;
10
+
11
+ export const MetricsTableRowCount = (props: MetricsTableRowCountProps) => {
12
+ const { count, total, ...restProps } = props;
13
+
14
+ return (
15
+ <FlexStack inline gap="xxxsmall" alignItems="bottom" {...restProps}>
16
+ <span>{count}</span>
17
+ <span>/</span>
18
+ <span>{total}</span>
19
+ </FlexStack>
20
+ );
21
+ };
@@ -18,7 +18,6 @@
18
18
  overflow: hidden;
19
19
  right: -2px; /* compensate for the button padding */
20
20
  color: var(--color-text-ultra-light);
21
- transition: var(--transition-out);
22
21
  }
23
22
 
24
23
  .directionIcon {
@@ -36,7 +35,6 @@
36
35
  .direction:active,
37
36
  .direction:focus {
38
37
  color: var(--color-text-dark);
39
- transition: var(--transition-in);
40
38
  }
41
39
 
42
40
  .directionAsc {
@@ -42,7 +42,7 @@
42
42
  }
43
43
 
44
44
  .item::before {
45
- content: "";
45
+ content: '';
46
46
  border-radius: var(--radius-medium);
47
47
  background: var(--color-highlight);
48
48
  display: block;
@@ -56,13 +56,15 @@
56
56
  transition: var(--transition-out);
57
57
  }
58
58
 
59
+ .item:focus::before,
60
+ .item:active::before,
59
61
  .item:hover::before {
60
62
  opacity: 1;
61
63
  transition: var(--transition-in);
62
64
  }
63
65
 
64
66
  .item + .item::after {
65
- content: "";
67
+ content: '';
66
68
  border-radius: var(--radius-medium);
67
69
  background: var(--color-outline);
68
70
  display: block;
@@ -75,7 +77,12 @@
75
77
  transition: var(--transition-out);
76
78
  }
77
79
 
78
- .item:hover::after, .item:hover + .item::after {
80
+ .item:focus::after,
81
+ .item:active::after,
82
+ .item:hover::after,
83
+ .item:focus + .item::after,
84
+ .item:active + .item::after,
85
+ .item:hover + .item::after {
79
86
  opacity: 0;
80
87
  transition: var(--transition-in);
81
88
  }
@@ -15,6 +15,7 @@ html {
15
15
 
16
16
  body {
17
17
  background: var(--color-background);
18
+ accent-color: var(--color-accent);
18
19
  color: var(--color-text);
19
20
  line-height: var(--line-height);
20
21
  }
@@ -59,12 +60,14 @@ code {
59
60
  }
60
61
 
61
62
  a {
62
- color: var(--color-primary);
63
+ color: var(--color-accent);
64
+ transition: var(--transition-out);
63
65
  }
64
66
 
65
- a:hover,
67
+ a:focus,
66
68
  a:active,
67
- a:focus {
68
- color: var(--color-primary-dark);
69
+ a:hover {
70
+ color: var(--color-accent-dark);
69
71
  outline: none;
72
+ transition: var(--transition-in);
70
73
  }
@@ -35,18 +35,18 @@
35
35
  * Color scheme: https://coolors.co/287acc-da444e-55b950-e5c110-192339-353538
36
36
  */
37
37
 
38
- --color-gray-25: #f9f9f9;
39
- /** https://hihayk.github.io/scale/#4/5/60/90/0/-0/0/0/3F3F47/63/63/71/white */
40
- --color-gray-50: #ececed;
41
- --color-gray-100: #c9c9cc;
42
- --color-gray-200: #a7a7aa;
43
- --color-gray-300: #848489;
44
- --color-gray-400: #626268;
45
- --color-gray-500: #3f3f47;
46
- --color-gray-600: #36363c;
47
- --color-gray-700: #2c2c32;
48
- --color-gray-800: #232327;
49
- --color-gray-900: #19191c;
38
+ --color-gray-25: #f9f9f9;
39
+ /** https://hihayk.github.io/scale/#4/5/60/90/0/-0/0/0/3F3F47/63/63/71/white */
40
+ --color-gray-50: #ececed;
41
+ --color-gray-100: #c9c9cc;
42
+ --color-gray-200: #a7a7aa;
43
+ --color-gray-300: #848489;
44
+ --color-gray-400: #626268;
45
+ --color-gray-500: #3f3f47;
46
+ --color-gray-600: #36363c;
47
+ --color-gray-700: #2c2c32;
48
+ --color-gray-800: #232327;
49
+ --color-gray-900: #19191c;
50
50
 
51
51
  --color-gray-ultra-light: var(--color-gray-200);
52
52
  --color-gray-light: var(--color-gray-300);
@@ -98,7 +98,7 @@
98
98
  --color-green-200: #b1dfaf;
99
99
  --color-green-300: #92d28f;
100
100
  --color-green-400: #74c670;
101
- --color-green-500: #55B950;
101
+ --color-green-500: #55b950;
102
102
  --color-green-600: #3ea839;
103
103
  --color-green-700: #2b9426;
104
104
  --color-green-800: #1b7b16;
@@ -112,7 +112,7 @@
112
112
 
113
113
  --color-yellow-25: #fffdf2;
114
114
  /* https://hihayk.github.io/scale/#4/5/40/80/0/-0/0/0/E5C110/229/193/16/white */
115
- --color-yellow-50: #faf3cf;
115
+ --color-yellow-50: #faf3cf;
116
116
  --color-yellow-100: #f6e9a9;
117
117
  --color-yellow-200: #f2df83;
118
118
  --color-yellow-300: #edd55d;
@@ -126,8 +126,8 @@
126
126
  --color-yellow-ultra-light: var(--color-yellow-100);
127
127
  --color-yellow-light: var(--color-yellow-300);
128
128
  --color-yellow: var(--color-yellow-500);
129
- --color-yellow-ultra-dark: var(--color-yellow-700);
130
- --color-yellow-dark: var(--color-yellow-900);
129
+ --color-yellow-dark: var(--color-yellow-700);
130
+ --color-yellow-ultra-dark: var(--color-yellow-900);
131
131
 
132
132
  --color-dark: #111;
133
133
  --color-light: #fff;
@@ -146,6 +146,10 @@ body {
146
146
  --color-text-ultra-dark: var(--color-gray-ultra-dark);
147
147
  --color-heading: var(--color-gray-ultra-dark);
148
148
 
149
+ --color-accent-light: var(--color-gray);
150
+ --color-accent: var(--color-gray-dark);
151
+ --color-accent-dark: var(--color-gray-ultra-dark);
152
+
149
153
  --color-success-light: var(--color-green-light);
150
154
  --color-success: var(--color-green);
151
155
  --color-success-dark: var(--color-green-dark);
@@ -188,7 +192,7 @@ body {
188
192
  --color-shadow: rgba(0, 0, 0, 0.25);
189
193
 
190
194
  --transition-duration-in: 0.16s;
191
- --transition-duration-out: 0.10s;
195
+ --transition-duration-out: 0.1s;
192
196
  --transition-in: all var(--transition-duration-in) ease-in;
193
197
  --transition-out: all var(--transition-duration-out) ease-out;
194
198
 
@@ -4,43 +4,73 @@
4
4
  gap: 0;
5
5
  }
6
6
 
7
- /** Space variation */
8
- .space--xxxsmall {
7
+ /** Gap variation */
8
+ .gap--xxxsmall {
9
9
  gap: var(--space-xxxsmall);
10
10
  }
11
11
 
12
- .space--xxsmall {
12
+ .gap--xxsmall {
13
13
  gap: var(--space-xxsmall);
14
14
  }
15
15
 
16
- .space--xsmall {
16
+ .gap--xsmall {
17
17
  gap: var(--space-xsmall);
18
18
  }
19
19
 
20
- .space--small {
20
+ .gap--small {
21
21
  gap: var(--space-small);
22
22
  }
23
23
 
24
- .space--medium {
24
+ .gap--medium {
25
25
  gap: var(--space-medium);
26
26
  }
27
27
 
28
- .space--large {
28
+ .gap--large {
29
29
  gap: var(--space-large);
30
30
  }
31
31
 
32
- .space--xlarge {
32
+ .gap--xlarge {
33
33
  gap: var(--space-xlarge);
34
34
  }
35
35
 
36
- .space--xxlarge {
36
+ .gap--xxlarge {
37
37
  gap: var(--space-xxlarge);
38
38
  }
39
39
 
40
- .space--xxxlarge {
40
+ .gap--xxxlarge {
41
41
  gap: var(--space-xxxlarge);
42
42
  }
43
43
 
44
+ /** Direction variation */
45
+ .direction--row {
46
+ flex-direction: row;
47
+ }
48
+
49
+ .direction--row-reverse {
50
+ flex-direction: row-reverse;
51
+ }
52
+
53
+ .direction--column {
54
+ flex-direction: column;
55
+ }
56
+
57
+ .direction--column-reverse {
58
+ flex-direction: column-reverse;
59
+ }
60
+
61
+ /** Wrap variation */
62
+ .wrap--nowrap {
63
+ flex-wrap: nowrap;
64
+ }
65
+
66
+ .wrap--wrap {
67
+ flex-wrap: wrap;
68
+ }
69
+
70
+ .wrap--wrap-reverse {
71
+ flex-wrap: wrap-reverse;
72
+ }
73
+
44
74
  /** Align items variation */
45
75
  .root {
46
76
  align-items: stretch;
@@ -62,6 +92,31 @@
62
92
  align-items: baseline;
63
93
  }
64
94
 
95
+ /** Justify content variation */
96
+ .justify-content--flex-start {
97
+ justify-content: flex-start;
98
+ }
99
+
100
+ .justify-content--flex-end {
101
+ justify-content: flex-end;
102
+ }
103
+
104
+ .justify-content--center {
105
+ justify-content: center;
106
+ }
107
+
108
+ .justify-content--space-between {
109
+ justify-content: space-between;
110
+ }
111
+
112
+ .justify-content--space-around {
113
+ justify-content: space-around;
114
+ }
115
+
116
+ .justify-content--space-evenly {
117
+ justify-content: space-evenly;
118
+ }
119
+
65
120
  /** Inline variation */
66
121
  .inline {
67
122
  display: inline-flex;