@bundle-stats/ui 4.8.4 → 4.9.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 (161) hide show
  1. package/lib/components/bundle-assets/bundle-assets.js +2 -2
  2. package/lib/components/bundle-assets/bundle-assets.js.map +1 -1
  3. package/lib/components/bundle-modules/bundle-modules.js +2 -2
  4. package/lib/components/bundle-modules/bundle-modules.js.map +1 -1
  5. package/lib/components/bundle-packages/bundle-packages.js +2 -2
  6. package/lib/components/bundle-packages/bundle-packages.js.map +1 -1
  7. package/lib/components/entry-info/entry-info.js +2 -1
  8. package/lib/components/entry-info/entry-info.js.map +1 -1
  9. package/lib/components/entry-info/entry-info.module.css +0 -6
  10. package/lib/components/index.js +1 -3
  11. package/lib/components/index.js.map +1 -1
  12. package/lib/components/metric-run-info/metric-run-info.js +2 -1
  13. package/lib/components/metric-run-info/metric-run-info.js.map +1 -1
  14. package/lib/components/metric-run-info/metric-run-info.module.css +0 -18
  15. package/lib/components/metrics-table/metrics-table.js +2 -1
  16. package/lib/components/metrics-table/metrics-table.js.map +1 -1
  17. package/lib/components/metrics-table/metrics-table.module.css +0 -18
  18. package/lib/components/metrics-table-title/metrics-table-title.js +2 -1
  19. package/lib/components/metrics-table-title/metrics-table-title.js.map +1 -1
  20. package/lib/components/metrics-table-title/metrics-table-title.module.css +0 -18
  21. package/lib/components/sort-button/sort-button.js +4 -3
  22. package/lib/components/sort-button/sort-button.js.map +1 -1
  23. package/lib/components/sort-button/sort-button.module.css +5 -12
  24. package/lib/components/summary/summary.module.css +0 -18
  25. package/lib/components/total-size-type-title/total-size-type-title.js +2 -1
  26. package/lib/components/total-size-type-title/total-size-type-title.js.map +1 -1
  27. package/lib/components/total-size-type-title/total-size-type-title.module.css +0 -18
  28. package/lib/css/variables.css +14 -14
  29. package/lib/ui/button/button.js +34 -0
  30. package/lib/ui/button/button.js.map +1 -0
  31. package/lib/ui/button/button.module.css +285 -0
  32. package/lib/{components/metrics-table-search → ui/button}/index.js +1 -1
  33. package/lib/ui/button/index.js.map +1 -0
  34. package/lib/ui/dropdown/dropdown.module.css +1 -3
  35. package/lib/ui/empty-set/empty-set.js +4 -3
  36. package/lib/ui/empty-set/empty-set.js.map +1 -1
  37. package/lib/ui/empty-set/empty-set.module.css +0 -17
  38. package/lib/ui/filters/filters.i18n.js +5 -1
  39. package/lib/ui/filters/filters.i18n.js.map +1 -1
  40. package/lib/ui/filters/filters.js +24 -7
  41. package/lib/ui/filters/filters.js.map +1 -1
  42. package/lib/ui/filters/filters.module.css +14 -36
  43. package/lib/ui/index.js +5 -1
  44. package/lib/ui/index.js.map +1 -1
  45. package/lib/ui/input/index.js.map +1 -1
  46. package/lib/ui/input/input.js +2 -10
  47. package/lib/ui/input/input.js.map +1 -1
  48. package/lib/ui/input-search/index.js +18 -0
  49. package/lib/ui/input-search/index.js.map +1 -0
  50. package/lib/ui/input-search/input-search.js +64 -0
  51. package/lib/ui/input-search/input-search.js.map +1 -0
  52. package/lib/{components/metrics-table-search/metrics-table-search.module.css → ui/input-search/input-search.module.css} +1 -18
  53. package/lib-esm/components/bundle-assets/bundle-assets.js +2 -2
  54. package/lib-esm/components/bundle-assets/bundle-assets.js.map +1 -1
  55. package/lib-esm/components/bundle-modules/bundle-modules.js +2 -2
  56. package/lib-esm/components/bundle-modules/bundle-modules.js.map +1 -1
  57. package/lib-esm/components/bundle-packages/bundle-packages.js +2 -2
  58. package/lib-esm/components/bundle-packages/bundle-packages.js.map +1 -1
  59. package/lib-esm/components/entry-info/entry-info.js +2 -1
  60. package/lib-esm/components/entry-info/entry-info.js.map +1 -1
  61. package/lib-esm/components/entry-info/entry-info.module.css +0 -6
  62. package/lib-esm/components/index.js +0 -1
  63. package/lib-esm/components/index.js.map +1 -1
  64. package/lib-esm/components/metric-run-info/metric-run-info.js +2 -1
  65. package/lib-esm/components/metric-run-info/metric-run-info.js.map +1 -1
  66. package/lib-esm/components/metric-run-info/metric-run-info.module.css +0 -18
  67. package/lib-esm/components/metrics-table/metrics-table.js +2 -1
  68. package/lib-esm/components/metrics-table/metrics-table.js.map +1 -1
  69. package/lib-esm/components/metrics-table/metrics-table.module.css +0 -18
  70. package/lib-esm/components/metrics-table-title/metrics-table-title.js +2 -1
  71. package/lib-esm/components/metrics-table-title/metrics-table-title.js.map +1 -1
  72. package/lib-esm/components/metrics-table-title/metrics-table-title.module.css +0 -18
  73. package/lib-esm/components/sort-button/sort-button.js +4 -3
  74. package/lib-esm/components/sort-button/sort-button.js.map +1 -1
  75. package/lib-esm/components/sort-button/sort-button.module.css +5 -12
  76. package/lib-esm/components/summary/summary.module.css +0 -18
  77. package/lib-esm/components/total-size-type-title/total-size-type-title.js +2 -1
  78. package/lib-esm/components/total-size-type-title/total-size-type-title.js.map +1 -1
  79. package/lib-esm/components/total-size-type-title/total-size-type-title.module.css +0 -18
  80. package/lib-esm/css/variables.css +14 -14
  81. package/lib-esm/ui/button/button.js +27 -0
  82. package/lib-esm/ui/button/button.js.map +1 -0
  83. package/lib-esm/ui/button/button.module.css +285 -0
  84. package/lib-esm/ui/button/index.js +2 -0
  85. package/lib-esm/ui/button/index.js.map +1 -0
  86. package/lib-esm/ui/dropdown/dropdown.module.css +1 -3
  87. package/lib-esm/ui/empty-set/empty-set.js +4 -3
  88. package/lib-esm/ui/empty-set/empty-set.js.map +1 -1
  89. package/lib-esm/ui/empty-set/empty-set.module.css +0 -17
  90. package/lib-esm/ui/filters/filters.i18n.js +4 -0
  91. package/lib-esm/ui/filters/filters.i18n.js.map +1 -1
  92. package/lib-esm/ui/filters/filters.js +25 -8
  93. package/lib-esm/ui/filters/filters.js.map +1 -1
  94. package/lib-esm/ui/filters/filters.module.css +14 -36
  95. package/lib-esm/ui/index.js +2 -0
  96. package/lib-esm/ui/index.js.map +1 -1
  97. package/lib-esm/ui/input/index.js.map +1 -1
  98. package/lib-esm/ui/input/input.js +2 -10
  99. package/lib-esm/ui/input/input.js.map +1 -1
  100. package/lib-esm/ui/input-search/index.js +2 -0
  101. package/lib-esm/ui/input-search/index.js.map +1 -0
  102. package/lib-esm/ui/input-search/input-search.js +34 -0
  103. package/lib-esm/ui/input-search/input-search.js.map +1 -0
  104. package/lib-esm/{components/metrics-table-search/metrics-table-search.module.css → ui/input-search/input-search.module.css} +1 -18
  105. package/package.json +9 -9
  106. package/src/components/bundle-assets/bundle-assets.jsx +4 -4
  107. package/src/components/bundle-modules/bundle-modules.tsx +4 -4
  108. package/src/components/bundle-packages/bundle-packages.jsx +4 -4
  109. package/src/components/entry-info/entry-info.module.css +0 -6
  110. package/src/components/entry-info/entry-info.tsx +4 -2
  111. package/src/components/index.js +0 -1
  112. package/src/components/metric-run-info/metric-run-info.module.css +0 -18
  113. package/src/components/metric-run-info/metric-run-info.tsx +3 -2
  114. package/src/components/metrics-table/metrics-table.module.css +0 -18
  115. package/src/components/metrics-table/metrics-table.tsx +9 -6
  116. package/src/components/metrics-table-title/metrics-table-title.jsx +7 -3
  117. package/src/components/metrics-table-title/metrics-table-title.module.css +0 -18
  118. package/src/components/sort-button/sort-button.module.css +5 -12
  119. package/src/components/sort-button/sort-button.tsx +5 -6
  120. package/src/components/summary/summary.module.css +0 -18
  121. package/src/components/total-size-type-title/total-size-type-title.jsx +4 -2
  122. package/src/components/total-size-type-title/total-size-type-title.module.css +0 -18
  123. package/src/css/variables.css +14 -14
  124. package/src/ui/button/button.module.css +285 -0
  125. package/src/ui/button/button.stories.tsx +108 -0
  126. package/src/ui/button/button.tsx +72 -0
  127. package/src/ui/button/index.ts +1 -0
  128. package/src/ui/dropdown/dropdown.module.css +1 -3
  129. package/src/ui/empty-set/empty-set.jsx +6 -5
  130. package/src/ui/empty-set/empty-set.module.css +0 -17
  131. package/src/ui/filters/filters.i18n.ts +4 -0
  132. package/src/ui/filters/filters.module.css +14 -36
  133. package/src/ui/filters/filters.tsx +76 -28
  134. package/src/ui/index.js +2 -0
  135. package/src/ui/input/input.stories.tsx +13 -0
  136. package/src/ui/input/input.tsx +16 -0
  137. package/src/ui/input-search/index.ts +1 -0
  138. package/src/{components/metrics-table-search/metrics-table-search.module.css → ui/input-search/input-search.module.css} +1 -18
  139. package/src/ui/input-search/input-search.tsx +85 -0
  140. package/types/components/index.d.ts +0 -1
  141. package/types/ui/button/button.d.ts +42 -0
  142. package/types/ui/button/index.d.ts +1 -0
  143. package/types/ui/filters/filters.i18n.d.ts +4 -0
  144. package/types/ui/index.d.ts +2 -0
  145. package/types/ui/input/index.d.ts +1 -1
  146. package/types/ui/input/input.d.ts +5 -18
  147. package/types/ui/input-search/index.d.ts +1 -0
  148. package/types/ui/input-search/input-search.d.ts +9 -0
  149. package/lib/components/metrics-table-search/index.js.map +0 -1
  150. package/lib/components/metrics-table-search/metrics-table-search.js +0 -73
  151. package/lib/components/metrics-table-search/metrics-table-search.js.map +0 -1
  152. package/lib-esm/components/metrics-table-search/index.js +0 -2
  153. package/lib-esm/components/metrics-table-search/index.js.map +0 -1
  154. package/lib-esm/components/metrics-table-search/metrics-table-search.js +0 -43
  155. package/lib-esm/components/metrics-table-search/metrics-table-search.js.map +0 -1
  156. package/src/components/metrics-table-search/index.js +0 -1
  157. package/src/components/metrics-table-search/metrics-table-search.jsx +0 -72
  158. package/src/ui/input/input.jsx +0 -20
  159. package/types/components/metrics-table-search/index.d.ts +0 -1
  160. package/types/components/metrics-table-search/metrics-table-search.d.ts +0 -17
  161. /package/src/ui/input/{index.js → index.ts} +0 -0
@@ -0,0 +1,72 @@
1
+ import React from 'react';
2
+ import cx from 'classnames';
3
+ import { Button as ButtonBaseComponent } from 'ariakit/button';
4
+
5
+ import css from './button.module.css';
6
+
7
+ const SIZE = {
8
+ SMALL: 'small',
9
+ MEDIUM: 'medium',
10
+ LARGE: 'large',
11
+ } as const;
12
+
13
+ const KIND = {
14
+ PRIMARY: 'primary',
15
+ SECONDARY: 'secondary',
16
+ DANGE: 'danger',
17
+ WARNING: 'warning',
18
+ INFO: 'info',
19
+ SUCCES: 'success',
20
+ } as const;
21
+
22
+ type Size = (typeof SIZE)[keyof typeof SIZE];
23
+ type Kind = (typeof KIND)[keyof typeof KIND];
24
+
25
+ interface ButtonProps {
26
+ outline?: boolean;
27
+ solid?: boolean;
28
+ kind?: Kind | 'default';
29
+ size?: Size;
30
+ radius?: Size | 'circle' | 'none';
31
+ padding?: Size | 'none';
32
+ }
33
+
34
+ export const Button = (props: ButtonProps & React.ComponentProps<typeof ButtonBaseComponent>) => {
35
+ const {
36
+ className = '',
37
+ outline = false,
38
+ solid = false,
39
+ kind = 'default',
40
+ size = 'medium',
41
+ radius = '',
42
+ padding = '',
43
+ ...restProps
44
+ } = props;
45
+
46
+ // Set padding and radius when provided or when outline/solid variations are set
47
+ const resolvedPadding = padding || ((outline || solid) && size);
48
+ const resolvedRadius = radius || ((outline || solid) && size);
49
+
50
+ const rootClassName = cx(
51
+ css.root,
52
+ css[size],
53
+ kind && css[kind],
54
+
55
+ outline && css.outline,
56
+ outline && css[`outline--${kind}`],
57
+
58
+ solid && css.solid,
59
+ solid && css[`solid--${kind}`],
60
+
61
+ resolvedPadding && css[`padding--${resolvedPadding}`],
62
+ resolvedRadius && css[`radius--${resolvedRadius}`],
63
+
64
+ css[size],
65
+ className,
66
+ );
67
+
68
+ return <ButtonBaseComponent {...restProps} className={rootClassName} />;
69
+ };
70
+
71
+ Button.SIZE = SIZE;
72
+ Button.KIND = KIND;
@@ -0,0 +1 @@
1
+ export * from './button';
@@ -11,12 +11,11 @@
11
11
  border-radius: var(--radius-small);
12
12
  padding: calc(var(--space-xxsmall) - 1px);
13
13
 
14
+ appearance: none;
14
15
  background: none;
15
16
  font-size: var(--size-small);
16
17
  line-height: var(--space-small);
17
18
  white-space: nowrap;
18
- appearance: none;
19
- cursor: pointer;
20
19
  color: var(--color-text-light);
21
20
  }
22
21
 
@@ -48,7 +47,6 @@
48
47
  .item {
49
48
  display: block;
50
49
  appearance: none;
51
- cursor: pointer;
52
50
  width: 100%;
53
51
  outline: none;
54
52
  border: 0;
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
 
4
- import { Stack } from '../../layout/stack';
5
4
  import I18N from '../../i18n';
5
+ import { Stack } from '../../layout/stack';
6
+ import { Button } from '../button';
6
7
  import css from './empty-set.module.css';
7
8
 
8
9
  export const EmptySet = (props) => {
@@ -12,16 +13,16 @@ export const EmptySet = (props) => {
12
13
  const actions = [
13
14
  ...(handleResetFilters
14
15
  ? [
15
- <button className={css.action} type="button" onClick={handleResetFilters}>
16
+ <Button kind="primary" type="button" onClick={handleResetFilters} className={css.action}>
16
17
  {I18N.RESET_FILTERS}
17
- </button>,
18
+ </Button>,
18
19
  ]
19
20
  : []),
20
21
  ...(handleViewAll
21
22
  ? [
22
- <button className={css.action} type="button" onClick={handleViewAll}>
23
+ <Button kind="primary" type="button" onClick={handleViewAll} className={css.action}>
23
24
  {I18N.VIEW_ALL}
24
- </button>,
25
+ </Button>,
25
26
  ]
26
27
  : []),
27
28
  ];
@@ -1,20 +1,3 @@
1
1
  .root {
2
2
  color: var(--color-text-light);
3
3
  }
4
-
5
- .action {
6
- appearance: none;
7
- padding: 0;
8
- background: none;
9
- border: none;
10
- color: var(--color-primary);
11
- cursor: pointer;
12
- text-decoration: underline;
13
- }
14
-
15
- .action:focus,
16
- .action:active,
17
- .action:hover {
18
- color: var(--color-primary-dark);
19
- text-decoration: none;
20
- }
@@ -1,2 +1,6 @@
1
+ export const GROUP_NOT_FOUND = 'No filters found';
2
+ export const GROUP_SEARCH = 'Search by filter name';
3
+ export const GROUP_SEARCH_CLEAR = 'Clear search';
1
4
  export const CLEAR = 'Clear all';
2
5
  export const CHECK = 'Check all';
6
+ export const ONLY = 'only';
@@ -10,13 +10,11 @@
10
10
  }
11
11
 
12
12
  .filterCheckbox {
13
- cursor: pointer;
14
13
  }
15
14
 
16
15
  .filterInput {
17
16
  flex: 0 0 auto;
18
17
  height: 1em;
19
- cursor: pointer;
20
18
  }
21
19
 
22
20
  .filterLabel {
@@ -28,29 +26,13 @@
28
26
  }
29
27
 
30
28
  .filterOnlyButton {
31
- padding: 0 var(--space-xxxsmall);
32
29
  display: none;
33
- appearance: none;
34
- border: none;
35
- border-radius: var(--radius-small);
36
- cursor: pointer;
37
30
  position: absolute;
38
31
  right: 2px;
39
32
  top: 50%;
40
33
  transform: translateY(-50%);
41
- transition: var(--transition-in);
42
- background: var(--color-info);
43
- color: var(--color-background);
34
+ padding: var(--space-xxxsmall);
44
35
  font-size: var(--size-xsmall);
45
- line-height: var(--line-height-header);
46
- }
47
-
48
- .filterOnlyButton:hover,
49
- .filterOnlyButton:active,
50
- .filterOnlyButton:focus {
51
- transition: var(--transition-out);
52
- background: var(--color-info-dark);
53
- color: var(--color-background);
54
36
  }
55
37
 
56
38
  /** cover item text */
@@ -116,6 +98,19 @@
116
98
  text-transform: lowercase;
117
99
  }
118
100
 
101
+ .filterGroupSearchWrapper {
102
+ padding-bottom: var(--space-xxxsmall);
103
+ margin-bottom: var(--space-xxxsmall);
104
+ border-bottom: 1px solid var(--color-outline);
105
+ }
106
+
107
+ .filterGroupSearchNotFound {
108
+ padding: var(--space-xxsmall) 0;
109
+ text-align: center;
110
+ font-size: var(--size-small);
111
+ color: var(--color-text-light);
112
+ }
113
+
119
114
  .filterGroupItems {
120
115
  max-height: calc(10 * (var(--space-small) + 2 * var(--space-xxxsmall)));
121
116
  overflow: auto;
@@ -129,23 +124,6 @@
129
124
  border-top: 1px solid var(--color-outline);
130
125
  }
131
126
 
132
- /* clear / check all */
133
- .filterGroupButton {
134
- margin-top: calc(0px - var(--space-xxxsmall));
135
- margin-bottom: calc(0px - var(--space-xxxsmall));
136
- margin-right: calc(0px - var(--space-xxxsmall));
137
- padding: var(--space-xxxsmall) 0;
138
- outline: none;
139
- appearance: none;
140
- border: none;
141
- background: none;
142
- cursor: pointer;
143
- white-space: nowrap;
144
- color: var(--color-primary);
145
- font-size: var(--size-small);
146
- line-height: 1;
147
- }
148
-
149
127
  .item {
150
128
  position: relative;
151
129
  flex: 0 0 auto;
@@ -1,9 +1,12 @@
1
- import React, { useCallback } from 'react';
1
+ import React, { useCallback, useMemo, useState } from 'react';
2
2
  import cx from 'classnames';
3
3
 
4
4
  import type { FilterFieldsData, FilterGroupFieldData } from '../../types';
5
5
  import { FlexStack } from '../../layout/flex-stack';
6
+ import { Stack } from '../../layout/stack';
7
+ import { Button } from '../button';
6
8
  import { Dropdown } from '../dropdown';
9
+ import { InputSearch } from '../input-search';
7
10
  import * as I18N from './filters.i18n';
8
11
  import { getGroupFiltersLabelSuffix, LABELS } from './filters.utils';
9
12
  import css from './filters.module.css';
@@ -47,9 +50,16 @@ const Filter = (props: FilterProps) => {
47
50
  </FlexStack>
48
51
 
49
52
  {getOnOnlyClick && (
50
- <button type="button" onClick={getOnOnlyClick(name)} className={css.filterOnlyButton}>
51
- only
52
- </button>
53
+ <Button
54
+ kind="info"
55
+ solid
56
+ size="small"
57
+ type="button"
58
+ onClick={getOnOnlyClick(name)}
59
+ className={css.filterOnlyButton}
60
+ >
61
+ {I18N.ONLY}
62
+ </Button>
53
63
  )}
54
64
  </Component>
55
65
  );
@@ -75,6 +85,8 @@ const FilterGroup = (props: FilterGroupProps) => {
75
85
  toggleFilters,
76
86
  } = props;
77
87
 
88
+ const [search, setSearch] = useState('');
89
+
78
90
  const { label: groupLabel, children: groupItems } = data;
79
91
 
80
92
  const areAllGroupItemsChecked = groupItems
@@ -108,6 +120,14 @@ const FilterGroup = (props: FilterGroupProps) => {
108
120
  });
109
121
  };
110
122
 
123
+ const filteredGroupItems = useMemo(() => {
124
+ if (!search) {
125
+ return groupItems;
126
+ }
127
+
128
+ return groupItems.filter((item) => item.label.match(new RegExp(`${search}`, 'i')));
129
+ }, [search, groupItems]);
130
+
111
131
  return (
112
132
  <Dropdown
113
133
  className={className}
@@ -118,8 +138,34 @@ const FilterGroup = (props: FilterGroupProps) => {
118
138
  {({ MenuItem, menuItemClassName }) => {
119
139
  return (
120
140
  <>
141
+ {groupItems.length > 10 && (
142
+ <div className={css.filterGroupSearchWrapper}>
143
+ <InputSearch
144
+ defaultValue={search}
145
+ onChange={setSearch}
146
+ placeholder={I18N.GROUP_SEARCH}
147
+ debounceWait={0}
148
+ />
149
+ </div>
150
+ )}
121
151
  <div className={css.filterGroupItems}>
122
- {groupItems.map(({ key: itemKey, ...itemData }) => {
152
+ {filteredGroupItems.length === 0 && (
153
+ <Stack className={css.filterGroupSearchNotFound}>
154
+ <p>{I18N.GROUP_NOT_FOUND}</p>
155
+ <div>
156
+ <Button
157
+ size="small"
158
+ kind="primary"
159
+ type="button"
160
+ onClick={() => setSearch('')}
161
+ className={css.filterGroupSearchNotFoundClear}
162
+ >
163
+ {I18N.GROUP_SEARCH_CLEAR}
164
+ </Button>
165
+ </div>
166
+ </Stack>
167
+ )}
168
+ {filteredGroupItems.map(({ key: itemKey, ...itemData }) => {
123
169
  const id = [groupKey, itemKey].join('.');
124
170
  const getOnOnlyClick = () => getOnGroupCheck(false, { [id]: true });
125
171
 
@@ -138,29 +184,31 @@ const FilterGroup = (props: FilterGroupProps) => {
138
184
  );
139
185
  })}
140
186
  </div>
141
- <div className={css.filterGroupActions}>
142
- {areAllGroupItemsChecked ? (
143
- <MenuItem
144
- id="clear-all"
145
- as="button"
146
- className={menuItemClassName}
147
- type="button"
148
- onClick={getOnGroupCheck(false)}
149
- >
150
- {I18N.CLEAR}
151
- </MenuItem>
152
- ) : (
153
- <MenuItem
154
- id="clear-all"
155
- as="button"
156
- className={menuItemClassName}
157
- type="button"
158
- onClick={getOnGroupCheck(true)}
159
- >
160
- {I18N.CHECK}
161
- </MenuItem>
162
- )}
163
- </div>
187
+ {filteredGroupItems.length !== 0 && (
188
+ <div className={css.filterGroupActions}>
189
+ {areAllGroupItemsChecked ? (
190
+ <MenuItem
191
+ id="clear-all"
192
+ as="button"
193
+ className={menuItemClassName}
194
+ type="button"
195
+ onClick={getOnGroupCheck(false)}
196
+ >
197
+ {I18N.CLEAR}
198
+ </MenuItem>
199
+ ) : (
200
+ <MenuItem
201
+ id="clear-all"
202
+ as="button"
203
+ className={menuItemClassName}
204
+ type="button"
205
+ onClick={getOnGroupCheck(true)}
206
+ >
207
+ {I18N.CHECK}
208
+ </MenuItem>
209
+ )}
210
+ </div>
211
+ )}
164
212
  </>
165
213
  );
166
214
  }}
package/src/ui/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { Alert } from './alert';
2
+ export { Button } from './button';
2
3
  export { Container } from './container';
3
4
  export { Dropdown } from './dropdown';
4
5
  export { EmptySet } from './empty-set';
@@ -8,6 +9,7 @@ export { HorizontalBarChart } from './horizontal-bar-chart';
8
9
  export { HoverCard } from './hover-card';
9
10
  export { Icon } from './icon';
10
11
  export { Input } from './input';
12
+ export { InputSearch } from './input-search';
11
13
  export { Loader } from './loader';
12
14
  export { Skeleton } from './skeleton';
13
15
  export { Table } from './table';
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+
3
+ import { getWrapperDecorator } from '../../stories';
4
+ import { Input } from '.';
5
+
6
+ export default {
7
+ title: 'UI/Input',
8
+ component: Input,
9
+ decorators: [getWrapperDecorator()],
10
+ };
11
+
12
+ export const Default = () => <Input placeholder="Search" />;
13
+ export const WithSize = () => <Input placeholder="Search" size="small" />;
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import cx from 'classnames';
3
+
4
+ import css from './input.module.css';
5
+
6
+ interface InputProps {
7
+ size?: 'small' | 'medium' | 'large';
8
+ }
9
+
10
+ export const Input = (props: InputProps & Omit<React.ComponentProps<'input'>, 'size'>) => {
11
+ const { className = '', size = 'medium', ...restProps } = props;
12
+
13
+ const rootClassName = cx(css.root, className, css[size]);
14
+
15
+ return <input className={rootClassName} {...restProps} />;
16
+ };
@@ -0,0 +1 @@
1
+ export * from './input-search';
@@ -9,33 +9,16 @@
9
9
  }
10
10
 
11
11
  .cancelButton {
12
- appearance: none;
13
- padding: 0;
14
- border: 0;
15
- background: none;
16
- cursor: pointer;
17
- border-radius: 50%;
18
12
  position: absolute;
19
- right: 2px;
13
+ right: var(--space-xxxsmall);
20
14
  top: 50%;
21
15
  transform: translateY(-50%);
22
- padding: var(--space-xxxsmall);
23
- width: var(--space-medium);
24
- height: var(--space-medium);
25
16
  background: radial-gradient(var(--color-background) 50%, transparent);
26
17
  color: var(--color-text-ultra-light);
27
- transition: var(--transition-in);
28
18
  }
29
19
 
30
20
  .cancelButton:focus,
31
21
  .cancelButton:hover,
32
22
  .cancelButton:active {
33
23
  color: var(--color-text-light);
34
- transition: var(--transition-out);
35
- }
36
-
37
- .cancelButtonIcon {
38
- display: block;
39
- width: var(--space-small);
40
- height: var(--space-small);
41
24
  }
@@ -0,0 +1,85 @@
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
+ import cx from 'classnames';
3
+ import debounce from 'lodash/debounce';
4
+ import noop from 'lodash/noop';
5
+
6
+ import { Button } from '../button';
7
+ import { Icon } from '../icon';
8
+ import { Input } from '../input';
9
+
10
+ import css from './input-search.module.css';
11
+
12
+ interface InputSearchProps {
13
+ placeholder?: string;
14
+ defaultValue?: string;
15
+ onChange?: (newValue: string) => void;
16
+ debounceWait?: number;
17
+ }
18
+
19
+ export const InputSearch = (
20
+ props: InputSearchProps & Omit<React.ComponentProps<'div'>, 'onChange'>,
21
+ ) => {
22
+ const {
23
+ className = '',
24
+ placeholder = 'Search',
25
+ defaultValue = '',
26
+ onChange = noop,
27
+ debounceWait = 500,
28
+ } = props;
29
+ const rootClassname = cx(css.root, className);
30
+
31
+ const [value, setValue] = useState(defaultValue);
32
+
33
+ // Update local state when default value changes
34
+ useEffect(() => {
35
+ setValue(defaultValue);
36
+ }, [defaultValue]);
37
+
38
+ const debouncedUpdateSearch = useCallback(debounce(onChange, debounceWait), [onChange]);
39
+
40
+ const changeValue = useCallback(
41
+ (newValue: string) => {
42
+ if (newValue !== value) {
43
+ debouncedUpdateSearch(newValue);
44
+ setValue(newValue);
45
+ }
46
+ },
47
+ [setValue, value],
48
+ );
49
+
50
+ const inputOnChange = useCallback(
51
+ (event: React.ChangeEvent<HTMLInputElement>) => {
52
+ changeValue(event.target.value);
53
+ },
54
+ [changeValue],
55
+ );
56
+
57
+ const clearButtonOnClick = useCallback(() => {
58
+ changeValue('');
59
+ }, [changeValue]);
60
+
61
+ return (
62
+ <div className={rootClassname}>
63
+ <Input
64
+ className={css.input}
65
+ placeholder={placeholder}
66
+ onChange={inputOnChange}
67
+ value={value}
68
+ size="small"
69
+ autoComplete="off"
70
+ />
71
+ {value && (
72
+ <Button
73
+ radius="circle"
74
+ padding="small"
75
+ type="button"
76
+ onClick={clearButtonOnClick}
77
+ aria-label="Clear search"
78
+ className={css.cancelButton}
79
+ >
80
+ <Icon className={css.cancelButtonIcon} glyph={Icon.ICONS.CANCEL} />
81
+ </Button>
82
+ )}
83
+ </div>
84
+ );
85
+ };
@@ -14,7 +14,6 @@ export { LighthouseTable } from "./lighthouse-table";
14
14
  export { Metric } from "./metric";
15
15
  export { MetricsTable } from "./metrics-table";
16
16
  export { MetricsTableOptions } from "./metrics-table-options";
17
- export { MetricsTableSearch } from "./metrics-table-search";
18
17
  export { MetricsTableTitle } from "./metrics-table-title";
19
18
  export { ModuleInfo } from "./module-info";
20
19
  export { Summary } from "./summary";
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import { Button as ButtonBaseComponent } from 'ariakit/button';
3
+ declare const SIZE: {
4
+ readonly SMALL: "small";
5
+ readonly MEDIUM: "medium";
6
+ readonly LARGE: "large";
7
+ };
8
+ declare const KIND: {
9
+ readonly PRIMARY: "primary";
10
+ readonly SECONDARY: "secondary";
11
+ readonly DANGE: "danger";
12
+ readonly WARNING: "warning";
13
+ readonly INFO: "info";
14
+ readonly SUCCES: "success";
15
+ };
16
+ type Size = (typeof SIZE)[keyof typeof SIZE];
17
+ type Kind = (typeof KIND)[keyof typeof KIND];
18
+ interface ButtonProps {
19
+ outline?: boolean;
20
+ solid?: boolean;
21
+ kind?: Kind | 'default';
22
+ size?: Size;
23
+ radius?: Size | 'circle' | 'none';
24
+ padding?: Size | 'none';
25
+ }
26
+ export declare const Button: {
27
+ (props: ButtonProps & React.ComponentProps<typeof ButtonBaseComponent>): React.JSX.Element;
28
+ SIZE: {
29
+ readonly SMALL: "small";
30
+ readonly MEDIUM: "medium";
31
+ readonly LARGE: "large";
32
+ };
33
+ KIND: {
34
+ readonly PRIMARY: "primary";
35
+ readonly SECONDARY: "secondary";
36
+ readonly DANGE: "danger";
37
+ readonly WARNING: "warning";
38
+ readonly INFO: "info";
39
+ readonly SUCCES: "success";
40
+ };
41
+ };
42
+ export {};
@@ -0,0 +1 @@
1
+ export * from './button';
@@ -1,2 +1,6 @@
1
+ export declare const GROUP_NOT_FOUND = "No filters found";
2
+ export declare const GROUP_SEARCH = "Search by filter name";
3
+ export declare const GROUP_SEARCH_CLEAR = "Clear search";
1
4
  export declare const CLEAR = "Clear all";
2
5
  export declare const CHECK = "Check all";
6
+ export declare const ONLY = "only";
@@ -1,4 +1,5 @@
1
1
  export { Alert } from "./alert";
2
+ export { Button } from "./button";
2
3
  export { Container } from "./container";
3
4
  export { Dropdown } from "./dropdown";
4
5
  export { EmptySet } from "./empty-set";
@@ -8,6 +9,7 @@ export { HorizontalBarChart } from "./horizontal-bar-chart";
8
9
  export { HoverCard } from "./hover-card";
9
10
  export { Icon } from "./icon";
10
11
  export { Input } from "./input";
12
+ export { InputSearch } from "./input-search";
11
13
  export { Loader } from "./loader";
12
14
  export { Skeleton } from "./skeleton";
13
15
  export { Table } from "./table";
@@ -1 +1 @@
1
- export * from "./input";
1
+ export * from './input';
@@ -1,19 +1,6 @@
1
- export function Input({ className, size, ...restProps }: {
2
- [x: string]: any;
3
- className: any;
4
- size: any;
5
- }): React.JSX.Element;
6
- export namespace Input {
7
- namespace propTypes {
8
- let className: PropTypes.Requireable<string>;
9
- let size: PropTypes.Requireable<string>;
10
- }
11
- namespace defaultProps {
12
- let className_1: string;
13
- export { className_1 as className };
14
- let size_1: string;
15
- export { size_1 as size };
16
- }
17
- }
18
1
  import React from 'react';
19
- import PropTypes from 'prop-types';
2
+ interface InputProps {
3
+ size?: 'small' | 'medium' | 'large';
4
+ }
5
+ export declare const Input: (props: InputProps & Omit<React.ComponentProps<'input'>, 'size'>) => React.JSX.Element;
6
+ export {};
@@ -0,0 +1 @@
1
+ export * from './input-search';