@bundle-stats/ui 3.3.0-alpha.1 → 3.3.1-beta.12

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 (240) hide show
  1. package/CHANGELOG.md +65 -13
  2. package/lib/app/app.js +126 -104
  3. package/lib/app/app.module.css +11 -4
  4. package/lib/app/app.stories.js +1 -22
  5. package/lib/app/header/header.js +3 -11
  6. package/lib/assets/icons.svg +0 -8
  7. package/lib/components/asset-info/asset-info.module.css +1 -0
  8. package/lib/components/bundle-assets/bundle-assets.js +105 -52
  9. package/lib/components/bundle-assets/bundle-assets.module.css +24 -26
  10. package/lib/components/bundle-assets-totals-table/bundle-assets-totals-table.js +16 -42
  11. package/lib/components/bundle-assets-totals-table/bundle-assets-totals-table.module.css +2 -2
  12. package/lib/components/bundle-assets-totals-table/bundle-assets-totals-table.stories.js +1 -20
  13. package/lib/components/bundle-modules/bundle-modules.js +68 -68
  14. package/lib/components/bundle-modules/bundle-modules.module.css +11 -2
  15. package/lib/components/bundle-modules/bundle-modules.utils.js +14 -10
  16. package/lib/components/bundle-modules/index.js +4 -4
  17. package/lib/components/bundle-packages/bundle-packages.js +100 -44
  18. package/lib/components/bundle-packages/bundle-packages.module.css +17 -21
  19. package/lib/components/delta/delta.module.css +1 -0
  20. package/lib/components/index.js +0 -8
  21. package/lib/components/job-header/job-header.js +3 -1
  22. package/lib/components/job-header/job-header.module.css +6 -8
  23. package/lib/components/jobs-header/jobs-header.module.css +5 -0
  24. package/lib/components/metrics-table/metrics-table.js +72 -59
  25. package/lib/components/metrics-table/metrics-table.module.css +18 -7
  26. package/lib/components/metrics-table-search/metrics-table-search.module.css +5 -4
  27. package/lib/components/metrics-table-title/metrics-table-title.js +9 -7
  28. package/lib/components/metrics-table-title/metrics-table-title.module.css +2 -0
  29. package/lib/components/module-info/module-info.js +2 -2
  30. package/lib/components/module-info/module-info.module.css +1 -0
  31. package/lib/components/summary/summary.js +7 -12
  32. package/lib/components/summary/summary.module.css +1 -1
  33. package/lib/components/summary/summary.stories.js +0 -29
  34. package/lib/components/summary-item/summary-item.js +18 -38
  35. package/lib/components/summary-item/summary-item.module.css +1 -34
  36. package/lib/components/summary-item/summary-item.stories.js +53 -51
  37. package/lib/components/total-size-type-title/total-size-type-title.js +7 -3
  38. package/lib/constants.js +4 -4
  39. package/lib/css/default.css +14 -3
  40. package/lib/css/variables.css +17 -17
  41. package/lib/hooks/search-params.js +31 -31
  42. package/lib/layout/box/box.module.css +9 -0
  43. package/lib/layout/footer/footer.module.css +1 -1
  44. package/lib/layout/index.js +8 -0
  45. package/lib/layout/separator.js +48 -0
  46. package/lib/layout/separator.module.css +5 -0
  47. package/lib/ui/alert/alert.js +3 -13
  48. package/lib/ui/dropdown/dropdown.js +21 -26
  49. package/lib/ui/dropdown/dropdown.module.css +11 -12
  50. package/lib/ui/dropdown/dropdown.stories.js +2 -9
  51. package/lib/ui/empty-set/empty-set.js +5 -4
  52. package/lib/ui/empty-set/empty-set.module.css +2 -2
  53. package/lib/ui/filters/filters.container.js +1 -1
  54. package/lib/ui/filters/filters.js +22 -7
  55. package/lib/ui/filters/filters.module.css +3 -3
  56. package/lib/ui/horizontal-bar-chart/horizontal-bar-chart.js +1 -1
  57. package/lib/ui/hover-card/hover-card.js +102 -0
  58. package/lib/ui/hover-card/hover-card.module.css +29 -0
  59. package/lib/ui/hover-card/hover-card.stories.js +56 -0
  60. package/lib/{components/budget-info → ui/hover-card}/index.js +4 -4
  61. package/lib/ui/icon/icon.js +6 -8
  62. package/lib/ui/icon/icon.module.css +1 -0
  63. package/lib/ui/index.js +8 -8
  64. package/lib/ui/table/table.js +5 -74
  65. package/lib/ui/table/table.module.css +41 -25
  66. package/lib/ui/table/table.stories.js +1 -1
  67. package/lib/ui/{popover → tag}/index.js +4 -4
  68. package/lib/ui/tag/tag.js +72 -0
  69. package/lib/ui/tag/tag.module.css +55 -0
  70. package/lib/ui/tag/tag.stories.js +38 -0
  71. package/lib/ui/tooltip/tooltip.js +10 -9
  72. package/lib/ui/tooltip/tooltip.module.css +2 -1
  73. package/lib-esm/app/app.js +121 -103
  74. package/lib-esm/app/app.module.css +11 -4
  75. package/lib-esm/app/app.stories.js +1 -22
  76. package/lib-esm/app/header/header.js +3 -10
  77. package/lib-esm/assets/icons.svg +0 -8
  78. package/lib-esm/components/asset-info/asset-info.module.css +1 -0
  79. package/lib-esm/components/bundle-assets/bundle-assets.js +98 -56
  80. package/lib-esm/components/bundle-assets/bundle-assets.module.css +24 -26
  81. package/lib-esm/components/bundle-assets-totals-table/bundle-assets-totals-table.js +13 -26
  82. package/lib-esm/components/bundle-assets-totals-table/bundle-assets-totals-table.module.css +2 -2
  83. package/lib-esm/components/bundle-assets-totals-table/bundle-assets-totals-table.stories.js +0 -18
  84. package/lib-esm/components/bundle-modules/bundle-modules.js +50 -51
  85. package/lib-esm/components/bundle-modules/bundle-modules.module.css +11 -2
  86. package/lib-esm/components/bundle-modules/bundle-modules.utils.js +14 -6
  87. package/lib-esm/components/bundle-modules/index.js +5 -3
  88. package/lib-esm/components/bundle-packages/bundle-packages.js +88 -41
  89. package/lib-esm/components/bundle-packages/bundle-packages.module.css +17 -21
  90. package/lib-esm/components/delta/delta.module.css +1 -0
  91. package/lib-esm/components/index.js +0 -1
  92. package/lib-esm/components/job-header/job-header.js +2 -1
  93. package/lib-esm/components/job-header/job-header.module.css +6 -8
  94. package/lib-esm/components/jobs-header/jobs-header.module.css +5 -0
  95. package/lib-esm/components/metrics-table/metrics-table.js +61 -53
  96. package/lib-esm/components/metrics-table/metrics-table.module.css +18 -7
  97. package/lib-esm/components/metrics-table-search/metrics-table-search.module.css +5 -4
  98. package/lib-esm/components/metrics-table-title/metrics-table-title.js +8 -7
  99. package/lib-esm/components/metrics-table-title/metrics-table-title.module.css +2 -0
  100. package/lib-esm/components/module-info/module-info.js +2 -2
  101. package/lib-esm/components/module-info/module-info.module.css +1 -0
  102. package/lib-esm/components/summary/summary.js +7 -11
  103. package/lib-esm/components/summary/summary.module.css +1 -1
  104. package/lib-esm/components/summary/summary.stories.js +0 -27
  105. package/lib-esm/components/summary-item/summary-item.js +16 -36
  106. package/lib-esm/components/summary-item/summary-item.module.css +1 -34
  107. package/lib-esm/components/summary-item/summary-item.stories.js +38 -50
  108. package/lib-esm/components/total-size-type-title/total-size-type-title.js +6 -3
  109. package/lib-esm/constants.js +4 -4
  110. package/lib-esm/css/default.css +14 -3
  111. package/lib-esm/css/variables.css +17 -17
  112. package/lib-esm/hooks/search-params.js +27 -28
  113. package/lib-esm/layout/box/box.module.css +9 -0
  114. package/lib-esm/layout/footer/footer.module.css +1 -1
  115. package/lib-esm/layout/index.js +1 -0
  116. package/lib-esm/layout/separator.js +28 -0
  117. package/lib-esm/layout/separator.module.css +5 -0
  118. package/lib-esm/ui/alert/alert.js +3 -6
  119. package/lib-esm/ui/dropdown/dropdown.js +20 -25
  120. package/lib-esm/ui/dropdown/dropdown.module.css +11 -12
  121. package/lib-esm/ui/dropdown/dropdown.stories.js +2 -7
  122. package/lib-esm/ui/empty-set/empty-set.js +4 -4
  123. package/lib-esm/ui/empty-set/empty-set.module.css +2 -2
  124. package/lib-esm/ui/filters/filters.js +20 -5
  125. package/lib-esm/ui/filters/filters.module.css +3 -3
  126. package/lib-esm/ui/hover-card/hover-card.js +83 -0
  127. package/lib-esm/ui/hover-card/hover-card.module.css +29 -0
  128. package/lib-esm/ui/hover-card/hover-card.stories.js +35 -0
  129. package/lib-esm/ui/hover-card/index.js +1 -0
  130. package/lib-esm/ui/icon/icon.js +3 -5
  131. package/lib-esm/ui/icon/icon.module.css +1 -0
  132. package/lib-esm/ui/index.js +1 -1
  133. package/lib-esm/ui/table/table.js +5 -65
  134. package/lib-esm/ui/table/table.module.css +41 -25
  135. package/lib-esm/ui/table/table.stories.js +1 -1
  136. package/lib-esm/ui/tag/index.js +1 -0
  137. package/lib-esm/ui/tag/tag.js +45 -0
  138. package/lib-esm/ui/tag/tag.module.css +55 -0
  139. package/lib-esm/ui/tag/tag.stories.js +23 -0
  140. package/lib-esm/ui/tooltip/tooltip.js +10 -9
  141. package/lib-esm/ui/tooltip/tooltip.module.css +2 -1
  142. package/package.json +33 -31
  143. package/src/app/app.jsx +136 -146
  144. package/src/app/app.module.css +11 -4
  145. package/src/app/header/header.jsx +1 -11
  146. package/src/assets/icons.svg +0 -8
  147. package/src/components/asset-info/asset-info.module.css +1 -0
  148. package/src/components/bundle-assets/bundle-assets.jsx +85 -31
  149. package/src/components/bundle-assets/bundle-assets.module.css +24 -26
  150. package/src/components/bundle-assets-totals-table/bundle-assets-totals-table.jsx +13 -25
  151. package/src/components/bundle-assets-totals-table/bundle-assets-totals-table.module.css +2 -2
  152. package/src/components/bundle-modules/bundle-modules.jsx +53 -36
  153. package/src/components/bundle-modules/bundle-modules.module.css +11 -2
  154. package/src/components/bundle-modules/bundle-modules.utils.js +16 -4
  155. package/src/components/bundle-modules/index.jsx +3 -0
  156. package/src/components/bundle-packages/bundle-packages.jsx +89 -39
  157. package/src/components/bundle-packages/bundle-packages.module.css +17 -21
  158. package/src/components/delta/delta.module.css +1 -0
  159. package/src/components/index.js +0 -1
  160. package/src/components/job-header/job-header.jsx +2 -1
  161. package/src/components/job-header/job-header.module.css +6 -8
  162. package/src/components/jobs-header/jobs-header.module.css +5 -0
  163. package/src/components/metrics-table/metrics-table.jsx +53 -44
  164. package/src/components/metrics-table/metrics-table.module.css +18 -7
  165. package/src/components/metrics-table-search/metrics-table-search.module.css +5 -4
  166. package/src/components/metrics-table-title/metrics-table-title.jsx +20 -21
  167. package/src/components/metrics-table-title/metrics-table-title.module.css +2 -0
  168. package/src/components/module-info/module-info.jsx +3 -7
  169. package/src/components/module-info/module-info.module.css +1 -0
  170. package/src/components/summary/summary.jsx +7 -8
  171. package/src/components/summary/summary.module.css +1 -1
  172. package/src/components/summary-item/summary-item.jsx +23 -40
  173. package/src/components/summary-item/summary-item.module.css +1 -34
  174. package/src/components/total-size-type-title/total-size-type-title.jsx +6 -9
  175. package/src/constants.js +11 -7
  176. package/src/css/default.css +14 -3
  177. package/src/css/variables.css +17 -17
  178. package/src/hooks/search-params.js +42 -33
  179. package/src/layout/box/box.module.css +9 -0
  180. package/src/layout/footer/footer.module.css +1 -1
  181. package/src/layout/index.js +1 -0
  182. package/src/layout/separator.jsx +25 -0
  183. package/src/layout/separator.module.css +5 -0
  184. package/src/ui/alert/alert.jsx +2 -7
  185. package/src/ui/dropdown/dropdown.jsx +16 -22
  186. package/src/ui/dropdown/dropdown.module.css +11 -12
  187. package/src/ui/empty-set/empty-set.jsx +25 -21
  188. package/src/ui/empty-set/empty-set.module.css +2 -2
  189. package/src/ui/filters/filters.jsx +64 -53
  190. package/src/ui/filters/filters.module.css +3 -3
  191. package/src/ui/hover-card/hover-card.jsx +73 -0
  192. package/src/ui/hover-card/hover-card.module.css +29 -0
  193. package/src/ui/hover-card/index.js +1 -0
  194. package/src/ui/icon/icon.jsx +11 -9
  195. package/src/ui/icon/icon.module.css +1 -0
  196. package/src/ui/index.js +1 -1
  197. package/src/ui/table/table.jsx +5 -52
  198. package/src/ui/table/table.module.css +41 -25
  199. package/src/ui/tag/index.js +1 -0
  200. package/src/ui/tag/tag.jsx +49 -0
  201. package/src/ui/tag/tag.module.css +55 -0
  202. package/src/ui/tooltip/tooltip.jsx +10 -14
  203. package/src/ui/tooltip/tooltip.module.css +2 -1
  204. package/lib/assets/icons/alert-circle.svg +0 -1
  205. package/lib/assets/icons/check-circle.svg +0 -1
  206. package/lib/components/budget-info/budget-info.js +0 -80
  207. package/lib/components/budget-info/budget-info.module.css +0 -40
  208. package/lib/components/budget-info/budget-info.stories.js +0 -44
  209. package/lib/components/budget-insights/budget-insights.js +0 -200
  210. package/lib/components/budget-insights/budget-insights.module.css +0 -53
  211. package/lib/components/budget-insights/budget-insights.stories.js +0 -104
  212. package/lib/components/budget-insights/index.js +0 -18
  213. package/lib/ui/popover/popover.js +0 -92
  214. package/lib/ui/popover/popover.module.css +0 -66
  215. package/lib/ui/popover/popover.stories.js +0 -26
  216. package/lib-esm/assets/icons/alert-circle.svg +0 -1
  217. package/lib-esm/assets/icons/check-circle.svg +0 -1
  218. package/lib-esm/components/budget-info/budget-info.js +0 -58
  219. package/lib-esm/components/budget-info/budget-info.module.css +0 -40
  220. package/lib-esm/components/budget-info/budget-info.stories.js +0 -30
  221. package/lib-esm/components/budget-info/index.js +0 -1
  222. package/lib-esm/components/budget-insights/budget-insights.js +0 -148
  223. package/lib-esm/components/budget-insights/budget-insights.module.css +0 -53
  224. package/lib-esm/components/budget-insights/budget-insights.stories.js +0 -84
  225. package/lib-esm/components/budget-insights/index.js +0 -1
  226. package/lib-esm/ui/popover/index.js +0 -1
  227. package/lib-esm/ui/popover/popover.js +0 -71
  228. package/lib-esm/ui/popover/popover.module.css +0 -66
  229. package/lib-esm/ui/popover/popover.stories.js +0 -14
  230. package/src/assets/icons/alert-circle.svg +0 -1
  231. package/src/assets/icons/check-circle.svg +0 -1
  232. package/src/components/budget-info/budget-info.jsx +0 -65
  233. package/src/components/budget-info/budget-info.module.css +0 -40
  234. package/src/components/budget-info/index.js +0 -1
  235. package/src/components/budget-insights/budget-insights.jsx +0 -157
  236. package/src/components/budget-insights/budget-insights.module.css +0 -53
  237. package/src/components/budget-insights/index.js +0 -1
  238. package/src/ui/popover/index.js +0 -1
  239. package/src/ui/popover/popover.jsx +0 -79
  240. package/src/ui/popover/popover.module.css +0 -66
@@ -9,7 +9,7 @@ import { getGroupFiltersLabelSuffix, LABELS } from './filters.utils';
9
9
  import css from './filters.module.css';
10
10
 
11
11
  const Filter = (props) => {
12
- const { className, label, name, getOnOnlyClick, ...inputProps } = props;
12
+ const { className, buttonClassName, label, name, getOnOnlyClick, ...inputProps } = props;
13
13
  const id = `filter-${name}`;
14
14
 
15
15
  const rootClassName = cx(css.filter, className);
@@ -17,26 +17,16 @@ const Filter = (props) => {
17
17
  return (
18
18
  <div className={rootClassName}>
19
19
  {/* eslint-disable */}
20
- <FlexStack space="xxxsmall" as="label" className={css.filterCheckbox}>
21
- {/* eslint-enabled */}
22
- <input
23
- className={css.filterInput}
24
- type="checkbox"
25
- id={id}
26
- name={name}
27
- {...inputProps}
28
- />
20
+ <FlexStack space="xxxsmall" as="label" className={cx(css.filterCheckbox, buttonClassName)}>
21
+ {/* eslint-enabled */}
22
+ <input className={css.filterInput} type="checkbox" id={id} name={name} {...inputProps} />
29
23
  <span className={css.filterLabel} title={label}>
30
24
  {label}
31
25
  </span>
32
26
  </FlexStack>
33
27
 
34
28
  {getOnOnlyClick && (
35
- <button
36
- className={css.filterOnlyButton}
37
- type="button"
38
- onClick={getOnOnlyClick(name)}
39
- >
29
+ <button className={css.filterOnlyButton} type="button" onClick={getOnOnlyClick(name)}>
40
30
  only
41
31
  </button>
42
32
  )}
@@ -46,6 +36,7 @@ const Filter = (props) => {
46
36
 
47
37
  Filter.propTypes = {
48
38
  className: PropTypes.string,
39
+ buttonClassName: PropTypes.string,
49
40
  name: PropTypes.string.isRequired,
50
41
  label: PropTypes.string.isRequired,
51
42
  getOnOnlyClick: PropTypes.func,
@@ -53,17 +44,23 @@ Filter.propTypes = {
53
44
 
54
45
  Filter.defaultProps = {
55
46
  className: '',
47
+ buttonClassName: '',
56
48
  getOnOnlyClick: null,
57
49
  };
58
50
 
59
51
  const FilterGroup = (props) => {
60
- const { groupKey, data, values, onCheckboxChange, toggleFilters } = props;
52
+ const { className, buttonClassName, groupKey, data, values, onCheckboxChange, toggleFilters } =
53
+ props;
61
54
 
62
55
  const { label: groupLabel, ...groupData } = data;
63
56
 
64
57
  const groupItems = Object.entries(groupData);
65
- const groupCheckboxes = groupItems.filter(([itemKey, item]) => typeof item?.defaultValue !== 'undefined');
66
- const isGroupChecked = groupCheckboxes.map(([itemKey]) => get(values, `${groupKey}.${itemKey}`)).reduce((agg, val) => agg && val, true);
58
+ const groupCheckboxes = groupItems.filter(
59
+ ([itemKey, item]) => typeof item?.defaultValue !== 'undefined',
60
+ );
61
+ const isGroupChecked = groupCheckboxes
62
+ .map(([itemKey]) => get(values, `${groupKey}.${itemKey}`))
63
+ .reduce((agg, val) => agg && val, true);
67
64
 
68
65
  const filterSuffix = getGroupFiltersLabelSuffix(groupItems);
69
66
  const hasCustomFilterSuffix = !Object.values(LABELS).includes(filterSuffix);
@@ -71,26 +68,34 @@ const FilterGroup = (props) => {
71
68
  <>
72
69
  {`${groupLabel}:`}
73
70
  &nbsp;
74
- <span className={cx(hasCustomFilterSuffix && css.labelSuffixCustom)}>
75
- {filterSuffix}
76
- </span>
71
+ <span className={cx(hasCustomFilterSuffix && css.labelSuffixCustom)}>{filterSuffix}</span>
77
72
  </>
78
73
  );
79
74
 
80
- const getOnGroupCheck = (value, overrides = {}) => () => {
81
- const newFilters = groupCheckboxes.reduce((agg, [itemKey]) => ({
82
- ...agg,
83
- [`${groupKey}.${itemKey}`]: value,
84
- }), {});
85
-
86
- toggleFilters({
87
- ...newFilters,
88
- ...overrides,
89
- });
90
- };
75
+ const getOnGroupCheck =
76
+ (value, overrides = {}) =>
77
+ () => {
78
+ const newFilters = groupCheckboxes.reduce(
79
+ (agg, [itemKey]) => ({
80
+ ...agg,
81
+ [`${groupKey}.${itemKey}`]: value,
82
+ }),
83
+ {},
84
+ );
85
+
86
+ toggleFilters({
87
+ ...newFilters,
88
+ ...overrides,
89
+ });
90
+ };
91
91
 
92
92
  return (
93
- <Dropdown label={dropdownLabel} ariaLabel={`${groupLabel}: ${filterSuffix}`}>
93
+ <Dropdown
94
+ className={className}
95
+ buttonClassName={buttonClassName}
96
+ label={dropdownLabel}
97
+ ariaLabel={`${groupLabel}: ${filterSuffix}`}
98
+ >
94
99
  {({ MenuItem, menu, menuItemClassName }) => {
95
100
  return (
96
101
  <>
@@ -100,7 +105,11 @@ const FilterGroup = (props) => {
100
105
  const getOnOnlyClick = () => getOnGroupCheck(false, { [id]: true });
101
106
 
102
107
  return (
103
- <MenuItem key={id} {...menu} className={cx(menuItemClassName, css.filterGroupItem)}>
108
+ <MenuItem
109
+ key={id}
110
+ {...menu}
111
+ className={cx(menuItemClassName, css.filterGroupItem)}
112
+ >
104
113
  <Filter
105
114
  name={id}
106
115
  label={itemData.label}
@@ -138,12 +147,14 @@ const FilterGroup = (props) => {
138
147
  </div>
139
148
  </>
140
149
  );
141
- }}
150
+ }}
142
151
  </Dropdown>
143
152
  );
144
153
  };
145
154
 
146
155
  FilterGroup.propTypes = {
156
+ className: PropTypes.string,
157
+ buttonClassName: PropTypes.string,
147
158
  groupKey: PropTypes.string.isRequired,
148
159
  data: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
149
160
  values: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
@@ -151,27 +162,27 @@ FilterGroup.propTypes = {
151
162
  toggleFilters: PropTypes.func.isRequired,
152
163
  };
153
164
 
165
+ FilterGroup.defaultProps = {
166
+ className: '',
167
+ buttonClassName: '',
168
+ };
169
+
154
170
  export const Filters = (props) => {
155
- const {
156
- className,
157
- values,
158
- filters,
159
- toggleFilter,
160
- toggleFilters,
161
- } = props;
171
+ const { className, values, filters, toggleFilter, toggleFilters } = props;
162
172
 
163
173
  const onCheckboxChange = ({ target }) => toggleFilter(target.name, target.checked);
164
174
  const rootClassName = cx(css.root, className);
165
175
 
166
176
  return (
167
177
  <form className={rootClassName}>
168
- <FlexStack className={css.items}>
178
+ <FlexStack space="xxsmall" className={css.items}>
169
179
  {Object.entries(filters).map(([name, data]) => {
170
180
  if (typeof data?.defaultValue !== 'undefined') {
171
181
  return (
172
182
  <Filter
173
183
  key={name}
174
184
  className={cx(css.item, css.filterStandalone)}
185
+ buttonClassName={css.itemButton}
175
186
  name={name}
176
187
  label={data.label}
177
188
  onChange={onCheckboxChange}
@@ -182,16 +193,16 @@ export const Filters = (props) => {
182
193
  }
183
194
 
184
195
  return (
185
- <div className={css.item}>
186
- <FilterGroup
187
- key={name}
188
- groupKey={name}
189
- data={data}
190
- values={values}
191
- onCheckboxChange={onCheckboxChange}
192
- toggleFilters={toggleFilters}
193
- />
194
- </div>
196
+ <FilterGroup
197
+ className={css.item}
198
+ buttonClassName={css.itemButton}
199
+ key={name}
200
+ groupKey={name}
201
+ data={data}
202
+ values={values}
203
+ onCheckboxChange={onCheckboxChange}
204
+ toggleFilters={toggleFilters}
205
+ />
195
206
  );
196
207
  })}
197
208
  </FlexStack>
@@ -11,6 +11,7 @@
11
11
  }
12
12
 
13
13
  .filterInput {
14
+ border-radius: var(--radius-small) 0 0 var(--radius-small);
14
15
  flex: 0 0 auto;
15
16
  height: 1em;
16
17
  cursor: pointer;
@@ -131,9 +132,8 @@
131
132
  .item {
132
133
  position: relative;
133
134
  flex: 0 0 auto;
134
- margin-right: -1px;
135
135
  }
136
136
 
137
- .item:hover {
138
- z-index: var(--layer-low); /* show collapsed border */
137
+ .itemButton {
138
+ border-radius: var(--radius-small);
139
139
  }
@@ -0,0 +1,73 @@
1
+ import React, { useCallback } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import cx from 'classnames';
4
+ import {
5
+ Hovercard,
6
+ HovercardAnchor,
7
+ HovercardArrow,
8
+ useHovercard,
9
+ useHovercardState,
10
+ } from 'ariakit/hovercard';
11
+
12
+ import css from './hover-card.module.css';
13
+
14
+ const resolveComponent = (as, href) => {
15
+ if (as) {
16
+ return as;
17
+ }
18
+
19
+ if (href) {
20
+ return 'a';
21
+ }
22
+
23
+ return 'span';
24
+ };
25
+
26
+ export const HoverCard = (props) => {
27
+ const { className, hoverCardClassName, href, as, label, children } = props;
28
+ const state = useHovercardState({ gutter: 8 });
29
+ const hoverCardProps = useHovercard({ state, portal: true });
30
+
31
+ // Fallback to span if no href
32
+ const Component = resolveComponent(as, href);
33
+
34
+ return (
35
+ <div className={cx(css.root, className)}>
36
+ <HovercardAnchor state={state} href={href} className={css.anchor} as={Component}>
37
+ {label}
38
+ </HovercardAnchor>
39
+ <Hovercard
40
+ {...hoverCardProps}
41
+ state={state}
42
+ className={cx(css.hoverCard, hoverCardClassName)}
43
+ style={{ zIndex: 10000 }}
44
+ >
45
+ <HovercardArrow size={24} />
46
+ {typeof children === 'function' ? children({ close: state.hide }) : children}
47
+ </Hovercard>
48
+ </div>
49
+ );
50
+ };
51
+
52
+ HoverCard.propTypes = {
53
+ /** Adopted child class name */
54
+ className: PropTypes.string,
55
+ /** Adopted child class name for hover card */
56
+ hoverCardClassName: PropTypes.string,
57
+ /** Anchor label */
58
+ label: PropTypes.node,
59
+ /** Anchor href */
60
+ href: PropTypes.string,
61
+ /** Anchor component */
62
+ as: PropTypes.elementType,
63
+ /** Hover card component */
64
+ children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
65
+ };
66
+
67
+ HoverCard.defaultProps = {
68
+ className: '',
69
+ hoverCardClassName: '',
70
+ label: '',
71
+ as: '',
72
+ href: '',
73
+ };
@@ -0,0 +1,29 @@
1
+ .root {
2
+ display: inline-block;
3
+ }
4
+
5
+ .anchor {
6
+ display: inline-block;
7
+ color: inherit;
8
+ text-decoration: none;
9
+ }
10
+
11
+ .anchor:hover {
12
+ color: var(--color-primary);
13
+ }
14
+
15
+ .anchor:focus {
16
+ outline: 0;
17
+ }
18
+
19
+ .hoverCard {
20
+ padding: var(--space-xsmall) var(--space-small);
21
+ border-radius: var(--radius-medium);
22
+ width: calc(100vw - 2 * var(--space-small));
23
+ max-width: 360px;
24
+ outline: none;
25
+ filter: drop-shadow(0 0 var(--space-xxsmall) var(--color-shadow));
26
+ will-change: filter;
27
+ background: var(--color-light);
28
+ font-size: var(--size-small);
29
+ }
@@ -0,0 +1 @@
1
+ export * from './hover-card';
@@ -5,13 +5,11 @@ import cx from 'classnames';
5
5
  import css from './icon.module.css';
6
6
 
7
7
  const ICONS = {
8
- ALERT_CIRCLE: 'alert-circle',
9
8
  ARROW: 'arrow',
10
9
  ARROW_RIGHT_CIRLCE: 'arrow-right-circle',
11
10
  CANCEL: 'cancel',
12
11
  CLOSE: 'close',
13
12
  CLOCK: 'clock',
14
- CHECK_CIRCLE: 'check-circle',
15
13
  COMMIT: 'commit',
16
14
  FILTER: 'filter',
17
15
  HELP: 'help',
@@ -20,13 +18,17 @@ const ICONS = {
20
18
  WARNING: 'warning',
21
19
  };
22
20
 
23
- export const Icon = ({ className, glyph, as: Component, size, ...restProps }) => (
24
- <Component className={cx(css.root, className, css[size])} {...restProps}>
25
- <svg className={css.icon}>
26
- <use xlinkHref={`#${glyph}`} />
27
- </svg>
28
- </Component>
29
- );
21
+ export const Icon = (props) => {
22
+ const { className, glyph, as: Component, size, ...restProps } = props;
23
+
24
+ return (
25
+ <Component className={cx(css.root, className, css[size])} {...restProps}>
26
+ <svg className={css.icon}>
27
+ <use xlinkHref={`#${glyph}`} />
28
+ </svg>
29
+ </Component>
30
+ );
31
+ };
30
32
 
31
33
  Icon.ICONS = ICONS;
32
34
 
@@ -1,5 +1,6 @@
1
1
  .root {
2
2
  display: inline-block;
3
+ vertical-align: middle; /** center align when parent display is inline/inline-block **/
3
4
  }
4
5
 
5
6
  .icon {
package/src/ui/index.js CHANGED
@@ -10,9 +10,9 @@ export { Input } from './input';
10
10
  export { Loader } from './loader';
11
11
  export { Logo } from './logo';
12
12
  export { Panels } from './panels';
13
- export { Popover } from './popover';
14
13
  export { Skeleton } from './skeleton';
15
14
  export { SortDropdown } from './sort-dropdown';
16
15
  export { Table } from './table';
17
16
  export { Tabs } from './tabs';
17
+ export { Tag } from './tag';
18
18
  export { Tooltip } from './tooltip';
@@ -4,53 +4,6 @@ import cx from 'classnames';
4
4
 
5
5
  import css from './table.module.css';
6
6
 
7
- const THead = (props) => <thead {...props} />
8
-
9
- const TBody = (props) => <tbody {...props} />;
10
-
11
- const Tr = (props) => {
12
- const { className, ...restProps } = props;
13
- return <tr className={cx(css.row, className)} {...restProps} />;
14
- };
15
-
16
- Tr.defaultProps = {
17
- className: '',
18
- };
19
-
20
- Tr.propTypes = {
21
- /** Adopted child class name */
22
- className: PropTypes.string,
23
- };
24
-
25
- const Th = (props) => {
26
- const { className, ...restProps } = props;
27
-
28
- return <th className={cx(css.cell, className)} {...restProps} />;
29
- };
30
-
31
- Th.defaultProps = {
32
- className: '',
33
- };
34
-
35
- Th.propTypes = {
36
- /** Adopted child class name */
37
- className: PropTypes.string,
38
- };
39
-
40
- const Td = (props) => {
41
- const { className, ...restProps } = props;
42
- return <td className={cx(css.cell, className)} {...restProps} />;
43
- };
44
-
45
- Td.defaultProps = {
46
- className: '',
47
- };
48
-
49
- Td.propTypes = {
50
- /** Adopted child class name */
51
- className: PropTypes.string,
52
- };
53
-
54
7
  export const Table = ({ className, emptyMessage, compact, outline, children }) => {
55
8
  const rootClassName = cx(css.root, className, compact && css.compact, outline && css.outline);
56
9
 
@@ -61,11 +14,11 @@ export const Table = ({ className, emptyMessage, compact, outline, children }) =
61
14
  return <table className={rootClassName}>{children}</table>;
62
15
  };
63
16
 
64
- Table.THead = THead;
65
- Table.TBody = TBody;
66
- Table.Th = Th;
67
- Table.Tr = Tr;
68
- Table.Td = Td;
17
+ Table.THead = 'thead';
18
+ Table.TBody = 'tbody';
19
+ Table.Tr = 'tr';
20
+ Table.Th = 'th';
21
+ Table.Td = 'td';
69
22
 
70
23
  Table.defaultProps = {
71
24
  className: '',
@@ -1,54 +1,54 @@
1
1
  .root {
2
2
  border-width: 0;
3
3
  width: 100%;
4
- border-collapse: collapse;
4
+ border-spacing: 0;
5
5
  empty-cells: show;
6
6
  background: var(--color-background);
7
+ text-align: left;
7
8
  }
8
9
 
9
- .cell {
10
+ .root th,
11
+ .root td {
10
12
  border: 1px solid var(--color-outline);
11
13
  border-width: 1px 0 0;
12
- padding: var(--space-small) var(--space-small);
13
- text-align: left;
14
- }
15
-
16
- tr:last-child .cell {
17
- border-bottom-width: 1px;
14
+ padding: var(--space-small);
18
15
  }
19
16
 
20
- .root thead .cell {
21
- border-width: 0 0 2px;
17
+ .root thead th {
18
+ border-width: 0 0 1px;
22
19
  text-transform: uppercase;
23
20
  vertical-align: top;
21
+ background: var(--color-highlight);
24
22
  }
25
23
 
26
- .root thead .cell:empty {
24
+ .root thead th:empty {
27
25
  display: none;
28
26
  }
29
27
 
30
- .root tbody .cell {
28
+ .root tbody th {
31
29
  font-weight: normal;
32
30
  }
33
31
 
34
- .root tbody .cell a {
32
+ .root tbody tr:first-child td,
33
+ .root tbody tr:first-child th {
34
+ border-top: 0;
35
+ }
36
+
37
+ .root tbody td a {
35
38
  color: inherit;
36
39
  text-decoration: none;
37
40
  }
38
41
 
39
- .root tbody .cell a:hover,
40
- .root tbody .cell a:focus,
41
- .root tbody .cell a:active
42
+ .root tbody td a:hover,
43
+ .root tbody td a:focus,
44
+ .root tbody td a:active
42
45
  {
43
46
  color: var(--color-primary);
44
47
  text-decoration: underline;
45
48
  }
46
49
 
47
- .root tbody tr:nth-child(odd) .cell {
48
- background-color: var(--color-highlight);
49
- }
50
-
51
- .root tbody tr:hover .cell {
50
+ .root tbody tr:hover th,
51
+ .root tbody tr:hover td {
52
52
  background-color: var(--color-highlight-warning);
53
53
  }
54
54
 
@@ -62,12 +62,27 @@ tr:last-child .cell {
62
62
 
63
63
  /* outline variation */
64
64
  .outline {
65
+ --table-radius: var(--radius-medium);
65
66
  border: 1px solid var(--color-outline);
66
- border-width: 0 1px;
67
+ border-radius: var(--table-radius);
68
+ }
69
+
70
+ .outline thead:first-child tr:first-child th:first-child,
71
+ .outline tbody:first-child tr:first-child td:first-child {
72
+ border-top-left-radius: var(--table-radius);
73
+ }
74
+
75
+ .outline thead tr:first-child th:last-child,
76
+ .outline tbody:first-child tr:first-child td:last-child {
77
+ border-top-right-radius: var(--table-radius);
78
+ }
79
+
80
+ .outline tbody:last-child tr:last-child td:first-child {
81
+ border-bottom-left-radius: var(--table-radius);
67
82
  }
68
83
 
69
- .outline thead tr:first-child .cell {
70
- border-top-width: 1px;
84
+ .outline tbody:last-child tr:last-child td:last-child {
85
+ border-bottom-right-radius: var(--table-radius);
71
86
  }
72
87
 
73
88
  .outline.empty {
@@ -75,7 +90,8 @@ tr:last-child .cell {
75
90
  }
76
91
 
77
92
  /* compact variation */
78
- .compact .cell {
93
+ .compact td,
94
+ .compact th {
79
95
  padding-top: var(--space-xsmall);
80
96
  padding-bottom: var(--space-xsmall);
81
97
  }
@@ -0,0 +1 @@
1
+ export * from './tag';
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import cx from 'classnames';
4
+
5
+ import css from './tag.module.css';
6
+
7
+ export const KINDS = {
8
+ DEFAULT: 'default',
9
+ SUCCESS: 'success',
10
+ INFO: 'info',
11
+ WARNING: 'warning',
12
+ DANGER: 'danger',
13
+ };
14
+
15
+ export const SIZES = {
16
+ SMALL: 'small',
17
+ MEDIUM: 'medium',
18
+ LARGE: 'large',
19
+ };
20
+
21
+ export const Tag = (props) => {
22
+ const {
23
+ className = '',
24
+ as: Component = 'span',
25
+ kind = KINDS.DEFAULT,
26
+ size = SIZES.MEDIUM,
27
+ ...restProps
28
+ } = props;
29
+ const rootClassName = cx(css.root, className, css[kind], css[size]);
30
+
31
+ return <Component className={rootClassName} {...restProps} />;
32
+ };
33
+
34
+ Tag.propTypes = {
35
+ className: PropTypes.string,
36
+ as: PropTypes.elementType,
37
+ kind: PropTypes.oneOf(Object.values(KINDS)),
38
+ size: PropTypes.oneOf(Object.values(SIZES)),
39
+ };
40
+
41
+ Tag.defaultProps = {
42
+ className: '',
43
+ as: 'span',
44
+ kind: KINDS.DEFAULT,
45
+ size: SIZES.MEDIUM,
46
+ };
47
+
48
+ Tag.KINDS = KINDS;
49
+ Tag.SIZES = SIZES;
@@ -0,0 +1,55 @@
1
+ .root {
2
+ display: inline-block;
3
+ font-family: var(--font-family);
4
+ font-weight: bold;
5
+ background: var(--color-text-light);
6
+ color: var(--color-light);
7
+ text-align: center;
8
+ text-transform: uppercase;
9
+ }
10
+
11
+ /** Kind variation */
12
+ .success {
13
+ background: var(--color-success);
14
+ }
15
+
16
+ .info {
17
+ background: var(--color-info);
18
+ }
19
+
20
+ .warning {
21
+ background: var(--color-warning-dark);
22
+ }
23
+
24
+ .danger {
25
+ background: var(--color-danger);
26
+ }
27
+
28
+ /** Size variation */
29
+ /** default: medium */
30
+ .root {
31
+ border-radius: var(--radius-medium);
32
+ padding: var(--space-xxxsmall);
33
+ min-width: var(--space-small);
34
+ height: var(--space-small);
35
+ font-size: 9px;
36
+ line-height: 1;
37
+ }
38
+
39
+ .small {
40
+ border-radius: var(--radius-small);
41
+ padding: calc(var(--space-xxxsmall) / 2);
42
+ height: var(--space-xsmall);
43
+ min-width: var(--space-xsmall);
44
+ font-size: 8px;
45
+ line-height: 1;
46
+ }
47
+
48
+ .large {
49
+ border-radius: var(--radius-large);
50
+ padding: var(--space-xxxsmall) var(--space-xxsmall);
51
+ min-width: var(--space-medium);
52
+ height: var(--space-medium);
53
+ font-size: 12px;
54
+ line-height: var(--space-small);
55
+ }