@bundle-stats/ui 4.16.0-beta.8 → 4.16.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.
- package/lib/components/bundle-assets/bundle-assets.js +4 -2
- package/lib/components/bundle-assets/bundle-assets.js.map +1 -1
- package/lib/components/bundle-assets-totals/bundle-assets-totals.js +4 -2
- package/lib/components/bundle-assets-totals/bundle-assets-totals.js.map +1 -1
- package/lib/components/bundle-modules/bundle-modules.js +4 -2
- package/lib/components/bundle-modules/bundle-modules.js.map +1 -1
- package/lib/components/bundle-packages/bundle-packages.js +4 -2
- package/lib/components/bundle-packages/bundle-packages.js.map +1 -1
- package/lib/components/metrics-table-export/metrics-table-export.js +12 -10
- package/lib/components/metrics-table-export/metrics-table-export.js.map +1 -1
- package/lib/components/metrics-table-options/metrics-table-options.js +7 -5
- package/lib/components/metrics-table-options/metrics-table-options.js.map +1 -1
- package/lib/components/metrics-table-options/metrics-table-options.module.css +5 -0
- package/lib/components/preview-source/preview-source.js +1 -1
- package/lib/components/preview-source/preview-source.js.map +1 -1
- package/lib/i18n.js +2 -0
- package/lib/i18n.js.map +1 -1
- package/lib/ui/tabs/index.js +15 -3
- package/lib/ui/tabs/index.js.map +1 -1
- package/lib/ui/tabs/tabs.js +9 -20
- package/lib/ui/tabs/tabs.js.map +1 -1
- package/lib/ui/tabs/tabs.module.css +6 -6
- package/lib-esm/components/bundle-assets/bundle-assets.js +5 -3
- package/lib-esm/components/bundle-assets/bundle-assets.js.map +1 -1
- package/lib-esm/components/bundle-assets-totals/bundle-assets-totals.js +5 -3
- package/lib-esm/components/bundle-assets-totals/bundle-assets-totals.js.map +1 -1
- package/lib-esm/components/bundle-modules/bundle-modules.js +5 -3
- package/lib-esm/components/bundle-modules/bundle-modules.js.map +1 -1
- package/lib-esm/components/bundle-packages/bundle-packages.js +5 -3
- package/lib-esm/components/bundle-packages/bundle-packages.js.map +1 -1
- package/lib-esm/components/metrics-table-export/metrics-table-export.js +13 -11
- package/lib-esm/components/metrics-table-export/metrics-table-export.js.map +1 -1
- package/lib-esm/components/metrics-table-options/metrics-table-options.js +7 -5
- package/lib-esm/components/metrics-table-options/metrics-table-options.js.map +1 -1
- package/lib-esm/components/metrics-table-options/metrics-table-options.module.css +5 -0
- package/lib-esm/components/preview-source/preview-source.js +1 -1
- package/lib-esm/components/preview-source/preview-source.js.map +1 -1
- package/lib-esm/i18n.js +2 -0
- package/lib-esm/i18n.js.map +1 -1
- package/lib-esm/ui/tabs/index.js +1 -1
- package/lib-esm/ui/tabs/index.js.map +1 -1
- package/lib-esm/ui/tabs/tabs.js +7 -19
- package/lib-esm/ui/tabs/tabs.js.map +1 -1
- package/lib-esm/ui/tabs/tabs.module.css +6 -6
- package/package.json +5 -5
- package/src/components/bundle-assets/bundle-assets.jsx +11 -3
- package/src/components/bundle-assets-totals/bundle-assets-totals.jsx +11 -3
- package/src/components/bundle-modules/bundle-modules.tsx +11 -3
- package/src/components/bundle-packages/bundle-packages.jsx +11 -3
- package/src/components/metrics-table-export/metrics-table-export.tsx +28 -19
- package/src/components/metrics-table-options/metrics-table-options.module.css +5 -0
- package/src/components/metrics-table-options/metrics-table-options.tsx +14 -6
- package/src/components/preview-source/preview-source.stories.tsx +13 -1
- package/src/components/preview-source/preview-source.tsx +1 -1
- package/src/i18n.js +2 -0
- package/src/ui/tabs/index.ts +1 -0
- package/src/ui/tabs/tabs.module.css +6 -6
- package/src/ui/tabs/tabs.stories.tsx +25 -0
- package/src/ui/tabs/tabs.tsx +32 -0
- package/types/components/metrics-table-export/metrics-table-export.d.ts +1 -0
- package/types/components/metrics-table-options/metrics-table-options.d.ts +1 -1
- package/types/i18n.d.ts +2 -0
- package/types/ui/tabs/index.d.ts +1 -1
- package/types/ui/tabs/tabs.d.ts +11 -41
- package/src/ui/tabs/index.js +0 -1
- package/src/ui/tabs/tabs.jsx +0 -39
|
@@ -3,7 +3,7 @@ import React, { useState } from 'react';
|
|
|
3
3
|
import type { ReportMetricRow } from '@bundle-stats/utils';
|
|
4
4
|
|
|
5
5
|
import { Stack } from '../../layout/stack';
|
|
6
|
-
import { Tabs } from '../../ui/tabs';
|
|
6
|
+
import { Tabs, TabItem } from '../../ui/tabs';
|
|
7
7
|
import { PreviewSource } from '../preview-source';
|
|
8
8
|
|
|
9
9
|
const generateSourceJSON = (items: Array<ReportMetricRow>): string => {
|
|
@@ -49,49 +49,58 @@ const generateSourceCSV = (items: Array<ReportMetricRow>): string => {
|
|
|
49
49
|
return output.join('\r');
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
const SOURCES =
|
|
53
|
-
{
|
|
52
|
+
const SOURCES = {
|
|
53
|
+
csv: {
|
|
54
54
|
label: 'CSV',
|
|
55
55
|
transformFn: generateSourceCSV,
|
|
56
|
-
extension: 'csv',
|
|
56
|
+
extension: '.csv',
|
|
57
57
|
},
|
|
58
|
-
{
|
|
58
|
+
json: {
|
|
59
59
|
label: 'JSON',
|
|
60
60
|
transformFn: generateSourceJSON,
|
|
61
|
-
extension: 'json',
|
|
61
|
+
extension: '.json',
|
|
62
62
|
},
|
|
63
|
-
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const SOURCE_ENTRIES = Object.entries(SOURCES);
|
|
66
|
+
const SOURCE_KEYS = Object.keys(SOURCES);
|
|
64
67
|
|
|
65
68
|
type MetricsTableExportProps = {
|
|
66
69
|
items: Array<ReportMetricRow>;
|
|
70
|
+
initialSourceType?: string;
|
|
67
71
|
download: string;
|
|
68
72
|
} & ComponentProps<typeof Stack>;
|
|
69
73
|
|
|
70
74
|
export const MetricsTableExport = (props: MetricsTableExportProps) => {
|
|
71
|
-
const { items, download, ...restProps } = props;
|
|
72
|
-
const [
|
|
75
|
+
const { initialSourceType = SOURCE_KEYS[0], items, download, ...restProps } = props;
|
|
76
|
+
const [selectedSourceType, setSelectedSourceType] = useState(initialSourceType);
|
|
73
77
|
|
|
74
78
|
return (
|
|
75
79
|
<Stack space="small" {...restProps}>
|
|
76
80
|
<Tabs>
|
|
77
|
-
{
|
|
78
|
-
<
|
|
79
|
-
onClick={() =>
|
|
80
|
-
isTabActive={
|
|
81
|
-
|
|
81
|
+
{SOURCE_ENTRIES.map(([sourceId, source]) => (
|
|
82
|
+
<TabItem
|
|
83
|
+
onClick={() => setSelectedSourceType(sourceId)}
|
|
84
|
+
isTabActive={selectedSourceType === sourceId}
|
|
85
|
+
id={`metrics-table-export-tab-${sourceId}`}
|
|
86
|
+
aria-controls={`metrics-table-export-panel-${sourceId}`}
|
|
87
|
+
key={sourceId}
|
|
82
88
|
>
|
|
83
89
|
{source.label}
|
|
84
|
-
</
|
|
90
|
+
</TabItem>
|
|
85
91
|
))}
|
|
86
92
|
</Tabs>
|
|
87
93
|
<div>
|
|
88
|
-
{
|
|
89
|
-
(source) =>
|
|
90
|
-
|
|
94
|
+
{SOURCE_ENTRIES.map(
|
|
95
|
+
([sourceId, source]) =>
|
|
96
|
+
selectedSourceType === sourceId && (
|
|
91
97
|
<PreviewSource
|
|
92
98
|
source={source.transformFn(items)}
|
|
93
99
|
rows={20}
|
|
94
|
-
download={`${download}
|
|
100
|
+
download={`${download}${source.extension}`}
|
|
101
|
+
role="tabpanel"
|
|
102
|
+
id={`metrics-table-export-panel-${sourceId}`}
|
|
103
|
+
aria-labelledby={`metrics-table-export-tab-${sourceId}`}
|
|
95
104
|
key={source.label}
|
|
96
105
|
/>
|
|
97
106
|
),
|
|
@@ -3,12 +3,12 @@ import React from 'react';
|
|
|
3
3
|
|
|
4
4
|
import I18N from '../../i18n';
|
|
5
5
|
import { Dropdown, DropdownItem } from '../../ui/dropdown';
|
|
6
|
-
import
|
|
6
|
+
import css from './metrics-table-options.module.css';
|
|
7
7
|
|
|
8
8
|
type MetricsTableOptionsProps = {
|
|
9
9
|
onViewAllClick?: () => void;
|
|
10
10
|
onResetClick?: () => void;
|
|
11
|
-
onExportClick?: () => void;
|
|
11
|
+
onExportClick?: (sourceType: string) => void;
|
|
12
12
|
} & ComponentProps<typeof Dropdown>;
|
|
13
13
|
|
|
14
14
|
export const MetricsTableOptions = (props: MetricsTableOptionsProps) => {
|
|
@@ -16,10 +16,18 @@ export const MetricsTableOptions = (props: MetricsTableOptionsProps) => {
|
|
|
16
16
|
|
|
17
17
|
return (
|
|
18
18
|
<Dropdown glyph="more-vertical" {...restProps}>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
<div className={css.group}>
|
|
20
|
+
{onResetClick && <DropdownItem onClick={onResetClick}>{I18N.RESET_FILTERS}</DropdownItem>}
|
|
21
|
+
{onViewAllClick && <DropdownItem onClick={onViewAllClick}>{I18N.VIEW_ALL}</DropdownItem>}
|
|
22
|
+
</div>
|
|
23
|
+
<div className={css.group}>
|
|
24
|
+
{onExportClick && (
|
|
25
|
+
<>
|
|
26
|
+
<DropdownItem onClick={() => onExportClick('csv')}>{I18N.EXPORT_CSV}</DropdownItem>
|
|
27
|
+
<DropdownItem onClick={() => onExportClick('json')}>{I18N.EXPORT_JSON}</DropdownItem>
|
|
28
|
+
</>
|
|
29
|
+
)}
|
|
30
|
+
</div>
|
|
23
31
|
</Dropdown>
|
|
24
32
|
);
|
|
25
33
|
};
|
|
@@ -29,7 +29,19 @@ const SOURCE = JSON.stringify(
|
|
|
29
29
|
|
|
30
30
|
export const Default: Story = {
|
|
31
31
|
args: {
|
|
32
|
-
source:
|
|
32
|
+
source: JSON.stringify(
|
|
33
|
+
[
|
|
34
|
+
{
|
|
35
|
+
label: 'Hey',
|
|
36
|
+
runs: [
|
|
37
|
+
{ value: 1, name: 'a' },
|
|
38
|
+
{ value: 2, name: 'b' },
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
null,
|
|
43
|
+
2,
|
|
44
|
+
),
|
|
33
45
|
download: 'bundle-stats--assets.json',
|
|
34
46
|
},
|
|
35
47
|
};
|
|
@@ -50,7 +50,7 @@ export const PreviewSource = (props: PreviewSourceProps) => {
|
|
|
50
50
|
)}
|
|
51
51
|
</ControlGroup>
|
|
52
52
|
)}
|
|
53
|
-
<Textarea readOnly rows={rows}
|
|
53
|
+
<Textarea readOnly rows={rows} value={source} className={css.content} />
|
|
54
54
|
</div>
|
|
55
55
|
);
|
|
56
56
|
};
|
package/src/i18n.js
CHANGED
|
@@ -22,6 +22,8 @@ export default {
|
|
|
22
22
|
RESET_FILTERS: 'Reset filters',
|
|
23
23
|
VIEW_ALL: 'View all entries',
|
|
24
24
|
EXPORT: 'Export',
|
|
25
|
+
EXPORT_CSV: 'Export CSV',
|
|
26
|
+
EXPORT_JSON: 'Export JSON',
|
|
25
27
|
|
|
26
28
|
COPY_TO_CLIPBOARD: 'Copy to clipboard',
|
|
27
29
|
COPY_TO_CLIPBOARD_DONE: 'Copied to clipboard',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './tabs';
|
|
@@ -4,13 +4,16 @@
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
.item {
|
|
7
|
+
appearance: none;
|
|
8
|
+
background: none;
|
|
9
|
+
border: 0;
|
|
7
10
|
position: relative;
|
|
8
11
|
display: inline-block;
|
|
9
12
|
padding: var(--space-xsmall) var(--space-small);
|
|
10
13
|
color: var(--color-text-ultra-light);
|
|
11
14
|
font-weight: bold;
|
|
12
15
|
text-decoration: none;
|
|
13
|
-
|
|
16
|
+
transition: var(--ui-transition-out);
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
.item::after {
|
|
@@ -27,8 +30,9 @@
|
|
|
27
30
|
.item:hover,
|
|
28
31
|
.item:active,
|
|
29
32
|
.item:focus {
|
|
30
|
-
color: var(--color-primary
|
|
33
|
+
color: var(--color-primary);
|
|
31
34
|
outline: none;
|
|
35
|
+
transition: var(--ui-transition-out);
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
.item:hover::after,
|
|
@@ -44,7 +48,3 @@
|
|
|
44
48
|
.itemActive::after {
|
|
45
49
|
background: currentColor;
|
|
46
50
|
}
|
|
47
|
-
|
|
48
|
-
.item + .item {
|
|
49
|
-
_margin-left: var(--space-medium);
|
|
50
|
-
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
|
|
4
|
+
import { getWrapperDecorator } from '../../stories';
|
|
5
|
+
import { Tabs, TabItem } from '.';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof Tabs> = {
|
|
8
|
+
title: 'UI/Tabs',
|
|
9
|
+
component: Tabs,
|
|
10
|
+
decorators: [getWrapperDecorator()],
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
|
|
15
|
+
type Story = StoryObj<typeof meta>;
|
|
16
|
+
|
|
17
|
+
export const Default: Story = {
|
|
18
|
+
render: () => (
|
|
19
|
+
<Tabs>
|
|
20
|
+
<TabItem isTabActive>Option A</TabItem>
|
|
21
|
+
<TabItem>Option B</TabItem>
|
|
22
|
+
<TabItem>Option C</TabItem>
|
|
23
|
+
</Tabs>
|
|
24
|
+
),
|
|
25
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ComponentProps, ElementType } from 'react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import cx from 'classnames';
|
|
4
|
+
|
|
5
|
+
import css from './tabs.module.css';
|
|
6
|
+
|
|
7
|
+
export type TabItemProps<T extends ElementType> = {
|
|
8
|
+
isTabActive?: boolean;
|
|
9
|
+
as?: T;
|
|
10
|
+
} & ComponentProps<T>;
|
|
11
|
+
|
|
12
|
+
export const TabItem = <T extends ElementType = 'button'>(props: TabItemProps<T>) => {
|
|
13
|
+
const { className = '', as: Component = 'button', isTabActive = false, ...restProps } = props;
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<Component
|
|
17
|
+
role="tab"
|
|
18
|
+
className={cx(css.item, className, isTabActive && css.itemActive)}
|
|
19
|
+
{...restProps}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type TabsProps = ComponentProps<'div'>;
|
|
25
|
+
|
|
26
|
+
export const Tabs = (props: TabsProps) => {
|
|
27
|
+
const { className = '', ...restProps } = props;
|
|
28
|
+
|
|
29
|
+
return <div role="tablist" className={cx(css.root, className)} {...restProps} />;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
Tabs.Item = TabItem;
|
|
@@ -4,6 +4,7 @@ import type { ReportMetricRow } from '@bundle-stats/utils';
|
|
|
4
4
|
import { Stack } from '../../layout/stack';
|
|
5
5
|
type MetricsTableExportProps = {
|
|
6
6
|
items: Array<ReportMetricRow>;
|
|
7
|
+
initialSourceType?: string;
|
|
7
8
|
download: string;
|
|
8
9
|
} & ComponentProps<typeof Stack>;
|
|
9
10
|
export declare const MetricsTableExport: (props: MetricsTableExportProps) => React.JSX.Element;
|
|
@@ -4,7 +4,7 @@ import { Dropdown } from '../../ui/dropdown';
|
|
|
4
4
|
type MetricsTableOptionsProps = {
|
|
5
5
|
onViewAllClick?: () => void;
|
|
6
6
|
onResetClick?: () => void;
|
|
7
|
-
onExportClick?: () => void;
|
|
7
|
+
onExportClick?: (sourceType: string) => void;
|
|
8
8
|
} & ComponentProps<typeof Dropdown>;
|
|
9
9
|
export declare const MetricsTableOptions: (props: MetricsTableOptionsProps) => React.JSX.Element;
|
|
10
10
|
export {};
|
package/types/i18n.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ declare namespace _default {
|
|
|
15
15
|
let RESET_FILTERS: string;
|
|
16
16
|
let VIEW_ALL: string;
|
|
17
17
|
let EXPORT: string;
|
|
18
|
+
let EXPORT_CSV: string;
|
|
19
|
+
let EXPORT_JSON: string;
|
|
18
20
|
let COPY_TO_CLIPBOARD: string;
|
|
19
21
|
let COPY_TO_CLIPBOARD_DONE: string;
|
|
20
22
|
let GITHUB_LINK_TITLE: string;
|
package/types/ui/tabs/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './tabs';
|
package/types/ui/tabs/tabs.d.ts
CHANGED
|
@@ -1,42 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
[x: string]: any;
|
|
3
|
-
className?: string | undefined;
|
|
4
|
-
}): React.JSX.Element;
|
|
5
|
-
export namespace Tabs {
|
|
6
|
-
export namespace defaultProps {
|
|
7
|
-
let className: string;
|
|
8
|
-
}
|
|
9
|
-
export namespace propTypes {
|
|
10
|
-
let className_1: PropTypes.Requireable<string>;
|
|
11
|
-
export { className_1 as className };
|
|
12
|
-
export let children: PropTypes.Validator<NonNullable<PropTypes.ReactNodeLike>>;
|
|
13
|
-
}
|
|
14
|
-
export { Item };
|
|
15
|
-
}
|
|
1
|
+
import type { ComponentProps, ElementType } from 'react';
|
|
16
2
|
import React from 'react';
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
let className_2: string;
|
|
28
|
-
export { className_2 as className };
|
|
29
|
-
export let as: string;
|
|
30
|
-
}
|
|
31
|
-
export { defaultProps_1 as defaultProps };
|
|
32
|
-
export namespace propTypes_1 {
|
|
33
|
-
let isTabActive_1: PropTypes.Requireable<boolean>;
|
|
34
|
-
export { isTabActive_1 as isTabActive };
|
|
35
|
-
let className_3: PropTypes.Requireable<string>;
|
|
36
|
-
export { className_3 as className };
|
|
37
|
-
let as_1: PropTypes.Requireable<PropTypes.ReactComponentLike>;
|
|
38
|
-
export { as_1 as as };
|
|
39
|
-
}
|
|
40
|
-
export { propTypes_1 as propTypes };
|
|
41
|
-
}
|
|
42
|
-
export {};
|
|
3
|
+
export type TabItemProps<T extends ElementType> = {
|
|
4
|
+
isTabActive?: boolean;
|
|
5
|
+
as?: T;
|
|
6
|
+
} & ComponentProps<T>;
|
|
7
|
+
export declare const TabItem: <T extends ElementType = "button">(props: TabItemProps<T>) => React.JSX.Element;
|
|
8
|
+
export type TabsProps = ComponentProps<'div'>;
|
|
9
|
+
export declare const Tabs: {
|
|
10
|
+
(props: TabsProps): React.JSX.Element;
|
|
11
|
+
Item: <T extends ElementType = "button">(props: TabItemProps<T>) => React.JSX.Element;
|
|
12
|
+
};
|
package/src/ui/tabs/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { Tabs } from './tabs';
|
package/src/ui/tabs/tabs.jsx
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import cx from 'classnames';
|
|
4
|
-
|
|
5
|
-
import css from './tabs.module.css';
|
|
6
|
-
|
|
7
|
-
const Item = ({ isTabActive, as: Component = 'span', className = '', ...restProps }) => (
|
|
8
|
-
<Component className={cx(css.item, className, isTabActive && css.itemActive)} {...restProps} />
|
|
9
|
-
);
|
|
10
|
-
|
|
11
|
-
Item.defaultProps = {
|
|
12
|
-
isTabActive: false,
|
|
13
|
-
className: '',
|
|
14
|
-
as: 'span',
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
Item.propTypes = {
|
|
18
|
-
isTabActive: PropTypes.bool,
|
|
19
|
-
className: PropTypes.string,
|
|
20
|
-
as: PropTypes.elementType,
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const Tabs = ({ className = '', ...restProps }) => (
|
|
24
|
-
<nav className={cx(css.root, className)} {...restProps} />
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
Tabs.defaultProps = {
|
|
28
|
-
className: '',
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
Tabs.propTypes = {
|
|
32
|
-
/** Adopted child class name */
|
|
33
|
-
className: PropTypes.string,
|
|
34
|
-
|
|
35
|
-
/** Component children */
|
|
36
|
-
children: PropTypes.node.isRequired,
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
Tabs.Item = Item;
|