gatsby-core-theme 44.1.7 → 44.2.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ # [44.2.0](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.1.8...v44.2.0) (2025-06-09)
2
+
3
+
4
+ * Merge branch 'tm-5437-translate-aria-labels' into 'master' ([63ddf09](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/63ddf09d10c25f973ee53d45c61f6c3c7f2e66d8))
5
+
6
+
7
+ ### Features
8
+
9
+ * useTranslate aria labels ([2b93d65](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/2b93d65ad56a5bb08d8d769e7aa26bd7f85794a2))
10
+
11
+ ## [44.1.8](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.1.7...v44.1.8) (2025-06-09)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * load defaultImg if there is no src ([34ed7d7](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/34ed7d77139f27b55e7ae05ea256c024b664727a))
17
+
18
+
19
+ * Merge branch 'tm-5506-load-deafult-img' into 'master' ([f65e038](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/f65e038d2e307cc87775f01478807d0ed3df4e99))
20
+
1
21
  ## [44.1.7](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.1.6...v44.1.7) (2025-06-09)
2
22
 
3
23
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-core-theme",
3
- "version": "44.1.7",
3
+ "version": "44.2.0",
4
4
  "description": "Gatsby Theme NPM Package",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -1,12 +1,14 @@
1
1
  import React from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import { MdGTranslate } from "@react-icons/all-files/md/MdGTranslate";
4
+ import useTranslate from "../../../../hooks/useTranslate/useTranslate";
4
5
 
5
6
  const TranslateLink = ({ translationKey, language }) => (
6
7
  <a
7
8
  href={`${process.env.HERCULES_BACKEND_URL}translations?key=${translationKey}&language=${language}`}
8
- aria-label="translation"
9
- target="_blank" rel="noreferrer"
9
+ aria-label={useTranslate("ariaLabel-translation", "translation")}
10
+ target="_blank"
11
+ rel="noreferrer"
10
12
  >
11
13
  <MdGTranslate />
12
14
  </a>
@@ -1,12 +1,12 @@
1
- import React, { useRef, useState } from 'react';
2
- import PropTypes from 'prop-types';
1
+ import React, { useRef, useState } from "react";
2
+ import PropTypes from "prop-types";
3
3
 
4
- import styles from './author-description.module.scss';
5
- import useTranslate from '~hooks/useTranslate/useTranslate';
4
+ import styles from "./author-description.module.scss";
5
+ import useTranslate from "~hooks/useTranslate/useTranslate";
6
6
 
7
7
  export default function AuthorDescription({
8
8
  author,
9
- template = '',
9
+ template = "",
10
10
  readMore = false,
11
11
  maximumLength = 30,
12
12
  }) {
@@ -19,27 +19,35 @@ export default function AuthorDescription({
19
19
  };
20
20
 
21
21
  return (
22
- <div className={`${styles.description || ''} ${styles[template]}`}>
22
+ <div className={`${styles.description || ""} ${styles[template]}`}>
23
23
  <div
24
24
  ref={biographyRef}
25
25
  className={`${styles.biography} ${
26
- author?.biography?.split(' ').length > maximumLength && readMore
26
+ author?.biography?.split(" ").length > maximumLength && readMore
27
27
  ? styles.showReadMore
28
- : ''
28
+ : ""
29
29
  }`}
30
30
  role="button"
31
- aria-label="Toggle biography read more"
31
+ aria-label={useTranslate(
32
+ "ariaLabel-toggleBiography",
33
+ "Toggle biography read more"
34
+ )}
32
35
  tabIndex={0}
33
36
  onClick={toggleReadMore}
34
37
  onKeyDown={toggleReadMore}
35
38
  // eslint-disable-next-line react/no-danger
36
39
  dangerouslySetInnerHTML={{
37
40
  __html:
38
- author?.biography?.split(' ').length > maximumLength && isReadMore && readMore
39
- ? `${author?.biography?.split(' ').slice(0, maximumLength).join(' ')} <span class='${
41
+ author?.biography?.split(" ").length > maximumLength &&
42
+ isReadMore &&
43
+ readMore
44
+ ? `${author?.biography
45
+ ?.split(" ")
46
+ .slice(0, maximumLength)
47
+ .join(" ")} <span class='${
40
48
  styles.contReadText
41
- // eslint-disable-next-line react-hooks/rules-of-hooks
42
- }'>${useTranslate('toggle_read', '...continue reading')}</span>`
49
+ // eslint-disable-next-line react-hooks/rules-of-hooks
50
+ }'>${useTranslate("toggle_read", "...continue reading")}</span>`
43
51
  : author?.biography,
44
52
  }}
45
53
  />
@@ -1,44 +1,59 @@
1
- import React from 'react';
1
+ import React from "react";
2
2
 
3
- import PropTypes from 'prop-types';
4
- import Link from '~hooks/link';
3
+ import PropTypes from "prop-types";
4
+ import Link from "~hooks/link";
5
5
 
6
- import styles from './breadcrumbs.module.scss';
7
- import keygen from '~helpers/keygen';
8
- import { excludeTemplates } from '../../../constants/excludedTemplates';
9
- import useTranslate from '~hooks/useTranslate/useTranslate';
6
+ import styles from "./breadcrumbs.module.scss";
7
+ import keygen from "~helpers/keygen";
8
+ import { excludeTemplates } from "../../../constants/excludedTemplates";
9
+ import useTranslate from "~hooks/useTranslate/useTranslate";
10
10
 
11
- function Breadcrumbs({ page, separator = <span aria-hidden="true"> / </span>, markets }) {
11
+ function Breadcrumbs({
12
+ page,
13
+ separator = <span aria-hidden="true"> / </span>,
14
+ markets,
15
+ }) {
12
16
  const activeMarket = markets && markets[page.market];
17
+ const breadcrumbAriaLabel = useTranslate(
18
+ "ariaLabel-breadcrumb",
19
+ "Breadcrumb"
20
+ );
21
+ const getTranslationArray = () => {
22
+ const translationArray = ["Home", `home_${page.type}`];
23
+ if (page.categories?.length > 0) {
24
+ translationArray.push(
25
+ `home_${page.template}_${page.categories[0].short_name}`
26
+ );
27
+ }
28
+ return translationArray;
29
+ };
30
+
31
+ const homeTranslation = useTranslate(getTranslationArray().reverse(), "Home");
13
32
 
14
33
  if (
15
34
  page.path ===
16
- `${activeMarket && activeMarket.path_prefix ? `${activeMarket.path_prefix}` : '/'}`
35
+ `${
36
+ activeMarket && activeMarket.path_prefix
37
+ ? `${activeMarket.path_prefix}`
38
+ : "/"
39
+ }`
17
40
  ) {
18
41
  return <></>;
19
42
  }
20
43
  const isExcludedTemplate = excludeTemplates.includes(page?.template);
21
44
 
22
- const getTranslationArray = () => {
23
- const translationArray = ['Home', `home_${page.type}`];
24
- if (page.categories?.length > 0) {
25
- translationArray.push(`home_${page.template}_${page.categories[0].short_name}`);
26
- }
27
- return translationArray;
28
- };
29
-
30
45
  return (
31
- <ol className={styles.breadcrumbs || ''} aria-label="Breadcrumb">
32
- <li className={styles.item || ''}>
46
+ <ol className={styles.breadcrumbs || ""} aria-label={breadcrumbAriaLabel}>
47
+ <li className={styles.item || ""}>
33
48
  {isExcludedTemplate ? (
34
- useTranslate(getTranslationArray().reverse(), 'Home')
49
+ homeTranslation
35
50
  ) : (
36
51
  <Link
37
- to={(activeMarket && activeMarket.path_prefix) || '/'}
52
+ to={(activeMarket && activeMarket.path_prefix) || "/"}
38
53
  title="Home"
39
54
  className="breadcrumbs-gtm"
40
55
  >
41
- {useTranslate(getTranslationArray().reverse(), 'Home')}
56
+ {homeTranslation}
42
57
  </Link>
43
58
  )}
44
59
 
@@ -48,7 +63,11 @@ function Breadcrumbs({ page, separator = <span aria-hidden="true"> / </span>, ma
48
63
  page.breadcrumbs.map((breadcrumb) => (
49
64
  <li key={keygen()} className={styles.item}>
50
65
  {breadcrumb.path ? (
51
- <Link to={breadcrumb.path} title={breadcrumb.label} className="breadcrumbs-gtm">
66
+ <Link
67
+ to={breadcrumb.path}
68
+ title={breadcrumb.label}
69
+ className="breadcrumbs-gtm"
70
+ >
52
71
  {breadcrumb.label}
53
72
  </Link>
54
73
  ) : (
@@ -57,7 +76,7 @@ function Breadcrumbs({ page, separator = <span aria-hidden="true"> / </span>, ma
57
76
  {separator}
58
77
  </li>
59
78
  ))}
60
- <li aria-current="page" className={styles.item || ''}>
79
+ <li aria-current="page" className={styles.item || ""}>
61
80
  {page.vanity_label ? page.vanity_label : page.title}
62
81
  </li>
63
82
  </ol>
@@ -1,21 +1,26 @@
1
- import React, { useContext } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { NavigationContext } from '~organisms/navigation/navigationContext';
4
- import styles from './menu-icon.module.scss';
1
+ import React, { useContext } from "react";
2
+ import PropTypes from "prop-types";
3
+ import { NavigationContext } from "~organisms/navigation/navigationContext";
4
+ import styles from "./menu-icon.module.scss";
5
+ import useTranslate from "../../../../hooks/useTranslate/useTranslate";
5
6
 
6
7
  const MenuIcon = ({ onClick, gtmClass }) => {
7
8
  const { showMenu } = useContext(NavigationContext);
8
9
 
9
10
  return (
10
11
  <div
11
- className={`${styles.menuIconContainer || ''} ${gtmClass}`}
12
+ className={`${styles.menuIconContainer || ""} ${gtmClass}`}
12
13
  onKeyDown={() => onClick()}
13
14
  onClick={() => onClick()}
14
15
  role="button"
15
- aria-label="Menu Icon"
16
+ aria-label={useTranslate("ariaLabel-menuIcon", "Menu Icon")}
16
17
  tabIndex={0}
17
18
  >
18
- <div className={`${styles.menuIcon || ''} ${(showMenu && styles.active) || ''}`}>
19
+ <div
20
+ className={`${styles.menuIcon || ""} ${
21
+ (showMenu && styles.active) || ""
22
+ }`}
23
+ >
19
24
  <div />
20
25
  </div>
21
26
  </div>
@@ -1,72 +1,88 @@
1
- import React, { useState, useContext, useEffect, useRef } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { toggleScroll } from 'gatsby-core-theme/src/helpers/scroll';
4
- import { NavigationContext } from 'gatsby-core-theme/src/components/organisms/navigation/navigationContext';
5
- import SpotlightItems from './notification-items/spotlight';
6
- import CardsItems from './notification-items/cards-v2';
7
- import BellIcon from '~images/icons/bell';
8
- import styles from './notifications.module.scss';
1
+ import React, { useState, useContext, useEffect, useRef } from "react";
2
+ import PropTypes from "prop-types";
3
+ import { toggleScroll } from "gatsby-core-theme/src/helpers/scroll";
4
+ import { NavigationContext } from "gatsby-core-theme/src/components/organisms/navigation/navigationContext";
5
+ import SpotlightItems from "./notification-items/spotlight";
6
+ import CardsItems from "./notification-items/cards-v2";
7
+ import BellIcon from "~images/icons/bell";
8
+ import styles from "./notifications.module.scss";
9
+ import useTranslate from "../../../hooks/useTranslate/useTranslate";
9
10
 
10
11
  const Notifications = ({ section }) => {
11
- const { setShowSearch, setShowMenu, showMenu, showSearch } = useContext(NavigationContext);
12
+ const { setShowSearch, setShowMenu, showMenu, showSearch } =
13
+ useContext(NavigationContext);
12
14
  const notificationRef = useRef(null);
13
15
  const [newNotification, setNewNotification] = useState(true);
14
16
  const [openNotification, setOpenNotification] = useState(false);
15
17
 
16
18
  const { modules } = section || {};
17
- const getNotifications = () => modules?.find((module) => module?.name === 'spotlights' || module?.name === 'cards_v2') || {};
19
+ const getNotifications = () =>
20
+ modules?.find(
21
+ (module) => module?.name === "spotlights" || module?.name === "cards_v2"
22
+ ) || {};
18
23
 
19
24
  const notificationActions = () => {
20
25
  setNewNotification(false);
21
26
  setOpenNotification(!openNotification);
22
27
 
23
28
  if (showSearch) {
24
- toggleScroll('search');
29
+ toggleScroll("search");
25
30
  setShowSearch(!showSearch);
26
31
  }
27
32
  if (showMenu) {
28
- toggleScroll('menu');
33
+ toggleScroll("menu");
29
34
  setShowMenu(!showMenu);
30
35
  }
31
-
32
36
  };
33
37
 
34
38
  useEffect(() => {
35
39
  function handleClickOutside(event) {
36
- if (notificationRef.current && !notificationRef.current.contains(event.target)) {
40
+ if (
41
+ notificationRef.current &&
42
+ !notificationRef.current.contains(event.target)
43
+ ) {
37
44
  setOpenNotification(false);
38
45
  }
39
46
  }
40
47
 
41
48
  // Bind the event listener
42
- document.addEventListener('mousedown', handleClickOutside);
49
+ document.addEventListener("mousedown", handleClickOutside);
43
50
 
44
51
  return () => {
45
52
  // Unbind the event listener on clean up
46
- document.removeEventListener('mousedown', handleClickOutside);
53
+ document.removeEventListener("mousedown", handleClickOutside);
47
54
  };
48
55
  }, [notificationRef]);
49
-
56
+
50
57
  return (
51
- <div ref={notificationRef} className={styles?.notificationOuter || ''}>
58
+ <div ref={notificationRef} className={styles?.notificationOuter || ""}>
52
59
  <div
53
- className={`${styles.notificationIcon || ''} ${
54
- newNotification ? styles.newNotification || '' : ''
60
+ className={`${styles.notificationIcon || ""} ${
61
+ newNotification ? styles.newNotification || "" : ""
55
62
  } notification-bell-gtm`}
56
63
  onKeyDown={() => notificationActions()}
57
64
  onClick={() => notificationActions()}
58
65
  role="button"
59
- aria-label="Notification Bell Icon"
66
+ aria-label={useTranslate(
67
+ "ariaLabel-notificationBellIcon",
68
+ "Notification Bell Icon"
69
+ )}
60
70
  tabIndex={0}
61
71
  >
62
72
  <BellIcon />
63
73
  </div>
64
- {openNotification && (
65
- getNotifications()?.name === 'cards_v2' ?
66
- <CardsItems module={getNotifications()} onClose={() => notificationActions()} /> :
67
- <SpotlightItems module={getNotifications()} onClose={() => notificationActions()} />
68
- )
69
- }
74
+ {openNotification &&
75
+ (getNotifications()?.name === "cards_v2" ? (
76
+ <CardsItems
77
+ module={getNotifications()}
78
+ onClose={() => notificationActions()}
79
+ />
80
+ ) : (
81
+ <SpotlightItems
82
+ module={getNotifications()}
83
+ onClose={() => notificationActions()}
84
+ />
85
+ ))}
70
86
  </div>
71
87
  );
72
88
  };
@@ -76,4 +92,5 @@ Notifications.propTypes = {
76
92
  section: PropTypes.shape({}),
77
93
  };
78
94
 
79
- export default Notifications;
95
+ export default Notifications;
96
+
@@ -1,131 +1,156 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import LazyImage from '~hooks/lazy-image';
4
- import keygen from '~helpers/keygen';
5
- import Link from '~hooks/link';
6
- import { imagePrettyUrl, getExtraField } from '~helpers/getters';
7
- import { getAltText, getImageFilename } from '~helpers/image';
8
- import useTranslate from '~hooks/useTranslate/useTranslate';
9
- import CloseIcon from '~images/icons/close';
10
- import styles from './notification-items.module.scss';
1
+ import React from "react";
2
+ import PropTypes from "prop-types";
3
+ import LazyImage from "~hooks/lazy-image";
4
+ import keygen from "~helpers/keygen";
5
+ import Link from "~hooks/link";
6
+ import { imagePrettyUrl, getExtraField } from "~helpers/getters";
7
+ import { getAltText, getImageFilename } from "~helpers/image";
8
+ import useTranslate from "~hooks/useTranslate/useTranslate";
9
+ import CloseIcon from "~images/icons/close";
10
+ import styles from "./notification-items.module.scss";
11
11
 
12
12
  const CardsItems = ({ module, onClose, useBanner = false }) => {
13
- const { items } = module;
14
- const noNewUpdates = useTranslate('noNewUpdates', 'No new items');
13
+ const { items } = module;
14
+ const noNewUpdates = useTranslate("noNewUpdates", "No new items");
15
15
 
16
- const getTimeAgo = (dateString) => {
17
- const date = new Date(dateString.replace(' ', 'T')); // Make it ISO-compliant
18
- const now = new Date();
16
+ const getTimeAgo = (dateString) => {
17
+ const date = new Date(dateString.replace(" ", "T")); // Make it ISO-compliant
18
+ const now = new Date();
19
19
 
20
- const diffMs = now.getTime() - date.getTime();
21
- const diffMinutes = Math.floor(diffMs / (1000 * 60));
22
- const diffHours = Math.floor(diffMinutes / 60);
23
- const diffDays = Math.floor(diffHours / 24);
24
- const diffMonths = Math.floor(diffDays / 30);
20
+ const diffMs = now.getTime() - date.getTime();
21
+ const diffMinutes = Math.floor(diffMs / (1000 * 60));
22
+ const diffHours = Math.floor(diffMinutes / 60);
23
+ const diffDays = Math.floor(diffHours / 24);
24
+ const diffMonths = Math.floor(diffDays / 30);
25
25
 
26
- let timeAgo = '';
26
+ let timeAgo = "";
27
27
 
28
- if (diffDays >= 32) {
29
- timeAgo = `${diffMonths} month${diffMonths > 1 ? 's' : ''} ago`;
30
- } else if (diffDays >= 1) {
31
- timeAgo = `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;
32
- } else if (diffHours >= 1) {
33
- timeAgo = `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`;
34
- } else {
35
- timeAgo = `${diffMinutes} minute${diffMinutes !== 1 ? 's' : ''} ago`;
36
- }
37
-
38
- return timeAgo;
28
+ if (diffDays >= 32) {
29
+ timeAgo = `${diffMonths} month${diffMonths > 1 ? "s" : ""} ago`;
30
+ } else if (diffDays >= 1) {
31
+ timeAgo = `${diffDays} day${diffDays > 1 ? "s" : ""} ago`;
32
+ } else if (diffHours >= 1) {
33
+ timeAgo = `${diffHours} hour${diffHours > 1 ? "s" : ""} ago`;
34
+ } else {
35
+ timeAgo = `${diffMinutes} minute${diffMinutes !== 1 ? "s" : ""} ago`;
39
36
  }
40
37
 
41
- const content = (item) => {
42
- const priorityImage = useBanner ? item?.banner || item?.relation?.logo?.fileName : item?.relation?.logo?.fileName;
43
- const img = getExtraField(item?.extra_fields, 'notification_image') || priorityImage || '';
44
- const imageSrc = imagePrettyUrl(img, 40, 40);
45
- const fileName = getImageFilename(imageSrc);
38
+ return timeAgo;
39
+ };
46
40
 
47
- const TitleTag = item?.title_tag || 'label';
48
- const ribbon = getExtraField(item?.extra_fields, 'notification_ribbon');
41
+ const content = (item) => {
42
+ const priorityImage = useBanner
43
+ ? item?.banner || item?.relation?.logo?.fileName
44
+ : item?.relation?.logo?.fileName;
45
+ const img =
46
+ getExtraField(item?.extra_fields, "notification_image") ||
47
+ priorityImage ||
48
+ "";
49
+ const imageSrc = imagePrettyUrl(img, 40, 40);
50
+ const fileName = getImageFilename(imageSrc);
49
51
 
50
-
52
+ const TitleTag = item?.title_tag || "label";
53
+ const ribbon = getExtraField(item?.extra_fields, "notification_ribbon");
51
54
 
52
- return (
53
- <div className={styles.notificationContent}>
54
- {img && (
55
- <LazyImage
56
- width={40}
57
- height={40}
58
- alt={getAltText(item?.image_object, item?.label || item?.link_text || fileName)}
59
- src={imageSrc}
60
- />
61
- )}
62
- <div className={styles.innerContent}>
63
- {item?.title && <TitleTag>{item?.title}</TitleTag>}
64
- {item?.description && (
65
- <div className={styles.subtitle} dangerouslySetInnerHTML={{ __html: item?.description }} />
66
- )}
67
- {item?.template && (
68
- <div className={styles.ribbonAndTime}>
69
- {ribbon && <span className={styles.ribbon}>{ribbon}</span>}
70
- <span className={styles.extraContent}>{getTimeAgo(item?.manual_updated_at || item?.updated_at || item?.manual_created_at || item?.created_at)}</span>
71
- </div>
72
- )}
73
- </div>
74
- </div>
75
- );
76
- };
77
55
  return (
78
- <div className={styles.container || ''}>
79
- <div className={styles.notificationsContainer || ''}>
80
- <span>
81
- {useTranslate('latestUpdates', 'Latest Updates')}
82
- <button
83
- type='button'
84
- onClick={onClose}
85
- className={styles.close || ''}
86
- aria-label="Close notifications"
87
- >
88
- <CloseIcon />
89
- </button>
90
- </span>
91
- {items?.length ? (
92
- <ul className={styles.notifications || ''}>
93
- {items.map((item) => (
94
- <li className={`${styles.notification} notification-item-gtm`} key={keygen()}>
95
- <Link
96
- to={item?.path}
97
- title={item?.title}
98
- className={`${styles.notificationLink} cards-gtm`}
99
- aria-label={`${item?.title} Link`}
100
- >
101
- {content(item)}
102
- </Link>
103
- </li>
104
- ))}
105
- </ul>
106
- ) : (
107
- <>{noNewUpdates}</>
56
+ <div className={styles.notificationContent}>
57
+ {img && (
58
+ <LazyImage
59
+ width={40}
60
+ height={40}
61
+ alt={getAltText(
62
+ item?.image_object,
63
+ item?.label || item?.link_text || fileName
64
+ )}
65
+ src={imageSrc}
66
+ />
67
+ )}
68
+ <div className={styles.innerContent}>
69
+ {item?.title && <TitleTag>{item?.title}</TitleTag>}
70
+ {item?.description && (
71
+ <div
72
+ className={styles.subtitle}
73
+ dangerouslySetInnerHTML={{ __html: item?.description }}
74
+ />
75
+ )}
76
+ {item?.template && (
77
+ <div className={styles.ribbonAndTime}>
78
+ {ribbon && <span className={styles.ribbon}>{ribbon}</span>}
79
+ <span className={styles.extraContent}>
80
+ {getTimeAgo(
81
+ item?.manual_updated_at ||
82
+ item?.updated_at ||
83
+ item?.manual_created_at ||
84
+ item?.created_at
108
85
  )}
86
+ </span>
109
87
  </div>
110
- <div className={styles.triangle} />
111
- <div
112
- className={styles.overlay}
113
- onKeyDown={onClose}
114
- onClick={onClose}
115
- role="button"
116
- aria-label="Notification Bell Icon"
117
- tabIndex={0}
118
- />
88
+ )}
119
89
  </div>
90
+ </div>
120
91
  );
92
+ };
93
+ return (
94
+ <div className={styles.container || ""}>
95
+ <div className={styles.notificationsContainer || ""}>
96
+ <span>
97
+ {useTranslate("latestUpdates", "Latest Updates")}
98
+ <button
99
+ type="button"
100
+ onClick={onClose}
101
+ className={styles.close || ""}
102
+ aria-label={useTranslate(
103
+ "ariaLabel-closeNotifications",
104
+ "Close notifications"
105
+ )}
106
+ >
107
+ <CloseIcon />
108
+ </button>
109
+ </span>
110
+ {items?.length ? (
111
+ <ul className={styles.notifications || ""}>
112
+ {items.map((item) => (
113
+ <li
114
+ className={`${styles.notification} notification-item-gtm`}
115
+ key={keygen()}
116
+ >
117
+ <Link
118
+ to={item?.path}
119
+ title={item?.title}
120
+ className={`${styles.notificationLink} cards-gtm`}
121
+ aria-label={`${item?.title} Link`}
122
+ >
123
+ {content(item)}
124
+ </Link>
125
+ </li>
126
+ ))}
127
+ </ul>
128
+ ) : (
129
+ <>{noNewUpdates}</>
130
+ )}
131
+ </div>
132
+ <div className={styles.triangle} />
133
+ <div
134
+ className={styles.overlay}
135
+ onKeyDown={onClose}
136
+ onClick={onClose}
137
+ role="button"
138
+ aria-label={useTranslate(
139
+ "ariaLabel-notificationBellIcon",
140
+ "Notification Bell Icon"
141
+ )}
142
+ tabIndex={0}
143
+ />
144
+ </div>
145
+ );
121
146
  };
122
147
 
123
148
  CardsItems.propTypes = {
124
- module: PropTypes.shape({
125
- items: PropTypes.arrayOf(PropTypes.shape({}))
126
- }),
127
- onClose: PropTypes.func,
128
- useBanner: PropTypes.bool
149
+ module: PropTypes.shape({
150
+ items: PropTypes.arrayOf(PropTypes.shape({})),
151
+ }),
152
+ onClose: PropTypes.func,
153
+ useBanner: PropTypes.bool,
129
154
  };
130
155
 
131
156
  export default CardsItems;