@bundle-stats/ui 4.2.5-beta.1 → 4.2.5-beta.3
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.
- package/lib/app/app.js +4 -4
- package/lib/app/app.js.map +1 -1
- package/lib/components/bundle-assets-totals-chart-bars/bundle-assets-totals-chart-bars.js +2 -8
- package/lib/components/bundle-assets-totals-chart-bars/bundle-assets-totals-chart-bars.js.map +1 -1
- package/lib/components/index.js +3 -1
- package/lib/components/index.js.map +1 -1
- package/lib/components/metric-run-info/metric-run-info.js +52 -33
- package/lib/components/metric-run-info/metric-run-info.js.map +1 -1
- package/lib/components/metric-run-info/metric-run-info.module.css +14 -36
- package/lib/components/metrics-table-title/metrics-table-title.module.css +1 -0
- package/lib/components/run-info/index.js +18 -0
- package/lib/components/run-info/index.js.map +1 -0
- package/lib/components/run-info/run-info.js +70 -0
- package/lib/components/run-info/run-info.js.map +1 -0
- package/lib/components/run-info/run-info.module.css +41 -0
- package/lib/components/summary/summary.js +5 -45
- package/lib/components/summary/summary.js.map +1 -1
- package/lib-esm/app/app.js +4 -4
- package/lib-esm/app/app.js.map +1 -1
- package/lib-esm/components/bundle-assets-totals-chart-bars/bundle-assets-totals-chart-bars.js +2 -8
- package/lib-esm/components/bundle-assets-totals-chart-bars/bundle-assets-totals-chart-bars.js.map +1 -1
- package/lib-esm/components/index.js +1 -0
- package/lib-esm/components/index.js.map +1 -1
- package/lib-esm/components/metric-run-info/metric-run-info.js +29 -33
- package/lib-esm/components/metric-run-info/metric-run-info.js.map +1 -1
- package/lib-esm/components/metric-run-info/metric-run-info.module.css +14 -36
- package/lib-esm/components/metrics-table-title/metrics-table-title.module.css +1 -0
- package/lib-esm/components/run-info/index.js +2 -0
- package/lib-esm/components/run-info/index.js.map +1 -0
- package/lib-esm/components/run-info/run-info.js +40 -0
- package/lib-esm/components/run-info/run-info.js.map +1 -0
- package/lib-esm/components/run-info/run-info.module.css +41 -0
- package/lib-esm/components/summary/summary.js +6 -23
- package/lib-esm/components/summary/summary.js.map +1 -1
- package/package.json +6 -6
- package/src/app/app.jsx +4 -0
- package/src/components/bundle-assets-totals-chart-bars/bundle-assets-totals-chart-bars.jsx +5 -10
- package/src/components/index.js +1 -0
- package/src/components/metric/metric.tsx +1 -1
- package/src/components/metric-run-info/metric-run-info.module.css +14 -36
- package/src/components/metric-run-info/metric-run-info.stories.tsx +14 -29
- package/src/components/metric-run-info/metric-run-info.tsx +68 -85
- package/src/components/metrics-table-title/metrics-table-title.module.css +1 -0
- package/src/components/run-info/index.ts +1 -0
- package/src/components/run-info/run-info.module.css +41 -0
- package/src/components/run-info/run-info.stories.tsx +49 -0
- package/src/components/run-info/run-info.tsx +106 -0
- package/src/components/summary/summary.stories.tsx +1 -0
- package/src/components/summary/summary.tsx +41 -62
- package/types/components/index.d.ts +1 -0
- package/types/components/metric/metric.d.ts +1 -1
- package/types/components/metric-run-info/metric-run-info.d.ts +10 -11
- package/types/components/run-info/index.d.ts +1 -0
- package/types/components/run-info/run-info.d.ts +15 -0
- package/types/components/summary/summary.d.ts +14 -4
|
@@ -1,49 +1,34 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Meta, Story } from '@storybook/react';
|
|
3
2
|
|
|
4
|
-
import {
|
|
3
|
+
import { Meta, Story } from '@storybook/react';
|
|
4
|
+
import { MetricRunInfo } from '.';
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
7
|
title: 'Components/MetricRunInfo',
|
|
8
8
|
component: MetricRunInfo,
|
|
9
9
|
} as Meta;
|
|
10
10
|
|
|
11
|
-
const Template: Story = (args) => <MetricRunInfo
|
|
11
|
+
const Template: Story = (args: any) => <MetricRunInfo {...args} />;
|
|
12
12
|
|
|
13
13
|
export const Default = Template.bind({});
|
|
14
14
|
|
|
15
15
|
Default.args = {
|
|
16
|
-
|
|
17
|
-
current:
|
|
18
|
-
baseline:
|
|
19
|
-
delta: '+20%',
|
|
20
|
-
deltaType: 'HIGH_NEGATIVE',
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const SizeLarge = Template.bind({});
|
|
24
|
-
|
|
25
|
-
SizeLarge.args = {
|
|
26
|
-
...Default.args,
|
|
27
|
-
size: 'large',
|
|
16
|
+
metricId: 'webpack.totalSizeByTypeALL',
|
|
17
|
+
current: 120 * 1024,
|
|
18
|
+
baseline: 100 * 1024,
|
|
28
19
|
};
|
|
29
20
|
|
|
30
|
-
export const
|
|
21
|
+
export const NoBaseline = Template.bind({});
|
|
31
22
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
NoBaseline.args = {
|
|
24
|
+
metricId: 'webpack.totalSizeByTypeALL',
|
|
25
|
+
current: 120 * 1024,
|
|
26
|
+
showBaseline: false,
|
|
35
27
|
};
|
|
36
28
|
|
|
37
|
-
export const
|
|
29
|
+
export const NoDelta = Template.bind({});
|
|
38
30
|
|
|
39
|
-
|
|
31
|
+
NoDelta.args = {
|
|
40
32
|
...Default.args,
|
|
41
|
-
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export const Loading = Template.bind({});
|
|
45
|
-
|
|
46
|
-
Loading.args = {
|
|
47
|
-
title: 'Bundle Size',
|
|
48
|
-
loading: true,
|
|
33
|
+
showDelta: false,
|
|
49
34
|
};
|
|
@@ -1,101 +1,84 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import
|
|
1
|
+
import React, { useCallback, useMemo } from 'react';
|
|
2
|
+
import { getGlobalMetricType, getMetricRunInfo } from '@bundle-stats/utils';
|
|
3
3
|
|
|
4
|
-
import { Icon } from '../../ui/icon';
|
|
5
|
-
import { HoverCard } from '../../ui/hover-card';
|
|
6
|
-
import { Tooltip } from '../../ui/tooltip';
|
|
7
|
-
import { Skeleton } from '../../ui/skeleton';
|
|
8
|
-
import { FlexStack } from '../../layout/flex-stack';
|
|
9
4
|
import { Stack } from '../../layout/stack';
|
|
10
|
-
import {
|
|
11
|
-
import { Delta } from '../delta';
|
|
5
|
+
import { RunInfo, RunInfoProps } from '../run-info';
|
|
12
6
|
import css from './metric-run-info.module.css';
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const matches = value.match(EXTRACT_VALUE_UNIT_PATTERN);
|
|
8
|
+
interface MetricInfoProps {
|
|
9
|
+
description: string;
|
|
10
|
+
url?: string;
|
|
11
|
+
}
|
|
19
12
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
const MetricHoverCard = ({ description, url }: MetricInfoProps) => {
|
|
14
|
+
// The component parent can be rendered inside a link, use button to avoid using nested links
|
|
15
|
+
const onClick = useCallback(() => {
|
|
16
|
+
if (url) {
|
|
17
|
+
window.open(url);
|
|
18
|
+
}
|
|
19
|
+
}, [url]);
|
|
23
20
|
|
|
24
|
-
return
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
return (
|
|
22
|
+
<Stack space="xxxsmall">
|
|
23
|
+
<p>{description}</p>
|
|
24
|
+
{url && (
|
|
25
|
+
<p>
|
|
26
|
+
<button type="button" onClick={onClick} className={css.readMoreLink}>
|
|
27
|
+
Read more
|
|
28
|
+
</button>
|
|
29
|
+
</p>
|
|
30
|
+
)}
|
|
31
|
+
</Stack>
|
|
32
|
+
);
|
|
28
33
|
};
|
|
29
34
|
|
|
30
35
|
export interface MetricRunInfoProps {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
as?: React.ElementType;
|
|
40
|
-
size?: 'medium' | 'large';
|
|
41
|
-
|
|
42
|
-
loading?: boolean;
|
|
36
|
+
metricId: string;
|
|
37
|
+
current: number;
|
|
38
|
+
baseline?: number;
|
|
39
|
+
showDelta?: boolean;
|
|
40
|
+
showMetricDescription?: boolean;
|
|
41
|
+
showBaseline?: boolean;
|
|
42
|
+
size?: RunInfoProps['size'];
|
|
43
|
+
loading?: RunInfoProps['loading'];
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
export const MetricRunInfo = ({
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
size = 'medium',
|
|
56
|
-
loading = false,
|
|
57
|
-
...restProps
|
|
58
|
-
}: MetricRunInfoProps & React.ComponentProps<'div'>) => {
|
|
59
|
-
const metricParams = getMetricParams(current);
|
|
60
|
-
const rootClassName = cx(css.root, className, css[size], delta && css.showDelta);
|
|
46
|
+
export const MetricRunInfo = (props: MetricRunInfoProps & React.ComponentProps<'div'>) => {
|
|
47
|
+
const {
|
|
48
|
+
metricId,
|
|
49
|
+
current,
|
|
50
|
+
baseline = 0,
|
|
51
|
+
showDelta = true,
|
|
52
|
+
showMetricDescription = true,
|
|
53
|
+
showBaseline = true,
|
|
54
|
+
...restProps
|
|
55
|
+
} = props;
|
|
61
56
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
{title && (
|
|
65
|
-
<FlexStack space="xxxsmall" alignItems="center" as="h3" className={css.title}>
|
|
66
|
-
<span>{title}</span>
|
|
57
|
+
const metric = getGlobalMetricType(metricId);
|
|
58
|
+
const metricRunInfo = getMetricRunInfo(metric, current, baseline || 0);
|
|
67
59
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
)}
|
|
73
|
-
{titleTooltip && (
|
|
74
|
-
<Tooltip title={titleTooltip} className={css.titleIcon}>
|
|
75
|
-
<Icon glyph={Icon.ICONS.HELP} />
|
|
76
|
-
</Tooltip>
|
|
77
|
-
)}
|
|
78
|
-
</FlexStack>
|
|
79
|
-
)}
|
|
60
|
+
const titleHoverCard = useMemo(() => {
|
|
61
|
+
if (showMetricDescription) {
|
|
62
|
+
return <MetricHoverCard description={metric.description} url={metric.url} />;
|
|
63
|
+
}
|
|
80
64
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
</Stack>
|
|
65
|
+
return null;
|
|
66
|
+
}, [showMetricDescription, metric]);
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<RunInfo
|
|
70
|
+
title={metric.label}
|
|
71
|
+
titleHoverCard={titleHoverCard}
|
|
72
|
+
enhance
|
|
73
|
+
current={metricRunInfo.displayValue}
|
|
74
|
+
{...(showBaseline && {
|
|
75
|
+
baseline: metric.formatter(baseline),
|
|
76
|
+
})}
|
|
77
|
+
{...(showDelta && showBaseline && {
|
|
78
|
+
delta: metricRunInfo.displayDeltaPercentage,
|
|
79
|
+
deltaType: metricRunInfo.deltaType,
|
|
80
|
+
})}
|
|
81
|
+
{...restProps}
|
|
82
|
+
/>
|
|
100
83
|
);
|
|
101
84
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './run-info';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
.title {
|
|
2
|
+
color: var(--color-text-ultra-light);
|
|
3
|
+
font-weight: bold;
|
|
4
|
+
font-size: var(--size-xsmall);
|
|
5
|
+
text-transform: uppercase;
|
|
6
|
+
white-space: nowrap;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.titleIcon {
|
|
10
|
+
flex: 0 0 var(--space-small);
|
|
11
|
+
margin-top: -4px !important;
|
|
12
|
+
margin-bottom: -4px !important;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.currentMetric {
|
|
16
|
+
color: var(--color-heading);
|
|
17
|
+
font-size: var(--size-xlarge);
|
|
18
|
+
line-height: var(--line-height-heading);
|
|
19
|
+
white-space: nowrap;
|
|
20
|
+
font-weight: bold;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.baselineMetric {
|
|
24
|
+
color: var(--color-text-light);
|
|
25
|
+
font-size: var(--size-medium);
|
|
26
|
+
line-height: var(--line-height-heading);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* Loading state */
|
|
30
|
+
.loading.currentMetric {
|
|
31
|
+
width: 8em;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.loading.baselineMetric {
|
|
35
|
+
width: 5em;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* Size large */
|
|
39
|
+
.large .currentMetric {
|
|
40
|
+
font-size: var(--size-xxxlarge);
|
|
41
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Meta, Story } from '@storybook/react';
|
|
3
|
+
|
|
4
|
+
import { RunInfo } from './run-info';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Components/RunInfo',
|
|
8
|
+
component: RunInfo,
|
|
9
|
+
} as Meta;
|
|
10
|
+
|
|
11
|
+
const Template: Story = (args) => <RunInfo id="webpack.totalSizeByTypeALL" {...args} />;
|
|
12
|
+
|
|
13
|
+
export const Default = Template.bind({});
|
|
14
|
+
|
|
15
|
+
Default.args = {
|
|
16
|
+
title: 'Bundle Size',
|
|
17
|
+
current: '120KiB',
|
|
18
|
+
baseline: '100KiB',
|
|
19
|
+
delta: '+20%',
|
|
20
|
+
deltaType: 'HIGH_NEGATIVE',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const SizeLarge = Template.bind({});
|
|
24
|
+
|
|
25
|
+
SizeLarge.args = {
|
|
26
|
+
...Default.args,
|
|
27
|
+
size: 'large',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const TitleHoverCard = Template.bind({});
|
|
31
|
+
|
|
32
|
+
TitleHoverCard.args = {
|
|
33
|
+
...Default.args,
|
|
34
|
+
titleHoverCard: 'Info',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const TitleTooltip = Template.bind({});
|
|
38
|
+
|
|
39
|
+
TitleTooltip.args = {
|
|
40
|
+
...Default.args,
|
|
41
|
+
titleTooltip: 'Info',
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const Loading = Template.bind({});
|
|
45
|
+
|
|
46
|
+
Loading.args = {
|
|
47
|
+
title: 'Bundle Size',
|
|
48
|
+
loading: true,
|
|
49
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import cx from 'classnames';
|
|
3
|
+
|
|
4
|
+
import { Icon } from '../../ui/icon';
|
|
5
|
+
import { HoverCard } from '../../ui/hover-card';
|
|
6
|
+
import { Tooltip } from '../../ui/tooltip';
|
|
7
|
+
import { Skeleton } from '../../ui/skeleton';
|
|
8
|
+
import { FlexStack } from '../../layout/flex-stack';
|
|
9
|
+
import { Stack } from '../../layout/stack';
|
|
10
|
+
import { Metric } from '../metric';
|
|
11
|
+
import { Delta } from '../delta';
|
|
12
|
+
import css from './run-info.module.css';
|
|
13
|
+
|
|
14
|
+
// Separate value and unit
|
|
15
|
+
const EXTRACT_VALUE_UNIT_PATTERN = /([\d|.|,| ]*)(\w*|%)$/;
|
|
16
|
+
|
|
17
|
+
const getMetricParams = (value: string): [string, string?] => {
|
|
18
|
+
const matches = value.match(EXTRACT_VALUE_UNIT_PATTERN);
|
|
19
|
+
|
|
20
|
+
if (!matches) {
|
|
21
|
+
return [value];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return [matches[1], matches[2]];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export interface RunInfoProps {
|
|
28
|
+
title?: string;
|
|
29
|
+
titleHoverCard?: React.ReactNode;
|
|
30
|
+
titleTooltip?: React.ReactNode;
|
|
31
|
+
current?: React.ReactNode;
|
|
32
|
+
baseline?: string;
|
|
33
|
+
delta?: string;
|
|
34
|
+
deltaType?: string;
|
|
35
|
+
|
|
36
|
+
as?: React.ElementType;
|
|
37
|
+
size?: 'medium' | 'large';
|
|
38
|
+
|
|
39
|
+
loading?: boolean;
|
|
40
|
+
enhance?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const RunInfo = ({
|
|
44
|
+
className = '',
|
|
45
|
+
title = '',
|
|
46
|
+
titleHoverCard = null,
|
|
47
|
+
titleTooltip = null,
|
|
48
|
+
current = '',
|
|
49
|
+
baseline = '',
|
|
50
|
+
delta = '',
|
|
51
|
+
deltaType = '',
|
|
52
|
+
as: Component = 'div',
|
|
53
|
+
size = 'medium',
|
|
54
|
+
loading = false,
|
|
55
|
+
enhance = false,
|
|
56
|
+
...restProps
|
|
57
|
+
}: RunInfoProps & React.ComponentProps<'div'>) => {
|
|
58
|
+
const rootClassName = cx(css.root, className, css[size], delta && css.showDelta);
|
|
59
|
+
|
|
60
|
+
const currentValueParams: [React.ReactNode, string?] = useMemo(() => {
|
|
61
|
+
if (!enhance || typeof current !== 'string') {
|
|
62
|
+
return [current];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return getMetricParams(current);
|
|
66
|
+
}, [current, enhance]);
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<Stack space="xxsmall" as={Component} className={rootClassName} {...restProps}>
|
|
70
|
+
{title && (
|
|
71
|
+
<FlexStack space="xxxsmall" alignItems="center" as="h3" className={css.title}>
|
|
72
|
+
<span>{title}</span>
|
|
73
|
+
{titleHoverCard && (
|
|
74
|
+
<HoverCard label={<Icon glyph={Icon.ICONS.HELP} />} className={css.titleIcon}>
|
|
75
|
+
{titleHoverCard}
|
|
76
|
+
</HoverCard>
|
|
77
|
+
)}
|
|
78
|
+
{titleTooltip && (
|
|
79
|
+
<Tooltip title={titleTooltip} className={css.titleIcon}>
|
|
80
|
+
<Icon glyph={Icon.ICONS.HELP} />
|
|
81
|
+
</Tooltip>
|
|
82
|
+
)}
|
|
83
|
+
</FlexStack>
|
|
84
|
+
)}
|
|
85
|
+
|
|
86
|
+
{!loading ? (
|
|
87
|
+
<Stack>
|
|
88
|
+
<Metric
|
|
89
|
+
className={css.currentMetric}
|
|
90
|
+
value={currentValueParams[0]}
|
|
91
|
+
unit={currentValueParams[1]}
|
|
92
|
+
inline
|
|
93
|
+
>
|
|
94
|
+
{delta && <Delta className={css.delta} displayValue={delta} deltaType={deltaType} />}
|
|
95
|
+
</Metric>
|
|
96
|
+
<Metric className={css.baselineMetric} value={baseline} />
|
|
97
|
+
</Stack>
|
|
98
|
+
) : (
|
|
99
|
+
<Stack>
|
|
100
|
+
<Skeleton as="p" className={cx(css.currentMetric, css.loading)} />
|
|
101
|
+
<Skeleton as="p" className={cx(css.baselineMetric, css.loading)} />
|
|
102
|
+
</Stack>
|
|
103
|
+
)}
|
|
104
|
+
</Stack>
|
|
105
|
+
);
|
|
106
|
+
};
|
|
@@ -1,74 +1,39 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
2
|
import cx from 'classnames';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
|
-
import { METRIC_COMPONENT_LINKS
|
|
4
|
+
import { METRIC_COMPONENT_LINKS } from '@bundle-stats/utils';
|
|
5
5
|
|
|
6
6
|
import { METRICS_WEBPACK_GENERAL } from '../../constants';
|
|
7
7
|
import { Box } from '../../layout/box';
|
|
8
8
|
import { FlexStack } from '../../layout/flex-stack';
|
|
9
|
-
import { Stack } from '../../layout/stack';
|
|
10
9
|
import { ComponentLink } from '../component-link';
|
|
11
10
|
import { MetricRunInfo, MetricRunInfoProps } from '../metric-run-info';
|
|
12
11
|
import css from './summary.module.css';
|
|
13
12
|
|
|
14
|
-
interface MetricInfoProps {
|
|
15
|
-
description: string;
|
|
16
|
-
url?: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const MetricInfo = ({ description, url }: MetricInfoProps) => {
|
|
20
|
-
// The component parent can be rendered inside a link, use button to avoid using nested links
|
|
21
|
-
const onClick = useCallback(() => {
|
|
22
|
-
if (url) {
|
|
23
|
-
window.open(url);
|
|
24
|
-
}
|
|
25
|
-
}, [url]);
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<Stack space="xxxsmall">
|
|
29
|
-
<p>{description}</p>
|
|
30
|
-
{url && (
|
|
31
|
-
<p>
|
|
32
|
-
<button type="button" onClick={onClick} className={css.readMoreLink}>
|
|
33
|
-
Read more
|
|
34
|
-
</button>
|
|
35
|
-
</p>
|
|
36
|
-
)}
|
|
37
|
-
</Stack>
|
|
38
|
-
);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
interface SummaryItemData {
|
|
42
|
-
current: number;
|
|
43
|
-
baseline: number;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
interface SummaryProps {
|
|
47
|
-
size?: MetricRunInfoProps['size'];
|
|
48
|
-
keys?: Array<string>;
|
|
49
|
-
data?: Record<string, SummaryItemData> | null;
|
|
50
|
-
loading?: boolean;
|
|
51
|
-
showSummaryItemDelta?: boolean;
|
|
52
|
-
summaryItemLink?: React.ElementType;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
13
|
interface SummaryItemProps {
|
|
56
14
|
metricId: string;
|
|
57
|
-
data?:
|
|
58
|
-
|
|
59
|
-
size
|
|
60
|
-
loading:
|
|
61
|
-
|
|
15
|
+
data?: Record<string, SummaryItemData> | null;
|
|
16
|
+
customLink: React.ElementType;
|
|
17
|
+
size?: MetricRunInfoProps['size'];
|
|
18
|
+
loading: boolean;
|
|
19
|
+
showDelta: boolean;
|
|
20
|
+
showBaseline: boolean;
|
|
62
21
|
}
|
|
63
22
|
|
|
64
23
|
const SummaryItem = (props: SummaryItemProps & React.ComponentProps<'div'>) => {
|
|
65
|
-
const {
|
|
24
|
+
const {
|
|
25
|
+
className = '',
|
|
26
|
+
metricId,
|
|
27
|
+
data,
|
|
28
|
+
customLink: SummaryItemCustomLink,
|
|
29
|
+
size,
|
|
30
|
+
loading,
|
|
31
|
+
showDelta,
|
|
32
|
+
showBaseline,
|
|
33
|
+
} = props;
|
|
66
34
|
|
|
67
35
|
const componentLink = METRIC_COMPONENT_LINKS.get(metricId);
|
|
68
|
-
|
|
69
36
|
const metricData = get(data, metricId, { current: 0, baseline: 0 });
|
|
70
|
-
const metric = getGlobalMetricType(metricId);
|
|
71
|
-
const metricRunInfo = getMetricRunInfo(metric, metricData.current, metricData.baseline);
|
|
72
37
|
|
|
73
38
|
return (
|
|
74
39
|
<Box
|
|
@@ -81,21 +46,33 @@ const SummaryItem = (props: SummaryItemProps & React.ComponentProps<'div'>) => {
|
|
|
81
46
|
className={className}
|
|
82
47
|
>
|
|
83
48
|
<MetricRunInfo
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
49
|
+
metricId={metricId}
|
|
50
|
+
current={metricData.current}
|
|
51
|
+
baseline={metricData.baseline}
|
|
52
|
+
showDelta={showDelta && componentLink?.showDelta}
|
|
53
|
+
showBaseline={showBaseline}
|
|
88
54
|
size={size}
|
|
89
55
|
loading={loading}
|
|
90
|
-
{...(showSummaryItemDelta && componentLink?.showDelta !== false && {
|
|
91
|
-
delta: metricRunInfo.displayDeltaPercentage,
|
|
92
|
-
deltaType: metricRunInfo.deltaType,
|
|
93
|
-
})}
|
|
94
56
|
/>
|
|
95
57
|
</Box>
|
|
96
58
|
);
|
|
97
59
|
};
|
|
98
60
|
|
|
61
|
+
interface SummaryItemData {
|
|
62
|
+
current: number;
|
|
63
|
+
baseline: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface SummaryProps {
|
|
67
|
+
size?: MetricRunInfoProps['size'];
|
|
68
|
+
keys?: Array<string>;
|
|
69
|
+
data?: SummaryItemProps['data'];
|
|
70
|
+
loading?: boolean;
|
|
71
|
+
showSummaryItemDelta?: SummaryItemProps['showDelta'];
|
|
72
|
+
showSummaryItemBaseline?: SummaryItemProps['showBaseline'];
|
|
73
|
+
summaryItemLink?: SummaryItemProps['customLink'];
|
|
74
|
+
}
|
|
75
|
+
|
|
99
76
|
export const Summary = ({
|
|
100
77
|
className = '',
|
|
101
78
|
size = 'medium',
|
|
@@ -103,6 +80,7 @@ export const Summary = ({
|
|
|
103
80
|
data = null,
|
|
104
81
|
loading = false,
|
|
105
82
|
showSummaryItemDelta = true,
|
|
83
|
+
showSummaryItemBaseline = true,
|
|
106
84
|
summaryItemLink = ComponentLink,
|
|
107
85
|
}: SummaryProps & React.ComponentProps<'div'>) => (
|
|
108
86
|
<Box className={cx(css.root, className)}>
|
|
@@ -113,10 +91,11 @@ export const Summary = ({
|
|
|
113
91
|
className={css.item}
|
|
114
92
|
metricId={metricId}
|
|
115
93
|
data={data}
|
|
116
|
-
|
|
94
|
+
customLink={summaryItemLink}
|
|
117
95
|
size={size}
|
|
118
96
|
loading={loading}
|
|
119
|
-
|
|
97
|
+
showDelta={showSummaryItemDelta}
|
|
98
|
+
showBaseline={showSummaryItemBaseline}
|
|
120
99
|
/>
|
|
121
100
|
))}
|
|
122
101
|
</FlexStack>
|
|
@@ -21,3 +21,4 @@ export { ModuleInfo } from "./module-info";
|
|
|
21
21
|
export { Summary } from "./summary";
|
|
22
22
|
export { TotalSizeTypeTitle } from "./total-size-type-title";
|
|
23
23
|
export { MetricRunInfo, MetricRunInfoProps } from "./metric-run-info";
|
|
24
|
+
export { RunInfo, RunInfoProps } from "./run-info";
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { RunInfoProps } from '../run-info';
|
|
2
3
|
export interface MetricRunInfoProps {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
size?: 'medium' | 'large';
|
|
12
|
-
loading?: boolean;
|
|
4
|
+
metricId: string;
|
|
5
|
+
current: number;
|
|
6
|
+
baseline?: number;
|
|
7
|
+
showDelta?: boolean;
|
|
8
|
+
showMetricDescription?: boolean;
|
|
9
|
+
showBaseline?: boolean;
|
|
10
|
+
size?: RunInfoProps['size'];
|
|
11
|
+
loading?: RunInfoProps['loading'];
|
|
13
12
|
}
|
|
14
|
-
export declare const MetricRunInfo: (
|
|
13
|
+
export declare const MetricRunInfo: (props: MetricRunInfoProps & React.ComponentProps<'div'>) => JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './run-info';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface RunInfoProps {
|
|
3
|
+
title?: string;
|
|
4
|
+
titleHoverCard?: React.ReactNode;
|
|
5
|
+
titleTooltip?: React.ReactNode;
|
|
6
|
+
current?: React.ReactNode;
|
|
7
|
+
baseline?: string;
|
|
8
|
+
delta?: string;
|
|
9
|
+
deltaType?: string;
|
|
10
|
+
as?: React.ElementType;
|
|
11
|
+
size?: 'medium' | 'large';
|
|
12
|
+
loading?: boolean;
|
|
13
|
+
enhance?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare const RunInfo: ({ className, title, titleHoverCard, titleTooltip, current, baseline, delta, deltaType, as: Component, size, loading, enhance, ...restProps }: RunInfoProps & React.ComponentProps<'div'>) => JSX.Element;
|