carbon-react 114.13.2 → 114.14.1
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/esm/components/link/link.component.js +7 -2
- package/esm/components/link/link.style.d.ts +1 -0
- package/esm/components/link/link.style.js +3 -4
- package/esm/components/select/filterable-select/filterable-select.component.js +15 -2
- package/esm/components/select/filterable-select/filterable-select.d.ts +7 -0
- package/esm/components/select/list-action-button/list-action-button.style.js +4 -1
- package/esm/components/select/multi-select/multi-select.component.js +15 -2
- package/esm/components/select/multi-select/multi-select.d.ts +7 -0
- package/esm/components/select/option/option.component.js +16 -5
- package/esm/components/select/option/option.style.js +4 -0
- package/esm/components/select/option-group-header/option-group-header.component.js +20 -8
- package/esm/components/select/option-group-header/option-group-header.style.js +3 -2
- package/esm/components/select/option-row/option-row.component.js +16 -5
- package/esm/components/select/option-row/option-row.style.js +4 -0
- package/esm/components/select/select-list/select-list-container.style.js +11 -1
- package/esm/components/select/select-list/select-list.component.js +136 -62
- package/esm/components/select/select-list/select-list.style.js +15 -18
- package/esm/components/select/simple-select/simple-select.component.js +15 -2
- package/esm/components/select/simple-select/simple-select.d.ts +7 -0
- package/lib/components/link/link.component.js +7 -1
- package/lib/components/link/link.style.d.ts +1 -0
- package/lib/components/link/link.style.js +3 -4
- package/lib/components/select/filterable-select/filterable-select.component.js +15 -2
- package/lib/components/select/filterable-select/filterable-select.d.ts +7 -0
- package/lib/components/select/list-action-button/list-action-button.style.js +4 -1
- package/lib/components/select/multi-select/multi-select.component.js +15 -2
- package/lib/components/select/multi-select/multi-select.d.ts +7 -0
- package/lib/components/select/option/option.component.js +16 -5
- package/lib/components/select/option/option.style.js +4 -0
- package/lib/components/select/option-group-header/option-group-header.component.js +20 -6
- package/lib/components/select/option-group-header/option-group-header.style.js +3 -2
- package/lib/components/select/option-row/option-row.component.js +16 -5
- package/lib/components/select/option-row/option-row.style.js +4 -0
- package/lib/components/select/select-list/select-list-container.style.js +11 -1
- package/lib/components/select/select-list/select-list.component.js +139 -63
- package/lib/components/select/select-list/select-list.style.js +15 -18
- package/lib/components/select/simple-select/simple-select.component.js +15 -2
- package/lib/components/select/simple-select/simple-select.d.ts +7 -0
- package/package.json +2 -1
- package/esm/components/select/select-list/update-list-scroll.js +0 -21
- package/lib/components/select/select-list/update-list-scroll.js +0 -28
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
function _extends() { _extends = Object.assign || 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, { useMemo } from "react";
|
|
3
|
+
import React, { useContext, useMemo } from "react";
|
|
4
4
|
import PropTypes from "prop-types";
|
|
5
5
|
import Icon from "../icon";
|
|
6
|
+
import MenuContext from "../menu/menu.context";
|
|
6
7
|
import Event from "../../__internal__/utils/helpers/events";
|
|
7
8
|
import { StyledLink, StyledContent } from "./link.style";
|
|
8
9
|
import tagComponent from "../../__internal__/utils/helpers/tags/tags";
|
|
@@ -29,6 +30,9 @@ const Link = /*#__PURE__*/React.forwardRef(({
|
|
|
29
30
|
...rest
|
|
30
31
|
}, ref) => {
|
|
31
32
|
const l = useLocale();
|
|
33
|
+
const {
|
|
34
|
+
inMenu
|
|
35
|
+
} = useContext(MenuContext);
|
|
32
36
|
|
|
33
37
|
const handleOnKeyDown = ev => {
|
|
34
38
|
if (onKeyDown) {
|
|
@@ -99,7 +103,8 @@ const Link = /*#__PURE__*/React.forwardRef(({
|
|
|
99
103
|
iconAlign: iconAlign,
|
|
100
104
|
hasContent: Boolean(children),
|
|
101
105
|
variant: variant,
|
|
102
|
-
isDarkBackground: isDarkBackground
|
|
106
|
+
isDarkBackground: isDarkBackground,
|
|
107
|
+
isMenuItem: inMenu
|
|
103
108
|
}, tagComponent("link", rest), isSkipLink && {
|
|
104
109
|
"data-element": "skip-link"
|
|
105
110
|
}), createLinkBasedOnType());
|
|
@@ -13,6 +13,7 @@ export interface StyledLinkProps {
|
|
|
13
13
|
}
|
|
14
14
|
interface PrivateStyledLinkProps {
|
|
15
15
|
hasContent: boolean;
|
|
16
|
+
isMenuItem?: boolean;
|
|
16
17
|
}
|
|
17
18
|
declare const StyledLink: import("styled-components").StyledComponent<"span", any, StyledLinkProps & PrivateStyledLinkProps, never>;
|
|
18
19
|
declare const StyledContent: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
@@ -45,7 +45,8 @@ const StyledLink = styled.span`
|
|
|
45
45
|
hasContent,
|
|
46
46
|
disabled,
|
|
47
47
|
variant,
|
|
48
|
-
isDarkBackground
|
|
48
|
+
isDarkBackground,
|
|
49
|
+
isMenuItem
|
|
49
50
|
}) => {
|
|
50
51
|
const colorMapKey = isDarkBackground ? "dark" : "light";
|
|
51
52
|
const {
|
|
@@ -54,8 +55,6 @@ const StyledLink = styled.span`
|
|
|
54
55
|
disabledColor
|
|
55
56
|
} = colorMap[colorMapKey](variant);
|
|
56
57
|
return css`
|
|
57
|
-
display: inline-block;
|
|
58
|
-
|
|
59
58
|
${isSkipLink && css`
|
|
60
59
|
a {
|
|
61
60
|
position: absolute;
|
|
@@ -126,7 +125,7 @@ const StyledLink = styled.span`
|
|
|
126
125
|
a,
|
|
127
126
|
button {
|
|
128
127
|
text-decoration: underline;
|
|
129
|
-
display: inline-block;
|
|
128
|
+
${isMenuItem && "display: inline-block;"}
|
|
130
129
|
|
|
131
130
|
${StyledIcon} {
|
|
132
131
|
display: inline-block;
|
|
@@ -47,6 +47,8 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
47
47
|
listPlacement = "bottom",
|
|
48
48
|
flipEnabled = true,
|
|
49
49
|
inputRef,
|
|
50
|
+
enableVirtualScroll,
|
|
51
|
+
virtualScrollOverscan,
|
|
50
52
|
...textboxProps
|
|
51
53
|
}, ref) => {
|
|
52
54
|
const [activeDescendantId, setActiveDescendantId] = useState();
|
|
@@ -428,7 +430,9 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
428
430
|
loaderDataRole: "filterable-select-list-loader",
|
|
429
431
|
listPlacement: listPlacement,
|
|
430
432
|
flipEnabled: flipEnabled,
|
|
431
|
-
isOpen: isOpen
|
|
433
|
+
isOpen: isOpen,
|
|
434
|
+
enableVirtualScroll: enableVirtualScroll,
|
|
435
|
+
virtualScrollOverscan: virtualScrollOverscan
|
|
432
436
|
}, children);
|
|
433
437
|
return /*#__PURE__*/React.createElement(StyledSelect, _extends({
|
|
434
438
|
hasTextCursor: true,
|
|
@@ -514,7 +518,16 @@ FilterableSelect.propTypes = { ...formInputPropTypes,
|
|
|
514
518
|
listPlacement: PropTypes.oneOf(["top", "bottom", "right", "left"]),
|
|
515
519
|
|
|
516
520
|
/** Use the opposite list placement if the set placement does not fit */
|
|
517
|
-
flipEnabled: PropTypes.bool
|
|
521
|
+
flipEnabled: PropTypes.bool,
|
|
522
|
+
|
|
523
|
+
/** Set this prop to enable a virtualised list of options. If it is not used then all options will be in the
|
|
524
|
+
* DOM at all times, which may cause performance problems on very large lists */
|
|
525
|
+
enableVirtualScroll: PropTypes.bool,
|
|
526
|
+
|
|
527
|
+
/** The number of options to render into the DOM at once, either side of the currently-visible ones.
|
|
528
|
+
* Higher values make for smoother scrolling but may impact performance.
|
|
529
|
+
* Only used if the `enableVirtualScroll` prop is set. */
|
|
530
|
+
virtualScrollOverscan: PropTypes.number
|
|
518
531
|
};
|
|
519
532
|
FilterableSelect.defaultProps = {
|
|
520
533
|
"data-component": "filterable-select"
|
|
@@ -51,6 +51,13 @@ export interface FilterableSelectProps
|
|
|
51
51
|
listPlacement?: Side;
|
|
52
52
|
/** Use the opposite list placement if the set placement does not fit */
|
|
53
53
|
flipEnabled?: boolean;
|
|
54
|
+
/** Set this prop to enable a virtualised list of options. If it is not used then all options will be in the
|
|
55
|
+
* DOM at all times, which may cause performance problems on very large lists */
|
|
56
|
+
enableVirtualScroll?: boolean;
|
|
57
|
+
/** The number of options to render into the DOM at once, either side of the currently-visible ones.
|
|
58
|
+
* Higher values make for smoother scrolling but may impact performance.
|
|
59
|
+
* Only used if the `enableVirtualScroll` prop is set. */
|
|
60
|
+
virtualScrollOverscan?: number;
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
declare function FilterableSelect(
|
|
@@ -5,13 +5,16 @@ const StyledListActionButtonWrapper = styled.div`
|
|
|
5
5
|
padding-bottom: var(--spacing100);
|
|
6
6
|
border-top: 1px solid var(--colorsUtilityDisabled600);
|
|
7
7
|
box-shadow: 0 0px 0 0 rgba(0, 0, 0, 0), 0 -8px 8px 0 rgba(0, 0, 0, 0.03);
|
|
8
|
+
width: 100%;
|
|
9
|
+
position: sticky;
|
|
10
|
+
bottom: 0;
|
|
11
|
+
background-color: inherit;
|
|
8
12
|
|
|
9
13
|
${StyledButton} {
|
|
10
14
|
border: none;
|
|
11
15
|
justify-content: left;
|
|
12
16
|
padding-left: var(--spacing200);
|
|
13
17
|
padding-right: var(--spacing200);
|
|
14
|
-
width: 100%;
|
|
15
18
|
}
|
|
16
19
|
`;
|
|
17
20
|
export default StyledListActionButtonWrapper;
|
|
@@ -48,6 +48,8 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
48
48
|
flipEnabled = true,
|
|
49
49
|
wrapPillText = true,
|
|
50
50
|
inputRef,
|
|
51
|
+
enableVirtualScroll,
|
|
52
|
+
virtualScrollOverscan,
|
|
51
53
|
...textboxProps
|
|
52
54
|
}, ref) => {
|
|
53
55
|
const [activeDescendantId, setActiveDescendantId] = useState();
|
|
@@ -438,7 +440,9 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
438
440
|
flipEnabled: flipEnabled,
|
|
439
441
|
loaderDataRole: "multi-select-list-loader",
|
|
440
442
|
multiselectValues: actualValue,
|
|
441
|
-
isOpen: isOpen
|
|
443
|
+
isOpen: isOpen,
|
|
444
|
+
enableVirtualScroll: enableVirtualScroll,
|
|
445
|
+
virtualScrollOverscan: virtualScrollOverscan
|
|
442
446
|
}, children);
|
|
443
447
|
return /*#__PURE__*/React.createElement(StyledSelectMultiSelect, _extends({
|
|
444
448
|
disabled: disabled,
|
|
@@ -523,7 +527,16 @@ MultiSelect.propTypes = { ...formInputPropTypes,
|
|
|
523
527
|
flipEnabled: PropTypes.bool,
|
|
524
528
|
|
|
525
529
|
/** Wraps the pill text when it would overflow the input width */
|
|
526
|
-
wrapPillText: PropTypes.bool
|
|
530
|
+
wrapPillText: PropTypes.bool,
|
|
531
|
+
|
|
532
|
+
/** Set this prop to enable a virtualised list of options. If it is not used then all options will be in the
|
|
533
|
+
* DOM at all times, which may cause performance problems on very large lists */
|
|
534
|
+
enableVirtualScroll: PropTypes.bool,
|
|
535
|
+
|
|
536
|
+
/** The number of options to render into the DOM at once, either side of the currently-visible ones.
|
|
537
|
+
* Higher values make for smoother scrolling but may impact performance.
|
|
538
|
+
* Only used if the `enableVirtualScroll` prop is set. */
|
|
539
|
+
virtualScrollOverscan: PropTypes.number
|
|
527
540
|
};
|
|
528
541
|
MultiSelect.defaultProps = {
|
|
529
542
|
"data-component": "multiselect"
|
|
@@ -48,6 +48,13 @@ export interface MultiSelectProps
|
|
|
48
48
|
flipEnabled?: boolean;
|
|
49
49
|
/** Wraps the pill text when it would overflow the input width */
|
|
50
50
|
wrapPillText?: boolean;
|
|
51
|
+
/** Set this prop to enable a virtualised list of options. If it is not used then all options will be in the
|
|
52
|
+
* DOM at all times, which may cause performance problems on very large lists */
|
|
53
|
+
enableVirtualScroll?: boolean;
|
|
54
|
+
/** The number of options to render into the DOM at once, either side of the currently-visible ones.
|
|
55
|
+
* Higher values make for smoother scrolling but may impact performance.
|
|
56
|
+
* Only used if the `enableVirtualScroll` prop is set. */
|
|
57
|
+
virtualScrollOverscan?: number;
|
|
51
58
|
}
|
|
52
59
|
|
|
53
60
|
declare function MultiSelect(
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign || 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
|
+
|
|
1
3
|
import React, { useContext } from "react";
|
|
2
4
|
import PropTypes from "prop-types";
|
|
3
5
|
import StyledOption from "./option.style";
|
|
@@ -10,7 +12,9 @@ const Option = /*#__PURE__*/React.forwardRef(({
|
|
|
10
12
|
id,
|
|
11
13
|
index,
|
|
12
14
|
hidden,
|
|
13
|
-
onClick
|
|
15
|
+
onClick,
|
|
16
|
+
style,
|
|
17
|
+
...rest
|
|
14
18
|
}, ref) => {
|
|
15
19
|
const selectListContext = useContext(SelectListContext);
|
|
16
20
|
let isSelected = selectListContext.currentOptionsListIndex === index;
|
|
@@ -38,7 +42,7 @@ const Option = /*#__PURE__*/React.forwardRef(({
|
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
return /*#__PURE__*/React.createElement(StyledOption, {
|
|
45
|
+
return /*#__PURE__*/React.createElement(StyledOption, _extends({
|
|
42
46
|
id: id,
|
|
43
47
|
ref: ref,
|
|
44
48
|
"aria-selected": isSelected,
|
|
@@ -46,8 +50,9 @@ const Option = /*#__PURE__*/React.forwardRef(({
|
|
|
46
50
|
onClick: handleClick,
|
|
47
51
|
isHighlighted: selectListContext.currentOptionsListIndex === index,
|
|
48
52
|
role: "option",
|
|
49
|
-
hidden: hidden
|
|
50
|
-
|
|
53
|
+
hidden: hidden,
|
|
54
|
+
style: style
|
|
55
|
+
}, rest), children || text);
|
|
51
56
|
});
|
|
52
57
|
Option.propTypes = {
|
|
53
58
|
/** The option's visible text, displayed within Textbox of Select, and used for filtering */
|
|
@@ -96,6 +101,12 @@ Option.propTypes = {
|
|
|
96
101
|
|
|
97
102
|
/** MultiSelect only - fill Pill background with color */
|
|
98
103
|
// eslint-disable-next-line react/no-unused-prop-types
|
|
99
|
-
fill: PropTypes.bool
|
|
104
|
+
fill: PropTypes.bool,
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @private
|
|
108
|
+
* @ignore
|
|
109
|
+
* object containing CSS styles to be passed to the underlying list-item */
|
|
110
|
+
style: PropTypes.object
|
|
100
111
|
};
|
|
101
112
|
export default Option;
|
|
@@ -1,17 +1,23 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign || 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
|
+
|
|
1
3
|
import React from "react";
|
|
2
4
|
import PropTypes from "prop-types";
|
|
3
5
|
import StyledOptionGroupHeader from "./option-group-header.style";
|
|
4
6
|
import Icon from "../../icon";
|
|
5
|
-
|
|
6
|
-
const OptionGroupHeader = ({
|
|
7
|
+
const OptionGroupHeader = /*#__PURE__*/React.forwardRef(({
|
|
7
8
|
label,
|
|
8
|
-
icon
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
icon,
|
|
10
|
+
style,
|
|
11
|
+
...rest
|
|
12
|
+
}, ref) => {
|
|
13
|
+
return /*#__PURE__*/React.createElement(StyledOptionGroupHeader, _extends({
|
|
14
|
+
style: style
|
|
15
|
+
}, rest, {
|
|
16
|
+
ref: ref
|
|
17
|
+
}), icon && /*#__PURE__*/React.createElement(Icon, {
|
|
11
18
|
type: icon
|
|
12
19
|
}), /*#__PURE__*/React.createElement("h4", null, label));
|
|
13
|
-
};
|
|
14
|
-
|
|
20
|
+
});
|
|
15
21
|
OptionGroupHeader.propTypes = {
|
|
16
22
|
/** Heading text */
|
|
17
23
|
label: PropTypes.string.isRequired,
|
|
@@ -21,6 +27,12 @@ OptionGroupHeader.propTypes = {
|
|
|
21
27
|
*
|
|
22
28
|
* Any valid Carbon icon name
|
|
23
29
|
*/
|
|
24
|
-
icon: PropTypes.string
|
|
30
|
+
icon: PropTypes.string,
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @private
|
|
34
|
+
* @ignore
|
|
35
|
+
* object containing CSS styles to be passed to the underlying DOM element */
|
|
36
|
+
style: PropTypes.object
|
|
25
37
|
};
|
|
26
38
|
export default OptionGroupHeader;
|
|
@@ -2,9 +2,10 @@ import styled from "styled-components";
|
|
|
2
2
|
import StyledIcon from "../../icon/icon.style";
|
|
3
3
|
const StyledOptionGroupHeader = styled.div`
|
|
4
4
|
box-sizing: border-box;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
position: absolute;
|
|
6
|
+
height: 40px;
|
|
7
7
|
padding-left: 16px;
|
|
8
|
+
padding-top: 16px;
|
|
8
9
|
display: flex;
|
|
9
10
|
align-items: center;
|
|
10
11
|
width: 100%;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign || 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
|
+
|
|
1
3
|
import React, { useContext } from "react";
|
|
2
4
|
import PropTypes from "prop-types";
|
|
3
5
|
import StyledOptionRow from "./option-row.style";
|
|
@@ -9,7 +11,9 @@ const OptionRow = /*#__PURE__*/React.forwardRef(({
|
|
|
9
11
|
onSelect,
|
|
10
12
|
value,
|
|
11
13
|
index,
|
|
12
|
-
hidden
|
|
14
|
+
hidden,
|
|
15
|
+
style,
|
|
16
|
+
...rest
|
|
13
17
|
}, ref) => {
|
|
14
18
|
const handleClick = () => {
|
|
15
19
|
onSelect({
|
|
@@ -26,7 +30,7 @@ const OptionRow = /*#__PURE__*/React.forwardRef(({
|
|
|
26
30
|
isSelected = selectListContext.multiselectValues.includes(value);
|
|
27
31
|
}
|
|
28
32
|
|
|
29
|
-
return /*#__PURE__*/React.createElement(StyledOptionRow, {
|
|
33
|
+
return /*#__PURE__*/React.createElement(StyledOptionRow, _extends({
|
|
30
34
|
id: id,
|
|
31
35
|
ref: ref,
|
|
32
36
|
"aria-selected": isSelected,
|
|
@@ -34,8 +38,9 @@ const OptionRow = /*#__PURE__*/React.forwardRef(({
|
|
|
34
38
|
onClick: handleClick,
|
|
35
39
|
isHighlighted: selectListContext.currentOptionsListIndex === index,
|
|
36
40
|
role: "option",
|
|
37
|
-
hidden: hidden
|
|
38
|
-
|
|
41
|
+
hidden: hidden,
|
|
42
|
+
style: style
|
|
43
|
+
}, rest), children);
|
|
39
44
|
});
|
|
40
45
|
OptionRow.propTypes = {
|
|
41
46
|
/** The option's visible text, displayed within Textbox of Select */
|
|
@@ -70,6 +75,12 @@ OptionRow.propTypes = {
|
|
|
70
75
|
* @private
|
|
71
76
|
* @ignore
|
|
72
77
|
* True when option should be hidden from the view (prop added by the SelectList component) */
|
|
73
|
-
hidden: PropTypes.bool
|
|
78
|
+
hidden: PropTypes.bool,
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @private
|
|
82
|
+
* @ignore
|
|
83
|
+
* object containing CSS styles to be passed to the underlying DOM element */
|
|
84
|
+
style: PropTypes.object
|
|
74
85
|
};
|
|
75
86
|
export default OptionRow;
|
|
@@ -3,12 +3,22 @@ import { baseTheme } from "../../../style/themes";
|
|
|
3
3
|
const StyledSelectListContainer = styled.div`
|
|
4
4
|
background-color: white;
|
|
5
5
|
box-shadow: var(--boxShadow100);
|
|
6
|
-
overflow: hidden;
|
|
7
6
|
animation: fadeIn 250ms ease-out;
|
|
8
7
|
position: absolute;
|
|
9
8
|
z-index: ${({
|
|
10
9
|
theme
|
|
11
10
|
}) => theme.zIndex.popover};
|
|
11
|
+
max-height: ${({
|
|
12
|
+
maxHeight
|
|
13
|
+
}) => `${maxHeight}px`};
|
|
14
|
+
overflow-y: auto;
|
|
15
|
+
display: flex;
|
|
16
|
+
flex-wrap: wrap;
|
|
17
|
+
align-items: flex-start;
|
|
18
|
+
|
|
19
|
+
${({
|
|
20
|
+
isLoading
|
|
21
|
+
}) => isLoading && "min-height: 150px"};
|
|
12
22
|
|
|
13
23
|
@keyframes fadeIn {
|
|
14
24
|
0% {
|