@bundle-stats/ui 3.2.2 → 3.3.0-alpha.0

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 (99) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/lib/app/app.js +31 -6
  3. package/lib/app/app.stories.js +24 -3
  4. package/lib/assets/icons/alert-circle.svg +1 -0
  5. package/lib/assets/icons/check-circle.svg +1 -0
  6. package/lib/assets/icons.svg +8 -0
  7. package/lib/components/browsertime-table/browsertime-table.js +1 -1
  8. package/lib/components/browsertime-table/browsertime-table.stories.js +1 -1
  9. package/lib/components/budget-info/budget-info.js +53 -0
  10. package/lib/components/budget-info/budget-info.module.css +28 -0
  11. package/lib/components/budget-info/budget-info.stories.js +42 -0
  12. package/lib/components/budget-info/index.js +18 -0
  13. package/lib/components/budget-insights/budget-insights.js +200 -0
  14. package/lib/components/budget-insights/budget-insights.module.css +53 -0
  15. package/lib/components/budget-insights/budget-insights.stories.js +104 -0
  16. package/lib/components/budget-insights/index.js +18 -0
  17. package/lib/components/bundle-assets/bundle-assets.js +3 -3
  18. package/lib/components/bundle-assets/bundle-assets.utils.js +2 -2
  19. package/lib/components/bundle-assets/index.js +3 -3
  20. package/lib/components/bundle-assets-totals-chart-bars/bundle-assets-totals-chart-bars.js +1 -1
  21. package/lib/components/bundle-assets-totals-table/bundle-assets-totals-table.js +45 -8
  22. package/lib/components/bundle-assets-totals-table/bundle-assets-totals-table.module.css +2 -2
  23. package/lib/components/bundle-assets-totals-table/bundle-assets-totals-table.stories.js +20 -1
  24. package/lib/components/bundle-modules/bundle-modules.js +3 -3
  25. package/lib/components/bundle-modules/bundle-modules.utils.js +2 -2
  26. package/lib/components/bundle-modules/index.js +3 -3
  27. package/lib/components/bundle-packages/bundle-packages.js +1 -1
  28. package/lib/components/bundle-packages/bundle-packages.utils.js +2 -2
  29. package/lib/components/bundle-packages/index.js +1 -1
  30. package/lib/components/lighthouse-table/lighthouse-table.js +1 -1
  31. package/lib/components/metrics-table/metrics-table.js +1 -1
  32. package/lib/components/metrics-table-search/metrics-table-search.js +1 -1
  33. package/lib/components/metrics-table-search/metrics-table-search.stories.js +1 -1
  34. package/lib/components/summary/summary.js +12 -7
  35. package/lib/components/summary/summary.module.css +1 -1
  36. package/lib/components/summary/summary.stories.js +29 -0
  37. package/lib/components/summary-item/summary-item.js +22 -5
  38. package/lib/components/summary-item/summary-item.module.css +15 -0
  39. package/lib/components/summary-item/summary-item.stories.js +51 -53
  40. package/lib/constants.js +6 -6
  41. package/lib/hooks/search-params.js +2 -2
  42. package/lib/query-state.js +1 -1
  43. package/lib/stories/wrapper.js +2 -2
  44. package/lib/ui/alert/alert.js +13 -3
  45. package/lib/ui/filters/filters.container.js +5 -5
  46. package/lib/ui/filters/filters.js +2 -2
  47. package/lib/ui/filters/filters.stories.js +3 -3
  48. package/lib/ui/horizontal-bar-chart/horizontal-bar-chart.js +3 -3
  49. package/lib/ui/icon/icon.js +2 -0
  50. package/lib/ui/panels/panels.js +2 -2
  51. package/lib/ui/popover/popover.js +1 -1
  52. package/lib/ui/tabs/tabs.js +2 -2
  53. package/lib/utils.js +2 -2
  54. package/lib-esm/app/app.js +57 -31
  55. package/lib-esm/app/app.stories.js +22 -1
  56. package/lib-esm/assets/icons/alert-circle.svg +1 -0
  57. package/lib-esm/assets/icons/check-circle.svg +1 -0
  58. package/lib-esm/assets/icons.svg +8 -0
  59. package/lib-esm/components/budget-info/budget-info.js +37 -0
  60. package/lib-esm/components/budget-info/budget-info.module.css +28 -0
  61. package/lib-esm/components/budget-info/budget-info.stories.js +26 -0
  62. package/lib-esm/components/budget-info/index.js +1 -0
  63. package/lib-esm/components/budget-insights/budget-insights.js +147 -0
  64. package/lib-esm/components/budget-insights/budget-insights.module.css +53 -0
  65. package/lib-esm/components/budget-insights/budget-insights.stories.js +84 -0
  66. package/lib-esm/components/budget-insights/index.js +1 -0
  67. package/lib-esm/components/bundle-assets-totals-table/bundle-assets-totals-table.js +24 -7
  68. package/lib-esm/components/bundle-assets-totals-table/bundle-assets-totals-table.module.css +2 -2
  69. package/lib-esm/components/bundle-assets-totals-table/bundle-assets-totals-table.stories.js +18 -0
  70. package/lib-esm/components/summary/summary.js +11 -7
  71. package/lib-esm/components/summary/summary.module.css +1 -1
  72. package/lib-esm/components/summary/summary.stories.js +27 -0
  73. package/lib-esm/components/summary-item/summary-item.js +20 -4
  74. package/lib-esm/components/summary-item/summary-item.module.css +15 -0
  75. package/lib-esm/components/summary-item/summary-item.stories.js +50 -38
  76. package/lib-esm/constants.js +4 -4
  77. package/lib-esm/ui/alert/alert.js +6 -3
  78. package/lib-esm/ui/filters/filters.container.js +39 -41
  79. package/lib-esm/ui/icon/icon.js +2 -0
  80. package/package.json +3 -3
  81. package/src/app/app.jsx +24 -8
  82. package/src/assets/icons/alert-circle.svg +1 -0
  83. package/src/assets/icons/check-circle.svg +1 -0
  84. package/src/assets/icons.svg +8 -0
  85. package/src/components/budget-info/budget-info.jsx +49 -0
  86. package/src/components/budget-info/budget-info.module.css +28 -0
  87. package/src/components/budget-info/index.js +1 -0
  88. package/src/components/budget-insights/budget-insights.jsx +152 -0
  89. package/src/components/budget-insights/budget-insights.module.css +53 -0
  90. package/src/components/budget-insights/index.js +1 -0
  91. package/src/components/bundle-assets-totals-table/bundle-assets-totals-table.jsx +28 -13
  92. package/src/components/bundle-assets-totals-table/bundle-assets-totals-table.module.css +2 -2
  93. package/src/components/summary/summary.jsx +8 -7
  94. package/src/components/summary/summary.module.css +1 -1
  95. package/src/components/summary-item/summary-item.jsx +13 -2
  96. package/src/components/summary-item/summary-item.module.css +15 -0
  97. package/src/constants.js +7 -7
  98. package/src/ui/alert/alert.jsx +7 -2
  99. package/src/ui/icon/icon.jsx +2 -0
@@ -0,0 +1,28 @@
1
+ .root {
2
+ display: inline-block;
3
+ line-height: 1em;
4
+ }
5
+
6
+ /* Budget over */
7
+ .over .icon {
8
+ color: var(--color-danger-light);
9
+ }
10
+
11
+ .over .icon:hover,
12
+ .over .icon:focus,
13
+ .over .icon:active
14
+ {
15
+ color: var(--color-danger);
16
+ }
17
+
18
+ /* Budget under */
19
+ .under .icon {
20
+ color: var(--color-success-light);
21
+ }
22
+
23
+ .under .icon:hover,
24
+ .under .icon:focus,
25
+ .under .icon:active
26
+ {
27
+ color: var(--color-success);
28
+ }
@@ -0,0 +1 @@
1
+ export * from './budget-info';
@@ -0,0 +1,152 @@
1
+ import React, { useMemo, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import cx from 'classnames';
4
+ import { METRIC_COMPONENT_LINKS, getGlobalMetricType } from '@bundle-stats/utils';
5
+
6
+ import { Box } from '../../layout/box';
7
+ import { Stack } from '../../layout/stack';
8
+ import { FlexStack } from '../../layout/flex-stack';
9
+ import { Alert } from '../../ui/alert';
10
+ import { Icon } from '../../ui/icon';
11
+ import { ComponentLink } from '../component-link';
12
+ import css from './budget-insights.module.css';
13
+
14
+ const Budget = (props) => {
15
+ const { className, metricKey, CustomLink, failed, budgetValue } = props;
16
+ const metric = getGlobalMetricType(metricKey);
17
+ const componentLinkOptions = METRIC_COMPONENT_LINKS.get(metricKey);
18
+
19
+ return (
20
+ <CustomLink className={cx(css.budget, className)} {...componentLinkOptions?.link}>
21
+ <span className={css.budgetLabel}>{metric.label}</span>
22
+ {` is ${failed ? 'over' : 'under'} `}
23
+ <span className={css.budgetValue}>{metric.formatter(budgetValue)}</span>
24
+ {` budget`}
25
+ </CustomLink>
26
+ );
27
+ };
28
+
29
+ Budget.propTypes = {
30
+ className: PropTypes.string,
31
+ metricKey: PropTypes.string.isRequired,
32
+ failed: PropTypes.bool.isRequired,
33
+ currentValue: PropTypes.number.isRequired,
34
+ budgetValue: PropTypes.number.isRequired,
35
+ CustomLink: PropTypes.elementType.isRequired,
36
+ };
37
+
38
+ Budget.defaultProps = {
39
+ className: '',
40
+ };
41
+
42
+ const BudgetsGroup = (props) => {
43
+ const { className, kind, source, budgets, CustomLink } = props;
44
+ const [showBudgets, setShowBudgets] = useState(false);
45
+
46
+ const isFailed = kind === 'danger';
47
+
48
+ return (
49
+ <Alert kind={kind} padding="none" className={cx(css.group, css[kind], className)}>
50
+ <Box
51
+ padding={['xsmall', 'small']}
52
+ className={css.groupHeader}
53
+ as="button"
54
+ type="button"
55
+ onClick={() => setShowBudgets(!showBudgets)}
56
+ >
57
+ <FlexStack space="xxsmall" className={css.groupTitle}>
58
+ <Icon
59
+ className={css.groupIcon}
60
+ glyph={isFailed ? Icon.ICONS.ALERT_CIRCLE : Icon.ICONS.CHECK_CIRCLE}
61
+ />
62
+ <span>
63
+ <strong>{budgets.length}</strong>
64
+ {` budget ${budgets.length > 1 ? 'checks' : 'check'} ${isFailed ? 'failed' : 'passed'}`}
65
+ </span>
66
+ <span className={css.groupTitleToggle}>{showBudgets ? 'hide' : 'show'} all</span>
67
+ </FlexStack>
68
+ </Box>
69
+
70
+ {showBudgets && (
71
+ <Box padding={['xsmall', 'small']} className={css.groupContent}>
72
+ <Stack space="none">
73
+ {budgets.map(([key, budget]) => (
74
+ <Budget
75
+ key={key}
76
+ source={source}
77
+ metricKey={`${source}.${key}`}
78
+ CustomLink={CustomLink}
79
+ {...budget}
80
+ />
81
+ ))}
82
+ </Stack>
83
+ </Box>
84
+ )}
85
+ </Alert>
86
+ );
87
+ };
88
+
89
+ BudgetsGroup.propTypes = {
90
+ className: PropTypes.string,
91
+ kind: PropTypes.oneOf(['success', 'danger']).isRequired,
92
+ source: PropTypes.string.isRequired,
93
+ budgets: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
94
+ CustomLink: PropTypes.elementType.isRequired,
95
+ };
96
+
97
+ BudgetsGroup.defaultProps = {
98
+ className: '',
99
+ };
100
+
101
+ export const BudgetInsights = (props) => {
102
+ const { className, source, budgets, CustomLink } = props;
103
+
104
+ const [failedBudgets, passedBudgets] = useMemo(() => {
105
+ const passed = [];
106
+ const failed = [];
107
+
108
+ Object.entries(budgets).forEach(([key, budget]) => {
109
+ if (budget.failed) {
110
+ failed.push([key, budget]);
111
+ } else {
112
+ passed.push([key, budget]);
113
+ }
114
+ });
115
+
116
+ return [failed, passed];
117
+ }, [budgets]);
118
+
119
+ return (
120
+ <Stack className={className} space="xsmall">
121
+ {failedBudgets.length > 0 && (
122
+ <BudgetsGroup
123
+ kind="danger"
124
+ source={source}
125
+ budgets={failedBudgets}
126
+ CustomLink={CustomLink}
127
+ />
128
+ )}
129
+
130
+ {passedBudgets.length > 0 && (
131
+ <BudgetsGroup
132
+ kind="success"
133
+ source={source}
134
+ budgets={passedBudgets}
135
+ CustomLink={CustomLink}
136
+ />
137
+ )}
138
+ </Stack>
139
+ );
140
+ };
141
+
142
+ BudgetInsights.propTypes = {
143
+ className: PropTypes.string,
144
+ source: PropTypes.string.isRequired,
145
+ budgets: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
146
+ CustomLink: PropTypes.elementType,
147
+ };
148
+
149
+ BudgetInsights.defaultProps = {
150
+ className: '',
151
+ CustomLink: ComponentLink,
152
+ };
@@ -0,0 +1,53 @@
1
+ .groupHeader {
2
+ width: 100%;
3
+ border: none;
4
+ background: none;
5
+ cursor: pointer;
6
+ color: inherit;
7
+ }
8
+
9
+ .groupTitle {
10
+ width: 100%;
11
+ align-items: center;
12
+ }
13
+
14
+ .groupTitle:hover {
15
+ color: var(--color-text-dark);
16
+ text-decoration: underline;
17
+ }
18
+
19
+ .groupTitleToggle {
20
+ margin: 0 0 0 auto !important;
21
+ }
22
+
23
+ .danger .groupIcon {
24
+ color: var(--color-danger);
25
+ }
26
+
27
+ .success .groupIcon {
28
+ color: var(--color-success);
29
+ }
30
+
31
+ .groupContent {
32
+ padding-top: 0px;
33
+ background: transparent;
34
+ }
35
+
36
+ .budget {
37
+ display: block;
38
+ color: var(--color-text);
39
+ text-decoration: none;
40
+ }
41
+
42
+ .budgetLabel,
43
+ .budgetValue {
44
+ color: var(--color-text-dark);
45
+ font-weight: 500;
46
+ }
47
+
48
+ .budget:hover,
49
+ .budget:focus,
50
+ .budget:active {
51
+ color: var(--color-text);
52
+ text-decoration: underline;
53
+ }
@@ -0,0 +1 @@
1
+ export * from './budget-insights';
@@ -1,29 +1,44 @@
1
- import React from 'react';
1
+ import React, { useCallback, useMemo } from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import { get } from 'lodash';
3
4
  import { getBundleAssetsFileTypeComponentLink } from '@bundle-stats/utils';
4
5
  import * as webpack from '@bundle-stats/utils/lib-esm/webpack';
5
6
 
6
7
  import { ASSETS_SIZES_FILE_TYPE_MAP } from '../../constants';
8
+ import { FlexStack } from '../../layout/flex-stack';
7
9
  import { MetricsTable } from '../metrics-table';
8
10
  import { ComponentLink } from '../component-link';
11
+ import { BudgetInfo } from '../budget-info';
12
+ import css from './bundle-assets-totals-table.module.css';
9
13
 
10
14
  export const BundleAssetsTotalsTable = ({
11
15
  className,
12
16
  jobs,
13
17
  customComponentLink: CustomComponentLink,
14
18
  }) => {
15
- const items = webpack.compareBySection.sizes(jobs);
16
-
17
- const renderRowHeader = (item) => {
18
- const fileType = ASSETS_SIZES_FILE_TYPE_MAP[item.key];
19
- const { section, title, params } = getBundleAssetsFileTypeComponentLink(fileType, item.label);
20
-
21
- return (
22
- <CustomComponentLink section={section} title={title} params={params}>
23
- {item.label}
24
- </CustomComponentLink>
25
- );
26
- };
19
+ const items = useMemo(() => webpack.compareBySection.sizes(jobs), [jobs]);
20
+ const budgets = jobs[0].insights?.webpack?.budgets;
21
+
22
+ const renderRowHeader = useCallback(
23
+ (item) => {
24
+ const fileType = ASSETS_SIZES_FILE_TYPE_MAP[item.key];
25
+ const { section, title, params } = getBundleAssetsFileTypeComponentLink(fileType, item.label);
26
+ const [_, ...metricSlugs] = item.key.split('.');
27
+ const metricKey = metricSlugs.join('.');
28
+ const budget = get(budgets, metricKey);
29
+ const metric = webpack.getMetricType(metricKey);
30
+
31
+ return (
32
+ <CustomComponentLink section={section} title={title} params={params}>
33
+ <FlexStack space="xxsmall" className={css.itemTitleText}>
34
+ <span>{item.label}</span>
35
+ {budget && <BudgetInfo budget={budget} metric={metric} />}
36
+ </FlexStack>
37
+ </CustomComponentLink>
38
+ );
39
+ },
40
+ [CustomComponentLink],
41
+ );
27
42
 
28
43
  return (
29
44
  <MetricsTable
@@ -1,3 +1,3 @@
1
- .title {
2
- color: var(--color-text-light);
1
+ .itemTitleText {
2
+ align-items: center;
3
3
  }
@@ -12,11 +12,14 @@ import { ComponentLink } from '../component-link';
12
12
  import { SummaryItem } from '../summary-item';
13
13
  import css from './summary.module.css';
14
14
 
15
+ const getSourceMetricId = (fullMetricId) => fullMetricId.split('.').slice(1).join('.');
16
+
15
17
  export const Summary = ({
16
18
  className,
17
19
  size,
18
20
  keys,
19
21
  data,
22
+ budgets,
20
23
  loading,
21
24
  showSummaryItemDelta,
22
25
  summaryItemLink: SummaryItemCustomLink,
@@ -24,13 +27,14 @@ export const Summary = ({
24
27
  <Box outline className={cx(css.root, className)}>
25
28
  <FlexStack className={css.items}>
26
29
  {Array.from(METRIC_COMPONENT_LINKS)
27
- .filter(([metricId]) => keys.includes(metricId))
30
+ .filter(([metricId]) => keys.includes(getSourceMetricId(metricId)))
28
31
  .map(([metricId, metricOptions]) => (
29
32
  <div key={metricId} className={css.item}>
30
33
  <SummaryItem
31
34
  size={size}
32
35
  id={metricId}
33
36
  data={get(data, metricId)}
37
+ budget={get(budgets, getSourceMetricId(metricId))}
34
38
  loading={loading}
35
39
  showMetricDescription
36
40
  showDelta={showSummaryItemDelta && metricOptions.showDelta !== false}
@@ -49,6 +53,7 @@ export const Summary = ({
49
53
  Summary.defaultProps = {
50
54
  className: '',
51
55
  data: null,
56
+ budgets: null,
52
57
  loading: false,
53
58
  size: '',
54
59
  keys: METRICS_WEBPACK_GENERAL,
@@ -60,12 +65,8 @@ Summary.propTypes = {
60
65
  className: PropTypes.string,
61
66
  size: PropTypes.string,
62
67
  keys: PropTypes.arrayOf(PropTypes.string),
63
- data: PropTypes.shape({
64
- [PropTypes.string]: PropTypes.shape({
65
- baseline: PropTypes.number,
66
- current: PropTypes.number,
67
- }),
68
- }),
68
+ data: PropTypes.object, // eslint-disable-line react/forbid-prop-types
69
+ budgets: PropTypes.object, // eslint-disable-line react/forbid-prop-types
69
70
  loading: PropTypes.bool,
70
71
  showSummaryItemDelta: PropTypes.bool,
71
72
  summaryItemLink: PropTypes.elementType,
@@ -4,7 +4,7 @@
4
4
  }
5
5
 
6
6
  .item {
7
- padding: var(--space-small) var(--space-xxlarge) var(--space-small) var(--space-small);
7
+ padding: var(--space-small);
8
8
  flex: 1 0 25%; /* force equal sizes */
9
9
  position: relative;
10
10
  z-index: 1;
@@ -9,6 +9,7 @@ import { Stack } from '../../layout/stack';
9
9
  import { FlexStack } from '../../layout/flex-stack';
10
10
  import { Metric } from '../metric';
11
11
  import { Delta } from '../delta';
12
+ import { BudgetInfo } from '../budget-info';
12
13
  import css from './summary-item.module.css';
13
14
 
14
15
  const MetricInfoPopover = ({ description, url }) => {
@@ -49,6 +50,7 @@ export const SummaryItem = ({
49
50
  loading,
50
51
  showDelta,
51
52
  showMetricDescription,
53
+ budget,
52
54
  ...props
53
55
  }) => {
54
56
  const { baseline, current } = data || { baseline: 0, current: 0 };
@@ -56,19 +58,20 @@ export const SummaryItem = ({
56
58
  const metric = getGlobalMetricType(id);
57
59
  const runInfo = getMetricRunInfo(metric, current, baseline);
58
60
  const showMetricDescriptionTooltip = showMetricDescription && metric?.description;
59
-
60
61
  const rootClassName = cx(css.root, className, css[size], showDelta && css.showDelta);
61
62
 
62
63
  return (
63
64
  <Stack space="xxsmall" as={Component} className={rootClassName} {...props}>
64
65
  <FlexStack as="h3" space="xxxsmall" className={css.title}>
65
- <span>{metric.label}</span>
66
+ <span className={css.titleLabel}>{metric.label}</span>
66
67
 
67
68
  {showMetricDescriptionTooltip && (
68
69
  <Popover className={css.icon} icon="help">
69
70
  <MetricInfoPopover {...metric} />
70
71
  </Popover>
71
72
  )}
73
+
74
+ {budget && <BudgetInfo className={css.budgetInfo} metric={metric} budget={budget} />}
72
75
  </FlexStack>
73
76
 
74
77
  {!loading ? (
@@ -108,6 +111,7 @@ SummaryItem.defaultProps = {
108
111
  loading: false,
109
112
  showMetricDescription: false,
110
113
  showDelta: true,
114
+ budget: undefined,
111
115
  };
112
116
 
113
117
  SummaryItem.propTypes = {
@@ -134,4 +138,11 @@ SummaryItem.propTypes = {
134
138
 
135
139
  /** Show delta */
136
140
  showDelta: PropTypes.bool,
141
+
142
+ /** Budget data */
143
+ budget: PropTypes.shape({
144
+ value: PropTypes.number,
145
+ budget: PropTypes.number,
146
+ overBudget: PropTypes.bool,
147
+ }),
137
148
  };
@@ -1,3 +1,8 @@
1
+ .root {
2
+ position: relative;
3
+ padding-right: var(--space-xlarge);
4
+ }
5
+
1
6
  .title {
2
7
  color: var(--color-text-ultra-light);
3
8
  font-weight: bold;
@@ -7,6 +12,10 @@
7
12
  white-space: nowrap;
8
13
  }
9
14
 
15
+ .titleLabel {
16
+ flex: 0 0 auto;
17
+ }
18
+
10
19
  .readMoreBtn {
11
20
  appearance: none;
12
21
  padding: 0;
@@ -26,6 +35,12 @@
26
35
  text-decoration: none;
27
36
  }
28
37
 
38
+ .budgetInfo {
39
+ position: absolute;
40
+ right: 0;
41
+ top: 0;
42
+ }
43
+
29
44
  .currentMetric {
30
45
  display: block;
31
46
  color: var(--color-heading);
package/src/constants.js CHANGED
@@ -47,11 +47,11 @@ export const ASSETS_SIZES_FILE_TYPE_MAP = FILE_TYPES.reduce(
47
47
  );
48
48
 
49
49
  export const METRICS_WEBPACK_GENERAL = [
50
- 'webpack.totalSizeByTypeALL',
51
- 'webpack.totalInitialSizeJS',
52
- 'webpack.totalInitialSizeCSS',
53
- 'webpack.cacheInvalidation',
50
+ 'totalSizeByTypeALL',
51
+ 'totalInitialSizeJS',
52
+ 'totalInitialSizeCSS',
53
+ 'cacheInvalidation',
54
54
  ];
55
- export const METRICS_WEBPACK_ASSETS = ['webpack.assetCount', 'webpack.chunkCount'];
56
- export const METRICS_WEBPACK_MODULES = ['webpack.moduleCount'];
57
- export const METRICS_WEBPACK_PACKAGES = ['webpack.packageCount', 'webpack.duplicatePackagesCount'];
55
+ export const METRICS_WEBPACK_ASSETS = ['assetCount', 'chunkCount'];
56
+ export const METRICS_WEBPACK_MODULES = ['moduleCount'];
57
+ export const METRICS_WEBPACK_PACKAGES = ['packageCount', 'duplicatePackagesCount'];
@@ -6,10 +6,15 @@ import { Box } from '../../layout/box';
6
6
  import css from './alert.module.css';
7
7
 
8
8
  export const Alert = (props) => {
9
- const { className, kind, children } = props;
9
+ const { className, kind, children, ...restProps } = props;
10
10
 
11
11
  return (
12
- <Box padding={['xsmall', 'small']} outline className={cx(css.root, className, css[kind])}>
12
+ <Box
13
+ padding={['xsmall', 'small']}
14
+ outline
15
+ className={cx(css.root, className, css[kind])}
16
+ {...restProps}
17
+ >
13
18
  {children}
14
19
  </Box>
15
20
  );
@@ -5,11 +5,13 @@ import cx from 'classnames';
5
5
  import css from './icon.module.css';
6
6
 
7
7
  const ICONS = {
8
+ ALERT_CIRCLE: 'alert-circle',
8
9
  ARROW: 'arrow',
9
10
  ARROW_RIGHT_CIRLCE: 'arrow-right-circle',
10
11
  CANCEL: 'cancel',
11
12
  CLOSE: 'close',
12
13
  CLOCK: 'clock',
14
+ CHECK_CIRCLE: 'check-circle',
13
15
  COMMIT: 'commit',
14
16
  FILTER: 'filter',
15
17
  HELP: 'help',