@bundle-stats/ui 4.0.3 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/metric/metric.js +40 -25
- package/lib/components/metric/metric.module.css +4 -14
- package/lib/components/summary-item/summary-item.js +18 -5
- package/lib/components/summary-item/summary-item.module.css +0 -9
- package/lib/ui/dropdown/dropdown.module.css +3 -2
- package/lib/ui/filters/filters.js +11 -8
- package/lib/ui/filters/filters.module.css +11 -12
- package/lib/ui/hover-card/hover-card.js +3 -8
- package/lib/ui/skeleton/skeleton.js +11 -5
- package/lib/ui/skeleton/skeleton.module.css +6 -2
- package/lib/ui/skeleton/skeleton.stories.js +48 -9
- package/lib/ui/sort-dropdown/sort-dropdown.js +90 -30
- package/lib/ui/sort-dropdown/sort-dropdown.module.css +5 -3
- package/lib-esm/components/metric/metric.js +40 -15
- package/lib-esm/components/metric/metric.module.css +4 -14
- package/lib-esm/components/summary-item/summary-item.js +12 -3
- package/lib-esm/components/summary-item/summary-item.module.css +0 -9
- package/lib-esm/ui/dropdown/dropdown.module.css +3 -2
- package/lib-esm/ui/filters/filters.js +9 -7
- package/lib-esm/ui/filters/filters.module.css +11 -12
- package/lib-esm/ui/hover-card/hover-card.js +3 -8
- package/lib-esm/ui/skeleton/skeleton.js +10 -4
- package/lib-esm/ui/skeleton/skeleton.module.css +6 -2
- package/lib-esm/ui/skeleton/skeleton.stories.js +32 -5
- package/lib-esm/ui/sort-dropdown/sort-dropdown.js +72 -23
- package/lib-esm/ui/sort-dropdown/sort-dropdown.module.css +5 -3
- package/package.json +5 -5
- package/src/components/metric/metric.jsx +32 -24
- package/src/components/metric/metric.module.css +4 -14
- package/src/components/summary-item/summary-item.jsx +26 -16
- package/src/components/summary-item/summary-item.module.css +0 -9
- package/src/ui/dropdown/dropdown.module.css +3 -2
- package/src/ui/filters/filters.jsx +24 -18
- package/src/ui/filters/filters.module.css +11 -12
- package/src/ui/hover-card/hover-card.jsx +1 -6
- package/src/ui/skeleton/skeleton.jsx +7 -3
- package/src/ui/skeleton/skeleton.module.css +6 -2
- package/src/ui/sort-dropdown/sort-dropdown.jsx +70 -27
- package/src/ui/sort-dropdown/sort-dropdown.module.css +5 -3
|
@@ -1,11 +1,67 @@
|
|
|
1
1
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
2
|
|
|
3
|
-
import React from 'react';
|
|
3
|
+
import React, { useMemo } from 'react';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import cx from 'classnames';
|
|
6
6
|
import { Dropdown } from '../dropdown';
|
|
7
7
|
import { Icon } from '../icon';
|
|
8
8
|
import css from './sort-dropdown.module.css';
|
|
9
|
+
|
|
10
|
+
const Item = _ref => {
|
|
11
|
+
let {
|
|
12
|
+
className,
|
|
13
|
+
as: Component,
|
|
14
|
+
id,
|
|
15
|
+
label,
|
|
16
|
+
active,
|
|
17
|
+
direction,
|
|
18
|
+
defaultDirection,
|
|
19
|
+
getButtonOnClick,
|
|
20
|
+
...restProps
|
|
21
|
+
} = _ref;
|
|
22
|
+
const buttonProps = useMemo(() => {
|
|
23
|
+
let resolveNextDirection = defaultDirection;
|
|
24
|
+
|
|
25
|
+
if (active) {
|
|
26
|
+
resolveNextDirection = direction === 'asc' ? 'desc' : 'asc';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (resolveNextDirection === 'desc') {
|
|
30
|
+
return {
|
|
31
|
+
className: css.itemAsc,
|
|
32
|
+
onClick: getButtonOnClick(id, 'desc'),
|
|
33
|
+
title: `Order data by ${label} descending`
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
onClick: getButtonOnClick(id, 'asc'),
|
|
39
|
+
title: `Order data by ${label} ascending`
|
|
40
|
+
};
|
|
41
|
+
}, [active, direction, defaultDirection, id, label]);
|
|
42
|
+
return /*#__PURE__*/React.createElement(Component, _extends({}, restProps, buttonProps, {
|
|
43
|
+
className: cx(className, css.item, active && css.itemActive, buttonProps.className)
|
|
44
|
+
}), /*#__PURE__*/React.createElement(Icon, {
|
|
45
|
+
className: css.itemIcon,
|
|
46
|
+
glyph: "arrow"
|
|
47
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
48
|
+
className: css.itemLabel
|
|
49
|
+
}, label));
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
Item.propTypes = {
|
|
53
|
+
className: PropTypes.string,
|
|
54
|
+
as: PropTypes.element.isRequired,
|
|
55
|
+
id: PropTypes.string.isRequired,
|
|
56
|
+
label: PropTypes.string.isRequired,
|
|
57
|
+
active: PropTypes.bool.isRequired,
|
|
58
|
+
direction: PropTypes.string.isRequired,
|
|
59
|
+
defaultDirection: PropTypes.string.isRequired,
|
|
60
|
+
getButtonOnClick: PropTypes.func.isRequired
|
|
61
|
+
};
|
|
62
|
+
Item.defaultProps = {
|
|
63
|
+
className: ''
|
|
64
|
+
};
|
|
9
65
|
export const SortDropdown = props => {
|
|
10
66
|
const {
|
|
11
67
|
className,
|
|
@@ -22,13 +78,13 @@ export const SortDropdown = props => {
|
|
|
22
78
|
label: customLabel,
|
|
23
79
|
glyph: "sort",
|
|
24
80
|
align: "right"
|
|
25
|
-
},
|
|
81
|
+
}, _ref2 => {
|
|
26
82
|
let {
|
|
27
83
|
MenuItem,
|
|
28
84
|
menu,
|
|
29
85
|
menuItemClassName,
|
|
30
86
|
menuItemActiveClassName
|
|
31
|
-
} =
|
|
87
|
+
} = _ref2;
|
|
32
88
|
|
|
33
89
|
const getButtonOnClick = (newField, newDirection) => () => {
|
|
34
90
|
onChange({
|
|
@@ -40,27 +96,20 @@ export const SortDropdown = props => {
|
|
|
40
96
|
|
|
41
97
|
return /*#__PURE__*/React.createElement("div", {
|
|
42
98
|
className: css.items
|
|
43
|
-
}, Object.entries(fields).map(
|
|
44
|
-
let [key, item] =
|
|
45
|
-
const buttonProps = direction === 'asc' ? {
|
|
46
|
-
className: css.itemAsc,
|
|
47
|
-
onClick: getButtonOnClick(key, 'desc'),
|
|
48
|
-
title: `Order data by ${item.label} descending`
|
|
49
|
-
} : {
|
|
50
|
-
onClick: getButtonOnClick(key, 'asc'),
|
|
51
|
-
title: `Order data by ${item.label} ascending`
|
|
52
|
-
};
|
|
99
|
+
}, Object.entries(fields).map(_ref3 => {
|
|
100
|
+
let [key, item] = _ref3;
|
|
53
101
|
const isActive = field === key;
|
|
54
|
-
return /*#__PURE__*/React.createElement(
|
|
55
|
-
key: key
|
|
56
|
-
|
|
57
|
-
className: cx(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
102
|
+
return /*#__PURE__*/React.createElement(Item, {
|
|
103
|
+
key: key,
|
|
104
|
+
as: MenuItem,
|
|
105
|
+
className: cx(menuItemClassName, isActive && menuItemActiveClassName),
|
|
106
|
+
id: key,
|
|
107
|
+
label: item.label,
|
|
108
|
+
direction: direction,
|
|
109
|
+
defaultDirection: item.defaultDirection,
|
|
110
|
+
active: isActive,
|
|
111
|
+
getButtonOnClick: getButtonOnClick
|
|
112
|
+
});
|
|
64
113
|
}));
|
|
65
114
|
});
|
|
66
115
|
};
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
.itemIcon {
|
|
7
|
-
|
|
7
|
+
flex: 0 0 auto;
|
|
8
|
+
visibility: hidden;
|
|
9
|
+
margin-right: var(--space-xxxsmall);
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
.itemLabel {
|
|
@@ -15,6 +17,6 @@
|
|
|
15
17
|
transform: rotate(180deg);
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
.
|
|
19
|
-
|
|
20
|
+
.itemActive .itemIcon {
|
|
21
|
+
visibility: visible;
|
|
20
22
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bundle-stats/ui",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.5",
|
|
4
4
|
"description": "UI components for BundleStats projects.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib-esm/index.js",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"babel-jest": "28.1.3",
|
|
55
55
|
"babel-plugin-lodash": "3.3.4",
|
|
56
56
|
"babel-plugin-require-context-hook": "1.0.0",
|
|
57
|
-
"chromatic": "6.7.
|
|
57
|
+
"chromatic": "6.7.2",
|
|
58
58
|
"classnames": "2.3.1",
|
|
59
59
|
"colormap": "2.3.2",
|
|
60
|
-
"core-js": "3.24.
|
|
60
|
+
"core-js": "3.24.1",
|
|
61
61
|
"cross-env": "7.0.3",
|
|
62
62
|
"enzyme": "3.11.0",
|
|
63
63
|
"enzyme-adapter-react-16": "1.15.6",
|
|
@@ -85,12 +85,12 @@
|
|
|
85
85
|
"react-router-dom": "^5.0.0"
|
|
86
86
|
},
|
|
87
87
|
"dependencies": {
|
|
88
|
-
"@bundle-stats/utils": "^4.0.
|
|
88
|
+
"@bundle-stats/utils": "^4.0.5",
|
|
89
89
|
"ariakit": "^2.0.0-next.33",
|
|
90
90
|
"date-fns": "^2.28.0",
|
|
91
91
|
"modern-css-reset": "^1.4.0",
|
|
92
92
|
"query-string": "^7.1.0",
|
|
93
93
|
"use-query-params": "^1.2.3"
|
|
94
94
|
},
|
|
95
|
-
"gitHead": "
|
|
95
|
+
"gitHead": "ead8c6d4de77aaa3eb9043054eba5429a1afc04a"
|
|
96
96
|
}
|
|
@@ -1,42 +1,51 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import cx from 'classnames';
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import css from './metric.module.css';
|
|
6
6
|
|
|
7
7
|
// Separate value and unit
|
|
8
8
|
const EXTRACT_VALUE_UNIT_PATTERN = /([\d|.|,| ]*)(\w*|%)$/;
|
|
9
9
|
|
|
10
|
-
export const Metric = ({ className, value, formatter, inline,
|
|
11
|
-
const
|
|
10
|
+
export const Metric = ({ className, value, formatter, inline, children, enhanced }) => {
|
|
11
|
+
const { displayValue, displayUnit } = useMemo(() => {
|
|
12
|
+
const formattedValue = formatter?.(value);
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
? formattedValue.match(EXTRACT_VALUE_UNIT_PATTERN)
|
|
17
|
-
: [null, formattedValue, null];
|
|
14
|
+
if (!formattedValue) {
|
|
15
|
+
return { displayValue: value };
|
|
16
|
+
}
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
if (!enhanced) {
|
|
19
|
+
return { displayValue: formattedValue };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const matches = formattedValue.match(EXTRACT_VALUE_UNIT_PATTERN);
|
|
23
|
+
|
|
24
|
+
if (!matches) {
|
|
25
|
+
return { displayValue: value };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
displayUnit: matches[2],
|
|
30
|
+
displayValue: matches[1],
|
|
31
|
+
};
|
|
32
|
+
}, [formatter, value]);
|
|
33
|
+
|
|
34
|
+
const rootClassName = cx(className, css.root, inline && css.inline);
|
|
25
35
|
|
|
26
36
|
return (
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
<span className={
|
|
30
|
-
{displayUnit && <span className={
|
|
31
|
-
</
|
|
32
|
-
<
|
|
33
|
-
</
|
|
37
|
+
<div className={rootClassName}>
|
|
38
|
+
<div className={css.display}>
|
|
39
|
+
<span className={css.displayValue}>{displayValue}</span>
|
|
40
|
+
{displayUnit && <span className={css.displayUnit}>{displayUnit}</span>}
|
|
41
|
+
</div>
|
|
42
|
+
<div className={css.delta}>{children}</div>
|
|
43
|
+
</div>
|
|
34
44
|
);
|
|
35
45
|
};
|
|
36
46
|
|
|
37
47
|
Metric.defaultProps = {
|
|
38
48
|
className: '',
|
|
39
|
-
anchored: false,
|
|
40
49
|
enhanced: false,
|
|
41
50
|
inline: false,
|
|
42
51
|
value: 0,
|
|
@@ -48,7 +57,6 @@ Metric.propTypes = {
|
|
|
48
57
|
className: PropTypes.string,
|
|
49
58
|
enhanced: PropTypes.bool,
|
|
50
59
|
inline: PropTypes.bool,
|
|
51
|
-
anchored: PropTypes.bool,
|
|
52
60
|
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
53
61
|
formatter: PropTypes.func,
|
|
54
62
|
children: PropTypes.node,
|
|
@@ -1,27 +1,17 @@
|
|
|
1
1
|
.root {
|
|
2
|
-
display: block;
|
|
3
2
|
letter-spacing: 0.05em;
|
|
4
3
|
}
|
|
5
4
|
|
|
6
5
|
.displayUnit {
|
|
7
|
-
|
|
6
|
+
font-size: var(--size-small);
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
.delta {
|
|
11
|
-
|
|
12
|
-
font-size: var(--size-xsmall);
|
|
10
|
+
font-size: var(--size-small);
|
|
13
11
|
}
|
|
14
12
|
|
|
15
|
-
.
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.anchored .delta {
|
|
20
|
-
position: absolute;
|
|
21
|
-
right: 0;
|
|
22
|
-
top: 100%;
|
|
23
|
-
line-height: 1;
|
|
24
|
-
margin-top: -2px;
|
|
13
|
+
.inline .display {
|
|
14
|
+
display: inline-block;
|
|
25
15
|
}
|
|
26
16
|
|
|
27
17
|
.inline .delta {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import cx from 'classnames';
|
|
4
4
|
import { getGlobalMetricType, getMetricRunInfo } from '@bundle-stats/utils';
|
|
@@ -10,18 +10,28 @@ import { Metric } from '../metric';
|
|
|
10
10
|
import { Delta } from '../delta';
|
|
11
11
|
import css from './summary-item.module.css';
|
|
12
12
|
|
|
13
|
-
const MetricInfo = ({ description, url }) =>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
13
|
+
const MetricInfo = ({ description, url }) => {
|
|
14
|
+
// The component parent can be rendered inside an anchor tag, using button
|
|
15
|
+
// to avoid using nesting links
|
|
16
|
+
const onClick = useCallback(() => {
|
|
17
|
+
if (url) {
|
|
18
|
+
window.open(url);
|
|
19
|
+
}
|
|
20
|
+
}, [url]);
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Stack space="xxxsmall">
|
|
24
|
+
<p>{description}</p>
|
|
25
|
+
{url && (
|
|
26
|
+
<p>
|
|
27
|
+
<button type="button" onClick={onClick} className={css.readMoreLink}>
|
|
28
|
+
Read more
|
|
29
|
+
</button>
|
|
30
|
+
</p>
|
|
31
|
+
)}
|
|
32
|
+
</Stack>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
25
35
|
|
|
26
36
|
MetricInfo.propTypes = {
|
|
27
37
|
description: PropTypes.string.isRequired,
|
|
@@ -52,7 +62,7 @@ export const SummaryItem = ({
|
|
|
52
62
|
const rootClassName = cx(css.root, className, css[size], showDelta && css.showDelta);
|
|
53
63
|
|
|
54
64
|
return (
|
|
55
|
-
<Stack space="
|
|
65
|
+
<Stack space="xxxsmall" as={Component} className={rootClassName} {...props}>
|
|
56
66
|
<h3 className={css.title}>
|
|
57
67
|
{showMetricDescriptionTooltip ? (
|
|
58
68
|
<HoverCard label={metric.label}>
|
|
@@ -84,8 +94,8 @@ export const SummaryItem = ({
|
|
|
84
94
|
</Stack>
|
|
85
95
|
) : (
|
|
86
96
|
<Stack>
|
|
87
|
-
<Skeleton className={cx(css.currentMetric, css.loading)} />
|
|
88
|
-
<Skeleton className={cx(css.baselineMetric, css.loading)} />
|
|
97
|
+
<Skeleton as="p" className={cx(css.currentMetric, css.loading)} />
|
|
98
|
+
<Skeleton as="p" className={cx(css.baselineMetric, css.loading)} />
|
|
89
99
|
</Stack>
|
|
90
100
|
)}
|
|
91
101
|
</Stack>
|
|
@@ -8,23 +8,15 @@
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
.currentMetric {
|
|
11
|
-
display: block;
|
|
12
11
|
color: var(--color-heading);
|
|
13
12
|
font-size: var(--size-xlarge);
|
|
14
|
-
line-height: var(--space-medium);
|
|
15
13
|
white-space: nowrap;
|
|
16
14
|
font-weight: bold;
|
|
17
15
|
}
|
|
18
16
|
|
|
19
|
-
.delta {
|
|
20
|
-
font-size: var(--size-small);
|
|
21
|
-
line-height: var(--space-medium);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
17
|
.baselineMetric {
|
|
25
18
|
color: var(--color-text-light);
|
|
26
19
|
font-size: var(--size-small);
|
|
27
|
-
line-height: var(--space-small);
|
|
28
20
|
}
|
|
29
21
|
|
|
30
22
|
.readMoreLink {
|
|
@@ -63,5 +55,4 @@
|
|
|
63
55
|
/* Size large */
|
|
64
56
|
.large .currentMetric {
|
|
65
57
|
font-size: var(--size-xxxlarge);
|
|
66
|
-
line-height: var(--space-medium);
|
|
67
58
|
}
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
background: var(--color-background);
|
|
41
41
|
min-width: 180px;
|
|
42
42
|
z-index: var(--layer-high);
|
|
43
|
-
padding: var(--space-
|
|
43
|
+
padding: var(--space-xxsmall) 0;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
.dropdown:focus {
|
|
@@ -55,12 +55,13 @@
|
|
|
55
55
|
width: 100%;
|
|
56
56
|
outline: none;
|
|
57
57
|
border: 0;
|
|
58
|
-
padding: var(--space-xxxsmall) var(--space-
|
|
58
|
+
padding: var(--space-xxxsmall) var(--space-xsmall);
|
|
59
59
|
background: none;
|
|
60
60
|
text-align: left;
|
|
61
61
|
color: var(--color-text-light);
|
|
62
62
|
font-size: var(--size-small);
|
|
63
63
|
line-height: inherit;
|
|
64
|
+
text-decoration: none;
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
.menuItem:hover {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import cx from 'classnames';
|
|
4
|
-
import { get } from 'lodash';
|
|
5
4
|
|
|
6
5
|
import { FlexStack } from '../../layout/flex-stack';
|
|
7
6
|
import { Dropdown } from '../dropdown';
|
|
@@ -9,13 +8,21 @@ import { getGroupFiltersLabelSuffix, LABELS } from './filters.utils';
|
|
|
9
8
|
import css from './filters.module.css';
|
|
10
9
|
|
|
11
10
|
const Filter = (props) => {
|
|
12
|
-
const {
|
|
13
|
-
|
|
11
|
+
const {
|
|
12
|
+
className,
|
|
13
|
+
as: Component = 'div',
|
|
14
|
+
buttonClassName,
|
|
15
|
+
label,
|
|
16
|
+
name,
|
|
17
|
+
getOnOnlyClick,
|
|
18
|
+
...inputProps
|
|
19
|
+
} = props;
|
|
14
20
|
|
|
21
|
+
const id = `filter-${name}`;
|
|
15
22
|
const rootClassName = cx(css.filter, className);
|
|
16
23
|
|
|
17
24
|
return (
|
|
18
|
-
<
|
|
25
|
+
<Component className={rootClassName}>
|
|
19
26
|
{/* eslint-disable */}
|
|
20
27
|
<FlexStack space="xxxsmall" as="label" className={cx(css.filterCheckbox, buttonClassName)}>
|
|
21
28
|
{/* eslint-enabled */}
|
|
@@ -30,12 +37,13 @@ const Filter = (props) => {
|
|
|
30
37
|
only
|
|
31
38
|
</button>
|
|
32
39
|
)}
|
|
33
|
-
</
|
|
40
|
+
</Component>
|
|
34
41
|
);
|
|
35
42
|
};
|
|
36
43
|
|
|
37
44
|
Filter.propTypes = {
|
|
38
45
|
className: PropTypes.string,
|
|
46
|
+
as: PropTypes.elementType,
|
|
39
47
|
buttonClassName: PropTypes.string,
|
|
40
48
|
name: PropTypes.string.isRequired,
|
|
41
49
|
label: PropTypes.string.isRequired,
|
|
@@ -44,6 +52,7 @@ Filter.propTypes = {
|
|
|
44
52
|
|
|
45
53
|
Filter.defaultProps = {
|
|
46
54
|
className: '',
|
|
55
|
+
as: 'div',
|
|
47
56
|
buttonClassName: '',
|
|
48
57
|
getOnOnlyClick: null,
|
|
49
58
|
};
|
|
@@ -105,20 +114,17 @@ const FilterGroup = (props) => {
|
|
|
105
114
|
const getOnOnlyClick = () => getOnGroupCheck(false, { [id]: true });
|
|
106
115
|
|
|
107
116
|
return (
|
|
108
|
-
<
|
|
117
|
+
<Filter
|
|
109
118
|
key={id}
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
getOnOnlyClick={getOnOnlyClick}
|
|
120
|
-
/>
|
|
121
|
-
</MenuItem>
|
|
119
|
+
className={menuItemClassName}
|
|
120
|
+
as={MenuItem}
|
|
121
|
+
name={id}
|
|
122
|
+
label={itemData.label}
|
|
123
|
+
onChange={onCheckboxChange}
|
|
124
|
+
checked={values[id]}
|
|
125
|
+
disabled={itemData.disabled}
|
|
126
|
+
getOnOnlyClick={getOnOnlyClick}
|
|
127
|
+
/>
|
|
122
128
|
);
|
|
123
129
|
})}
|
|
124
130
|
</div>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/* Checkbox + label + button */
|
|
2
2
|
.filter {
|
|
3
|
+
/* Update MenuItem padding */
|
|
4
|
+
padding-top: calc(var(--space-xxxsmall) / 2);
|
|
5
|
+
padding-bottom: calc(var(--space-xxxsmall) / 2);
|
|
6
|
+
|
|
3
7
|
position: relative;
|
|
4
8
|
width: 100%;
|
|
5
9
|
max-width: 240px;
|
|
@@ -11,7 +15,6 @@
|
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
.filterInput {
|
|
14
|
-
border-radius: var(--radius-small) 0 0 var(--radius-small);
|
|
15
18
|
flex: 0 0 auto;
|
|
16
19
|
height: 1em;
|
|
17
20
|
cursor: pointer;
|
|
@@ -26,17 +29,17 @@
|
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
.filterOnlyButton {
|
|
29
|
-
padding: var(--space-
|
|
32
|
+
padding: var(--space-xxxsmall) var(--space-xsmall);
|
|
30
33
|
display: none;
|
|
31
34
|
appearance: none;
|
|
32
35
|
border: none;
|
|
33
36
|
background: linear-gradient(90deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255) 30%);
|
|
34
37
|
cursor: pointer;
|
|
35
|
-
line-height: 1;
|
|
36
38
|
position: absolute;
|
|
37
39
|
right: 0;
|
|
38
|
-
top:
|
|
39
|
-
|
|
40
|
+
top: 0;
|
|
41
|
+
bottom: 0;
|
|
42
|
+
line-height: var(--space-xsmall);
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
/** filter disabled state */
|
|
@@ -63,6 +66,7 @@
|
|
|
63
66
|
|
|
64
67
|
/** Filter standard variation */
|
|
65
68
|
.filterStandalone {
|
|
69
|
+
padding: 0;
|
|
66
70
|
width: auto;
|
|
67
71
|
color: var(--color-text-light);
|
|
68
72
|
z-index: var(--layout-xlow); /* show collapsed border */
|
|
@@ -95,16 +99,11 @@
|
|
|
95
99
|
overflow: auto;
|
|
96
100
|
}
|
|
97
101
|
|
|
98
|
-
.filterGroupItem {
|
|
99
|
-
padding-top: 2px;
|
|
100
|
-
padding-bottom: 2px;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
102
|
.filterGroupActions {
|
|
104
|
-
margin-top: var(--space-
|
|
103
|
+
margin-top: var(--space-xxxsmall);
|
|
105
104
|
padding-top: var(--space-xxxsmall);
|
|
106
105
|
padding-bottom: var(--space-xxxsmall);
|
|
107
|
-
margin-bottom: calc(0px - var(--space-
|
|
106
|
+
margin-bottom: calc(0px - var(--space-xxsmall));
|
|
108
107
|
border-top: 1px solid var(--color-outline);
|
|
109
108
|
}
|
|
110
109
|
|
|
@@ -25,16 +25,12 @@ const resolveComponent = (as, href) => {
|
|
|
25
25
|
|
|
26
26
|
export const HoverCard = (props) => {
|
|
27
27
|
const { className, anchorClassName, hoverCardClassName, href, as, label, children } = props;
|
|
28
|
-
const state = useHovercardState({ gutter: 8 });
|
|
28
|
+
const state = useHovercardState({ gutter: 8, timeout: 700 });
|
|
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 handleOnClick = (event) => {
|
|
35
|
-
event.preventDefault();
|
|
36
|
-
};
|
|
37
|
-
|
|
38
34
|
return (
|
|
39
35
|
<div className={cx(css.root, className)}>
|
|
40
36
|
<HovercardAnchor
|
|
@@ -50,7 +46,6 @@ export const HoverCard = (props) => {
|
|
|
50
46
|
state={state}
|
|
51
47
|
className={cx(css.hoverCard, hoverCardClassName)}
|
|
52
48
|
style={{ zIndex: 10000 }}
|
|
53
|
-
onClick={handleOnClick}
|
|
54
49
|
>
|
|
55
50
|
<HovercardArrow size={24} />
|
|
56
51
|
{typeof children === 'function' ? children({ close: state.hide }) : children}
|
|
@@ -5,16 +5,20 @@ import cx from 'classnames';
|
|
|
5
5
|
import css from './skeleton.module.css';
|
|
6
6
|
|
|
7
7
|
export const Skeleton = (props) => {
|
|
8
|
-
const { className, ...restProps } = props;
|
|
9
|
-
const rootClassName = cx(css.root, className);
|
|
8
|
+
const { className, as: Component, block, ...restProps } = props;
|
|
9
|
+
const rootClassName = cx(css.root, className, block && css.block);
|
|
10
10
|
|
|
11
|
-
return <
|
|
11
|
+
return <Component className={rootClassName} {...restProps} />;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
Skeleton.propTypes = {
|
|
15
15
|
className: PropTypes.string,
|
|
16
|
+
as: PropTypes.elementType,
|
|
17
|
+
block: PropTypes.bool,
|
|
16
18
|
};
|
|
17
19
|
|
|
18
20
|
Skeleton.defaultProps = {
|
|
19
21
|
className: '',
|
|
22
|
+
as: 'p',
|
|
23
|
+
block: false,
|
|
20
24
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
.root {
|
|
2
|
-
|
|
3
|
-
background: linear-gradient(transparent 10%, currentColor 10.1%, currentColor 90%, transparent 90.1%);
|
|
2
|
+
background: linear-gradient(transparent 12.5%, currentColor 12.6%, currentColor 86.4%, transparent 86.5%);
|
|
4
3
|
opacity: 0.06;
|
|
5
4
|
pointer-events: none;
|
|
5
|
+
min-width: 6em;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
/** empty char to keep the text height */
|
|
@@ -11,3 +11,7 @@
|
|
|
11
11
|
content: '\A0';
|
|
12
12
|
color: transparent;
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
.block {
|
|
16
|
+
background: currentColor;
|
|
17
|
+
}
|