@blaze-cms/react-page-builder 0.146.0-node18-core-styles-tooltips.3 → 0.146.0-node18-core-styles-tooltips.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/CHANGELOG.md +20 -0
- package/lib/components/Button.js +57 -11
- package/lib/components/Button.js.map +1 -1
- package/lib/components/List/ListFactory.js.map +1 -1
- package/lib/components/MenuItem/MenuItemRender.js +17 -5
- package/lib/components/MenuItem/MenuItemRender.js.map +1 -1
- package/lib/hooks/helpers/StoreImages.js +61 -41
- package/lib/hooks/helpers/StoreImages.js.map +1 -1
- package/lib/variants/LiveBlogList/LiveBlogList.js +45 -48
- package/lib/variants/LiveBlogList/LiveBlogList.js.map +1 -1
- package/lib-es/components/Button.js +12 -7
- package/lib-es/components/Button.js.map +1 -1
- package/lib-es/components/List/ListFactory.js +1 -1
- package/lib-es/components/List/ListFactory.js.map +1 -1
- package/lib-es/components/MenuItem/MenuItemRender.js +16 -3
- package/lib-es/components/MenuItem/MenuItemRender.js.map +1 -1
- package/lib-es/hooks/helpers/StoreImages.js +44 -30
- package/lib-es/hooks/helpers/StoreImages.js.map +1 -1
- package/lib-es/variants/LiveBlogList/LiveBlogList.js +41 -51
- package/lib-es/variants/LiveBlogList/LiveBlogList.js.map +1 -1
- package/package.json +3 -3
- package/src/components/Button.js +13 -9
- package/src/components/List/ListFactory.js +1 -1
- package/src/components/MenuItem/MenuItemRender.js +17 -3
- package/src/hooks/helpers/StoreImages.js +33 -31
- package/src/variants/LiveBlogList/LiveBlogList.js +50 -46
- package/tests/unit/src/components/MenuItem/MenuItemRender.test.js +25 -2
- package/tests/unit/src/components/MenuItem/__snapshots__/MenuItem.test.js.snap +1 -0
- package/tests/unit/src/variants/LiveBlogList/LiveBlogList.test.js +121 -0
- package/tests/unit/src/variants/LiveBlogList/constants.js +10 -0
|
@@ -5,13 +5,14 @@ import Button from '@blaze-react/button';
|
|
|
5
5
|
import { FaPlus, FaMinus } from 'react-icons/fa';
|
|
6
6
|
import { BsPinAngleFill } from 'react-icons/bs';
|
|
7
7
|
dayjs.extend(relativeTime);
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
const COLLAPSE_HEIGHT = 380;
|
|
9
|
+
const LiveBlogList = ({
|
|
10
|
+
children,
|
|
11
|
+
date,
|
|
12
|
+
published,
|
|
13
|
+
featured,
|
|
14
|
+
alternativeHeadline
|
|
15
|
+
}) => {
|
|
15
16
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
16
17
|
const [shouldShowButton, setShouldShowButton] = useState(false);
|
|
17
18
|
const [{
|
|
@@ -19,64 +20,53 @@ const LiveBlogList = props => {
|
|
|
19
20
|
displayedTime
|
|
20
21
|
}, setDisplayedDate] = useState({
|
|
21
22
|
displayedDate: ' ',
|
|
22
|
-
|
|
23
|
+
displayedTime: ''
|
|
23
24
|
});
|
|
24
|
-
const usedDate = date
|
|
25
|
+
const usedDate = date;
|
|
25
26
|
const contentRef = useRef(null);
|
|
26
27
|
useEffect(() => {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return () => {
|
|
38
|
-
clearTimeout(timeout);
|
|
39
|
-
};
|
|
28
|
+
const el = contentRef.current;
|
|
29
|
+
if (!el) return;
|
|
30
|
+
const check = () => setShouldShowButton(el.scrollHeight > COLLAPSE_HEIGHT);
|
|
31
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
32
|
+
check();
|
|
33
|
+
const ro = new ResizeObserver(check);
|
|
34
|
+
ro.observe(el);
|
|
35
|
+
return () => ro.disconnect();
|
|
36
|
+
}
|
|
37
|
+
check();
|
|
40
38
|
}, [children]);
|
|
41
39
|
useEffect(() => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
setDisplayedDate({
|
|
54
|
-
displayedDate: newDate,
|
|
55
|
-
displayedTime: dayjs(usedDate).format('HH:mm')
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
}, [date, published, usedDate]);
|
|
59
|
-
const toggleExpanded = () => {
|
|
60
|
-
setIsExpanded(!isExpanded);
|
|
61
|
-
};
|
|
40
|
+
if (!usedDate) return;
|
|
41
|
+
const days = dayjs().diff(dayjs(usedDate), 'day');
|
|
42
|
+
const lessThanAYear = days < 365;
|
|
43
|
+
let newDate;
|
|
44
|
+
if (days < 1) newDate = dayjs(usedDate).fromNow();else if (lessThanAYear) newDate = dayjs(usedDate).format('DD MMM');else newDate = dayjs(usedDate).format('DD MMM YYYY');
|
|
45
|
+
setDisplayedDate({
|
|
46
|
+
displayedDate: newDate,
|
|
47
|
+
displayedTime: lessThanAYear ? dayjs(usedDate).format('HH:mm') : null
|
|
48
|
+
});
|
|
49
|
+
}, [usedDate]);
|
|
50
|
+
const toggleExpanded = () => setIsExpanded(value => !value);
|
|
62
51
|
const isCollapsed = !isExpanded;
|
|
63
|
-
const
|
|
64
|
-
const modifier = featured ? ` ${baseClass}--featured` : '';
|
|
65
|
-
const className = `${baseClass}${modifier}`;
|
|
52
|
+
const showHeader = usedDate || alternativeHeadline || featured;
|
|
66
53
|
return /*#__PURE__*/React.createElement("div", {
|
|
67
|
-
className:
|
|
68
|
-
},
|
|
54
|
+
className: `live-blog-container${featured ? ' live-blog-container--featured' : ''}`
|
|
55
|
+
}, showHeader && /*#__PURE__*/React.createElement("div", {
|
|
69
56
|
className: "live-blog-date"
|
|
70
|
-
}, featured && /*#__PURE__*/React.createElement(BsPinAngleFill, null), /*#__PURE__*/React.createElement("span", {
|
|
57
|
+
}, featured && /*#__PURE__*/React.createElement(BsPinAngleFill, null), usedDate && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
71
58
|
className: "live-blog-date--date"
|
|
72
|
-
}, displayedDate), /*#__PURE__*/React.createElement("span", {
|
|
59
|
+
}, displayedDate), displayedTime && /*#__PURE__*/React.createElement("span", {
|
|
73
60
|
className: "live-blog-date--time"
|
|
74
|
-
}, displayedTime)), /*#__PURE__*/React.createElement("
|
|
61
|
+
}, displayedTime)), alternativeHeadline && /*#__PURE__*/React.createElement("span", {
|
|
62
|
+
className: "live-blog-date--headline"
|
|
63
|
+
}, alternativeHeadline)), /*#__PURE__*/React.createElement("div", {
|
|
75
64
|
ref: contentRef,
|
|
76
|
-
className: `live-blog-content ${isCollapsed ? 'live-blog-content--collapsed' : 'live-blog-content--opened'}`
|
|
65
|
+
className: `live-blog-content ${isCollapsed ? 'live-blog-content--collapsed collapsed' : 'live-blog-content--opened opened'}`
|
|
77
66
|
}, children), shouldShowButton && /*#__PURE__*/React.createElement("div", {
|
|
78
67
|
className: "live-blog-button-wrapper"
|
|
79
68
|
}, /*#__PURE__*/React.createElement(Button, {
|
|
69
|
+
"aria-label": isExpanded ? 'Show Less' : 'Show More',
|
|
80
70
|
className: "live-blog-toggle",
|
|
81
71
|
onClick: toggleExpanded,
|
|
82
72
|
type: "button"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LiveBlogList.js","names":["React","useRef","useState","useEffect","dayjs","relativeTime","Button","FaPlus","FaMinus","BsPinAngleFill","extend","
|
|
1
|
+
{"version":3,"file":"LiveBlogList.js","names":["React","useRef","useState","useEffect","dayjs","relativeTime","Button","FaPlus","FaMinus","BsPinAngleFill","extend","COLLAPSE_HEIGHT","LiveBlogList","children","date","published","featured","alternativeHeadline","isExpanded","setIsExpanded","shouldShowButton","setShouldShowButton","displayedDate","displayedTime","setDisplayedDate","usedDate","contentRef","el","current","check","scrollHeight","ResizeObserver","ro","observe","disconnect","days","diff","lessThanAYear","newDate","fromNow","format","toggleExpanded","value","isCollapsed","showHeader","createElement","className","Fragment","ref","onClick","type"],"sources":["../../../src/variants/LiveBlogList/LiveBlogList.js"],"sourcesContent":["import React, { useRef, useState, useEffect } from 'react';\nimport dayjs from 'dayjs';\nimport relativeTime from 'dayjs/plugin/relativeTime';\nimport Button from '@blaze-react/button';\nimport { FaPlus, FaMinus } from 'react-icons/fa';\nimport { BsPinAngleFill } from 'react-icons/bs';\n\ndayjs.extend(relativeTime);\n\nconst COLLAPSE_HEIGHT = 380;\n\nconst LiveBlogList = ({ children, date, published, featured, alternativeHeadline }) => {\n const [isExpanded, setIsExpanded] = useState(false);\n const [shouldShowButton, setShouldShowButton] = useState(false);\n const [{ displayedDate, displayedTime }, setDisplayedDate] = useState({\n displayedDate: ' ',\n displayedTime: ''\n });\n const usedDate = date;\n const contentRef = useRef(null);\n\n useEffect(() => {\n const el = contentRef.current;\n if (!el) return;\n\n const check = () => setShouldShowButton(el.scrollHeight > COLLAPSE_HEIGHT);\n\n if (typeof ResizeObserver !== 'undefined') {\n check();\n const ro = new ResizeObserver(check);\n ro.observe(el);\n return () => ro.disconnect();\n }\n check();\n }, [children]);\n\n useEffect(() => {\n if (!usedDate) return;\n const days = dayjs().diff(dayjs(usedDate), 'day');\n const lessThanAYear = days < 365;\n\n let newDate;\n if (days < 1) newDate = dayjs(usedDate).fromNow();\n else if (lessThanAYear) newDate = dayjs(usedDate).format('DD MMM');\n else newDate = dayjs(usedDate).format('DD MMM YYYY');\n\n setDisplayedDate({\n displayedDate: newDate,\n displayedTime: lessThanAYear ? dayjs(usedDate).format('HH:mm') : null\n });\n }, [usedDate]);\n\n const toggleExpanded = () => setIsExpanded(value => !value);\n const isCollapsed = !isExpanded;\n const showHeader = usedDate || alternativeHeadline || featured;\n\n return (\n <div className={`live-blog-container${featured ? ' live-blog-container--featured' : ''}`}>\n {showHeader && (\n <div className=\"live-blog-date\">\n {featured && <BsPinAngleFill />}\n {usedDate && (\n <>\n <span className=\"live-blog-date--date\">{displayedDate}</span>\n {displayedTime && <span className=\"live-blog-date--time\">{displayedTime}</span>}\n </>\n )}\n {alternativeHeadline && (\n <span className=\"live-blog-date--headline\">{alternativeHeadline}</span>\n )}\n </div>\n )}\n\n <div\n ref={contentRef}\n className={`live-blog-content ${\n isCollapsed\n ? 'live-blog-content--collapsed collapsed'\n : 'live-blog-content--opened opened'\n }`}>\n {children}\n </div>\n\n {shouldShowButton && (\n <div className=\"live-blog-button-wrapper\">\n <Button\n aria-label={isExpanded ? 'Show Less' : 'Show More'}\n className=\"live-blog-toggle\"\n onClick={toggleExpanded}\n type=\"button\">\n {isExpanded ? (\n <>\n <FaMinus className=\"toggle-icon\" /> Show Less\n </>\n ) : (\n <>\n <FaPlus className=\"toggle-icon\" /> Show More\n </>\n )}\n </Button>\n </div>\n )}\n </div>\n );\n};\n\nexport default LiveBlogList;\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blaze-cms/react-page-builder",
|
|
3
|
-
"version": "0.146.0-node18-core-styles-tooltips.
|
|
3
|
+
"version": "0.146.0-node18-core-styles-tooltips.5",
|
|
4
4
|
"description": "Blaze react page builder",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib-es/index.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@blaze-cms/core-errors-ui": "0.146.0-node18-core-styles-tooltips.3",
|
|
33
33
|
"@blaze-cms/image-cdn-react": "0.3.0-alpha.7",
|
|
34
34
|
"@blaze-cms/nextjs-components": "0.146.0-node18-core-styles-tooltips.3",
|
|
35
|
-
"@blaze-cms/plugin-search-ui": "0.146.0-node18-core-styles-tooltips.
|
|
35
|
+
"@blaze-cms/plugin-search-ui": "0.146.0-node18-core-styles-tooltips.5",
|
|
36
36
|
"@blaze-cms/setup-ui": "0.146.0-node18-core-styles-tooltips.3",
|
|
37
37
|
"@blaze-cms/utils": "0.146.0-node18-core-styles-tooltips.3",
|
|
38
38
|
"@blaze-cms/utils-handlebars": "0.146.0-node18-core-styles-tooltips.3",
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"lib/*",
|
|
93
93
|
"lib-es/*"
|
|
94
94
|
],
|
|
95
|
-
"gitHead": "
|
|
95
|
+
"gitHead": "d6b0cd14687e7fe634aade939e3b28c67aabda02"
|
|
96
96
|
}
|
package/src/components/Button.js
CHANGED
|
@@ -54,19 +54,23 @@ const Button = props => {
|
|
|
54
54
|
return !!(url || hasChildren(children));
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
-
const logout = () => {
|
|
58
|
-
handleLogout(client);
|
|
59
|
-
if (hasChildren(children)) return setShowChildren(true);
|
|
57
|
+
const logout = async () => {
|
|
58
|
+
await handleLogout(client);
|
|
60
59
|
|
|
61
|
-
if (
|
|
60
|
+
if (hasChildren(children)) {
|
|
61
|
+
setShowChildren(true);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
if (!urlToUse) {
|
|
66
|
+
return router.reload();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
window.location.href = urlToUse;
|
|
66
70
|
};
|
|
67
71
|
|
|
68
|
-
const handleClick = () => {
|
|
69
|
-
if (isLogoutButton) logout();
|
|
72
|
+
const handleClick = async () => {
|
|
73
|
+
if (isLogoutButton) await logout();
|
|
70
74
|
if (!url && !isLogoutButton) setShowChildren(!showChildren);
|
|
71
75
|
};
|
|
72
76
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
|
1
2
|
import React, { useState, useContext, useEffect } from 'react';
|
|
2
3
|
import PropTypes from 'prop-types';
|
|
3
4
|
import { FaChevronDown, FaChevronUp } from 'react-icons/fa';
|
|
@@ -29,6 +30,7 @@ const MenuItemRender = ({ children, eventType, text, modifier, url, parent }) =>
|
|
|
29
30
|
const isActive = router ? isUrlPathMatch(router.asPath, urlToUse) : false;
|
|
30
31
|
const isActiveParent = router ? hasActiveChild(router.asPath, children) : false;
|
|
31
32
|
const shouldPreOpen = openActiveSubmenus && isActiveParent && isClickEvent;
|
|
33
|
+
const hasValidChildren = hasChildren(children);
|
|
32
34
|
|
|
33
35
|
const [displayChildren, setDisplayChildren] = useState(shouldPreOpen);
|
|
34
36
|
|
|
@@ -65,7 +67,11 @@ const MenuItemRender = ({ children, eventType, text, modifier, url, parent }) =>
|
|
|
65
67
|
}
|
|
66
68
|
};
|
|
67
69
|
|
|
68
|
-
const
|
|
70
|
+
const handleMobileClick = () => {
|
|
71
|
+
if (!urlToUse && hasValidChildren) {
|
|
72
|
+
setDisplayChildren(!displayChildren);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
69
75
|
|
|
70
76
|
const menuItemLinkClassname = classnames('menu--item--link', {
|
|
71
77
|
'menu--item--link--active': isActive,
|
|
@@ -74,7 +80,11 @@ const MenuItemRender = ({ children, eventType, text, modifier, url, parent }) =>
|
|
|
74
80
|
|
|
75
81
|
return (
|
|
76
82
|
<li className={modifier} onMouseEnter={handleItemEvent} onMouseLeave={handleItemEvent}>
|
|
77
|
-
<div
|
|
83
|
+
<div
|
|
84
|
+
className={menuItemLinkClassname}
|
|
85
|
+
onClick={handleMobileClick}
|
|
86
|
+
role={!urlToUse && hasValidChildren ? 'button' : undefined}
|
|
87
|
+
tabIndex={!urlToUse && hasValidChildren ? 0 : undefined}>
|
|
78
88
|
{urlToUse ? (
|
|
79
89
|
<BlazeLink href={urlToUse}>{textToUse}</BlazeLink>
|
|
80
90
|
) : (
|
|
@@ -86,7 +96,11 @@ const MenuItemRender = ({ children, eventType, text, modifier, url, parent }) =>
|
|
|
86
96
|
<i
|
|
87
97
|
role="button"
|
|
88
98
|
className="menu--item--link--icon"
|
|
89
|
-
onClick={
|
|
99
|
+
onClick={e => {
|
|
100
|
+
e.stopPropagation();
|
|
101
|
+
setDisplayChildren(!displayChildren);
|
|
102
|
+
}}
|
|
103
|
+
tabIndex={0}>
|
|
90
104
|
{displayChildren ? <FaChevronUp /> : <FaChevronDown />}
|
|
91
105
|
</i>
|
|
92
106
|
)}
|
|
@@ -1,48 +1,50 @@
|
|
|
1
1
|
class StoreImages {
|
|
2
|
-
|
|
3
|
-
this.images = [];
|
|
4
|
-
this.id = null;
|
|
5
|
-
this.toggleModal = () => {};
|
|
6
|
-
this.setSelectedImage = () => {};
|
|
7
|
-
}
|
|
2
|
+
#images = [];
|
|
8
3
|
|
|
9
|
-
|
|
10
|
-
this.images = [];
|
|
11
|
-
}
|
|
4
|
+
#pageBuilderID = null;
|
|
12
5
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
.map((item, index, final) => final.indexOf(item) === index && index)
|
|
17
|
-
.filter(item => images[item])
|
|
18
|
-
.map(item => images[item]);
|
|
6
|
+
#handlers = {
|
|
7
|
+
toggleModal: () => {},
|
|
8
|
+
onSelect: () => {}
|
|
19
9
|
};
|
|
20
10
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
this.setSelectedImage(index);
|
|
25
|
-
}
|
|
26
|
-
};
|
|
11
|
+
get images() {
|
|
12
|
+
return [...this.#images];
|
|
13
|
+
}
|
|
27
14
|
|
|
28
|
-
|
|
29
|
-
this
|
|
30
|
-
|
|
31
|
-
};
|
|
15
|
+
resetImages() {
|
|
16
|
+
this.#images = [];
|
|
17
|
+
}
|
|
32
18
|
|
|
33
|
-
|
|
34
|
-
if (
|
|
19
|
+
setHandlers({ toggleModal, setSelectedImage }) {
|
|
20
|
+
if (typeof toggleModal === 'function') this.#handlers.toggleModal = toggleModal;
|
|
21
|
+
if (typeof setSelectedImage === 'function') this.#handlers.onSelect = setSelectedImage;
|
|
22
|
+
}
|
|
35
23
|
|
|
36
|
-
|
|
24
|
+
addImages(newImages, { pageBuilderID } = {}, handlers = {}) {
|
|
25
|
+
if (!Array.isArray(newImages) || newImages.length === 0) {
|
|
26
|
+
return this.images;
|
|
27
|
+
}
|
|
37
28
|
|
|
38
|
-
if (pageBuilderID !== this
|
|
29
|
+
if (pageBuilderID != null && pageBuilderID !== this.#pageBuilderID) {
|
|
39
30
|
this.resetImages();
|
|
40
|
-
this
|
|
31
|
+
this.#pageBuilderID = pageBuilderID;
|
|
41
32
|
}
|
|
42
33
|
|
|
43
|
-
this
|
|
34
|
+
const merged = this.#images.concat(newImages);
|
|
35
|
+
this.#images = Array.from(new Map(merged.map(img => [img.imageId, img])).values());
|
|
44
36
|
|
|
37
|
+
this.setHandlers(handlers);
|
|
45
38
|
return this.images;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
toggleModal = () => {
|
|
42
|
+
this.#handlers.toggleModal();
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
handleSelectedImage = imageId => {
|
|
46
|
+
const idx = this.#images.findIndex(img => img.imageId === imageId);
|
|
47
|
+
if (idx !== -1) this.#handlers.onSelect(idx);
|
|
46
48
|
};
|
|
47
49
|
}
|
|
48
50
|
|
|
@@ -7,83 +7,87 @@ import { BsPinAngleFill } from 'react-icons/bs';
|
|
|
7
7
|
|
|
8
8
|
dayjs.extend(relativeTime);
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
|
|
10
|
+
const COLLAPSE_HEIGHT = 380;
|
|
11
|
+
|
|
12
|
+
const LiveBlogList = ({ children, date, published, featured, alternativeHeadline }) => {
|
|
12
13
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
13
14
|
const [shouldShowButton, setShouldShowButton] = useState(false);
|
|
14
15
|
const [{ displayedDate, displayedTime }, setDisplayedDate] = useState({
|
|
15
16
|
displayedDate: ' ',
|
|
16
|
-
|
|
17
|
+
displayedTime: ''
|
|
17
18
|
});
|
|
18
|
-
const usedDate = date
|
|
19
|
-
|
|
19
|
+
const usedDate = date;
|
|
20
20
|
const contentRef = useRef(null);
|
|
21
21
|
|
|
22
22
|
useEffect(() => {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
setShouldShowButton(true);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}, 500); // delay to wait for content load
|
|
31
|
-
// todo: change to use mutation observer
|
|
23
|
+
const el = contentRef.current;
|
|
24
|
+
if (!el) return;
|
|
25
|
+
|
|
26
|
+
const check = () => setShouldShowButton(el.scrollHeight > COLLAPSE_HEIGHT);
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
29
|
+
check();
|
|
30
|
+
const ro = new ResizeObserver(check);
|
|
31
|
+
ro.observe(el);
|
|
32
|
+
return () => ro.disconnect();
|
|
33
|
+
}
|
|
34
|
+
check();
|
|
36
35
|
}, [children]);
|
|
37
36
|
|
|
38
37
|
useEffect(() => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
} else {
|
|
48
|
-
newDate = dayjs(usedDate).format('DD MMM YYYY');
|
|
49
|
-
}
|
|
50
|
-
setDisplayedDate({
|
|
51
|
-
displayedDate: newDate,
|
|
52
|
-
displayedTime: dayjs(usedDate).format('HH:mm')
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}, [date, published, usedDate]);
|
|
38
|
+
if (!usedDate) return;
|
|
39
|
+
const days = dayjs().diff(dayjs(usedDate), 'day');
|
|
40
|
+
const lessThanAYear = days < 365;
|
|
41
|
+
|
|
42
|
+
let newDate;
|
|
43
|
+
if (days < 1) newDate = dayjs(usedDate).fromNow();
|
|
44
|
+
else if (lessThanAYear) newDate = dayjs(usedDate).format('DD MMM');
|
|
45
|
+
else newDate = dayjs(usedDate).format('DD MMM YYYY');
|
|
56
46
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
47
|
+
setDisplayedDate({
|
|
48
|
+
displayedDate: newDate,
|
|
49
|
+
displayedTime: lessThanAYear ? dayjs(usedDate).format('HH:mm') : null
|
|
50
|
+
});
|
|
51
|
+
}, [usedDate]);
|
|
60
52
|
|
|
53
|
+
const toggleExpanded = () => setIsExpanded(value => !value);
|
|
61
54
|
const isCollapsed = !isExpanded;
|
|
62
|
-
const
|
|
63
|
-
const modifier = featured ? ` ${baseClass}--featured` : '';
|
|
64
|
-
const className = `${baseClass}${modifier}`;
|
|
55
|
+
const showHeader = usedDate || alternativeHeadline || featured;
|
|
65
56
|
|
|
66
57
|
return (
|
|
67
|
-
<div className={
|
|
68
|
-
{
|
|
58
|
+
<div className={`live-blog-container${featured ? ' live-blog-container--featured' : ''}`}>
|
|
59
|
+
{showHeader && (
|
|
69
60
|
<div className="live-blog-date">
|
|
70
61
|
{featured && <BsPinAngleFill />}
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
{usedDate && (
|
|
63
|
+
<>
|
|
64
|
+
<span className="live-blog-date--date">{displayedDate}</span>
|
|
65
|
+
{displayedTime && <span className="live-blog-date--time">{displayedTime}</span>}
|
|
66
|
+
</>
|
|
67
|
+
)}
|
|
68
|
+
{alternativeHeadline && (
|
|
69
|
+
<span className="live-blog-date--headline">{alternativeHeadline}</span>
|
|
70
|
+
)}
|
|
73
71
|
</div>
|
|
74
72
|
)}
|
|
75
73
|
|
|
76
74
|
<div
|
|
77
75
|
ref={contentRef}
|
|
78
76
|
className={`live-blog-content ${
|
|
79
|
-
isCollapsed
|
|
77
|
+
isCollapsed
|
|
78
|
+
? 'live-blog-content--collapsed collapsed'
|
|
79
|
+
: 'live-blog-content--opened opened'
|
|
80
80
|
}`}>
|
|
81
81
|
{children}
|
|
82
82
|
</div>
|
|
83
83
|
|
|
84
84
|
{shouldShowButton && (
|
|
85
85
|
<div className="live-blog-button-wrapper">
|
|
86
|
-
<Button
|
|
86
|
+
<Button
|
|
87
|
+
aria-label={isExpanded ? 'Show Less' : 'Show More'}
|
|
88
|
+
className="live-blog-toggle"
|
|
89
|
+
onClick={toggleExpanded}
|
|
90
|
+
type="button">
|
|
87
91
|
{isExpanded ? (
|
|
88
92
|
<>
|
|
89
93
|
<FaMinus className="toggle-icon" /> Show Less
|
|
@@ -7,6 +7,8 @@ import { render, fireEvent } from '@testing-library/react';
|
|
|
7
7
|
import '@testing-library/jest-dom/extend-expect';
|
|
8
8
|
import MenuRender from '../../../../../src/components/MenuItem/MenuItemRender';
|
|
9
9
|
|
|
10
|
+
const MENU_ITEM_CHILDREN_CLASS = 'menu--item-children';
|
|
11
|
+
|
|
10
12
|
let mockAsPathValue = '/';
|
|
11
13
|
|
|
12
14
|
jest.mock('next/router', () => {
|
|
@@ -75,7 +77,7 @@ describe('MenuRender component', () => {
|
|
|
75
77
|
);
|
|
76
78
|
|
|
77
79
|
fireEvent.mouseEnter(getByText('Parent'));
|
|
78
|
-
let childContainer = container.querySelector(
|
|
80
|
+
let childContainer = container.querySelector(`.${MENU_ITEM_CHILDREN_CLASS}`);
|
|
79
81
|
expect(childContainer).not.toHaveClass('hidden');
|
|
80
82
|
|
|
81
83
|
mockAsPathValue = '/new-route';
|
|
@@ -85,7 +87,28 @@ describe('MenuRender component', () => {
|
|
|
85
87
|
</MenuRender>
|
|
86
88
|
);
|
|
87
89
|
|
|
88
|
-
childContainer = container.querySelector(
|
|
90
|
+
childContainer = container.querySelector(`.${MENU_ITEM_CHILDREN_CLASS}`);
|
|
91
|
+
expect(childContainer).toHaveClass('hidden');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('toggles display of children when chevron icon is clicked', () => {
|
|
95
|
+
const { container } = render(
|
|
96
|
+
<MenuRender eventType="click" text="Parent">
|
|
97
|
+
<div data-testid="child">Child</div>
|
|
98
|
+
</MenuRender>
|
|
99
|
+
);
|
|
100
|
+
let childContainer = container.querySelector(`.${MENU_ITEM_CHILDREN_CLASS}`);
|
|
101
|
+
expect(childContainer).toHaveClass('hidden');
|
|
102
|
+
|
|
103
|
+
const chevronIcon = container.querySelector('.menu--item--link--icon');
|
|
104
|
+
expect(chevronIcon).toBeInTheDocument();
|
|
105
|
+
|
|
106
|
+
chevronIcon.click();
|
|
107
|
+
childContainer = container.querySelector(`.${MENU_ITEM_CHILDREN_CLASS}`);
|
|
108
|
+
expect(childContainer).not.toHaveClass('hidden');
|
|
109
|
+
|
|
110
|
+
chevronIcon.click();
|
|
111
|
+
childContainer = container.querySelector(`.${MENU_ITEM_CHILDREN_CLASS}`);
|
|
89
112
|
expect(childContainer).toHaveClass('hidden');
|
|
90
113
|
});
|
|
91
114
|
});
|