@bundle-stats/ui 3.2.7-beta.5 → 3.2.9

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 (61) hide show
  1. package/CHANGELOG.md +2 -2
  2. package/lib/app/app.js +124 -79
  3. package/lib/components/asset-info/asset-info.module.css +1 -0
  4. package/lib/components/bundle-assets/bundle-assets.js +97 -57
  5. package/lib/components/bundle-assets/bundle-assets.module.css +19 -13
  6. package/lib/components/bundle-assets-totals-table/bundle-assets-totals-table.js +13 -3
  7. package/lib/components/bundle-modules/bundle-modules.js +49 -64
  8. package/lib/components/bundle-packages/bundle-packages.js +94 -46
  9. package/lib/components/bundle-packages/bundle-packages.module.css +14 -14
  10. package/lib/components/metrics-table/metrics-table.js +72 -59
  11. package/lib/components/metrics-table/metrics-table.module.css +18 -7
  12. package/lib/components/module-info/module-info.js +2 -2
  13. package/lib/hooks/search-params.js +25 -25
  14. package/lib/ui/empty-set/empty-set.js +5 -4
  15. package/lib/ui/empty-set/empty-set.module.css +2 -2
  16. package/lib/ui/hover-card/hover-card.js +6 -5
  17. package/lib/ui/hover-card/hover-card.module.css +6 -7
  18. package/lib/ui/table/table.js +5 -74
  19. package/lib/ui/table/table.module.css +23 -19
  20. package/lib/ui/table/table.stories.js +1 -1
  21. package/lib/ui/tooltip/tooltip.module.css +1 -0
  22. package/lib-esm/app/app.js +118 -76
  23. package/lib-esm/components/asset-info/asset-info.module.css +1 -0
  24. package/lib-esm/components/bundle-assets/bundle-assets.js +91 -61
  25. package/lib-esm/components/bundle-assets/bundle-assets.module.css +19 -13
  26. package/lib-esm/components/bundle-assets-totals-table/bundle-assets-totals-table.js +6 -3
  27. package/lib-esm/components/bundle-modules/bundle-modules.js +31 -47
  28. package/lib-esm/components/bundle-packages/bundle-packages.js +83 -43
  29. package/lib-esm/components/bundle-packages/bundle-packages.module.css +14 -14
  30. package/lib-esm/components/metrics-table/metrics-table.js +61 -53
  31. package/lib-esm/components/metrics-table/metrics-table.module.css +18 -7
  32. package/lib-esm/components/module-info/module-info.js +2 -2
  33. package/lib-esm/hooks/search-params.js +21 -22
  34. package/lib-esm/ui/empty-set/empty-set.js +4 -4
  35. package/lib-esm/ui/empty-set/empty-set.module.css +2 -2
  36. package/lib-esm/ui/hover-card/hover-card.js +6 -5
  37. package/lib-esm/ui/hover-card/hover-card.module.css +6 -7
  38. package/lib-esm/ui/table/table.js +5 -65
  39. package/lib-esm/ui/table/table.module.css +23 -19
  40. package/lib-esm/ui/table/table.stories.js +1 -1
  41. package/lib-esm/ui/tooltip/tooltip.module.css +1 -0
  42. package/package.json +3 -3
  43. package/src/app/app.jsx +135 -133
  44. package/src/components/asset-info/asset-info.module.css +1 -0
  45. package/src/components/bundle-assets/bundle-assets.jsx +94 -59
  46. package/src/components/bundle-assets/bundle-assets.module.css +19 -13
  47. package/src/components/bundle-assets-totals-table/bundle-assets-totals-table.jsx +2 -0
  48. package/src/components/bundle-modules/bundle-modules.jsx +28 -38
  49. package/src/components/bundle-packages/bundle-packages.jsx +80 -43
  50. package/src/components/bundle-packages/bundle-packages.module.css +14 -14
  51. package/src/components/metrics-table/metrics-table.jsx +53 -44
  52. package/src/components/metrics-table/metrics-table.module.css +18 -7
  53. package/src/components/module-info/module-info.jsx +2 -2
  54. package/src/hooks/search-params.js +24 -22
  55. package/src/ui/empty-set/empty-set.jsx +25 -21
  56. package/src/ui/empty-set/empty-set.module.css +2 -2
  57. package/src/ui/hover-card/hover-card.jsx +5 -10
  58. package/src/ui/hover-card/hover-card.module.css +6 -7
  59. package/src/ui/table/table.jsx +5 -52
  60. package/src/ui/table/table.module.css +23 -19
  61. package/src/ui/tooltip/tooltip.module.css +1 -0
@@ -12,7 +12,8 @@ import styles from './metrics-table.module.css';
12
12
 
13
13
  const METRIC_TYPE_DATA = getGlobalMetricType(null, METRIC_TYPE_FILE_SIZE);
14
14
 
15
- const getRowsRunTotal = (rows, runIndex) => sum(rows.map((row) => get(row, `runs[${runIndex}].value`, 0)));
15
+ const getRowsRunTotal = (rows, runIndex) =>
16
+ sum(rows.map((row) => get(row, `runs[${runIndex}].value`, 0)));
16
17
 
17
18
  const getHeaderLabelCells = (rows) => (run, runIndex, runs) => {
18
19
  const isBaseline = runIndex === runs.length - 1;
@@ -102,46 +103,58 @@ const getHeaderRows = (runs, items, showHeaderSum, title) => [
102
103
  : []),
103
104
  ];
104
105
 
105
- const generateRowCells = (item, index, items) => {
106
- const isBaseline = index === items.length - 1;
106
+ const MetricsTableRow = ({ item, renderRowHeader }) => (
107
+ <Table.Tr className={cx(!item.changed && styles.unchanged)}>
108
+ <Table.Th className={styles.metricName}>{renderRowHeader(item)}</Table.Th>
107
109
 
108
- // eslint-disable-next-line react/destructuring-assignment
109
- if (!item || typeof item.value === 'undefined') {
110
- return ['-', ...(!isBaseline ? [''] : [])];
111
- }
110
+ {item.runs.map((run, index) => {
111
+ const isBaseline = index === item.runs.length - 1;
112
+ const valueClassName = cx(styles.value, !isBaseline && styles.current);
112
113
 
113
- const { displayValue, deltaPercentage, displayDeltaPercentage, deltaType } = item;
114
+ // Empty cells if no value
115
+ if (!run || typeof run.value === 'undefined') {
116
+ return (
117
+ <>
118
+ <Table.Td className={valueClassName}>-</Table.Td>
119
+ {!isBaseline && <Table.Td className={styles.delta} />}
120
+ </>
121
+ );
122
+ }
114
123
 
115
- const cells = [<Metric value={displayValue} />];
124
+ const { displayValue, deltaPercentage, displayDeltaPercentage, deltaType } = run;
116
125
 
117
- if (!isBaseline) {
118
- cells.push(
119
- typeof deltaPercentage === 'number' && (
120
- <Delta displayValue={displayDeltaPercentage} deltaType={deltaType} />
121
- ),
122
- );
123
- }
126
+ return (
127
+ <>
128
+ <Table.Td className={valueClassName}>
129
+ <Metric value={displayValue} />
130
+ </Table.Td>
131
+ {!isBaseline && typeof deltaPercentage === 'number' && (
132
+ <Table.Td className={styles.delta}>
133
+ <Delta displayValue={displayDeltaPercentage} deltaType={deltaType} />
134
+ </Table.Td>
135
+ )}
136
+ </>
137
+ );
138
+ })}
139
+ </Table.Tr>
140
+ );
124
141
 
125
- return cells;
142
+ MetricsTableRow.propTypes = {
143
+ item: PropTypes.shape({
144
+ changed: PropTypes.bool,
145
+ runs: PropTypes.arrayOf(
146
+ PropTypes.shape({
147
+ value: PropTypes.number,
148
+ displayValue: PropTypes.string,
149
+ deltaPercentage: PropTypes.number,
150
+ displayDeltaPercentage: PropTypes.string,
151
+ deltaType: PropTypes.string,
152
+ }),
153
+ ),
154
+ }).isRequired,
155
+ renderRowHeader: PropTypes.func.isRequired,
126
156
  };
127
157
 
128
- const getRows = (runs, items, renderRowHeader) =>
129
- items.map((item, index) => {
130
- const { changed } = item;
131
-
132
- return {
133
- key: item?.key || index,
134
- className: changed ? '' : styles.unchanged,
135
- cells: [
136
- // Metric name
137
- renderRowHeader(item),
138
-
139
- // Metric item values
140
- ...item.runs.map(generateRowCells).flat(),
141
- ],
142
- };
143
- });
144
-
145
158
  export const MetricsTable = ({
146
159
  className,
147
160
  renderRowHeader,
@@ -151,9 +164,11 @@ export const MetricsTable = ({
151
164
  showHeaderSum,
152
165
  headerRows,
153
166
  title,
167
+ ...restProps
154
168
  }) => {
155
169
  const { headers, columnClassNames } = useMemo(() => {
156
170
  const headerColumns = getHeaderRows(runs, items, showHeaderSum, title);
171
+
157
172
  return {
158
173
  headers: [...headerRows, ...headerColumns],
159
174
  // First header row has the column class names
@@ -161,8 +176,6 @@ export const MetricsTable = ({
161
176
  };
162
177
  }, [headerRows, runs, items, showHeaderSum, title]);
163
178
 
164
- const rows = useMemo(() => getRows(runs, items, renderRowHeader), [runs, items, renderRowHeader]);
165
-
166
179
  const rootClassName = cx(
167
180
  styles.root,
168
181
  className,
@@ -171,7 +184,7 @@ export const MetricsTable = ({
171
184
  );
172
185
 
173
186
  return (
174
- <Table className={rootClassName} compact>
187
+ <Table className={rootClassName} compact {...restProps}>
175
188
  <Table.THead>
176
189
  {headers.map((headerRow) => {
177
190
  const { cells, className: rowClassName } = headerRow.cells
@@ -188,13 +201,9 @@ export const MetricsTable = ({
188
201
  })}
189
202
  </Table.THead>
190
203
  <Table.TBody>
191
- {!isEmpty(rows) ? (
192
- rows.map(({ key, className: rowClassName, cells }) => (
193
- <Table.Tr key={key} className={rowClassName}>
194
- {cells.map((cell, index) => (
195
- <Table.Td className={columnClassNames[index]}>{cell}</Table.Td>
196
- ))}
197
- </Table.Tr>
204
+ {!isEmpty(items) ? (
205
+ items.map((item) => (
206
+ <MetricsTableRow key={item.key} item={item} renderRowHeader={renderRowHeader} />
198
207
  ))
199
208
  ) : (
200
209
  <Table.Tr>
@@ -1,11 +1,11 @@
1
- .jobName a {
1
+ .root a {
2
2
  color: inherit;
3
3
  text-decoration: none;
4
4
  }
5
5
 
6
- .jobName a:hover,
7
- .jobName a:active,
8
- .jobName a:focus {
6
+ .root a:hover,
7
+ .root a:active,
8
+ .root a:focus {
9
9
  color: var(--color-primary);
10
10
  text-decoration: underline;
11
11
  }
@@ -15,21 +15,31 @@
15
15
  width: 100%;
16
16
  }
17
17
 
18
- .value {
18
+ .root .value {
19
19
  padding-left: var(--space-large);
20
20
  text-align: right;
21
+ vertical-align: baseline;
21
22
  }
22
23
 
23
- .delta {
24
+ .root .delta {
24
25
  padding-left: 0;
25
26
  text-align: left;
26
27
  font-size: var(--size-xsmall);
28
+ vertical-align: baseline;
27
29
  }
28
30
 
29
- .value.current {
31
+ .root tbody .delta {
32
+ line-height: 1.6rem; /* baseline alignment with the value */
33
+ }
34
+
35
+ .root .value.current {
30
36
  padding-right: var(--space-xxsmall);
31
37
  }
32
38
 
39
+ .jobName {
40
+ white-space: nowrap;
41
+ }
42
+
33
43
  /* columns overrides for showHeaderSum */
34
44
  .showHeaderSum .headerRowColumns .value,
35
45
  .showHeaderSum .headerRowColumns .delta {
@@ -45,6 +55,7 @@
45
55
  }
46
56
 
47
57
  /** rows */
58
+ .multipleRuns .unchanged th,
48
59
  .multipleRuns .unchanged td {
49
60
  color: var(--color-text-light);
50
61
  }
@@ -20,7 +20,7 @@ export const ModuleInfo = (props) => {
20
20
  } = props;
21
21
 
22
22
  return (
23
- <Stack space="small" className={className}>
23
+ <Stack space="xsmall" className={className}>
24
24
  {item.runs.map((run, index) => {
25
25
  const TitleComponent = index !== 0 ? 'h4' : 'h3';
26
26
  const key = `module-info-${run?.name || index}-${index}`;
@@ -30,7 +30,7 @@ export const ModuleInfo = (props) => {
30
30
  <TitleComponent>{labels[index]}</TitleComponent>
31
31
  {index === 0 && !isEmpty(run?.chunkIds) && (
32
32
  <div className={css.chunks}>
33
- <strong className={css.chunksTitle}>Chunks:</strong>
33
+ <span className={css.chunksTitle}>Chunks:</span>
34
34
  {run.chunkIds.map((chunkId) => {
35
35
  const chunk = find(chunks, { id: chunkId });
36
36
 
@@ -7,8 +7,11 @@ const ACTION_RESET_DEFAULT = 'RESET_DEFAULT';
7
7
  const ACTION_RESET_ALL = 'RESET_ALL';
8
8
  const ACTION_SET = 'SET';
9
9
 
10
+ const SEARCH_DEFAULT = '';
11
+ const SEARCH_DEFAULT_PATTERN = /.*/;
12
+
10
13
  const getSearchPattern = (search) => {
11
- let searchPattern = /.*/;
14
+ let searchPattern = SEARCH_DEFAULT_PATTERN;
12
15
 
13
16
  if (!search || !search.trim()) {
14
17
  return searchPattern;
@@ -31,52 +34,51 @@ const getSearchReducer =
31
34
 
32
35
  switch (type) {
33
36
  case ACTION_SET_FILTERS: {
34
- setParentState({
37
+ const newState = {
35
38
  filters: payload,
36
39
  search: state.search,
37
- });
38
-
39
- return {
40
- ...state,
41
- filters: payload,
42
40
  };
41
+ setParentState(newState);
42
+ return newState;
43
43
  }
44
44
 
45
45
  case ACTION_SET_SEARCH: {
46
- setParentState({
46
+ const newState = {
47
47
  filters: state.filters,
48
48
  search: payload,
49
- });
49
+ };
50
+
51
+ setParentState(newState);
50
52
 
51
53
  return {
52
- ...state,
53
- search: payload,
54
+ ...newState,
54
55
  searchPattern: getSearchPattern(payload),
55
56
  };
56
57
  }
57
58
 
58
59
  case ACTION_RESET_DEFAULT: {
59
- setParentState({
60
+ const newState = {
60
61
  filters: defaultFilters,
61
- search: '',
62
- });
62
+ search: SEARCH_DEFAULT,
63
+ };
64
+
65
+ setParentState(newState);
63
66
 
64
67
  return {
65
- filters: defaultFilters,
66
- search: '',
68
+ ...newState,
67
69
  searchPattern: getSearchPattern(),
68
70
  };
69
71
  }
70
72
 
71
73
  case ACTION_RESET_ALL: {
72
- setParentState({
74
+ const newState = {
73
75
  filters: allEntriesFilters,
74
- search: '',
75
- });
76
+ search: SEARCH_DEFAULT,
77
+ };
78
+ setParentState(newState);
76
79
 
77
80
  return {
78
- filters: allEntriesFilters,
79
- search: '',
81
+ ...newState,
80
82
  searchPattern: getSearchPattern(),
81
83
  };
82
84
  }
@@ -97,7 +99,7 @@ export const generateState = (filters, search) => ({
97
99
  });
98
100
 
99
101
  export const useSearchParams = ({
100
- search: parentSearch,
102
+ search: parentSearch = SEARCH_DEFAULT,
101
103
 
102
104
  filters: parentFilters,
103
105
  defaultFilters,
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
 
4
+ import { Stack } from '../../layout/stack';
4
5
  import I18N from '../../i18n';
5
6
  import css from './empty-set.module.css';
6
7
 
@@ -9,30 +10,33 @@ export const EmptySet = (props) => {
9
10
 
10
11
  const message = filtered ? `No ${resources} found.` : `No ${resources} available.`;
11
12
  const actions = [
12
- ...handleResetFilters ? [
13
- (
14
- <button className={css.action} type="button" onClick={handleResetFilters}>
15
- {I18N.RESET_FILTERS}
16
- </button>
17
- )
18
- ] : [],
19
- ...handleViewAll ? [(
20
- <button className={css.action} type="button" onClick={handleViewAll}>
21
- {I18N.VIEW_ALL}
22
- </button>
23
- )] : [],
13
+ ...(handleResetFilters
14
+ ? [
15
+ <button className={css.action} type="button" onClick={handleResetFilters}>
16
+ {I18N.RESET_FILTERS}
17
+ </button>,
18
+ ]
19
+ : []),
20
+ ...(handleViewAll
21
+ ? [
22
+ <button className={css.action} type="button" onClick={handleViewAll}>
23
+ {I18N.VIEW_ALL}
24
+ </button>,
25
+ ]
26
+ : []),
24
27
  ];
25
28
 
26
29
  return (
27
- <div className={css.root}>
28
- <p className={css.text}>{message}</p>
29
- {filtered && actions.map((action, index) => (
30
- <>
31
- {index > 0 && ' or '}
32
- {action}
33
- </>
34
- ))}
35
- </div>
30
+ <Stack space="xxsmall" className={css.root}>
31
+ <p>{message}</p>
32
+ {filtered &&
33
+ actions.map((action, index) => (
34
+ <>
35
+ {index > 0 && ' or '}
36
+ {action}
37
+ </>
38
+ ))}
39
+ </Stack>
36
40
  );
37
41
  };
38
42
 
@@ -1,5 +1,5 @@
1
- .text {
2
- margin-bottom: 0;
1
+ .root {
2
+ color: var(--color-text-light);
3
3
  }
4
4
 
5
5
  .action {
@@ -24,21 +24,13 @@ const resolveComponent = (as, href) => {
24
24
  };
25
25
 
26
26
  export const HoverCard = (props) => {
27
- const { className, href, as, label, children } = props;
27
+ const { className, hoverCardClassName, href, as, label, children } = props;
28
28
  const state = useHovercardState({ gutter: 8 });
29
29
  const hoverCardProps = useHovercard({ state, portal: true });
30
30
 
31
31
  // Fallback to span if no href
32
32
  const Component = resolveComponent(as, href);
33
33
 
34
- const handleOnClose = useCallback(
35
- (event) => {
36
- state.hide();
37
- event.preventDefault();
38
- },
39
- [state],
40
- );
41
-
42
34
  return (
43
35
  <div className={cx(css.root, className)}>
44
36
  <HovercardAnchor state={state} href={href} className={css.anchor} as={Component}>
@@ -47,7 +39,7 @@ export const HoverCard = (props) => {
47
39
  <Hovercard
48
40
  {...hoverCardProps}
49
41
  state={state}
50
- className={css.hoverCard}
42
+ className={cx(css.hoverCard, hoverCardClassName)}
51
43
  style={{ zIndex: 10000 }}
52
44
  >
53
45
  <HovercardArrow size={24} />
@@ -60,6 +52,8 @@ export const HoverCard = (props) => {
60
52
  HoverCard.propTypes = {
61
53
  /** Adopted child class name */
62
54
  className: PropTypes.string,
55
+ /** Adopted child class name for hover card */
56
+ hoverCardClassName: PropTypes.string,
63
57
  /** Anchor label */
64
58
  label: PropTypes.node,
65
59
  /** Anchor href */
@@ -72,6 +66,7 @@ HoverCard.propTypes = {
72
66
 
73
67
  HoverCard.defaultProps = {
74
68
  className: '',
69
+ hoverCardClassName: '',
75
70
  label: '',
76
71
  as: '',
77
72
  href: '',
@@ -8,20 +8,19 @@
8
8
  text-decoration: none;
9
9
  }
10
10
 
11
- a.anchor,
12
- buton.anchor {
13
- cursor: pointer;
11
+ .anchor:hover {
12
+ color: var(--color-primary);
14
13
  }
15
14
 
16
- a.anchor:hover,
17
- button.anchor:hover {
18
- text-decoration: underline;
15
+ .anchor:focus {
16
+ outline: 0;
19
17
  }
20
18
 
21
19
  .hoverCard {
22
20
  padding: var(--space-xsmall) var(--space-small);
23
21
  border-radius: var(--radius-medium);
24
- max-width: 320px;
22
+ width: calc(100vw - 2 * var(--space-small));
23
+ max-width: 360px;
25
24
  outline: none;
26
25
  filter: drop-shadow(0 0 var(--space-xxsmall) var(--color-shadow));
27
26
  will-change: filter;
@@ -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: '',
@@ -4,48 +4,51 @@
4
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
+ padding: var(--space-small);
14
15
  }
15
16
 
16
- .root thead .cell {
17
+ .root thead th {
17
18
  border-width: 0 0 1px;
18
19
  text-transform: uppercase;
19
20
  vertical-align: top;
20
21
  background: var(--color-highlight);
21
22
  }
22
23
 
23
- .root thead .cell:empty {
24
+ .root thead th:empty {
24
25
  display: none;
25
26
  }
26
27
 
27
- .root tbody .cell {
28
+ .root tbody th {
28
29
  font-weight: normal;
29
30
  }
30
31
 
31
- .root tbody tr:first-child .cell {
32
+ .root tbody tr:first-child td,
33
+ .root tbody tr:first-child th {
32
34
  border-top: 0;
33
35
  }
34
36
 
35
- .root tbody .cell a {
37
+ .root tbody td a {
36
38
  color: inherit;
37
39
  text-decoration: none;
38
40
  }
39
41
 
40
- .root tbody .cell a:hover,
41
- .root tbody .cell a:focus,
42
- .root tbody .cell a:active
42
+ .root tbody td a:hover,
43
+ .root tbody td a:focus,
44
+ .root tbody td a:active
43
45
  {
44
46
  color: var(--color-primary);
45
47
  text-decoration: underline;
46
48
  }
47
49
 
48
- .root tbody tr:hover .cell {
50
+ .root tbody tr:hover th,
51
+ .root tbody tr:hover td {
49
52
  background-color: var(--color-highlight-warning);
50
53
  }
51
54
 
@@ -64,21 +67,21 @@
64
67
  border-radius: var(--table-radius);
65
68
  }
66
69
 
67
- .outline thead tr:first-child .cell:first-child,
68
- .outline tbody:first-child tr:first-child .cell:first-child {
70
+ .outline thead:first-child tr:first-child th:first-child,
71
+ .outline tbody:first-child tr:first-child td:first-child {
69
72
  border-top-left-radius: var(--table-radius);
70
73
  }
71
74
 
72
- .outline thead tr:first-child .cell:last-child,
73
- .outline tbody:first-child tr:first-child .cell:last-child {
75
+ .outline thead tr:first-child th:last-child,
76
+ .outline tbody:first-child tr:first-child td:last-child {
74
77
  border-top-right-radius: var(--table-radius);
75
78
  }
76
79
 
77
- .outline tbody:last-child tr:last-child .cell:first-child {
80
+ .outline tbody:last-child tr:last-child td:first-child {
78
81
  border-bottom-left-radius: var(--table-radius);
79
82
  }
80
83
 
81
- .outline tbody:last-child tr:last-child .cell:last-child {
84
+ .outline tbody:last-child tr:last-child td:last-child {
82
85
  border-bottom-right-radius: var(--table-radius);
83
86
  }
84
87
 
@@ -87,7 +90,8 @@
87
90
  }
88
91
 
89
92
  /* compact variation */
90
- .compact .cell {
93
+ .compact td,
94
+ .compact th {
91
95
  padding-top: var(--space-xsmall);
92
96
  padding-bottom: var(--space-xsmall);
93
97
  }
@@ -16,6 +16,7 @@
16
16
  background: var(--color-light);
17
17
  color: var(--color-text);
18
18
  filter: drop-shadow(0 0 var(--space-xxxsmall) var(--color-shadow));
19
+ will-change: filter;
19
20
  font-size: var(--size-xsmall);
20
21
  line-height: var(--space-small);
21
22
  }