@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.
Files changed (48) hide show
  1. package/lib/components/bundle-modules/bundle-modules.constants.js +9 -0
  2. package/lib/components/bundle-modules/bundle-modules.constants.js.map +1 -0
  3. package/lib/components/bundle-modules/bundle-modules.js +11 -1
  4. package/lib/components/bundle-modules/bundle-modules.js.map +1 -1
  5. package/lib/components/bundle-modules/bundle-modules.module.css +4 -0
  6. package/lib/components/bundle-modules/index.js +11 -3
  7. package/lib/components/bundle-modules/index.js.map +1 -1
  8. package/lib/components/module-info/module-info.js +11 -8
  9. package/lib/components/module-info/module-info.js.map +1 -1
  10. package/lib/ui/button/button.js +5 -7
  11. package/lib/ui/button/button.js.map +1 -1
  12. package/lib/ui/button/button.module.css +1 -3
  13. package/lib/ui/dropdown/dropdown.js +2 -6
  14. package/lib/ui/dropdown/dropdown.js.map +1 -1
  15. package/lib/ui/dropdown/dropdown.module.css +1 -26
  16. package/lib/ui/filters/filters.module.css +1 -0
  17. package/lib-esm/components/bundle-modules/bundle-modules.constants.js +6 -0
  18. package/lib-esm/components/bundle-modules/bundle-modules.constants.js.map +1 -0
  19. package/lib-esm/components/bundle-modules/bundle-modules.js +11 -1
  20. package/lib-esm/components/bundle-modules/bundle-modules.js.map +1 -1
  21. package/lib-esm/components/bundle-modules/bundle-modules.module.css +4 -0
  22. package/lib-esm/components/bundle-modules/index.js +12 -4
  23. package/lib-esm/components/bundle-modules/index.js.map +1 -1
  24. package/lib-esm/components/module-info/module-info.js +12 -9
  25. package/lib-esm/components/module-info/module-info.js.map +1 -1
  26. package/lib-esm/ui/button/button.js +4 -5
  27. package/lib-esm/ui/button/button.js.map +1 -1
  28. package/lib-esm/ui/button/button.module.css +1 -3
  29. package/lib-esm/ui/dropdown/dropdown.js +2 -6
  30. package/lib-esm/ui/dropdown/dropdown.js.map +1 -1
  31. package/lib-esm/ui/dropdown/dropdown.module.css +1 -26
  32. package/lib-esm/ui/filters/filters.module.css +1 -0
  33. package/package.json +8 -8
  34. package/src/components/bundle-modules/bundle-modules.constants.ts +4 -0
  35. package/src/components/bundle-modules/bundle-modules.module.css +4 -0
  36. package/src/components/bundle-modules/bundle-modules.tsx +31 -0
  37. package/src/components/bundle-modules/bundle-modules.types.d.ts +1 -1
  38. package/src/components/bundle-modules/index.tsx +13 -3
  39. package/src/components/module-info/module-info.tsx +22 -19
  40. package/src/ui/button/button.module.css +1 -3
  41. package/src/ui/button/button.stories.tsx +23 -23
  42. package/src/ui/button/button.tsx +6 -7
  43. package/src/ui/dropdown/dropdown.jsx +8 -8
  44. package/src/ui/dropdown/dropdown.module.css +1 -26
  45. package/src/ui/filters/filters.module.css +1 -0
  46. package/types/components/bundle-modules/bundle-modules.constants.d.ts +4 -0
  47. package/types/components/bundle-modules/bundle-modules.d.ts +3 -0
  48. 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 { FlexStack } from '../../layout/flex-stack';
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, { state: menuState, className: cx(css.button, buttonClassName), disabled: disabled, tabIndex: null },
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,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,GAAG,MAAM,uBAAuB,CAAC;AAExC,MAAM,IAAI,GAAG,CAAC,EAAE,SAAS,GAAG,EAAE,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,SAAS,EAAE,EAAE,EAAE,CAAC,CACnE,oBAAC,QAAQ,IAAC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC,KAAM,SAAS,GAAI,CAC5F,CAAC;AAEF,IAAI,CAAC,SAAS,GAAG;IACf,SAAS,EAAE,SAAS,CAAC,MAAM;IAC3B,QAAQ,EAAE,SAAS,CAAC,IAAI;CACzB,CAAC;AAEF,IAAI,CAAC,YAAY,GAAG;IAClB,SAAS,EAAE,EAAE;IACb,QAAQ,EAAE,KAAK;CAChB,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,EAAE;IAChC,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC1F,MAAM,aAAa,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IAEjC,OAAO,CACL,6BAAK,SAAS,EAAE,aAAa;QAC3B,oBAAC,UAAU,IACT,KAAK,EAAE,SAAS,EAChB,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EAC1C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,IAAI;YAEd,oBAAC,SAAS,IAAC,KAAK,EAAC,UAAU,EAAC,UAAU,EAAC,QAAQ,EAAC,SAAS,EAAE,GAAG,CAAC,KAAK;gBACjE,KAAK,IAAI,oBAAC,IAAI,IAAC,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,GAAI;gBACzD,KAAK,IAAI,8BAAM,SAAS,EAAE,GAAG,CAAC,SAAS,IAAG,KAAK,CAAQ,CAC9C,CACD;QACb,oBAAC,IAAI,IAAC,KAAK,EAAE,SAAS,gBAAc,SAAS,IAAI,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,QAAQ,IAC5E,OAAO,QAAQ,KAAK,UAAU;YAC7B,CAAC,CAAC,QAAQ,CAAC;gBACP,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,SAAS;gBACf,iBAAiB,EAAE,GAAG,CAAC,IAAI;gBAC3B,uBAAuB,EAAE,GAAG,CAAC,UAAU;aACxC,CAAC;YACJ,CAAC,CAAC,QAAQ,CACP,CACH,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,QAAQ,CAAC,YAAY,GAAG;IACtB,SAAS,EAAE,EAAE;IACb,eAAe,EAAE,EAAE;IACnB,KAAK,EAAE,IAAI;IACX,SAAS,EAAE,EAAE;IACb,KAAK,EAAE,IAAI;IACX,QAAQ,EAAE,KAAK;CAChB,CAAC;AAEF,QAAQ,CAAC,SAAS,GAAG;IAEnB,SAAS,EAAE,SAAS,CAAC,MAAM;IAG3B,eAAe,EAAE,SAAS,CAAC,MAAM;IAGjC,KAAK,EAAE,SAAS,CAAC,IAAI;IAGrB,SAAS,EAAE,SAAS,CAAC,MAAM;IAG3B,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IAG9D,QAAQ,EAAE,SAAS,CAAC,IAAI;IAGxB,QAAQ,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU;CAChG,CAAC;AAEF,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC"}
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],
@@ -33,6 +33,7 @@
33
33
  transform: translateY(-50%);
34
34
  padding: var(--space-xxxsmall);
35
35
  font-size: var(--size-xsmall);
36
+ line-height: 1.1;
36
37
  }
37
38
 
38
39
  /** cover item text */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bundle-stats/ui",
3
- "version": "4.10.0",
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.15",
43
- "@storybook/react": "7.6.15",
44
- "@storybook/react-webpack5": "7.6.15",
45
- "@types/react": "18.2.55",
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.15",
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.10.0",
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": "1ed77f899eb226ad095b77bfdc1561aab67640b6"
80
+ "gitHead": "65a2a7d1efda921feb43cbdd1d25068b7738180f"
81
81
  }
@@ -0,0 +1,4 @@
1
+ export enum ModuleMetric {
2
+ SIZE = 'value',
3
+ TOTAL_SIZE = 'totalSize',
4
+ }
@@ -12,6 +12,10 @@
12
12
  margin-right: -1px; /** collapse border */
13
13
  }
14
14
 
15
+ .metricSelector {
16
+ border-bottom: 1px solid var(--color-outline);
17
+ }
18
+
15
19
  .nameTagDuplicated {
16
20
  margin-right: var(--space-xxxsmall);
17
21
  vertical-align: baseline;
@@ -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}
@@ -13,7 +13,7 @@ export type ReportMetricModuleRow = {
13
13
  } & ReportMetricRun &
14
14
  Module;
15
15
 
16
- interface Job {
16
+ export interface Job {
17
17
  label: string;
18
18
  internalBuildNumber: number;
19
19
  meta?: {
@@ -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
- const result = webpack.compareBySection.modules(jobs, [addRowFlags]);
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
- {!isEmpty(currentRun?.chunkIds) && (
77
- <EntryInfo.Meta label="Chunks" className={css.chunks}>
78
- {currentRun.chunkIds.map((chunkId) => {
79
- const chunk = chunks?.find(({ id }) => id === chunkId);
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
- if (!chunk) {
82
- return null;
83
- }
83
+ if (!chunk) {
84
+ return null;
85
+ }
84
86
 
85
- return (
86
- <EntryInfoMetaLink
87
- as={CustomComponentLink}
88
- {...getBundleModulesByChunk(chunkIds, chunkId)}
89
- className={css.chunksItem}
90
- >
91
- {chunk.name}
92
- </EntryInfoMetaLink>
93
- );
94
- })}
95
- </EntryInfo.Meta>
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-xsmall);
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(Button.SIZE).map((size) => (
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(Button.KIND).map((kind) => (
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(Button.KIND).map((kind) => (
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(Button.KIND).map((kind) => (
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(Button.KIND).map((kind) => (
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(Button.KIND).map((kind) => (
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(Button.SIZE).map((size) => (
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(Button.KIND).map((kind) => (
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(Button.KIND).map((kind) => (
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(Button.SIZE).map((size) => (
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(Button.KIND).map((kind) => (
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(Button.SIZE).map((size) => (
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(Button.KIND).map((kind) => (
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(Button.KIND).map((kind) => (
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(Button.SIZE).map((size) => (
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(Button.KIND).map((kind) => (
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(Button.KIND).map((kind) => (
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(Button.SIZE).map((size) => (
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(Button.KIND).map((kind) => (
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(Button.SIZE).map((size) => (
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(Button.KIND).map((kind) => (
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(Button.KIND).map((kind) => (
218
+ {Object.values(BUTTON_KIND).map((kind) => (
219
219
  <Button solid kind={kind} key={kind} disabled>
220
220
  Action {kind}
221
221
  </Button>
@@ -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 SIZE = {
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 KIND = {
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 SIZE)[keyof typeof SIZE];
24
- type Kind = (typeof KIND)[keyof typeof KIND];
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
- export const Button = <T extends React.ElementType = 'button'>(
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.SIZE = SIZE;
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 { FlexStack } from '../../layout/flex-stack';
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
- state={menuState}
33
- className={cx(css.button, buttonClassName)}
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
- <FlexStack space="xxxsmall" alignItems="center" className={css.label}>
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],
@@ -33,6 +33,7 @@
33
33
  transform: translateY(-50%);
34
34
  padding: var(--space-xxxsmall);
35
35
  font-size: var(--size-xsmall);
36
+ line-height: 1.1;
36
37
  }
37
38
 
38
39
  /** cover item text */
@@ -0,0 +1,4 @@
1
+ export declare enum ModuleMetric {
2
+ SIZE = "value",
3
+ TOTAL_SIZE = "totalSize"
4
+ }