@bundle-stats/ui 4.22.2 → 4.23.0-beta.1

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 (227) hide show
  1. package/.babelrc.js +65 -24
  2. package/globals.d.ts +13 -0
  3. package/lib/app/app.js +3 -0
  4. package/lib/app/app.js.map +1 -1
  5. package/lib/app/app.module.css +11 -1
  6. package/lib/components/bundle-modules/index.js.map +1 -1
  7. package/lib/components/delta/delta.js +3 -13
  8. package/lib/components/delta/delta.js.map +1 -1
  9. package/lib/components/delta/delta.module.css +13 -12
  10. package/lib/components/delta/index.js.map +1 -1
  11. package/lib/components/index.js +3 -1
  12. package/lib/components/index.js.map +1 -1
  13. package/lib/components/insight-icon/insight-icon.module.css +6 -6
  14. package/lib/components/job-name/job-name.js +1 -2
  15. package/lib/components/job-name/job-name.js.map +1 -1
  16. package/lib/components/metric-change-legend/index.js +18 -0
  17. package/lib/components/metric-change-legend/index.js.map +1 -0
  18. package/lib/components/metric-change-legend/metric-change-legend.js +91 -0
  19. package/lib/components/metric-change-legend/metric-change-legend.js.map +1 -0
  20. package/lib/components/metric-change-legend/metric-change-legend.module.css +69 -0
  21. package/lib/components/metric-run-info/metric-run-info.js +30 -7
  22. package/lib/components/metric-run-info/metric-run-info.js.map +1 -1
  23. package/lib/components/metrics-display-selector/metrics-display-selector.js +7 -9
  24. package/lib/components/metrics-display-selector/metrics-display-selector.js.map +1 -1
  25. package/lib/components/metrics-display-selector/metrics-display-selector.module.css +0 -25
  26. package/lib/components/metrics-table-header/metrics-table-header.js +8 -8
  27. package/lib/components/metrics-table-header/metrics-table-header.js.map +1 -1
  28. package/lib/components/metrics-table-header/metrics-table-header.module.css +8 -12
  29. package/lib/components/metrics-table-options/metrics-table-options.js +1 -1
  30. package/lib/components/metrics-table-options/metrics-table-options.js.map +1 -1
  31. package/lib/components/metrics-table-title/metrics-table-title.js +1 -1
  32. package/lib/components/metrics-table-title/metrics-table-title.js.map +1 -1
  33. package/lib/components/run-info/run-info.js +26 -14
  34. package/lib/components/run-info/run-info.js.map +1 -1
  35. package/lib/components/run-info/run-info.module.css +35 -26
  36. package/lib/components/summary/summary.js +9 -10
  37. package/lib/components/summary/summary.js.map +1 -1
  38. package/lib/components/summary/summary.module.css +60 -10
  39. package/lib/constants.js +13 -1
  40. package/lib/constants.js.map +1 -1
  41. package/lib/css/default.css +1 -1
  42. package/lib/css/variables.css +71 -58
  43. package/lib/hooks/rows-sort.js +13 -12
  44. package/lib/hooks/rows-sort.js.map +1 -1
  45. package/lib/ui/button/button.js.map +1 -1
  46. package/lib/ui/dialog/dialog.js +4 -2
  47. package/lib/ui/dialog/dialog.js.map +1 -1
  48. package/lib/ui/dialog/dialog.module.css +22 -0
  49. package/lib/ui/dropdown/dropdown.js +4 -3
  50. package/lib/ui/dropdown/dropdown.js.map +1 -1
  51. package/lib/ui/dropdown/dropdown.module.css +11 -0
  52. package/lib/ui/empty-set/empty-set.js +3 -3
  53. package/lib/ui/empty-set/empty-set.js.map +1 -1
  54. package/lib/ui/hover-card/hover-card.js +1 -1
  55. package/lib/ui/hover-card/hover-card.js.map +1 -1
  56. package/lib/ui/hover-card/hover-card.module.css +14 -0
  57. package/lib/ui/table/table.module.css +0 -1
  58. package/lib/ui/tooltip/tooltip.js +1 -1
  59. package/lib/ui/tooltip/tooltip.js.map +1 -1
  60. package/lib/ui/tooltip/tooltip.module.css +11 -0
  61. package/lib-esm/app/app.js +4 -1
  62. package/lib-esm/app/app.js.map +1 -1
  63. package/lib-esm/app/app.module.css +11 -1
  64. package/lib-esm/components/bundle-modules/index.js.map +1 -1
  65. package/lib-esm/components/delta/delta.js +3 -13
  66. package/lib-esm/components/delta/delta.js.map +1 -1
  67. package/lib-esm/components/delta/delta.module.css +13 -12
  68. package/lib-esm/components/delta/index.js.map +1 -1
  69. package/lib-esm/components/index.js +1 -0
  70. package/lib-esm/components/index.js.map +1 -1
  71. package/lib-esm/components/insight-icon/insight-icon.module.css +6 -6
  72. package/lib-esm/components/job-name/job-name.js +1 -2
  73. package/lib-esm/components/job-name/job-name.js.map +1 -1
  74. package/lib-esm/components/metric-change-legend/index.js +2 -0
  75. package/lib-esm/components/metric-change-legend/index.js.map +1 -0
  76. package/lib-esm/components/metric-change-legend/metric-change-legend.js +84 -0
  77. package/lib-esm/components/metric-change-legend/metric-change-legend.js.map +1 -0
  78. package/lib-esm/components/metric-change-legend/metric-change-legend.module.css +69 -0
  79. package/lib-esm/components/metric-run-info/metric-run-info.js +31 -8
  80. package/lib-esm/components/metric-run-info/metric-run-info.js.map +1 -1
  81. package/lib-esm/components/metrics-display-selector/metrics-display-selector.js +7 -9
  82. package/lib-esm/components/metrics-display-selector/metrics-display-selector.js.map +1 -1
  83. package/lib-esm/components/metrics-display-selector/metrics-display-selector.module.css +0 -25
  84. package/lib-esm/components/metrics-table-header/metrics-table-header.js +8 -8
  85. package/lib-esm/components/metrics-table-header/metrics-table-header.js.map +1 -1
  86. package/lib-esm/components/metrics-table-header/metrics-table-header.module.css +8 -12
  87. package/lib-esm/components/metrics-table-options/metrics-table-options.js +1 -1
  88. package/lib-esm/components/metrics-table-options/metrics-table-options.js.map +1 -1
  89. package/lib-esm/components/metrics-table-title/metrics-table-title.js +1 -1
  90. package/lib-esm/components/metrics-table-title/metrics-table-title.js.map +1 -1
  91. package/lib-esm/components/run-info/run-info.js +26 -14
  92. package/lib-esm/components/run-info/run-info.js.map +1 -1
  93. package/lib-esm/components/run-info/run-info.module.css +35 -26
  94. package/lib-esm/components/summary/summary.js +10 -11
  95. package/lib-esm/components/summary/summary.js.map +1 -1
  96. package/lib-esm/components/summary/summary.module.css +60 -10
  97. package/lib-esm/constants.js +12 -0
  98. package/lib-esm/constants.js.map +1 -1
  99. package/lib-esm/css/default.css +1 -1
  100. package/lib-esm/css/variables.css +71 -58
  101. package/lib-esm/hooks/rows-sort.js +10 -8
  102. package/lib-esm/hooks/rows-sort.js.map +1 -1
  103. package/lib-esm/ui/button/button.js.map +1 -1
  104. package/lib-esm/ui/dialog/dialog.js +4 -2
  105. package/lib-esm/ui/dialog/dialog.js.map +1 -1
  106. package/lib-esm/ui/dialog/dialog.module.css +22 -0
  107. package/lib-esm/ui/dropdown/dropdown.js +4 -3
  108. package/lib-esm/ui/dropdown/dropdown.js.map +1 -1
  109. package/lib-esm/ui/dropdown/dropdown.module.css +11 -0
  110. package/lib-esm/ui/empty-set/empty-set.js +3 -3
  111. package/lib-esm/ui/empty-set/empty-set.js.map +1 -1
  112. package/lib-esm/ui/hover-card/hover-card.js +1 -1
  113. package/lib-esm/ui/hover-card/hover-card.js.map +1 -1
  114. package/lib-esm/ui/hover-card/hover-card.module.css +14 -0
  115. package/lib-esm/ui/table/table.module.css +0 -1
  116. package/lib-esm/ui/tooltip/tooltip.js +1 -1
  117. package/lib-esm/ui/tooltip/tooltip.js.map +1 -1
  118. package/lib-esm/ui/tooltip/tooltip.module.css +11 -0
  119. package/package.json +26 -15
  120. package/src/app/app.jsx +6 -1
  121. package/src/app/app.module.css +11 -1
  122. package/src/app/app.stories.tsx +2 -2
  123. package/src/components/asset-info/asset-info.stories.tsx +47 -39
  124. package/src/components/asset-name/asset-name.stories.tsx +1 -3
  125. package/src/components/asset-not-predictive/asset-not-predictive.stories.tsx +22 -15
  126. package/src/components/browsertime-table/browsertime-table.stories.tsx +45 -0
  127. package/src/components/bundle-assets-totals/bundle-assets-totals.stories.tsx +47 -0
  128. package/src/components/bundle-modules/bundle-modules.stories.tsx +191 -0
  129. package/src/components/bundle-modules/bundle-modules.tsx +1 -1
  130. package/src/components/bundle-modules/index.tsx +4 -0
  131. package/src/components/bundle-packages/bundle-packages.stories.tsx +87 -0
  132. package/src/components/delta/delta.module.css +13 -12
  133. package/src/components/delta/delta.stories.tsx +57 -0
  134. package/src/components/delta/delta.tsx +32 -0
  135. package/src/components/entry-info/entry-info.stories.tsx +49 -54
  136. package/src/components/{index.js → index.ts} +7 -2
  137. package/src/components/insight-icon/insight-icon.module.css +6 -6
  138. package/src/components/insights/insights.stories.tsx +36 -33
  139. package/src/components/job-name/job-name.jsx +2 -3
  140. package/src/components/job-name/job-name.stories.tsx +46 -0
  141. package/src/components/jobs-header/jobs-header.stories.tsx +19 -15
  142. package/src/components/lighthouse-table/lighthouse-table.stories.tsx +30 -0
  143. package/src/components/metric/metric.stories.tsx +24 -22
  144. package/src/components/metric-change-legend/index.ts +1 -0
  145. package/src/components/metric-change-legend/metric-change-legend.module.css +69 -0
  146. package/src/components/metric-change-legend/metric-change-legend.stories.tsx +13 -0
  147. package/src/components/metric-change-legend/metric-change-legend.tsx +148 -0
  148. package/src/components/metric-run-info/metric-run-info.stories.tsx +45 -41
  149. package/src/components/metric-run-info/metric-run-info.tsx +41 -17
  150. package/src/components/metrics-display-selector/metrics-display-selector.module.css +0 -25
  151. package/src/components/metrics-display-selector/metrics-display-selector.tsx +25 -37
  152. package/src/components/metrics-table/metrics-table.stories.tsx +33 -13
  153. package/src/components/metrics-table/metrics-table.tsx +1 -1
  154. package/src/components/metrics-table-header/metrics-table-header.module.css +8 -12
  155. package/src/components/metrics-table-header/metrics-table-header.tsx +14 -10
  156. package/src/components/metrics-table-options/metrics-table-options.tsx +1 -1
  157. package/src/components/metrics-table-title/metrics-table-title.jsx +1 -1
  158. package/src/components/module-info/module-info.stories.tsx +41 -30
  159. package/src/components/package-info/package-info.stories.tsx +20 -15
  160. package/src/components/run-info/run-info.module.css +35 -26
  161. package/src/components/run-info/run-info.stories.tsx +47 -39
  162. package/src/components/run-info/run-info.tsx +132 -73
  163. package/src/components/summary/summary.module.css +60 -10
  164. package/src/components/summary/summary.stories.tsx +26 -32
  165. package/src/components/summary/summary.tsx +47 -50
  166. package/src/constants.ts +13 -0
  167. package/src/css/default.css +1 -1
  168. package/src/css/variables.css +71 -58
  169. package/src/hooks/rows-sort.ts +9 -6
  170. package/src/layout/box/box.stories.tsx +35 -28
  171. package/src/layout/flex-stack/flex-stack.stories.tsx +79 -48
  172. package/src/layout/footer/footer.stories.tsx +30 -0
  173. package/src/layout/stack/stack.stories.tsx +68 -44
  174. package/src/ui/alert/alert.stories.tsx +25 -21
  175. package/src/ui/button/button.stories.tsx +181 -176
  176. package/src/ui/button/button.tsx +8 -1
  177. package/src/ui/container/container.stories.tsx +28 -21
  178. package/src/ui/control-group/control-group.stories.tsx +23 -16
  179. package/src/ui/dialog/dialog.module.css +22 -0
  180. package/src/ui/dialog/dialog.tsx +9 -2
  181. package/src/ui/dropdown/dropdown.module.css +11 -0
  182. package/src/ui/dropdown/dropdown.stories.tsx +23 -15
  183. package/src/ui/dropdown/dropdown.tsx +5 -1
  184. package/src/ui/empty-set/empty-set.jsx +16 -4
  185. package/src/ui/empty-set/empty-set.stories.tsx +41 -0
  186. package/src/ui/file-name/file-name.stories.tsx +45 -0
  187. package/src/ui/filters/filters.stories.tsx +29 -26
  188. package/src/ui/hover-card/hover-card.module.css +14 -0
  189. package/src/ui/hover-card/hover-card.stories.tsx +35 -26
  190. package/src/ui/hover-card/hover-card.tsx +1 -1
  191. package/src/ui/icon/icon.stories.tsx +36 -28
  192. package/src/ui/input/input.stories.tsx +17 -5
  193. package/src/ui/input-search/input-search.stories.tsx +31 -0
  194. package/src/ui/loader/loader.stories.tsx +22 -0
  195. package/src/ui/skeleton/skeleton.stories.tsx +42 -0
  196. package/src/ui/table/table.module.css +0 -1
  197. package/src/ui/table/table.stories.tsx +244 -218
  198. package/src/ui/tag/tag.stories.tsx +11 -10
  199. package/src/ui/toolbar/toolbar.stories.tsx +41 -0
  200. package/src/ui/tooltip/tooltip.module.css +11 -0
  201. package/src/ui/tooltip/tooltip.tsx +1 -1
  202. package/types/components/bundle-modules/bundle-modules.d.ts +1 -1
  203. package/types/components/bundle-modules/index.d.ts +2 -1
  204. package/types/components/delta/delta.d.ts +7 -21
  205. package/types/components/delta/index.d.ts +1 -1
  206. package/types/components/index.d.ts +25 -20
  207. package/types/components/metric-change-legend/index.d.ts +1 -0
  208. package/types/components/metric-change-legend/metric-change-legend.d.ts +4 -0
  209. package/types/components/metric-run-info/metric-run-info.d.ts +2 -6
  210. package/types/components/metrics-table/metrics-table.d.ts +1 -1
  211. package/types/components/metrics-table-header/metrics-table-header.d.ts +1 -1
  212. package/types/components/run-info/run-info.d.ts +16 -7
  213. package/types/constants.d.ts +12 -0
  214. package/types/hooks/rows-sort.d.ts +2 -2
  215. package/types/ui/button/button.d.ts +1 -1
  216. package/types/ui/dialog/dialog.d.ts +3 -2
  217. package/types/ui/dropdown/dropdown.d.ts +1 -0
  218. package/vitest.config.ts +47 -0
  219. package/vitest.setup.ts +26 -0
  220. package/lib/assets/icons.svg.js +0 -100
  221. package/lib/assets/icons.svg.js.map +0 -1
  222. package/lib-esm/assets/icons.svg.js +0 -63
  223. package/lib-esm/assets/icons.svg.js.map +0 -1
  224. package/src/assets/icons.svg.jsx +0 -279
  225. package/src/components/delta/delta.jsx +0 -22
  226. package/types/assets/icons.svg.d.ts +0 -2
  227. /package/src/components/delta/{index.js → index.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  import React, { type MouseEvent, useCallback, useMemo, ElementType } from 'react';
2
- import { getGlobalMetricType, getMetricRunInfo } from '@bundle-stats/utils';
2
+ import { getGlobalMetricType, getMetricRunInfo, MetricTypes } from '@bundle-stats/utils';
3
3
  import { Focusable } from 'ariakit/focusable';
4
4
 
5
5
  import { Stack } from '../../layout/stack';
@@ -8,11 +8,11 @@ import { Icon } from '../../ui/icon';
8
8
  import { RunInfo, RunInfoProps } from '../run-info';
9
9
  import css from './metric-run-info.module.css';
10
10
 
11
- interface MetricInfoProps {
11
+ type MetricInfoProps = {
12
12
  title: string;
13
13
  description?: string;
14
14
  url?: string;
15
- }
15
+ };
16
16
 
17
17
  const MetricHoverCard = ({ title, description, url }: MetricInfoProps) => {
18
18
  // The component parent can be rendered inside a link or a button
@@ -50,17 +50,13 @@ const MetricHoverCard = ({ title, description, url }: MetricInfoProps) => {
50
50
  );
51
51
  };
52
52
 
53
- export interface MetricRunInfoProps {
53
+ export type MetricRunInfoProps = {
54
54
  metricId: string;
55
55
  current: number;
56
56
  baseline?: number;
57
- showDelta?: boolean;
58
57
  showMetricDescription?: boolean;
59
- showBaseline?: boolean;
60
58
  titleWrapper?: ElementType;
61
- size?: RunInfoProps['size'];
62
- loading?: RunInfoProps['loading'];
63
- }
59
+ } & Pick<RunInfoProps, 'showDelta' | 'showBaseline' | 'size' | 'loading'>;
64
60
 
65
61
  export const MetricRunInfo = (props: MetricRunInfoProps & React.ComponentProps<'div'>) => {
66
62
  const {
@@ -92,16 +88,47 @@ export const MetricRunInfo = (props: MetricRunInfoProps & React.ComponentProps<'
92
88
  [CustomTitleWrapper, metric.label],
93
89
  );
94
90
 
91
+ const baselineProps = useMemo(() => {
92
+ if (showBaseline) {
93
+ return {
94
+ showBaseline,
95
+ baseline: metric.formatter(baseline),
96
+ };
97
+ }
98
+
99
+ return { showBaseline };
100
+ }, [showBaseline, baseline]);
101
+
95
102
  const deltaProps = useMemo(() => {
96
- if (!showDelta || metric.skipDelta || !('delta' in metricRunInfo)) {
97
- return {};
103
+ if (!showDelta || metric.skipDelta) {
104
+ return {
105
+ showDelta: false,
106
+ };
107
+ }
108
+
109
+ // If the delta data is missing, do not render the dats
110
+ if (!('delta' in metricRunInfo)) {
111
+ return {
112
+ showDelta: false,
113
+ };
114
+ }
115
+
116
+ // For file sizes, show the real data
117
+ if (metric.type === MetricTypes.FileSize) {
118
+ return {
119
+ showDelta: true,
120
+ delta: metricRunInfo.displayDelta,
121
+ deltaType: metricRunInfo.deltaType,
122
+ deltaPercentage: metricRunInfo.displayDeltaPercentage,
123
+ };
98
124
  }
99
125
 
100
126
  return {
101
- delta: metricRunInfo.displayDeltaPercentage,
127
+ showDelta: true,
128
+ delta: metricRunInfo.displayDelta,
102
129
  deltaType: metricRunInfo.deltaType,
103
130
  };
104
- }, [metricRunInfo]);
131
+ }, [metric, metricRunInfo, showDelta]);
105
132
 
106
133
  return (
107
134
  <RunInfo
@@ -109,10 +136,7 @@ export const MetricRunInfo = (props: MetricRunInfoProps & React.ComponentProps<'
109
136
  titleHoverCard={titleHoverCard}
110
137
  enhance
111
138
  current={metricRunInfo.displayValue}
112
- showBaseline={showBaseline}
113
- {...(showBaseline && {
114
- baseline: metric.formatter(baseline),
115
- })}
139
+ {...baselineProps}
116
140
  {...deltaProps}
117
141
  {...restProps}
118
142
  />
@@ -7,31 +7,6 @@
7
7
  padding: calc(var(--space-xxsmall) - 1px);
8
8
  }
9
9
 
10
- .dropdownGroupAnchor {
11
- border: none;
12
- border-radius: 0;
13
- position: relative;
14
- }
15
-
16
- .dropdownGroupAnchor::before {
17
- content: '';
18
- display: block;
19
- width: 1px;
20
- background: var(--color-outline-dark);
21
- position: absolute;
22
- left: 0;
23
- top: var(--space-xxxsmall);
24
- bottom: var(--space-xxxsmall);
25
- }
26
-
27
- .dropdownGroupAnchor:hover,
28
- .dropdownGroupAnchor:focus,
29
- .dropdownGroupAnchor:active {
30
- border-color: var(--color-outline);
31
- box-shadow: none;
32
- background: none;
33
- }
34
-
35
10
  .dropdownGroup:hover {
36
11
  border-color: var(--color-outline-dark);
37
12
  transition: var(--transition-in);
@@ -90,44 +90,32 @@ export const MetricsDisplaySelector = (
90
90
  );
91
91
 
92
92
  return (
93
- <FlexStack className={itemClassName} key={displayType}>
94
- <Button
95
- size="small"
96
- glyph={displayProps.glyph}
97
- onClick={() => onSelect(displayType)}
98
- className={css.dropdownGroupButton}
99
- >
100
- {displayProps.label}
101
- </Button>
102
- <Dropdown
103
- glyph={Icon.ICONS.CHEVRON_DOWN}
104
- placement="bottom-end"
105
- shift={-1}
106
- className={css.dropdownGroupAnchor}
107
- >
108
- {displayGroupsData.map((displayGroupData) => {
109
- const isGroupActive = isActive && displayGroupData.value === groupBy;
93
+ <Dropdown
94
+ label={displayProps.label}
95
+ glyph={displayProps.glyph}
96
+ placement="bottom-end"
97
+ shift={-1}
98
+ className={itemClassName}
99
+ key={displayType}
100
+ >
101
+ {displayGroupsData.map((displayGroupData) => {
102
+ const isGroupActive = isActive && displayGroupData.value === groupBy;
110
103
 
111
- return (
112
- <DropdownItem
113
- onClick={() => onSelect(displayType, displayGroupData.value)}
114
- isActive={isGroupActive}
115
- className={cx(css.dropdownItem, isGroupActive && css.dropdownItemActive)}
116
- key={displayGroupData.value}
117
- >
118
- <FlexStack space="xxxsmall" alignItems="center">
119
- <Icon
120
- glyph={Icon.ICONS.CHECK}
121
- size="small"
122
- className={css.dropdownItemIcon}
123
- />
124
- <span>{displayGroupData.label}</span>
125
- </FlexStack>
126
- </DropdownItem>
127
- );
128
- })}
129
- </Dropdown>
130
- </FlexStack>
104
+ return (
105
+ <DropdownItem
106
+ onClick={() => onSelect(displayType, displayGroupData.value)}
107
+ isActive={isGroupActive}
108
+ className={cx(css.dropdownItem, isGroupActive && css.dropdownItemActive)}
109
+ key={displayGroupData.value}
110
+ >
111
+ <FlexStack space="xxxsmall" alignItems="center">
112
+ <Icon glyph={Icon.ICONS.CHECK} size="small" className={css.dropdownItemIcon} />
113
+ <span>{displayGroupData.label}</span>
114
+ </FlexStack>
115
+ </DropdownItem>
116
+ );
117
+ })}
118
+ </Dropdown>
131
119
  );
132
120
  })}
133
121
  </ControlGroup>
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
-
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { MetricRunInfoDeltaType } from '@bundle-stats/utils';
4
+
4
5
  import { getWrapperDecorator } from '../../stories';
5
6
  import { MetricsTable } from '.';
6
7
 
@@ -204,22 +205,41 @@ const ITEMS_MULTIPLE_RUNS = [
204
205
  },
205
206
  ];
206
207
 
207
- export default {
208
+ const meta = {
208
209
  title: 'Components/MetricsTable',
209
210
  component: MetricsTable,
210
211
  decorators: [getWrapperDecorator()],
211
- };
212
+ } satisfies Meta<typeof MetricsTable>;
212
213
 
213
- export const Default = () => <MetricsTable runs={RUNS.slice(0, 1)} items={ITEMS_SINGLE_RUN} />;
214
+ export default meta;
214
215
 
215
- export const MultipleRuns = () => <MetricsTable runs={RUNS} items={ITEMS_MULTIPLE_RUNS} />;
216
+ type Story = StoryObj<typeof meta>;
216
217
 
217
- export const WithHeaderSum = () => (
218
- <MetricsTable
219
- runs={RUNS}
220
- items={[ITEMS_MULTIPLE_RUNS[0], ITEMS_MULTIPLE_RUNS[4]]}
221
- showHeaderSum
222
- />
223
- );
218
+ export const Default: Story = {
219
+ args: {
220
+ runs: RUNS.slice(0, 1),
221
+ items: ITEMS_SINGLE_RUN,
222
+ },
223
+ };
224
224
 
225
- export const Empty = () => <MetricsTable runs={RUNS} items={[]} />;
225
+ export const MultipleRuns: Story = {
226
+ args: {
227
+ runs: RUNS,
228
+ items: ITEMS_MULTIPLE_RUNS,
229
+ },
230
+ };
231
+
232
+ export const WithHeaderSum: Story = {
233
+ args: {
234
+ runs: RUNS,
235
+ items: [ITEMS_MULTIPLE_RUNS[0], ITEMS_MULTIPLE_RUNS[4]],
236
+ showHeaderSum: true,
237
+ },
238
+ };
239
+
240
+ export const Empty: Story = {
241
+ args: {
242
+ runs: RUNS,
243
+ items: [],
244
+ },
245
+ };
@@ -68,7 +68,7 @@ const Row = ({ className = '', item, renderHeader, ...restProps }: RowProps) =>
68
68
 
69
69
  interface MetricsTableProps extends Omit<React.ComponentProps<typeof Table>, 'title'> {
70
70
  runs: Array<{
71
- label: string;
71
+ label: React.ReactNode;
72
72
  internalBuildNumber: number;
73
73
  }>;
74
74
  items: Array<ReportMetricRow>;
@@ -4,23 +4,23 @@
4
4
  padding-bottom: var(--space-xxsmall);
5
5
  }
6
6
 
7
- .root .metric {
7
+ .root .colMetric {
8
8
  width: 55%;
9
9
  vertical-align: middle;
10
10
  }
11
11
 
12
- .root .job {
12
+ .root .colJob {
13
13
  padding-top: var(--space-xxsmall);
14
14
  text-align: right;
15
15
  }
16
16
 
17
- .root .value {
17
+ .root .colValue {
18
18
  text-align: right;
19
19
  vertical-align: baseline;
20
20
  width: 15%;
21
21
  }
22
22
 
23
- .root .delta {
23
+ .root .colDelta {
24
24
  text-align: right;
25
25
  font-size: var(--size-xsmall);
26
26
  vertical-align: baseline;
@@ -28,21 +28,17 @@
28
28
  color: pink;
29
29
  }
30
30
 
31
- .root .deltaPercentage {
31
+ .root .colDeltaPercentage {
32
32
  width: 5%;
33
33
  }
34
34
 
35
- .jobName {
36
- white-space: nowrap;
37
- }
38
-
39
35
  /* columns overrides for showHeaderSum */
40
- .showHeaderSum .job {
36
+ .showHeaderSum .colJob {
41
37
  border-bottom: 0;
42
- padding-bottom: 0;
38
+ padding-bottom: var(--space-xxxsmall);
43
39
  }
44
40
 
45
- .showHeaderSum .sum {
41
+ .showHeaderSum .colSum {
46
42
  padding-top: 0;
47
43
  font-size: var(--size-small);
48
44
  vertical-align: middle;
@@ -21,7 +21,7 @@ const BASELINE_COLUMN_SPAN = 1;
21
21
  const CURRENT_COLUMN_SPAN = 3;
22
22
 
23
23
  interface JobColumnProps {
24
- job: { label: string; internalBuildNumber: number };
24
+ job: { label: React.ReactNode; internalBuildNumber: number };
25
25
  isBaseline: boolean;
26
26
  }
27
27
 
@@ -34,11 +34,10 @@ const JobColumn = ({ job, isBaseline }: JobColumnProps) => {
34
34
  }
35
35
 
36
36
  return (
37
- <Table.Th className={cx(css.col, css.job)} colSpan={colSpan}>
37
+ <Table.Th className={cx(css.col, css.colJob)} colSpan={colSpan}>
38
38
  <JobName
39
39
  title={isBaseline ? I18N.BASELINE_TITLE : I18N.CURRENT_TITLE}
40
40
  internalBuildNumber={internalBuildNumber}
41
- className={css.jobName}
42
41
  >
43
42
  {label}
44
43
  </JobName>
@@ -65,7 +64,7 @@ const SumColumn = ({ rows, isBaseline, runIndex, updateSort, sort }: ColumnSumPr
65
64
 
66
65
  return (
67
66
  <>
68
- <Table.Th className={cx(css.col, css.value, css.sum)}>
67
+ <Table.Th className={cx(css.col, css.colValue, css.colSum)}>
69
68
  <SortButton
70
69
  fieldPath={fieldPath}
71
70
  fieldName="value"
@@ -78,7 +77,7 @@ const SumColumn = ({ rows, isBaseline, runIndex, updateSort, sort }: ColumnSumPr
78
77
  </Table.Th>
79
78
  {!isBaseline && (
80
79
  <>
81
- <Table.Th className={cx(css.col, css.delta, css.sum)}>
80
+ <Table.Th className={cx(css.col, css.colDelta, css.colSum)}>
82
81
  <SortButton
83
82
  fieldPath={fieldPath}
84
83
  fieldName="delta"
@@ -91,7 +90,7 @@ const SumColumn = ({ rows, isBaseline, runIndex, updateSort, sort }: ColumnSumPr
91
90
  )}
92
91
  </SortButton>
93
92
  </Table.Th>
94
- <Table.Th className={cx(css.col, css.delta, css.deltaPercentage, css.sum)}>
93
+ <Table.Th className={cx(css.col, css.colDelta, css.colDeltaPercentage, css.colSum)}>
95
94
  <SortButton
96
95
  fieldPath={fieldPath}
97
96
  fieldName="deltaPercentage"
@@ -122,7 +121,7 @@ export interface MetricsTableHeaderProps {
122
121
  /**
123
122
  * Array of jobs
124
123
  */
125
- jobs: Array<{ label: string; internalBuildNumber: number }>;
124
+ jobs: Array<{ label: React.ReactNode; internalBuildNumber: number }>;
126
125
  /**
127
126
  * Report rows
128
127
  */
@@ -147,17 +146,22 @@ export const MetricsTableHeader = (
147
146
  return (
148
147
  <Table.THead className={rootClassName}>
149
148
  <Table.Tr>
150
- <Table.Th className={cx(css.col, css.metric)} rowSpan={showSum ? 2 : 1}>
149
+ <Table.Th className={cx(css.col, css.colMetric)} rowSpan={showSum ? 2 : 1}>
151
150
  {metricTitle || ' '}
152
151
  </Table.Th>
153
152
  {jobs.map((job, runIndex) => (
154
- <JobColumn job={job} isBaseline={runIndex === jobs.length - 1} />
153
+ <JobColumn
154
+ key={job.internalBuildNumber}
155
+ job={job}
156
+ isBaseline={runIndex === jobs.length - 1}
157
+ />
155
158
  ))}
156
159
  </Table.Tr>
157
160
  {showSum && (
158
161
  <Table.Tr>
159
- {jobs.map((_, runIndex) => (
162
+ {jobs.map((job, runIndex) => (
160
163
  <SumColumn
164
+ key={job.internalBuildNumber}
161
165
  rows={rows}
162
166
  isBaseline={runIndex === jobs.length - 1}
163
167
  runIndex={runIndex}
@@ -15,7 +15,7 @@ export const MetricsTableOptions = (props: MetricsTableOptionsProps) => {
15
15
  const { onViewAllClick, onResetClick, onExportClick, ...restProps } = props;
16
16
 
17
17
  return (
18
- <Dropdown glyph="more-vertical" placement="bottom-end" {...restProps}>
18
+ <Dropdown glyph="more-vertical" placement="bottom-end" showChevron={false} {...restProps}>
19
19
  <div className={css.group}>
20
20
  {onResetClick && <DropdownItem onClick={onResetClick}>{I18N.RESET_FILTERS}</DropdownItem>}
21
21
  {onViewAllClick && <DropdownItem onClick={onViewAllClick}>{I18N.VIEW_ALL}</DropdownItem>}
@@ -15,7 +15,7 @@ export const MetricsTableTitle = (props) => {
15
15
  const rootClassName = cx(css.root, className);
16
16
 
17
17
  return (
18
- <Stack space="none" className={rootClassName}>
18
+ <Stack space="xxxsmall" className={rootClassName}>
19
19
  <FlexStack space="xxxsmall" alignItems="center" as="h3" className={css.title}>
20
20
  <span>{title}</span>
21
21
 
@@ -1,21 +1,37 @@
1
- import React from 'react';
2
-
1
+ import type { Meta, StoryObj } from '@storybook/react';
3
2
  import { action } from 'storybook/actions';
4
3
 
5
4
  import { getWrapperDecorator } from '../../stories';
6
5
  import { ModuleInfo } from '.';
7
6
 
8
- export default {
7
+ const ITEM = {
8
+ key: './node_modules/lodash/fp/merge.js',
9
+ label: './node_modules/lodash/fp/merge.js',
10
+ biggerIsBetter: false,
11
+ changed: true,
12
+ thirdParty: true,
13
+ duplicated: true,
14
+ fileType: 'JS',
15
+ };
16
+
17
+ const meta = {
9
18
  title: 'Components/ModuleInfo',
10
19
  component: ModuleInfo,
11
20
  decorators: [getWrapperDecorator()],
12
- };
21
+ args: {
22
+ labels: ['Job #2', 'Job #1'],
23
+ onClose: action('CLOSE'),
24
+ },
25
+ } satisfies Meta<typeof ModuleInfo>;
13
26
 
14
- export const Default = () => (
15
- <ModuleInfo
16
- item={{
17
- label: './node_modules/lodash/fp/merge.js',
18
- duplicated: true,
27
+ export default meta;
28
+
29
+ type Story = StoryObj<typeof meta>;
30
+
31
+ export const Default: Story = {
32
+ args: {
33
+ item: {
34
+ ...ITEM,
19
35
  runs: [
20
36
  {
21
37
  name: './node_modules/lodash/fp/merge.js',
@@ -29,8 +45,8 @@ export const Default = () => (
29
45
  displayValue: '3KiB',
30
46
  },
31
47
  ] as any,
32
- }}
33
- chunks={[
48
+ },
49
+ chunks: [
34
50
  {
35
51
  id: '1',
36
52
  name: 'chunk-1',
@@ -43,18 +59,15 @@ export const Default = () => (
43
59
  id: '3',
44
60
  name: 'chunk-3',
45
61
  },
46
- ]}
47
- chunkIds={['1', '2', '3']}
48
- labels={['Job #2', 'Job #1']}
49
- onClose={action('CLOSE')}
50
- />
51
- );
62
+ ],
63
+ chunkIds: ['1', '2', '3'],
64
+ },
65
+ };
52
66
 
53
- export const Duplicates = () => (
54
- <ModuleInfo
55
- item={{
56
- label: './node_modules/lodash/fp/merge.js',
57
- duplicated: true,
67
+ export const Duplicates: Story = {
68
+ args: {
69
+ item: {
70
+ ...ITEM,
58
71
  runs: [
59
72
  {
60
73
  name: './node_modules/lodash/fp/merge.js',
@@ -68,8 +81,8 @@ export const Duplicates = () => (
68
81
  displayValue: '3KiB',
69
82
  },
70
83
  ] as any,
71
- }}
72
- chunks={[
84
+ },
85
+ chunks: [
73
86
  {
74
87
  id: '1',
75
88
  name: 'chunk-1',
@@ -90,9 +103,7 @@ export const Duplicates = () => (
90
103
  id: '5',
91
104
  name: 'chunk-5',
92
105
  },
93
- ]}
94
- chunkIds={['1', '2', '3', '4', '5']}
95
- labels={['Job #2', 'Job #1']}
96
- onClose={action('CLOSE')}
97
- />
98
- );
106
+ ],
107
+ chunkIds: ['1', '2', '3', '4', '5'],
108
+ },
109
+ };
@@ -1,14 +1,9 @@
1
- import React from 'react';
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { action } from 'storybook/actions';
2
3
 
3
4
  import { getWrapperDecorator } from '../../stories';
4
5
  import { PackageInfo } from '.';
5
6
 
6
- export default {
7
- title: 'Components/PackageInfo',
8
- component: PackageInfo,
9
- decorators: [getWrapperDecorator()],
10
- };
11
-
12
7
  const RUNS = [
13
8
  {
14
9
  name: 'lodash',
@@ -23,14 +18,24 @@ const RUNS = [
23
18
  },
24
19
  ];
25
20
 
26
- export const Default = () => (
27
- <PackageInfo
28
- name="lodash~1"
29
- item={{
21
+ const meta = {
22
+ title: 'Components/PackageInfo',
23
+ component: PackageInfo,
24
+ decorators: [getWrapperDecorator()],
25
+ } satisfies Meta<typeof PackageInfo>;
26
+
27
+ export default meta;
28
+
29
+ type Story = StoryObj<typeof meta>;
30
+
31
+ export const Default: Story = {
32
+ args: {
33
+ item: {
30
34
  label: 'lodash',
31
35
  duplicate: true,
32
36
  runs: RUNS as any,
33
- }}
34
- labels={['Job #2', 'Job #1']}
35
- />
36
- );
37
+ },
38
+ labels: ['Job #2', 'Job #1'],
39
+ onClose: action('CLOSE'),
40
+ },
41
+ };