@bundle-stats/ui 4.13.0-beta.2 → 4.13.0-beta.20

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 (279) hide show
  1. package/lib/app/app.js +4 -8
  2. package/lib/app/app.js.map +1 -1
  3. package/lib/app/app.module.css +2 -2
  4. package/lib/assets/icons.svg +70 -67
  5. package/lib/assets/icons.svg.js +14 -12
  6. package/lib/assets/icons.svg.js.map +1 -1
  7. package/lib/components/bundle-assets/bundle-assets.js +47 -8
  8. package/lib/components/bundle-assets/bundle-assets.js.map +1 -1
  9. package/lib/components/bundle-assets/bundle-assets.module.css +0 -5
  10. package/lib/components/bundle-assets-totals/bundle-assets-totals.js +25 -14
  11. package/lib/components/bundle-assets-totals/bundle-assets-totals.js.map +1 -1
  12. package/lib/components/bundle-modules/bundle-modules.i18n.js +1 -1
  13. package/lib/components/bundle-modules/bundle-modules.js +45 -14
  14. package/lib/components/bundle-modules/bundle-modules.js.map +1 -1
  15. package/lib/components/bundle-modules/bundle-modules.module.css +0 -5
  16. package/lib/components/bundle-packages/bundle-packages.js +45 -6
  17. package/lib/components/bundle-packages/bundle-packages.js.map +1 -1
  18. package/lib/components/bundle-packages/bundle-packages.module.css +0 -5
  19. package/lib/components/delta/delta.js +1 -1
  20. package/lib/components/delta/delta.js.map +1 -1
  21. package/lib/components/delta/delta.module.css +10 -1
  22. package/lib/components/index.js +1 -3
  23. package/lib/components/index.js.map +1 -1
  24. package/lib/components/jobs-header/jobs-header.module.css +0 -4
  25. package/lib/components/metrics-display-selector/metrics-display-selector.js +42 -5
  26. package/lib/components/metrics-display-selector/metrics-display-selector.js.map +1 -1
  27. package/lib/components/metrics-display-selector/metrics-display-selector.module.css +15 -7
  28. package/lib/components/metrics-table/metrics-table.i18n.js +1 -6
  29. package/lib/components/metrics-table/metrics-table.i18n.js.map +1 -1
  30. package/lib/components/metrics-table/metrics-table.js +4 -37
  31. package/lib/components/metrics-table/metrics-table.js.map +1 -1
  32. package/lib/components/metrics-table/metrics-table.module.css +1 -44
  33. package/lib/components/{total-size-type-title → metrics-table-header}/index.js +1 -1
  34. package/lib/components/metrics-table-header/index.js.map +1 -0
  35. package/lib/components/metrics-table-header/metrics-table-header.i18n.js +9 -0
  36. package/lib/components/metrics-table-header/metrics-table-header.i18n.js.map +1 -0
  37. package/lib/components/metrics-table-header/metrics-table-header.js +79 -0
  38. package/lib/components/metrics-table-header/metrics-table-header.js.map +1 -0
  39. package/lib/components/metrics-table-header/metrics-table-header.module.css +51 -0
  40. package/lib/components/metrics-table-options/metrics-table-options.js +2 -2
  41. package/lib/components/metrics-table-options/metrics-table-options.js.map +1 -1
  42. package/lib/components/metrics-table-title/metrics-table-title.js +1 -1
  43. package/lib/components/metrics-table-title/metrics-table-title.js.map +1 -1
  44. package/lib/components/metrics-table-title/metrics-table-title.module.css +4 -4
  45. package/lib/components/metrics-treemap/index.js +4 -0
  46. package/lib/components/metrics-treemap/index.js.map +1 -1
  47. package/lib/components/metrics-treemap/metrics-treemap.constants.js +3 -0
  48. package/lib/components/metrics-treemap/metrics-treemap.constants.js.map +1 -0
  49. package/lib/components/metrics-treemap/metrics-treemap.i18n.js +6 -0
  50. package/lib/components/metrics-treemap/metrics-treemap.i18n.js.map +1 -0
  51. package/lib/components/metrics-treemap/metrics-treemap.js +96 -70
  52. package/lib/components/metrics-treemap/metrics-treemap.js.map +1 -1
  53. package/lib/components/metrics-treemap/metrics-treemap.module.css +163 -51
  54. package/lib/components/metrics-treemap/metrics-treemap.utils.js +109 -0
  55. package/lib/components/metrics-treemap/metrics-treemap.utils.js.map +1 -0
  56. package/lib/components/module-info/module-info.js +1 -2
  57. package/lib/components/module-info/module-info.js.map +1 -1
  58. package/lib/components/run-info/run-info.module.css +7 -7
  59. package/lib/components/sort-button/sort-button.module.css +1 -0
  60. package/lib/css/variables.css +14 -13
  61. package/lib/hooks/metrics-display-type.js +45 -24
  62. package/lib/hooks/metrics-display-type.js.map +1 -1
  63. package/lib/hooks/search-params.js +1 -0
  64. package/lib/hooks/search-params.js.map +1 -1
  65. package/lib/layout/box/box.module.css +4 -2
  66. package/lib/layout/flex-stack/flex-stack.js +3 -4
  67. package/lib/layout/flex-stack/flex-stack.js.map +1 -1
  68. package/lib/layout/flex-stack/flex-stack.module.css +19 -23
  69. package/lib/ui/button/button.js +5 -4
  70. package/lib/ui/button/button.js.map +1 -1
  71. package/lib/ui/button/button.module.css +55 -53
  72. package/lib/ui/dropdown/dropdown.js +10 -40
  73. package/lib/ui/dropdown/dropdown.js.map +1 -1
  74. package/lib/ui/dropdown/index.js.map +1 -1
  75. package/lib/ui/filters/filters.js +33 -35
  76. package/lib/ui/filters/filters.js.map +1 -1
  77. package/lib/ui/filters/filters.module.css +55 -67
  78. package/lib/ui/hover-card/hover-card.js +1 -1
  79. package/lib/ui/hover-card/hover-card.js.map +1 -1
  80. package/lib/ui/icon/icon.js +2 -1
  81. package/lib/ui/icon/icon.js.map +1 -1
  82. package/lib/ui/input-search/input-search.js +1 -1
  83. package/lib/ui/input-search/input-search.js.map +1 -1
  84. package/lib/ui/loader/loader.js +1 -1
  85. package/lib/ui/loader/loader.js.map +1 -1
  86. package/lib/ui/table/table.module.css +30 -0
  87. package/lib/ui/tag/tag.module.css +3 -3
  88. package/lib/ui/toolbar/toolbar.module.css +1 -3
  89. package/lib-esm/app/app.js +4 -8
  90. package/lib-esm/app/app.js.map +1 -1
  91. package/lib-esm/app/app.module.css +2 -2
  92. package/lib-esm/assets/icons.svg +70 -67
  93. package/lib-esm/assets/icons.svg.js +14 -12
  94. package/lib-esm/assets/icons.svg.js.map +1 -1
  95. package/lib-esm/components/bundle-assets/bundle-assets.js +48 -9
  96. package/lib-esm/components/bundle-assets/bundle-assets.js.map +1 -1
  97. package/lib-esm/components/bundle-assets/bundle-assets.module.css +0 -5
  98. package/lib-esm/components/bundle-assets-totals/bundle-assets-totals.js +26 -15
  99. package/lib-esm/components/bundle-assets-totals/bundle-assets-totals.js.map +1 -1
  100. package/lib-esm/components/bundle-modules/bundle-modules.i18n.js +1 -1
  101. package/lib-esm/components/bundle-modules/bundle-modules.js +46 -15
  102. package/lib-esm/components/bundle-modules/bundle-modules.js.map +1 -1
  103. package/lib-esm/components/bundle-modules/bundle-modules.module.css +0 -5
  104. package/lib-esm/components/bundle-packages/bundle-packages.js +46 -7
  105. package/lib-esm/components/bundle-packages/bundle-packages.js.map +1 -1
  106. package/lib-esm/components/bundle-packages/bundle-packages.module.css +0 -5
  107. package/lib-esm/components/delta/delta.js +1 -1
  108. package/lib-esm/components/delta/delta.js.map +1 -1
  109. package/lib-esm/components/delta/delta.module.css +10 -1
  110. package/lib-esm/components/index.js +0 -1
  111. package/lib-esm/components/index.js.map +1 -1
  112. package/lib-esm/components/jobs-header/jobs-header.module.css +0 -4
  113. package/lib-esm/components/metrics-display-selector/metrics-display-selector.js +42 -5
  114. package/lib-esm/components/metrics-display-selector/metrics-display-selector.js.map +1 -1
  115. package/lib-esm/components/metrics-display-selector/metrics-display-selector.module.css +15 -7
  116. package/lib-esm/components/metrics-table/metrics-table.i18n.js +0 -5
  117. package/lib-esm/components/metrics-table/metrics-table.i18n.js.map +1 -1
  118. package/lib-esm/components/metrics-table/metrics-table.js +4 -37
  119. package/lib-esm/components/metrics-table/metrics-table.js.map +1 -1
  120. package/lib-esm/components/metrics-table/metrics-table.module.css +1 -44
  121. package/lib-esm/components/metrics-table-header/index.js +2 -0
  122. package/lib-esm/components/metrics-table-header/index.js.map +1 -0
  123. package/lib-esm/components/metrics-table-header/metrics-table-header.i18n.js +6 -0
  124. package/lib-esm/components/metrics-table-header/metrics-table-header.i18n.js.map +1 -0
  125. package/lib-esm/components/metrics-table-header/metrics-table-header.js +49 -0
  126. package/lib-esm/components/metrics-table-header/metrics-table-header.js.map +1 -0
  127. package/lib-esm/components/metrics-table-header/metrics-table-header.module.css +51 -0
  128. package/lib-esm/components/metrics-table-options/metrics-table-options.js +3 -3
  129. package/lib-esm/components/metrics-table-options/metrics-table-options.js.map +1 -1
  130. package/lib-esm/components/metrics-table-title/metrics-table-title.js +1 -1
  131. package/lib-esm/components/metrics-table-title/metrics-table-title.js.map +1 -1
  132. package/lib-esm/components/metrics-table-title/metrics-table-title.module.css +4 -4
  133. package/lib-esm/components/metrics-treemap/index.js +1 -0
  134. package/lib-esm/components/metrics-treemap/index.js.map +1 -1
  135. package/lib-esm/components/metrics-treemap/metrics-treemap.constants.js +2 -0
  136. package/lib-esm/components/metrics-treemap/metrics-treemap.constants.js.map +1 -0
  137. package/lib-esm/components/metrics-treemap/metrics-treemap.i18n.js +3 -0
  138. package/lib-esm/components/metrics-treemap/metrics-treemap.i18n.js.map +1 -0
  139. package/lib-esm/components/metrics-treemap/metrics-treemap.js +98 -71
  140. package/lib-esm/components/metrics-treemap/metrics-treemap.js.map +1 -1
  141. package/lib-esm/components/metrics-treemap/metrics-treemap.module.css +163 -51
  142. package/lib-esm/components/metrics-treemap/metrics-treemap.utils.js +105 -0
  143. package/lib-esm/components/metrics-treemap/metrics-treemap.utils.js.map +1 -0
  144. package/lib-esm/components/module-info/module-info.js +1 -2
  145. package/lib-esm/components/module-info/module-info.js.map +1 -1
  146. package/lib-esm/components/run-info/run-info.module.css +7 -7
  147. package/lib-esm/components/sort-button/sort-button.module.css +1 -0
  148. package/lib-esm/css/variables.css +14 -13
  149. package/lib-esm/hooks/metrics-display-type.js +46 -24
  150. package/lib-esm/hooks/metrics-display-type.js.map +1 -1
  151. package/lib-esm/hooks/search-params.js +1 -0
  152. package/lib-esm/hooks/search-params.js.map +1 -1
  153. package/lib-esm/layout/box/box.module.css +4 -2
  154. package/lib-esm/layout/flex-stack/flex-stack.js +3 -4
  155. package/lib-esm/layout/flex-stack/flex-stack.js.map +1 -1
  156. package/lib-esm/layout/flex-stack/flex-stack.module.css +19 -23
  157. package/lib-esm/ui/button/button.js +5 -4
  158. package/lib-esm/ui/button/button.js.map +1 -1
  159. package/lib-esm/ui/button/button.module.css +55 -53
  160. package/lib-esm/ui/dropdown/dropdown.js +8 -39
  161. package/lib-esm/ui/dropdown/dropdown.js.map +1 -1
  162. package/lib-esm/ui/dropdown/index.js.map +1 -1
  163. package/lib-esm/ui/filters/filters.js +34 -36
  164. package/lib-esm/ui/filters/filters.js.map +1 -1
  165. package/lib-esm/ui/filters/filters.module.css +55 -67
  166. package/lib-esm/ui/hover-card/hover-card.js +1 -1
  167. package/lib-esm/ui/hover-card/hover-card.js.map +1 -1
  168. package/lib-esm/ui/icon/icon.js +2 -1
  169. package/lib-esm/ui/icon/icon.js.map +1 -1
  170. package/lib-esm/ui/input-search/input-search.js +1 -1
  171. package/lib-esm/ui/input-search/input-search.js.map +1 -1
  172. package/lib-esm/ui/loader/loader.js +1 -1
  173. package/lib-esm/ui/loader/loader.js.map +1 -1
  174. package/lib-esm/ui/table/table.module.css +30 -0
  175. package/lib-esm/ui/tag/tag.module.css +3 -3
  176. package/lib-esm/ui/toolbar/toolbar.module.css +1 -3
  177. package/package.json +10 -10
  178. package/src/app/app.jsx +4 -12
  179. package/src/app/app.module.css +2 -2
  180. package/src/assets/icons/check.svg +4 -0
  181. package/src/assets/icons.svg +70 -67
  182. package/src/assets/icons.svg.jsx +12 -12
  183. package/src/components/bundle-assets/bundle-assets.jsx +85 -12
  184. package/src/components/bundle-assets/bundle-assets.module.css +0 -5
  185. package/src/components/bundle-assets-totals/bundle-assets-totals.jsx +71 -35
  186. package/src/components/bundle-modules/bundle-modules.i18n.ts +1 -1
  187. package/src/components/bundle-modules/bundle-modules.module.css +0 -5
  188. package/src/components/bundle-modules/bundle-modules.tsx +123 -45
  189. package/src/components/bundle-packages/bundle-packages.jsx +79 -10
  190. package/src/components/bundle-packages/bundle-packages.module.css +0 -5
  191. package/src/components/delta/delta.jsx +1 -1
  192. package/src/components/delta/delta.module.css +10 -1
  193. package/src/components/index.js +0 -1
  194. package/src/components/jobs-header/jobs-header.module.css +0 -4
  195. package/src/components/metrics-display-selector/metrics-display-selector.module.css +15 -7
  196. package/src/components/metrics-display-selector/metrics-display-selector.stories.tsx +33 -0
  197. package/src/components/metrics-display-selector/metrics-display-selector.tsx +86 -28
  198. package/src/components/metrics-table/metrics-table.i18n.ts +0 -7
  199. package/src/components/metrics-table/metrics-table.module.css +1 -44
  200. package/src/components/metrics-table/metrics-table.tsx +17 -153
  201. package/src/components/metrics-table-header/index.ts +1 -0
  202. package/src/components/metrics-table-header/metrics-table-header.i18n.ts +6 -0
  203. package/src/components/metrics-table-header/metrics-table-header.module.css +51 -0
  204. package/src/components/metrics-table-header/metrics-table-header.tsx +172 -0
  205. package/src/components/metrics-table-options/metrics-table-options.jsx +4 -10
  206. package/src/components/metrics-table-title/metrics-table-title.jsx +1 -1
  207. package/src/components/metrics-table-title/metrics-table-title.module.css +4 -4
  208. package/src/components/metrics-treemap/__tests__/metrics-treemap.utils.ts +188 -0
  209. package/src/components/metrics-treemap/index.ts +1 -0
  210. package/src/components/metrics-treemap/metrics-treemap.constants.ts +52 -0
  211. package/src/components/metrics-treemap/metrics-treemap.i18n.ts +2 -0
  212. package/src/components/metrics-treemap/metrics-treemap.module.css +163 -51
  213. package/src/components/metrics-treemap/metrics-treemap.stories.tsx +44 -10
  214. package/src/components/metrics-treemap/metrics-treemap.tsx +340 -142
  215. package/src/components/metrics-treemap/metrics-treemap.utils.ts +162 -0
  216. package/src/components/module-info/module-info.tsx +1 -1
  217. package/src/components/run-info/run-info.module.css +7 -7
  218. package/src/components/sort-button/sort-button.module.css +1 -0
  219. package/src/css/variables.css +14 -13
  220. package/src/hooks/metrics-display-type.ts +79 -29
  221. package/src/hooks/search-params.js +1 -0
  222. package/src/layout/box/box.module.css +4 -2
  223. package/src/layout/flex-stack/flex-stack.module.css +19 -23
  224. package/src/layout/flex-stack/flex-stack.tsx +2 -8
  225. package/src/ui/button/button.module.css +55 -53
  226. package/src/ui/button/button.stories.tsx +16 -9
  227. package/src/ui/button/button.tsx +8 -7
  228. package/src/ui/dropdown/dropdown.stories.tsx +25 -0
  229. package/src/ui/dropdown/dropdown.tsx +66 -0
  230. package/src/ui/filters/filters.module.css +55 -67
  231. package/src/ui/filters/filters.stories.tsx +109 -0
  232. package/src/ui/filters/filters.tsx +128 -167
  233. package/src/ui/hover-card/hover-card.tsx +1 -1
  234. package/src/ui/icon/icon.tsx +2 -1
  235. package/src/ui/input-search/input-search.tsx +1 -0
  236. package/src/ui/loader/loader.jsx +1 -1
  237. package/src/ui/table/table.module.css +30 -0
  238. package/src/ui/tag/tag.module.css +3 -3
  239. package/src/ui/toolbar/toolbar.module.css +1 -3
  240. package/types/components/bundle-assets-totals/bundle-assets-totals.d.ts +5 -1
  241. package/types/components/bundle-modules/bundle-modules.i18n.d.ts +1 -1
  242. package/types/components/delta/delta.d.ts +2 -2
  243. package/types/components/index.d.ts +0 -1
  244. package/types/components/metrics-display-selector/metrics-display-selector.d.ts +5 -3
  245. package/types/components/metrics-table/metrics-table.d.ts +4 -10
  246. package/types/components/metrics-table/metrics-table.i18n.d.ts +0 -5
  247. package/types/components/metrics-table-header/index.d.ts +1 -0
  248. package/types/components/metrics-table-header/metrics-table-header.d.ts +15 -0
  249. package/types/components/metrics-table-header/metrics-table-header.i18n.d.ts +5 -0
  250. package/types/components/metrics-treemap/index.d.ts +1 -0
  251. package/types/components/metrics-treemap/metrics-treemap.constants.d.ts +20 -0
  252. package/types/components/metrics-treemap/metrics-treemap.d.ts +7 -5
  253. package/types/components/metrics-treemap/metrics-treemap.i18n.d.ts +2 -0
  254. package/types/components/metrics-treemap/metrics-treemap.utils.d.ts +5 -0
  255. package/types/hooks/metrics-display-type.d.ts +8 -2
  256. package/types/ui/dropdown/dropdown.d.ts +12 -47
  257. package/types/ui/dropdown/index.d.ts +1 -1
  258. package/types/ui/filters/filters.d.ts +2 -7
  259. package/types/ui/icon/icon.d.ts +4 -2
  260. package/types/ui/loader/loader.d.ts +2 -2
  261. package/lib/components/bundle-assets-totals/bundle-assets-totals.module.css +0 -7
  262. package/lib/components/total-size-type-title/index.js.map +0 -1
  263. package/lib/components/total-size-type-title/total-size-type-title.js +0 -32
  264. package/lib/components/total-size-type-title/total-size-type-title.js.map +0 -1
  265. package/lib/components/total-size-type-title/total-size-type-title.module.css +0 -14
  266. package/lib-esm/components/bundle-assets-totals/bundle-assets-totals.module.css +0 -7
  267. package/lib-esm/components/total-size-type-title/index.js +0 -2
  268. package/lib-esm/components/total-size-type-title/index.js.map +0 -1
  269. package/lib-esm/components/total-size-type-title/total-size-type-title.js +0 -25
  270. package/lib-esm/components/total-size-type-title/total-size-type-title.js.map +0 -1
  271. package/lib-esm/components/total-size-type-title/total-size-type-title.module.css +0 -14
  272. package/src/components/bundle-assets-totals/bundle-assets-totals.module.css +0 -7
  273. package/src/components/total-size-type-title/index.js +0 -1
  274. package/src/components/total-size-type-title/total-size-type-title.jsx +0 -41
  275. package/src/components/total-size-type-title/total-size-type-title.module.css +0 -14
  276. package/src/ui/dropdown/dropdown.jsx +0 -88
  277. package/types/components/total-size-type-title/index.d.ts +0 -1
  278. package/types/components/total-size-type-title/total-size-type-title.d.ts +0 -14
  279. /package/src/ui/dropdown/{index.js → index.ts} +0 -0
@@ -1,4 +1,4 @@
1
- import React, { useCallback } from 'react';
1
+ import React, { useCallback, useMemo } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useHistory } from 'react-router-dom';
4
4
  import {
@@ -7,73 +7,103 @@ import {
7
7
  } from '@bundle-stats/utils';
8
8
  import * as webpack from '@bundle-stats/utils/lib-esm/webpack';
9
9
 
10
+ import config from '../../config.json';
10
11
  import { ASSETS_SIZES_FILE_TYPE_MAP, SECTION_URLS, MetricsDisplayType } from '../../constants';
11
12
  import { useMetricsDisplayType } from '../../hooks/metrics-display-type';
13
+ import I18N from '../../i18n';
12
14
  import { Toolbar } from '../../ui/toolbar';
13
- import { MetricsTreemap } from '../metrics-treemap';
15
+ import { Table } from '../../ui/table';
16
+ import { Box } from '../../layout/box';
17
+ import { Stack } from '../../layout/stack';
14
18
  import { MetricsDisplaySelector } from '../metrics-display-selector';
15
- import { TotalSizeTypeTitle } from '../total-size-type-title';
16
19
  import { MetricsTable } from '../metrics-table';
20
+ import { MetricsTableTitle } from '../metrics-table-title';
21
+ import { MetricsTableHeader } from '../metrics-table-header';
22
+ import { MetricsTreemap, getTreemapNodes } from '../metrics-treemap';
17
23
  import { ComponentLink } from '../component-link';
18
- import css from './bundle-assets-totals.module.css';
24
+
25
+ const metricsTableTitle = (
26
+ <MetricsTableTitle
27
+ title={I18N.ASSET_TOTALS}
28
+ popoverInfo={I18N.ASSET_TOTALS_INFO}
29
+ popoverHref={config.documentation.assets}
30
+ />
31
+ );
19
32
 
20
33
  export const BundleAssetsTotals = ({
21
34
  className,
22
35
  jobs,
23
36
  customComponentLink: CustomComponentLink,
37
+ onTreemapItemClick,
24
38
  ...restProps
25
39
  }) => {
26
40
  const [displayType, setDisplayType] = useMetricsDisplayType();
27
41
  const history = useHistory();
28
42
 
29
- const items = webpack.compareBySection.sizes(jobs);
43
+ const items = useMemo(() => webpack.compareBySection.sizes(jobs), [jobs]);
30
44
 
31
- const renderRowHeader = (item) => {
32
- const fileType = ASSETS_SIZES_FILE_TYPE_MAP[item.key];
33
- const { section, title, params } = getBundleAssetsFileTypeComponentLink(fileType, item.label);
45
+ const renderRowHeader = useCallback(
46
+ (item) => {
47
+ const fileType = ASSETS_SIZES_FILE_TYPE_MAP[item.key];
48
+ const { section, title, params } = getBundleAssetsFileTypeComponentLink(fileType, item.label);
34
49
 
35
- return (
36
- <CustomComponentLink section={section} title={title} params={params}>
37
- {item.label}
38
- </CustomComponentLink>
39
- );
40
- };
50
+ return (
51
+ <CustomComponentLink section={section} title={title} params={params}>
52
+ {item.label}
53
+ </CustomComponentLink>
54
+ );
55
+ },
56
+ [CustomComponentLink],
57
+ );
41
58
 
42
59
  const handleMetricsTreemapItemClick = useCallback(
43
60
  (entryId) => {
44
61
  const fileType = ASSETS_SIZES_FILE_TYPE_MAP[entryId];
45
62
  const { section, params } = getBundleAssetsFileTypeComponentLink(fileType, '');
46
- const search = getComponentStateQueryString(params);
47
- const nextUrl = `${SECTION_URLS[section]}?${search}`;
63
+ const queryParams = getComponentStateQueryString(params);
48
64
 
65
+ const nextUrl = `${SECTION_URLS[section]}?${queryParams}`;
49
66
  history.push(nextUrl);
50
67
  },
51
68
  [history],
52
69
  );
53
70
 
54
71
  return (
55
- <div className={className}>
72
+ <Stack space="xsmall" as="section" className={className}>
56
73
  <Toolbar
57
- className={css.toolbar}
58
74
  renderActions={() => (
59
- <MetricsDisplaySelector onSelect={setDisplayType} value={displayType} />
75
+ <MetricsDisplaySelector onSelect={setDisplayType} value={displayType.value} />
60
76
  )}
61
- >
62
- <TotalSizeTypeTitle />
63
- </Toolbar>
64
- {displayType === MetricsDisplayType.TABLE && (
65
- <MetricsTable
66
- runs={jobs}
67
- items={items}
68
- renderRowHeader={renderRowHeader}
69
- showHeaderSum
70
- {...restProps}
71
- />
72
- )}
73
- {displayType === MetricsDisplayType.TREEMAP && (
74
- <MetricsTreemap items={items} onItemClick={handleMetricsTreemapItemClick} />
75
- )}
76
- </div>
77
+ />
78
+ <Box outline as="main">
79
+ {displayType.value === MetricsDisplayType.TABLE && (
80
+ <MetricsTable
81
+ title={metricsTableTitle}
82
+ runs={jobs}
83
+ items={items}
84
+ renderRowHeader={renderRowHeader}
85
+ showHeaderSum
86
+ {...restProps}
87
+ />
88
+ )}
89
+ {displayType.value === MetricsDisplayType.TREEMAP && (
90
+ <>
91
+ <Table compact>
92
+ <MetricsTableHeader
93
+ metricTitle={metricsTableTitle}
94
+ showSum
95
+ jobs={jobs}
96
+ rows={items}
97
+ />
98
+ </Table>
99
+ <MetricsTreemap
100
+ treeNodes={getTreemapNodes(items)}
101
+ onItemClick={onTreemapItemClick || handleMetricsTreemapItemClick}
102
+ />
103
+ </>
104
+ )}
105
+ </Box>
106
+ </Stack>
77
107
  );
78
108
  };
79
109
 
@@ -81,6 +111,7 @@ BundleAssetsTotals.defaultProps = {
81
111
  className: '',
82
112
  jobs: [],
83
113
  customComponentLink: ComponentLink,
114
+ onTreemapItemClick: undefined,
84
115
  };
85
116
 
86
117
  BundleAssetsTotals.propTypes = {
@@ -91,4 +122,9 @@ BundleAssetsTotals.propTypes = {
91
122
  jobs: PropTypes.array, // eslint-disable-line react/forbid-prop-types
92
123
 
93
124
  customComponentLink: PropTypes.elementType,
125
+
126
+ /**
127
+ * Treemap item onClick
128
+ */
129
+ onTreemapItemClick: PropTypes.func,
94
130
  };
@@ -1,4 +1,4 @@
1
- export const SEARCH = 'Search by module name';
1
+ export const SEARCH = 'Search by module path';
2
2
  export const CHANGED = 'Changed';
3
3
  export const DUPLICATE = 'Duplicate';
4
4
  export const CHUNK = 'Chunk';
@@ -2,14 +2,9 @@
2
2
  color: var(--color-text-light);
3
3
  }
4
4
 
5
- .toolbar {
6
- border-bottom: 1px solid var(--color-outline);
7
- }
8
-
9
5
  .toolbarSearch {
10
6
  width: 100%;
11
7
  max-width: 240px;
12
- margin-right: -1px; /** collapse border */
13
8
  }
14
9
 
15
10
  .metricSelector {
@@ -5,20 +5,24 @@ import { SECTIONS, COMPONENT } from '@bundle-stats/utils';
5
5
  import { SortAction } from '../../types';
6
6
  import config from '../../config.json';
7
7
  import I18N from '../../i18n';
8
- import { Box } from '../../layout/box';
9
8
  import { MetricsDisplayType } from '../../constants';
9
+ import { Box } from '../../layout/box';
10
10
  import { FlexStack } from '../../layout/flex-stack';
11
+ import { Stack } from '../../layout/stack';
11
12
  import { Button } from '../../ui/button';
13
+ import { ControlGroup } from '../../ui/control-group';
12
14
  import { EmptySet } from '../../ui/empty-set';
13
15
  import { FileName } from '../../ui/file-name';
14
16
  import { Filters } from '../../ui/filters';
15
17
  import { InputSearch } from '../../ui/input-search';
16
18
  import { Tag } from '../../ui/tag';
19
+ import { Table } from '../../ui/table';
17
20
  import { Toolbar } from '../../ui/toolbar';
18
21
  import { Tooltip } from '../../ui/tooltip';
19
22
  import { ComponentLink } from '../component-link';
20
23
  import { MetricsTable } from '../metrics-table';
21
- import { MetricsTreemap } from '../metrics-treemap';
24
+ import { MetricsTableHeader } from '../metrics-table-header';
25
+ import { MetricsTreemap, getTreemapNodes, getTreemapNodesGroupedByPath } from '../metrics-treemap';
22
26
  import { MetricsTableOptions } from '../metrics-table-options';
23
27
  import { MetricsDisplaySelector } from '../metrics-display-selector';
24
28
  import { MetricsTableTitle } from '../metrics-table-title';
@@ -30,6 +34,10 @@ import * as I18N_MODULES from './bundle-modules.i18n';
30
34
  import css from './bundle-modules.module.css';
31
35
  import { useMetricsDisplayType } from '../../hooks/metrics-display-type';
32
36
 
37
+ const DISPLAY_TYPE_GROUPS = {
38
+ [MetricsDisplayType.TREEMAP]: ['folder'],
39
+ };
40
+
33
41
  interface RowHeaderProps {
34
42
  row: ReportMetricModuleRow;
35
43
  filters?: any;
@@ -44,7 +52,9 @@ const RowHeader = (props: RowHeaderProps) => {
44
52
  return (
45
53
  <CustomComponentLink
46
54
  section={SECTIONS.MODULES}
47
- params={{ [COMPONENT.BUNDLE_MODULES]: { filters, search, entryId: row.key, moduleMetric } }}
55
+ params={{
56
+ [COMPONENT.BUNDLE_MODULES]: { filters, search, entryId: row.key, metric: moduleMetric },
57
+ }}
48
58
  className={css.name}
49
59
  >
50
60
  {row.duplicated && (
@@ -55,6 +65,59 @@ const RowHeader = (props: RowHeaderProps) => {
55
65
  );
56
66
  };
57
67
 
68
+ interface ViewMetricsTreemapProps {
69
+ metricsTableTitle: React.ReactNode;
70
+ jobs: Array<any>;
71
+ items: Array<any>;
72
+ displayType: { value: MetricsDisplayType; groupBy?: string };
73
+ emptyMessage: React.ReactNode;
74
+ showEntryInfo: React.ComponentProps<typeof MetricsTreemap>['onItemClick'];
75
+ updateSearch: (newSerarch: string) => void;
76
+ }
77
+
78
+ const ViewMetricsTreemap = (props: ViewMetricsTreemapProps) => {
79
+ const { metricsTableTitle, jobs, items, displayType, emptyMessage, showEntryInfo, updateSearch } =
80
+ props;
81
+
82
+ const treeNodes = useMemo(() => {
83
+ if (displayType.groupBy === 'folder') {
84
+ return getTreemapNodesGroupedByPath(items);
85
+ }
86
+
87
+ return getTreemapNodes(items);
88
+ }, [items, displayType]);
89
+
90
+ const onGroupClick = useCallback(
91
+ (groupPath: string) => {
92
+ // Search by group path
93
+ // 1. use `^` to match only the string beggining
94
+ // 2. add `/` suffix to match only exact directories
95
+ // 3. if the group path is empty(root), clear search
96
+ if (groupPath) {
97
+ updateSearch(`^${groupPath}/`);
98
+ } else {
99
+ updateSearch('');
100
+ }
101
+ },
102
+ [updateSearch],
103
+ );
104
+
105
+ return (
106
+ <>
107
+ <Table compact>
108
+ <MetricsTableHeader metricTitle={metricsTableTitle} showSum jobs={jobs} rows={items} />
109
+ </Table>
110
+ <MetricsTreemap
111
+ treeNodes={treeNodes}
112
+ nested={Boolean(displayType.groupBy)}
113
+ emptyMessage={emptyMessage}
114
+ onItemClick={showEntryInfo}
115
+ onGroupClick={onGroupClick}
116
+ />
117
+ </>
118
+ );
119
+ };
120
+
58
121
  interface BundleModulesProps extends React.ComponentProps<'div'> {
59
122
  jobs?: Array<Job>;
60
123
  items?: Array<ReportMetricModuleRow>;
@@ -111,7 +174,7 @@ export const BundleModules = (props: BundleModulesProps) => {
111
174
  const rootClassName = cx(css.root, className);
112
175
  const jobLabels = jobs?.map((job) => job?.label);
113
176
 
114
- const [displayType, setDisplayType] = useMetricsDisplayType();
177
+ const [displayType, setDisplayType] = useMetricsDisplayType(DISPLAY_TYPE_GROUPS);
115
178
 
116
179
  const filterFieldsData = useMemo(
117
180
  () => generateFilterFieldsData({ filters, chunks, compareMode: jobs.length > 1 }),
@@ -140,7 +203,7 @@ export const BundleModules = (props: BundleModulesProps) => {
140
203
  customComponentLink={CustomComponentLink}
141
204
  />
142
205
  ),
143
- [jobs, chunks, CustomComponentLink, filters, search],
206
+ [jobs, chunks, CustomComponentLink, filters, search, moduleMetric],
144
207
  );
145
208
 
146
209
  const emptyMessage = useMemo(
@@ -165,12 +228,17 @@ export const BundleModules = (props: BundleModulesProps) => {
165
228
 
166
229
  return (
167
230
  <>
168
- <div className={rootClassName}>
231
+ <Stack space="xsmall" as="section" className={rootClassName}>
169
232
  <Toolbar
170
233
  className={css.toolbar}
171
234
  renderActions={({ actionClassName }) => (
172
235
  <FlexStack space="xxsmall" className={cx(css.dropdown, actionClassName)}>
173
- <MetricsDisplaySelector onSelect={setDisplayType} value={displayType} />
236
+ <MetricsDisplaySelector
237
+ onSelect={setDisplayType}
238
+ value={displayType.value}
239
+ groupBy={displayType.groupBy}
240
+ groups={DISPLAY_TYPE_GROUPS}
241
+ />
174
242
  <MetricsTableOptions
175
243
  handleViewAll={resetAllFilters}
176
244
  handleResetFilters={resetFilters}
@@ -192,45 +260,55 @@ export const BundleModules = (props: BundleModulesProps) => {
192
260
  />
193
261
  </FlexStack>
194
262
  </Toolbar>
195
- <Box padding={['xsmall', 'small']} className={css.metricSelector}>
196
- <FlexStack space="xxsmall" as="nav">
197
- <Button
198
- outline
199
- active={moduleMetric === ModuleMetric.SIZE}
200
- size="small"
201
- type="button"
202
- onClick={() => setModuleMetric(ModuleMetric.SIZE)}
203
- >
204
- <Tooltip title="Size (excluding duplicate modules)">Module size</Tooltip>
205
- </Button>
206
- <Button
207
- outline
208
- active={moduleMetric === ModuleMetric.TOTAL_SIZE}
209
- size="small"
210
- type="button"
211
- onClick={() => setModuleMetric(ModuleMetric.TOTAL_SIZE)}
212
- >
213
- <Tooltip title="Size (including duplicate modules)">Module total size</Tooltip>
214
- </Button>
215
- </FlexStack>
263
+ <Box outline as="main">
264
+ <Box padding={['xsmall', 'small']} className={css.metricSelector}>
265
+ <ControlGroup as="nav">
266
+ <Button
267
+ outline
268
+ active={moduleMetric === ModuleMetric.SIZE}
269
+ size="small"
270
+ type="button"
271
+ onClick={() => setModuleMetric(ModuleMetric.SIZE)}
272
+ >
273
+ <Tooltip title="Size (excluding duplicate modules)">Module size</Tooltip>
274
+ </Button>
275
+ <Button
276
+ outline
277
+ active={moduleMetric === ModuleMetric.TOTAL_SIZE}
278
+ size="small"
279
+ type="button"
280
+ onClick={() => setModuleMetric(ModuleMetric.TOTAL_SIZE)}
281
+ >
282
+ <Tooltip title="Size (including duplicate modules)">Module total size</Tooltip>
283
+ </Button>
284
+ </ControlGroup>
285
+ </Box>
286
+ {displayType.value === MetricsDisplayType.TABLE && (
287
+ <MetricsTable
288
+ className={css.table}
289
+ items={items}
290
+ runs={jobs}
291
+ renderRowHeader={renderRowHeader}
292
+ emptyMessage={emptyMessage}
293
+ showHeaderSum
294
+ title={metricsTableTitle}
295
+ sort={sort}
296
+ updateSort={updateSort}
297
+ />
298
+ )}
299
+ {displayType.value === MetricsDisplayType.TREEMAP && (
300
+ <ViewMetricsTreemap
301
+ metricsTableTitle={metricsTableTitle}
302
+ jobs={jobs}
303
+ items={items}
304
+ displayType={displayType}
305
+ emptyMessage={emptyMessage}
306
+ showEntryInfo={showEntryInfo}
307
+ updateSearch={updateSearch}
308
+ />
309
+ )}
216
310
  </Box>
217
- {displayType === MetricsDisplayType.TABLE && (
218
- <MetricsTable
219
- className={css.table}
220
- items={items}
221
- runs={jobs}
222
- renderRowHeader={renderRowHeader}
223
- emptyMessage={emptyMessage}
224
- showHeaderSum
225
- title={metricsTableTitle}
226
- sort={sort}
227
- updateSort={updateSort}
228
- />
229
- )}
230
- {displayType === MetricsDisplayType.TREEMAP && (
231
- <MetricsTreemap emptyMessage={emptyMessage} items={items} onItemClick={showEntryInfo} />
232
- )}
233
- </div>
311
+ </Stack>
234
312
  {entryItem && (
235
313
  <ModuleInfo
236
314
  className={css.moduleInfo}
@@ -5,14 +5,18 @@ import { COMPONENT, PACKAGE_FILTERS, PACKAGES_SEPARATOR, SECTIONS } from '@bundl
5
5
 
6
6
  import config from '../../config.json';
7
7
  import I18N from '../../i18n';
8
+ import { Box } from '../../layout/box';
8
9
  import { FlexStack } from '../../layout/flex-stack';
10
+ import { Stack } from '../../layout/stack';
9
11
  import { InputSearch } from '../../ui/input-search';
10
12
  import { EmptySet } from '../../ui/empty-set';
11
13
  import { Filters } from '../../ui/filters';
12
14
  import { Tag } from '../../ui/tag';
15
+ import { Table } from '../../ui/table';
13
16
  import { Toolbar } from '../../ui/toolbar';
14
17
  import { ComponentLink } from '../component-link';
15
18
  import { MetricsTable } from '../metrics-table';
19
+ import { MetricsTableHeader } from '../metrics-table-header';
16
20
  import { MetricsTableOptions } from '../metrics-table-options';
17
21
  import { MetricsTableTitle } from '../metrics-table-title';
18
22
  import { PackageInfo } from '../package-info';
@@ -20,9 +24,13 @@ import { SEARCH_PLACEHOLDER } from './bundle-packages.i18n';
20
24
  import css from './bundle-packages.module.css';
21
25
  import { MetricsDisplaySelector } from '../metrics-display-selector';
22
26
  import { MetricsDisplayType } from '../../constants';
23
- import { MetricsTreemap } from '../metrics-treemap';
27
+ import { MetricsTreemap, getTreemapNodes, getTreemapNodesGroupedByPath } from '../metrics-treemap';
24
28
  import { useMetricsDisplayType } from '../../hooks/metrics-display-type';
25
29
 
30
+ const DISPLAY_TYPE_GROUPS = {
31
+ [MetricsDisplayType.TREEMAP]: ['folder'],
32
+ };
33
+
26
34
  const getDropdownFilters = ({ compareMode, filters }) => ({
27
35
  [PACKAGE_FILTERS.CHANGED]: {
28
36
  label: 'Changed',
@@ -111,6 +119,60 @@ RowHeader.propTypes = {
111
119
  search: PropTypes.string,
112
120
  };
113
121
 
122
+ const ViewMetricsTreemap = (props) => {
123
+ const { metricsTableTitle, jobs, items, displayType, emptyMessage, showEntryInfo, updateSearch } = props;
124
+
125
+ const treeNodes = useMemo(() => {
126
+ if (displayType.groupBy === 'folder') {
127
+ return getTreemapNodesGroupedByPath(items);
128
+ }
129
+
130
+ return getTreemapNodes(items);
131
+ }, [items, displayType.groupBy]);
132
+
133
+ const onGroupClick = useCallback(
134
+ (groupPath) => {
135
+ // Search by group path
136
+ // 1. use `^` to match only the string beggining
137
+ // 2. add `/` suffix to match only exact directories
138
+ // 3. if the group path is empty(root), clear search
139
+ if (groupPath) {
140
+ updateSearch(`^${groupPath}/`);
141
+ } else {
142
+ updateSearch('');
143
+ }
144
+ },
145
+ [updateSearch],
146
+ );
147
+
148
+ return (
149
+ <>
150
+ <Table compact>
151
+ <MetricsTableHeader metricTitle={metricsTableTitle} showSum jobs={jobs} rows={items} />
152
+ </Table>
153
+ <MetricsTreemap
154
+ treeNodes={treeNodes}
155
+ nested={Boolean(displayType.groupBy)}
156
+ emptyMessage={emptyMessage}
157
+ onItemClick={showEntryInfo}
158
+ onGroupClick={onGroupClick}
159
+ />
160
+ </>
161
+ );
162
+ };
163
+
164
+ ViewMetricsTreemap.propTypes = {
165
+ jobs: PropTypes.arrayOf(PropTypes.object).isRequired, // eslint-disable-line react/forbid-prop-types
166
+ items: PropTypes.arrayOf(PropTypes.object).isRequired, // eslint-disable-line react/forbid-prop-types
167
+ metricsTableTitle: PropTypes.node.isRequired,
168
+ displayType: PropTypes.shape({
169
+ groupBy: PropTypes.string,
170
+ }).isRequired,
171
+ emptyMessage: PropTypes.node.isRequired,
172
+ showEntryInfo: PropTypes.func.isRequired,
173
+ updateSearch: PropTypes.func.isRequired,
174
+ };
175
+
114
176
  export const BundlePackages = (props) => {
115
177
  const {
116
178
  className,
@@ -135,7 +197,7 @@ export const BundlePackages = (props) => {
135
197
 
136
198
  const jobLabels = jobs?.map((job) => job?.label);
137
199
 
138
- const [displayType, setDisplayType] = useMetricsDisplayType();
200
+ const [displayType, setDisplayType] = useMetricsDisplayType(DISPLAY_TYPE_GROUPS);
139
201
 
140
202
  const dropdownFilters = useMemo(
141
203
  () => getDropdownFilters({ compareMode: jobs?.length > 1, filters }),
@@ -189,12 +251,12 @@ export const BundlePackages = (props) => {
189
251
 
190
252
  return (
191
253
  <>
192
- <section className={cx(css.root, className)}>
254
+ <Stack space="xsmall" as="section" className={cx(css.root, className)}>
193
255
  <Toolbar
194
256
  className={css.toolbar}
195
257
  renderActions={({ actionClassName }) => (
196
258
  <FlexStack space="xxsmall" className={cx(css.dropdown, actionClassName)}>
197
- <MetricsDisplaySelector onSelect={setDisplayType} value={displayType} />
259
+ <MetricsDisplaySelector onSelect={setDisplayType} value={displayType.value} groupBy={displayType.groupBy} groups={DISPLAY_TYPE_GROUPS} />
198
260
  <MetricsTableOptions
199
261
  handleViewAll={resetAllFilters}
200
262
  handleResetFilters={resetFilters}
@@ -217,8 +279,8 @@ export const BundlePackages = (props) => {
217
279
  />
218
280
  </FlexStack>
219
281
  </Toolbar>
220
- <main>
221
- {displayType === MetricsDisplayType.TABLE && (
282
+ <Box outline as="main">
283
+ {displayType.value === MetricsDisplayType.TABLE && (
222
284
  <MetricsTable
223
285
  runs={jobs}
224
286
  items={items}
@@ -230,11 +292,18 @@ export const BundlePackages = (props) => {
230
292
  updateSort={updateSort}
231
293
  />
232
294
  )}
233
- {displayType === MetricsDisplayType.TREEMAP && (
234
- <MetricsTreemap emptyMessage={emptyMessage} items={items} onItemClick={showEntryInfo} />
295
+ {displayType.value === MetricsDisplayType.TREEMAP && (
296
+ <ViewMetricsTreemap
297
+ jobs={jobs}
298
+ items={items}
299
+ displayType={displayType}
300
+ emptyMessage={emptyMessage}
301
+ showEntryInfo={showEntryInfo}
302
+ updateSearch={updateSearch}
303
+ />
235
304
  )}
236
- </main>
237
- </section>
305
+ </Box>
306
+ </Stack>
238
307
  {entryItem && (
239
308
  <PackageInfo
240
309
  className={css.packageInfo}
@@ -2,14 +2,9 @@
2
2
  color: var(--color-text-light);
3
3
  }
4
4
 
5
- .toolbar {
6
- border-bottom: 1px solid var(--color-outline);
7
- }
8
-
9
5
  .toolbarSearch {
10
6
  width: 100%;
11
7
  max-width: 240px;
12
- margin-right: -1px; /** collapse border */
13
8
  }
14
9
 
15
10
  .hoverCard {
@@ -4,7 +4,7 @@ import cx from 'classnames';
4
4
 
5
5
  import css from './delta.module.css';
6
6
 
7
- export const Delta = ({ className, displayValue, deltaType, inverted }) => {
7
+ export const Delta = ({ className = '', displayValue, deltaType, inverted = false }) => {
8
8
  const rootClassName = cx(css.root, className, inverted && css.inverted, css[deltaType]);
9
9
  return <span className={rootClassName}>{displayValue}</span>;
10
10
  };
@@ -4,6 +4,10 @@
4
4
  white-space: nowrap;
5
5
  }
6
6
 
7
+ .CHANGE {
8
+ color: var(--color-info);
9
+ }
10
+
7
11
  .HIGH_NEGATIVE {
8
12
  color: var(--color-red-dark);
9
13
  }
@@ -29,11 +33,16 @@
29
33
  }
30
34
 
31
35
  .inverted {
32
- border-radius: var(--radius-small);
36
+ padding: 0 2px;
37
+ border-radius: var(--radius-xsmall);
33
38
  background-color: var(--color-gray-ultra-light);
34
39
  color: var(--color-light);
35
40
  }
36
41
 
42
+ .inverted.CHANGE {
43
+ background: var(--color-info-light);
44
+ }
45
+
37
46
  .inverted.HIGH_NEGATIVE {
38
47
  background: var(--color-red-dark);
39
48
  }
@@ -18,4 +18,3 @@ export { MetricsTableTitle } from './metrics-table-title';
18
18
  export { ModuleInfo } from './module-info';
19
19
  export { RunInfo, RunInfoProps } from './run-info';
20
20
  export { Summary } from './summary';
21
- export { TotalSizeTypeTitle } from './total-size-type-title';
@@ -24,10 +24,6 @@
24
24
  background: linear-gradient(90deg, transparent, var(--color-background));
25
25
  }
26
26
 
27
- .item + .item {
28
- margin-left: var(--space-small);
29
- }
30
-
31
27
  .item:first-child {
32
28
  border-left: 0;
33
29
  padding-left: 0;
@@ -1,10 +1,18 @@
1
- .button {
2
- text-decoration: none;
1
+ .buttonActive {
2
+ background: var(--color-highlight);
3
3
  }
4
4
 
5
- .buttonActive,
6
- .buttonActive:active,
7
- .buttonActive:focus {
8
- color: var(--color-primary);
9
- border-color: var(--color-primary);
5
+ /* explicit ControlGroup last item styles to override ariakit injected sibling nodes */
6
+ .itemLast {
7
+ border-top-right-radius: var(--radius-small) !important;
8
+ border-bottom-right-radius: var(--radius-small) !important;
9
+ }
10
+
11
+ .dropdownItemIcon {
12
+ opacity: 0;
13
+ transition: var(--transition-out);
14
+ }
15
+
16
+ .dropdownItemActive .dropdownItemIcon {
17
+ opacity: 1;
10
18
  }