@bundle-stats/ui 4.10.0 → 4.12.0-beta.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-modules/bundle-modules.constants.js +9 -0
- package/lib/components/bundle-modules/bundle-modules.constants.js.map +1 -0
- package/lib/components/bundle-modules/bundle-modules.js +11 -1
- package/lib/components/bundle-modules/bundle-modules.js.map +1 -1
- package/lib/components/bundle-modules/bundle-modules.module.css +4 -0
- package/lib/components/bundle-modules/index.js +11 -3
- package/lib/components/bundle-modules/index.js.map +1 -1
- package/lib/components/module-info/module-info.js +11 -8
- package/lib/components/module-info/module-info.js.map +1 -1
- package/lib/ui/button/button.js +5 -7
- package/lib/ui/button/button.js.map +1 -1
- package/lib/ui/button/button.module.css +1 -3
- package/lib/ui/dropdown/dropdown.js +2 -6
- package/lib/ui/dropdown/dropdown.js.map +1 -1
- package/lib/ui/dropdown/dropdown.module.css +1 -26
- package/lib/ui/filters/filters.module.css +1 -0
- package/lib-esm/components/bundle-modules/bundle-modules.constants.js +6 -0
- package/lib-esm/components/bundle-modules/bundle-modules.constants.js.map +1 -0
- package/lib-esm/components/bundle-modules/bundle-modules.js +11 -1
- package/lib-esm/components/bundle-modules/bundle-modules.js.map +1 -1
- package/lib-esm/components/bundle-modules/bundle-modules.module.css +4 -0
- package/lib-esm/components/bundle-modules/index.js +12 -4
- package/lib-esm/components/bundle-modules/index.js.map +1 -1
- package/lib-esm/components/module-info/module-info.js +12 -9
- package/lib-esm/components/module-info/module-info.js.map +1 -1
- package/lib-esm/ui/button/button.js +4 -5
- package/lib-esm/ui/button/button.js.map +1 -1
- package/lib-esm/ui/button/button.module.css +1 -3
- package/lib-esm/ui/dropdown/dropdown.js +2 -6
- package/lib-esm/ui/dropdown/dropdown.js.map +1 -1
- package/lib-esm/ui/dropdown/dropdown.module.css +1 -26
- package/lib-esm/ui/filters/filters.module.css +1 -0
- package/package.json +8 -8
- package/src/components/bundle-modules/bundle-modules.constants.ts +4 -0
- package/src/components/bundle-modules/bundle-modules.module.css +4 -0
- package/src/components/bundle-modules/bundle-modules.tsx +31 -0
- package/src/components/bundle-modules/bundle-modules.types.d.ts +1 -1
- package/src/components/bundle-modules/index.tsx +13 -3
- package/src/components/module-info/module-info.tsx +22 -19
- package/src/ui/button/button.module.css +1 -3
- package/src/ui/button/button.stories.tsx +23 -23
- package/src/ui/button/button.tsx +6 -7
- package/src/ui/dropdown/dropdown.jsx +8 -8
- package/src/ui/dropdown/dropdown.module.css +1 -26
- package/src/ui/filters/filters.module.css +1 -0
- package/types/components/bundle-modules/bundle-modules.constants.d.ts +4 -0
- package/types/components/bundle-modules/bundle-modules.d.ts +3 -0
- package/types/ui/button/button.d.ts +5 -20
|
@@ -2,8 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import cx from 'classnames';
|
|
4
4
|
import { Menu, MenuButton, MenuItem, useMenuState } from 'ariakit/menu';
|
|
5
|
-
import {
|
|
6
|
-
import { Icon } from '../icon';
|
|
5
|
+
import { Button, BUTTON_SIZE } from '../button';
|
|
7
6
|
import css from './dropdown.module.css';
|
|
8
7
|
const Item = ({ className = '', isActive = false, ...restProps }) => (React.createElement(MenuItem, { className: cx(css.item, className, isActive && css.itemActive), ...restProps }));
|
|
9
8
|
Item.propTypes = {
|
|
@@ -19,10 +18,7 @@ export const Dropdown = (props) => {
|
|
|
19
18
|
const rootClassName = cx(css.root, className);
|
|
20
19
|
const menuState = useMenuState();
|
|
21
20
|
return (React.createElement("div", { className: rootClassName },
|
|
22
|
-
React.createElement(MenuButton, {
|
|
23
|
-
React.createElement(FlexStack, { space: "xxxsmall", alignItems: "center", className: css.label },
|
|
24
|
-
glyph && React.createElement(Icon, { className: css.labelIcon, glyph: glyph }),
|
|
25
|
-
label && React.createElement("span", { className: css.labelText }, label))),
|
|
21
|
+
React.createElement(MenuButton, { as: Button, outline: true, size: BUTTON_SIZE.SMALL, glyph: glyph, disabled: disabled, state: menuState, tabIndex: null, className: cx(css.button, buttonClassName) }, label),
|
|
26
22
|
React.createElement(Menu, { state: menuState, "aria-label": ariaLabel || label, className: css.dropdown }, typeof children === 'function'
|
|
27
23
|
? children({
|
|
28
24
|
MenuItem: Item,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.js","sourceRoot":"","sources":["../../../src/ui/dropdown/dropdown.jsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAExE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"dropdown.js","sourceRoot":"","sources":["../../../src/ui/dropdown/dropdown.jsx"],"names":[],"mappings":"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"}
|
|
@@ -1,31 +1,5 @@
|
|
|
1
|
-
.root {
|
|
2
|
-
display: inline-block;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
1
|
.button {
|
|
6
|
-
background: none;
|
|
7
|
-
border: none;
|
|
8
|
-
padding: 0;
|
|
9
|
-
|
|
10
|
-
border: 1px solid var(--color-outline);
|
|
11
|
-
border-radius: var(--radius-small);
|
|
12
|
-
padding: calc(var(--space-xxsmall) - 1px);
|
|
13
|
-
|
|
14
|
-
appearance: none;
|
|
15
|
-
background: none;
|
|
16
|
-
font-size: var(--size-small);
|
|
17
|
-
line-height: var(--space-small);
|
|
18
2
|
white-space: nowrap;
|
|
19
|
-
color: var(--color-text-light);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.button[aria-expanded=true],
|
|
23
|
-
.button:hover,
|
|
24
|
-
.button:focus,
|
|
25
|
-
.button:active {
|
|
26
|
-
outline: none;
|
|
27
|
-
box-shadow: var(--outline-hover);
|
|
28
|
-
color: var(--color-text);
|
|
29
3
|
}
|
|
30
4
|
|
|
31
5
|
.button[disabled] {
|
|
@@ -62,6 +36,7 @@
|
|
|
62
36
|
font-size: var(--size-small);
|
|
63
37
|
line-height: inherit;
|
|
64
38
|
text-decoration: none;
|
|
39
|
+
cursor: default;
|
|
65
40
|
}
|
|
66
41
|
|
|
67
42
|
.item[data-active-item],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bundle-stats/ui",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.12.0-beta.0",
|
|
4
4
|
"description": "UI components for BundleStats projects.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib-esm/index.js",
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"@babel/preset-env": "7.23.9",
|
|
40
40
|
"@babel/preset-react": "7.23.3",
|
|
41
41
|
"@babel/preset-typescript": "7.23.3",
|
|
42
|
-
"@storybook/addon-essentials": "7.6.
|
|
43
|
-
"@storybook/react": "7.6.
|
|
44
|
-
"@storybook/react-webpack5": "7.6.
|
|
45
|
-
"@types/react": "18.2.
|
|
42
|
+
"@storybook/addon-essentials": "7.6.16",
|
|
43
|
+
"@storybook/react": "7.6.16",
|
|
44
|
+
"@storybook/react-webpack5": "7.6.16",
|
|
45
|
+
"@types/react": "18.2.57",
|
|
46
46
|
"@types/react-router-dom": "5.3.3",
|
|
47
47
|
"babel-plugin-require-context-hook": "1.0.0",
|
|
48
48
|
"classnames": "2.5.1",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"react-dom": "18.2.0",
|
|
60
60
|
"react-router-dom": "5.3.4",
|
|
61
61
|
"rimraf": "5.0.5",
|
|
62
|
-
"storybook": "7.6.
|
|
62
|
+
"storybook": "7.6.16",
|
|
63
63
|
"typescript": "5.1.6",
|
|
64
64
|
"typescript-plugin-css-modules": "5.1.0"
|
|
65
65
|
},
|
|
@@ -72,10 +72,10 @@
|
|
|
72
72
|
"react-router-dom": "^5.0.0"
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
-
"@bundle-stats/utils": "^4.
|
|
75
|
+
"@bundle-stats/utils": "^4.12.0-beta.0",
|
|
76
76
|
"ariakit": "2.0.0-next.44",
|
|
77
77
|
"modern-css-reset": "1.4.0",
|
|
78
78
|
"use-query-params": "2.2.1"
|
|
79
79
|
},
|
|
80
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "65a2a7d1efda921feb43cbdd1d25068b7738180f"
|
|
81
81
|
}
|
|
@@ -18,9 +18,13 @@ import { MetricsTableOptions } from '../metrics-table-options';
|
|
|
18
18
|
import { MetricsTableTitle } from '../metrics-table-title';
|
|
19
19
|
import { ModuleInfo } from '../module-info';
|
|
20
20
|
import { generateFilterFieldsData } from './bundle-modules.utils';
|
|
21
|
+
import { ModuleMetric } from './bundle-modules.constants';
|
|
21
22
|
import type { Chunk, Job, ReportMetricModuleRow } from './bundle-modules.types';
|
|
22
23
|
import * as I18N_MODULES from './bundle-modules.i18n';
|
|
23
24
|
import css from './bundle-modules.module.css';
|
|
25
|
+
import { Box } from '../../layout';
|
|
26
|
+
import { Button } from '../../ui';
|
|
27
|
+
import { Tooltip } from '../../ui/tooltip';
|
|
24
28
|
|
|
25
29
|
interface RowHeaderProps {
|
|
26
30
|
row: ReportMetricModuleRow;
|
|
@@ -68,6 +72,9 @@ interface BundleModulesProps extends React.ComponentProps<'div'> {
|
|
|
68
72
|
entryId?: string;
|
|
69
73
|
hideEntryInfo: () => void;
|
|
70
74
|
|
|
75
|
+
moduleMetric: ModuleMetric;
|
|
76
|
+
setModuleMetric: (newValue: ModuleMetric) => void;
|
|
77
|
+
|
|
71
78
|
customComponentLink: React.ElementType;
|
|
72
79
|
}
|
|
73
80
|
|
|
@@ -89,6 +96,8 @@ export const BundleModules = (props: BundleModulesProps) => {
|
|
|
89
96
|
updateSearch,
|
|
90
97
|
entryId,
|
|
91
98
|
hideEntryInfo,
|
|
99
|
+
moduleMetric,
|
|
100
|
+
setModuleMetric,
|
|
92
101
|
customComponentLink: CustomComponentLink = ComponentLink,
|
|
93
102
|
} = props;
|
|
94
103
|
|
|
@@ -172,6 +181,28 @@ export const BundleModules = (props: BundleModulesProps) => {
|
|
|
172
181
|
/>
|
|
173
182
|
</FlexStack>
|
|
174
183
|
</Toolbar>
|
|
184
|
+
<Box padding={['xsmall', 'small']} className={css.metricSelector}>
|
|
185
|
+
<FlexStack space="xxsmall" as="nav">
|
|
186
|
+
<Button
|
|
187
|
+
outline
|
|
188
|
+
kind={moduleMetric === ModuleMetric.SIZE ? 'primary' : 'default'}
|
|
189
|
+
size="small"
|
|
190
|
+
type="button"
|
|
191
|
+
onClick={() => setModuleMetric(ModuleMetric.SIZE)}
|
|
192
|
+
>
|
|
193
|
+
<Tooltip title="Size (excluding duplicate modules)">Module size</Tooltip>
|
|
194
|
+
</Button>
|
|
195
|
+
<Button
|
|
196
|
+
outline
|
|
197
|
+
kind={moduleMetric === ModuleMetric.TOTAL_SIZE ? 'primary' : 'default'}
|
|
198
|
+
size="small"
|
|
199
|
+
type="button"
|
|
200
|
+
onClick={() => setModuleMetric(ModuleMetric.TOTAL_SIZE)}
|
|
201
|
+
>
|
|
202
|
+
<Tooltip title="Size (including duplicate modules)">Module total size</Tooltip>
|
|
203
|
+
</Button>
|
|
204
|
+
</FlexStack>
|
|
205
|
+
</Box>
|
|
175
206
|
<MetricsTable
|
|
176
207
|
className={css.table}
|
|
177
208
|
items={items}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useMemo } from 'react';
|
|
1
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
2
2
|
// @ts-ignore
|
|
3
3
|
import * as webpack from '@bundle-stats/utils/lib-esm/webpack';
|
|
4
4
|
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
generateFilters,
|
|
15
15
|
getCustomSort,
|
|
16
16
|
} from './bundle-modules.utils';
|
|
17
|
+
import { ModuleMetric } from './bundle-modules.constants';
|
|
17
18
|
import * as types from './bundle-modules.types';
|
|
18
19
|
|
|
19
20
|
interface BundleModulesProps
|
|
@@ -46,6 +47,8 @@ interface BundleModulesProps
|
|
|
46
47
|
export const BundleModules = (props: BundleModulesProps) => {
|
|
47
48
|
const { jobs, filters, search, setState, sortBy, direction, ...restProps } = props;
|
|
48
49
|
|
|
50
|
+
const [moduleMetric, setModuleMetric] = useState<ModuleMetric>(ModuleMetric.SIZE);
|
|
51
|
+
|
|
49
52
|
const { chunks, chunkIds } = useMemo(() => extractChunkData(jobs), [jobs]);
|
|
50
53
|
|
|
51
54
|
const { defaultFilters, allEntriesFilters } = useMemo(
|
|
@@ -62,12 +65,17 @@ export const BundleModules = (props: BundleModulesProps) => {
|
|
|
62
65
|
});
|
|
63
66
|
|
|
64
67
|
const { rows, totalRowCount } = useMemo(() => {
|
|
65
|
-
|
|
68
|
+
let result;
|
|
69
|
+
if (moduleMetric === ModuleMetric.TOTAL_SIZE) {
|
|
70
|
+
result = webpack.compareModuleDuplicateSize(jobs, [addRowFlags]);
|
|
71
|
+
} else if (moduleMetric === ModuleMetric.SIZE) {
|
|
72
|
+
result = webpack.compareBySection.modules(jobs, [addRowFlags]);
|
|
73
|
+
}
|
|
66
74
|
return {
|
|
67
75
|
rows: result as Array<types.ReportMetricModuleRow>,
|
|
68
76
|
totalRowCount: result.length,
|
|
69
77
|
};
|
|
70
|
-
}, [jobs]);
|
|
78
|
+
}, [jobs, moduleMetric]);
|
|
71
79
|
|
|
72
80
|
const filteredRows = useRowsFilter({
|
|
73
81
|
rows,
|
|
@@ -97,6 +105,8 @@ export const BundleModules = (props: BundleModulesProps) => {
|
|
|
97
105
|
allItems={rows}
|
|
98
106
|
totalRowCount={totalRowCount}
|
|
99
107
|
hideEntryInfo={hideEntryInfo}
|
|
108
|
+
moduleMetric={moduleMetric}
|
|
109
|
+
setModuleMetric={setModuleMetric}
|
|
100
110
|
/>
|
|
101
111
|
);
|
|
102
112
|
};
|
|
@@ -48,7 +48,6 @@ export const ModuleInfo = (props: ModuleInfoProps & React.ComponentProps<'div'>)
|
|
|
48
48
|
} = props;
|
|
49
49
|
|
|
50
50
|
const rootClassName = cx(css.root, className);
|
|
51
|
-
const currentRun = item.runs?.[0];
|
|
52
51
|
|
|
53
52
|
const tags = useMemo(() => {
|
|
54
53
|
if (!item.duplicated) {
|
|
@@ -73,26 +72,30 @@ export const ModuleInfo = (props: ModuleInfoProps & React.ComponentProps<'div'>)
|
|
|
73
72
|
return (
|
|
74
73
|
<EntryInfo item={item} labels={labels} tags={tags} onClose={onClose} className={rootClassName}>
|
|
75
74
|
<Stack space="xxxsmall">
|
|
76
|
-
{
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
{item.runs?.map(
|
|
76
|
+
(currentRun, index) =>
|
|
77
|
+
!isEmpty(currentRun?.chunkIds) && (
|
|
78
|
+
<EntryInfo.Meta label="Chunks" className={css.chunks}>
|
|
79
|
+
Job #{index + 1}:
|
|
80
|
+
{currentRun.chunkIds.map((chunkId) => {
|
|
81
|
+
const chunk = chunks?.find(({ id }) => id === chunkId);
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
if (!chunk) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
84
86
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
87
|
+
return (
|
|
88
|
+
<EntryInfoMetaLink
|
|
89
|
+
as={CustomComponentLink}
|
|
90
|
+
{...getBundleModulesByChunk(chunkIds, chunkId)}
|
|
91
|
+
className={css.chunksItem}
|
|
92
|
+
>
|
|
93
|
+
{chunk.name}
|
|
94
|
+
</EntryInfoMetaLink>
|
|
95
|
+
);
|
|
96
|
+
})}
|
|
97
|
+
</EntryInfo.Meta>
|
|
98
|
+
),
|
|
96
99
|
)}
|
|
97
100
|
|
|
98
101
|
{item?.fileType && (
|
|
@@ -250,14 +250,12 @@ a.root {
|
|
|
250
250
|
.small {
|
|
251
251
|
font-size: var(--size-small);
|
|
252
252
|
gap: var(--space-xxxsmall);
|
|
253
|
-
line-height: var(--space-
|
|
253
|
+
line-height: var(--space-small);
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
.small .glyph {
|
|
257
257
|
width: calc(var(--space-xsmall) + 2px);
|
|
258
258
|
height: calc(var(--space-xsmall) + 2px);
|
|
259
|
-
margin-top: -1px;
|
|
260
|
-
margin-bottom: -1px;
|
|
261
259
|
}
|
|
262
260
|
|
|
263
261
|
.medium {
|
|
@@ -4,7 +4,7 @@ import { Meta, Story } from '@storybook/react';
|
|
|
4
4
|
import { Stack } from '../../layout/stack';
|
|
5
5
|
import { FlexStack } from '../../layout/flex-stack';
|
|
6
6
|
import { Icon } from '../icon';
|
|
7
|
-
import { Button } from '.';
|
|
7
|
+
import { Button, BUTTON_SIZE, BUTTON_KIND } from '.';
|
|
8
8
|
|
|
9
9
|
export default {
|
|
10
10
|
title: 'UI/Button',
|
|
@@ -26,7 +26,7 @@ export const All = () => (
|
|
|
26
26
|
<Stack space="medium">
|
|
27
27
|
<h2>Size</h2>
|
|
28
28
|
<Items>
|
|
29
|
-
{Object.values(
|
|
29
|
+
{Object.values(BUTTON_SIZE).map((size) => (
|
|
30
30
|
<Button size={size} key={size}>
|
|
31
31
|
Action {size}
|
|
32
32
|
</Button>
|
|
@@ -37,7 +37,7 @@ export const All = () => (
|
|
|
37
37
|
<h2>Kind</h2>
|
|
38
38
|
<Stack space="medium">
|
|
39
39
|
<Items>
|
|
40
|
-
{Object.values(
|
|
40
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
41
41
|
<Button kind={kind} key={kind}>
|
|
42
42
|
Action {kind}
|
|
43
43
|
</Button>
|
|
@@ -45,7 +45,7 @@ export const All = () => (
|
|
|
45
45
|
</Items>
|
|
46
46
|
<h3>Active</h3>
|
|
47
47
|
<Items>
|
|
48
|
-
{Object.values(
|
|
48
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
49
49
|
<Button kind={kind} key={kind} active>
|
|
50
50
|
Action {kind}
|
|
51
51
|
</Button>
|
|
@@ -53,7 +53,7 @@ export const All = () => (
|
|
|
53
53
|
</Items>
|
|
54
54
|
<h3>As link</h3>
|
|
55
55
|
<Items>
|
|
56
|
-
{Object.values(
|
|
56
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
57
57
|
<Button kind={kind} key={kind} as="a" href="#">
|
|
58
58
|
Action {kind}
|
|
59
59
|
</Button>
|
|
@@ -61,7 +61,7 @@ export const All = () => (
|
|
|
61
61
|
</Items>
|
|
62
62
|
<h3>With icon</h3>
|
|
63
63
|
<Items>
|
|
64
|
-
{Object.values(
|
|
64
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
65
65
|
<Button glyph={Icon.ICONS.ARROW_RIGHT_CIRLCE} kind={kind} key={kind}>
|
|
66
66
|
Action {kind}
|
|
67
67
|
</Button>
|
|
@@ -69,7 +69,7 @@ export const All = () => (
|
|
|
69
69
|
</Items>
|
|
70
70
|
<h3>Disabled</h3>
|
|
71
71
|
<Items>
|
|
72
|
-
{Object.values(
|
|
72
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
73
73
|
<Button kind={kind} key={kind} disabled>
|
|
74
74
|
Action {kind}
|
|
75
75
|
</Button>
|
|
@@ -80,12 +80,12 @@ export const All = () => (
|
|
|
80
80
|
<Stack space="medium">
|
|
81
81
|
<h2>Outline & Kind</h2>
|
|
82
82
|
<Stack space="medium">
|
|
83
|
-
{Object.values(
|
|
83
|
+
{Object.values(BUTTON_SIZE).map((size) => (
|
|
84
84
|
<Items key={size}>
|
|
85
85
|
<Button outline size={size}>
|
|
86
86
|
Action default
|
|
87
87
|
</Button>
|
|
88
|
-
{Object.values(
|
|
88
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
89
89
|
<Button outline kind={kind} key={kind} size={size}>
|
|
90
90
|
Action {kind}
|
|
91
91
|
</Button>
|
|
@@ -97,19 +97,19 @@ export const All = () => (
|
|
|
97
97
|
<Button outline active>
|
|
98
98
|
Action default
|
|
99
99
|
</Button>
|
|
100
|
-
{Object.values(
|
|
100
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
101
101
|
<Button outline kind={kind} key={kind} active>
|
|
102
102
|
Action {kind}
|
|
103
103
|
</Button>
|
|
104
104
|
))}
|
|
105
105
|
</Items>
|
|
106
106
|
<h3>With icon</h3>
|
|
107
|
-
{Object.values(
|
|
107
|
+
{Object.values(BUTTON_SIZE).map((size) => (
|
|
108
108
|
<Items key={size}>
|
|
109
109
|
<Button glyph={Icon.ICONS.ARROW_RIGHT_CIRLCE} outline size={size}>
|
|
110
110
|
Action default
|
|
111
111
|
</Button>
|
|
112
|
-
{Object.values(
|
|
112
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
113
113
|
<Button
|
|
114
114
|
glyph={Icon.ICONS.ARROW_RIGHT_CIRLCE}
|
|
115
115
|
outline
|
|
@@ -123,10 +123,10 @@ export const All = () => (
|
|
|
123
123
|
</Items>
|
|
124
124
|
))}
|
|
125
125
|
<h3>Only icon</h3>
|
|
126
|
-
{Object.values(
|
|
126
|
+
{Object.values(BUTTON_SIZE).map((size) => (
|
|
127
127
|
<Items key={size}>
|
|
128
128
|
<Button glyph={Icon.ICONS.ARROW_RIGHT_CIRLCE} outline size={size} />
|
|
129
|
-
{Object.values(
|
|
129
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
130
130
|
<Button
|
|
131
131
|
glyph={Icon.ICONS.ARROW_RIGHT_CIRLCE}
|
|
132
132
|
outline
|
|
@@ -142,7 +142,7 @@ export const All = () => (
|
|
|
142
142
|
<Button outline disabled>
|
|
143
143
|
Action default
|
|
144
144
|
</Button>
|
|
145
|
-
{Object.values(
|
|
145
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
146
146
|
<Button outline kind={kind} key={kind} disabled>
|
|
147
147
|
Action {kind}
|
|
148
148
|
</Button>
|
|
@@ -153,12 +153,12 @@ export const All = () => (
|
|
|
153
153
|
<Stack space="medium">
|
|
154
154
|
<h2>Solid & Kind</h2>
|
|
155
155
|
<Stack space="medium">
|
|
156
|
-
{Object.values(
|
|
156
|
+
{Object.values(BUTTON_SIZE).map((size) => (
|
|
157
157
|
<Items key={size}>
|
|
158
158
|
<Button solid size={size}>
|
|
159
159
|
Action default
|
|
160
160
|
</Button>
|
|
161
|
-
{Object.values(
|
|
161
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
162
162
|
<Button solid kind={kind} key={kind} size={size}>
|
|
163
163
|
Action {kind}
|
|
164
164
|
</Button>
|
|
@@ -170,19 +170,19 @@ export const All = () => (
|
|
|
170
170
|
<Button solid active>
|
|
171
171
|
Action default
|
|
172
172
|
</Button>
|
|
173
|
-
{Object.values(
|
|
173
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
174
174
|
<Button solid kind={kind} key={kind} active>
|
|
175
175
|
Action {kind}
|
|
176
176
|
</Button>
|
|
177
177
|
))}
|
|
178
178
|
</Items>
|
|
179
179
|
<h3>With icon</h3>
|
|
180
|
-
{Object.values(
|
|
180
|
+
{Object.values(BUTTON_SIZE).map((size) => (
|
|
181
181
|
<Items key={size}>
|
|
182
182
|
<Button glyph={Icon.ICONS.ARROW_RIGHT_CIRLCE} solid size={size}>
|
|
183
183
|
Action default
|
|
184
184
|
</Button>
|
|
185
|
-
{Object.values(
|
|
185
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
186
186
|
<Button
|
|
187
187
|
glyph={Icon.ICONS.ARROW_RIGHT_CIRLCE}
|
|
188
188
|
solid
|
|
@@ -196,10 +196,10 @@ export const All = () => (
|
|
|
196
196
|
</Items>
|
|
197
197
|
))}
|
|
198
198
|
<h3>Only icon</h3>
|
|
199
|
-
{Object.values(
|
|
199
|
+
{Object.values(BUTTON_SIZE).map((size) => (
|
|
200
200
|
<Items key={size}>
|
|
201
201
|
<Button glyph={Icon.ICONS.ARROW_RIGHT_CIRLCE} solid size={size} />
|
|
202
|
-
{Object.values(
|
|
202
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
203
203
|
<Button
|
|
204
204
|
glyph={Icon.ICONS.ARROW_RIGHT_CIRLCE}
|
|
205
205
|
solid
|
|
@@ -215,7 +215,7 @@ export const All = () => (
|
|
|
215
215
|
<Button solid disabled>
|
|
216
216
|
Action default
|
|
217
217
|
</Button>
|
|
218
|
-
{Object.values(
|
|
218
|
+
{Object.values(BUTTON_KIND).map((kind) => (
|
|
219
219
|
<Button solid kind={kind} key={kind} disabled>
|
|
220
220
|
Action {kind}
|
|
221
221
|
</Button>
|
package/src/ui/button/button.tsx
CHANGED
|
@@ -5,13 +5,13 @@ import { Button as ButtonBaseComponent } from 'ariakit/button';
|
|
|
5
5
|
import { Icon as BaseIcon } from '../icon';
|
|
6
6
|
import css from './button.module.css';
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
export const BUTTON_SIZE = {
|
|
9
9
|
SMALL: 'small',
|
|
10
10
|
MEDIUM: 'medium',
|
|
11
11
|
LARGE: 'large',
|
|
12
12
|
} as const;
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
export const BUTTON_KIND = {
|
|
15
15
|
PRIMARY: 'primary',
|
|
16
16
|
SECONDARY: 'secondary',
|
|
17
17
|
DANGE: 'danger',
|
|
@@ -20,8 +20,8 @@ const KIND = {
|
|
|
20
20
|
SUCCES: 'success',
|
|
21
21
|
} as const;
|
|
22
22
|
|
|
23
|
-
type Size = (typeof
|
|
24
|
-
type Kind = (typeof
|
|
23
|
+
type Size = (typeof BUTTON_SIZE)[keyof typeof BUTTON_SIZE];
|
|
24
|
+
type Kind = (typeof BUTTON_KIND)[keyof typeof BUTTON_KIND];
|
|
25
25
|
|
|
26
26
|
interface ButtonProps<T extends React.ElementType> {
|
|
27
27
|
outline?: boolean;
|
|
@@ -37,7 +37,7 @@ interface ButtonProps<T extends React.ElementType> {
|
|
|
37
37
|
rightGlyph?: React.ComponentProps<typeof BaseIcon>['glyph'];
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
const ButtonComponent = <T extends React.ElementType = 'button'>(
|
|
41
41
|
props: ButtonProps<T> & Omit<React.ComponentPropsWithoutRef<T>, keyof ButtonProps<T>>,
|
|
42
42
|
) => {
|
|
43
43
|
const {
|
|
@@ -92,5 +92,4 @@ export const Button = <T extends React.ElementType = 'button'>(
|
|
|
92
92
|
);
|
|
93
93
|
};
|
|
94
94
|
|
|
95
|
-
Button
|
|
96
|
-
Button.KIND = KIND;
|
|
95
|
+
export const Button = React.forwardRef(ButtonComponent);
|
|
@@ -3,8 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import cx from 'classnames';
|
|
4
4
|
import { Menu, MenuButton, MenuItem, useMenuState } from 'ariakit/menu';
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import { Icon } from '../icon';
|
|
6
|
+
import { Button, BUTTON_SIZE } from '../button';
|
|
8
7
|
import css from './dropdown.module.css';
|
|
9
8
|
|
|
10
9
|
const Item = ({ className = '', isActive = false, ...restProps }) => (
|
|
@@ -29,15 +28,16 @@ export const Dropdown = (props) => {
|
|
|
29
28
|
return (
|
|
30
29
|
<div className={rootClassName}>
|
|
31
30
|
<MenuButton
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
as={Button}
|
|
32
|
+
outline
|
|
33
|
+
size={BUTTON_SIZE.SMALL}
|
|
34
|
+
glyph={glyph}
|
|
34
35
|
disabled={disabled}
|
|
36
|
+
state={menuState}
|
|
35
37
|
tabIndex={null}
|
|
38
|
+
className={cx(css.button, buttonClassName)}
|
|
36
39
|
>
|
|
37
|
-
|
|
38
|
-
{glyph && <Icon className={css.labelIcon} glyph={glyph} />}
|
|
39
|
-
{label && <span className={css.labelText}>{label}</span>}
|
|
40
|
-
</FlexStack>
|
|
40
|
+
{label}
|
|
41
41
|
</MenuButton>
|
|
42
42
|
<Menu state={menuState} aria-label={ariaLabel || label} className={css.dropdown}>
|
|
43
43
|
{typeof children === 'function'
|
|
@@ -1,31 +1,5 @@
|
|
|
1
|
-
.root {
|
|
2
|
-
display: inline-block;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
1
|
.button {
|
|
6
|
-
background: none;
|
|
7
|
-
border: none;
|
|
8
|
-
padding: 0;
|
|
9
|
-
|
|
10
|
-
border: 1px solid var(--color-outline);
|
|
11
|
-
border-radius: var(--radius-small);
|
|
12
|
-
padding: calc(var(--space-xxsmall) - 1px);
|
|
13
|
-
|
|
14
|
-
appearance: none;
|
|
15
|
-
background: none;
|
|
16
|
-
font-size: var(--size-small);
|
|
17
|
-
line-height: var(--space-small);
|
|
18
2
|
white-space: nowrap;
|
|
19
|
-
color: var(--color-text-light);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.button[aria-expanded=true],
|
|
23
|
-
.button:hover,
|
|
24
|
-
.button:focus,
|
|
25
|
-
.button:active {
|
|
26
|
-
outline: none;
|
|
27
|
-
box-shadow: var(--outline-hover);
|
|
28
|
-
color: var(--color-text);
|
|
29
3
|
}
|
|
30
4
|
|
|
31
5
|
.button[disabled] {
|
|
@@ -62,6 +36,7 @@
|
|
|
62
36
|
font-size: var(--size-small);
|
|
63
37
|
line-height: inherit;
|
|
64
38
|
text-decoration: none;
|
|
39
|
+
cursor: default;
|
|
65
40
|
}
|
|
66
41
|
|
|
67
42
|
.item[data-active-item],
|