gatsby-core-theme 1.3.0 → 1.4.2

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 (80) hide show
  1. package/.storybook/main.js +2 -3
  2. package/.storybook/preview.js +1 -4
  3. package/CHANGELOG.md +94 -0
  4. package/gatsby-node.esm.js +59 -19
  5. package/jest.config.js +1 -0
  6. package/package.json +1 -1
  7. package/src/components/app.js +12 -7
  8. package/src/components/atoms/archive/items/index.js +1 -1
  9. package/src/components/atoms/author/index.js +3 -2
  10. package/src/components/atoms/author-box/author-box.test.js +1 -5
  11. package/src/components/atoms/author-box/index.js +42 -13
  12. package/src/components/atoms/breadcrumbs/index.js +8 -4
  13. package/src/components/atoms/button/button.test.js +7 -0
  14. package/src/components/atoms/button/index.js +10 -3
  15. package/src/components/atoms/carousel/arrow/index.js +3 -2
  16. package/src/components/atoms/carousel/pagination-item/index.js +3 -2
  17. package/src/components/atoms/collapse/index.js +3 -1
  18. package/src/components/atoms/custom-select/index.js +2 -1
  19. package/src/components/atoms/logo/index.js +2 -2
  20. package/src/components/atoms/menu/items/index.js +6 -0
  21. package/src/components/atoms/menu/items/item/index.js +5 -4
  22. package/src/components/atoms/menu/menu-icon/index.js +4 -4
  23. package/src/components/atoms/module-title/index.js +2 -1
  24. package/src/components/atoms/not-found/index.js +14 -0
  25. package/src/components/atoms/not-found/not-found.module.scss +16 -0
  26. package/src/components/atoms/open-graph/index.js +5 -5
  27. package/src/components/atoms/operator-cta/index.js +15 -5
  28. package/src/components/atoms/operator-cta/{operator-cta.test.disabled.js → operator-cta.test.js} +12 -1
  29. package/src/components/atoms/operator-info-block/index.js +8 -1
  30. package/src/components/atoms/search/autocomplete/operator.js +1 -1
  31. package/src/components/atoms/spotlights/index.js +15 -4
  32. package/src/components/molecules/carousel/default-slide/index.js +4 -0
  33. package/src/components/molecules/counter/index.js +2 -2
  34. package/src/components/molecules/footer/index.js +6 -2
  35. package/src/components/molecules/header/header.test.js +0 -1
  36. package/src/components/molecules/link-list/index.js +9 -1
  37. package/src/components/molecules/main/index.js +3 -1
  38. package/src/components/molecules/menu/index.js +5 -1
  39. package/src/components/molecules/operator-banner/index.js +17 -7
  40. package/src/components/molecules/operator-banner/operator-banner.test.js +1 -1
  41. package/src/components/molecules/pagination/index.js +16 -5
  42. package/src/components/molecules/pagination/pagination.test.js +3 -3
  43. package/src/components/molecules/pagination/with-midpoints.js +41 -17
  44. package/src/components/molecules/pagination/with-midpoints.test.js +7 -8
  45. package/src/components/molecules/search/index.js +14 -3
  46. package/src/components/molecules/slider/index.js +27 -3
  47. package/src/components/molecules/toplist/default-row/index.js +27 -4
  48. package/src/components/organisms/accordion/accordion.test.js +3 -3
  49. package/src/components/organisms/accordion/index.js +1 -1
  50. package/src/components/organisms/anchor/index.js +2 -1
  51. package/src/components/organisms/archive/archive.test.js +8 -1
  52. package/src/components/organisms/archive/index.js +12 -12
  53. package/src/components/organisms/cards/cards.stories.js +1 -0
  54. package/src/components/organisms/cards/index.js +1 -1
  55. package/src/components/organisms/carousel/index.js +16 -17
  56. package/src/components/organisms/cookie-consent/cookie-consent.stories.js +6 -1
  57. package/src/components/organisms/cookie-consent/index.js +2 -0
  58. package/src/components/organisms/form/index.js +1 -0
  59. package/src/components/organisms/navigation/index.js +4 -4
  60. package/src/components/organisms/search/index.js +1 -1
  61. package/src/components/organisms/toplist/index.js +15 -19
  62. package/src/components/organisms/toplist/list/index.js +22 -29
  63. package/src/components/pages/body/index.js +9 -5
  64. package/src/components/pages/search/index.js +36 -1
  65. package/src/components/pages/tracker/index.js +8 -4
  66. package/src/constants/pick-keys.js +2 -0
  67. package/src/context/TranslationsProvider.js +9 -0
  68. package/src/helpers/processor/index.js +20 -3
  69. package/src/helpers/processor/processor.test.js +14 -0
  70. package/src/hooks/lazy-image/lazy-image.stories.js +1 -0
  71. package/src/hooks/link/index.js +2 -0
  72. package/src/hooks/link/link.test.js +9 -0
  73. package/src/hooks/modal/modal-content.js +7 -3
  74. package/src/hooks/modal/modal.test.js +3 -2
  75. package/src/hooks/tabs/index.js +4 -1
  76. package/src/hooks/tabs/tab/tab-list.js +4 -1
  77. package/src/hooks/tabs/tab/tab.js +11 -2
  78. package/src/pages/sitemap/index.js +77 -0
  79. package/src/pages/sitemap/sitemap.module.scss +21 -0
  80. package/tests/factories/relations/operator.factory.js +33 -0
@@ -6,23 +6,21 @@ import Slide from '~molecules/carousel/default-slide';
6
6
  import keygen from '~helpers/keygen';
7
7
  import styles from './carousel.module.scss';
8
8
 
9
- const Carousel = ({ module = {}, settings = {}, CustomSlideComponent }) => {
10
- return (
11
- <div className={styles.carouselContainer}>
12
- <Slider {...settings}>
13
- {module.items.map((item) => (
14
- <div key={keygen()} className={styles.carouselItem}>
15
- {CustomSlideComponent !== undefined ? (
16
- <CustomSlideComponent item={item} />
17
- ) : (
18
- <Slide item={item} />
19
- )}
20
- </div>
21
- ))}
22
- </Slider>
23
- </div>
24
- );
25
- };
9
+ const Carousel = ({ module = {}, settings = {}, CustomSlideComponent, gtmClass = '' }) => (
10
+ <div className={styles.carouselContainer}>
11
+ <Slider {...settings} gtmClass={gtmClass}>
12
+ {module.items.map((item) => (
13
+ <div key={keygen()} className={styles.carouselItem}>
14
+ {CustomSlideComponent !== undefined ? (
15
+ <CustomSlideComponent item={item} gtmClass={gtmClass} />
16
+ ) : (
17
+ <Slide item={item} gtmClass={gtmClass} />
18
+ )}
19
+ </div>
20
+ ))}
21
+ </Slider>
22
+ </div>
23
+ );
26
24
 
27
25
  Carousel.propTypes = {
28
26
  module: PropTypes.shape({
@@ -38,6 +36,7 @@ Carousel.propTypes = {
38
36
  }),
39
37
  settings: PropTypes.shape(PropTypes.object),
40
38
  CustomSlideComponent: PropTypes.element,
39
+ gtmClass: PropTypes.string,
41
40
  };
42
41
 
43
42
  export default Carousel;
@@ -5,6 +5,7 @@ import {
5
5
  Primary,
6
6
  PRIMARY_STORY,
7
7
  ArgsTable,
8
+ // eslint-disable-next-line import/no-extraneous-dependencies
8
9
  } from '@storybook/addon-docs/blocks';
9
10
 
10
11
  import CookieConsent from '.';
@@ -96,7 +97,11 @@ const Template = (args) => (
96
97
  <p>
97
98
  We use cookies in order to optimise our site and improve your experience with us. By using
98
99
  the site you consent to our
99
- <a href="/cookies"> &nbsp; Cookie Policy</a>.
100
+ <a href="/cookies" className="cookie-consent-gtm">
101
+ {' '}
102
+ &nbsp; Cookie Policy
103
+ </a>
104
+ .
100
105
  </p>
101
106
  </CookieConsent>
102
107
  </div>
@@ -42,6 +42,7 @@ const CookieConsent = ({
42
42
  btnText={acceptText}
43
43
  isInternalLink={false}
44
44
  isButton
45
+ gtmClass="cookie-consent-gtm btn-cta"
45
46
  />
46
47
 
47
48
  {declineText && (
@@ -50,6 +51,7 @@ const CookieConsent = ({
50
51
  btnText={declineText}
51
52
  isInternalLink={false}
52
53
  isButton
54
+ gtmClass="cookie-consent-gtm btn-cta"
53
55
  />
54
56
  )}
55
57
  </Sticky>
@@ -128,6 +128,7 @@ const FormComponent = ({
128
128
  isButton
129
129
  btnText={state.loading ? 'sending...' : buttonLabel}
130
130
  disabled={state.loading}
131
+ gtmClass="form-gtm btn-cta"
131
132
  />
132
133
  </div>
133
134
  )}
@@ -37,8 +37,8 @@ const Navigation = ({
37
37
  const navRef = useRef(React.createRef());
38
38
  const showMenu = template !== 'ppc';
39
39
  const logoPosition = showMenu ? 'space-between' : 'center';
40
-
41
- const Search = hasSearch ? loadable(() => import('~organisms/search')) : null;
40
+
41
+ const Search = hasSearch ? loadable(() => import('~organisms/search')) : null;
42
42
 
43
43
  if (options.mobile.stopScrollOnOpen) toggleScroll('', true);
44
44
 
@@ -62,12 +62,12 @@ const Navigation = ({
62
62
  >
63
63
  <nav className={styles.nav} style={{ justifyContent: logoPosition }} ref={navRef}>
64
64
  <NavigationProvider>
65
- <Link className={styles.logo} to="/" onClick={onClickHandler}>
65
+ <Link className={`${styles.logo} main-menu-gtm logo-cta`} to="/" onClick={onClickHandler}>
66
66
  <img alt="logo" src={logo} width={logoWidth} height={logoHeight} />
67
67
  </Link>
68
68
  {showMenu && (
69
69
  <>
70
- <Menu section={section} menu={menu} options={options} />
70
+ <Menu section={section} menu={menu} options={options} gtmClass="main-menu-gtm" />
71
71
  {hasSearch && <Search className={styles.search} searchIcon={searchIcon} />}
72
72
  </>
73
73
  )}
@@ -45,7 +45,7 @@ const SearchForm = ({ className, searchIcon, iconWidth = 24, iconHeight = 24 })
45
45
  type="button"
46
46
  aria-label="Search"
47
47
  onClick={handleOnSearchIconClick}
48
- className={`${styles.searchButton} ${showSearch && styles.active}`}
48
+ className={`${styles.searchButton} ${showSearch && styles.active} search-gtm btn-cta`}
49
49
  >
50
50
  {searchIcon === null ? (
51
51
  <FaSearch />
@@ -6,25 +6,21 @@ import Tabs from '~hooks/tabs';
6
6
 
7
7
  const TopList = ({ module, toplistHeading, CustomRow, page }) => {
8
8
  const template = page?.template;
9
- const translations = page?.translations;
10
9
  return (
11
- <Tabs tabsAlign="right">
12
- {module.items.map((toplist) => {
13
- return (
14
- <div label={toplist.title} key={keygen()}>
15
- {toplistHeading}
16
- <List
17
- toplist={toplist}
18
- CustomRow={CustomRow}
19
- translations={translations}
20
- hasLoadMoreButton={toplist.show_load_more}
21
- initItemsCount={toplist.num_items_initial_load}
22
- loadItemsCount={toplist.num_items_load_more}
23
- pageTemplate={template}
24
- />
25
- </div>
26
- );
27
- })}
10
+ <Tabs tabsAlign="right" gtmClass="toplist-tabs-menu-gtm">
11
+ {module.items.map((toplist) => (
12
+ <div label={toplist.title} key={keygen()}>
13
+ {toplistHeading}
14
+ <List
15
+ toplist={toplist}
16
+ CustomRow={CustomRow}
17
+ hasLoadMoreButton={toplist.show_load_more}
18
+ initItemsCount={toplist.num_items_initial_load}
19
+ loadItemsCount={toplist.num_items_load_more}
20
+ pageTemplate={template}
21
+ />
22
+ </div>
23
+ ))}
28
24
  </Tabs>
29
25
  );
30
26
  };
@@ -33,7 +29,7 @@ TopList.propTypes = {
33
29
  module: PropTypes.shape({ items: PropTypes.arrayOf(PropTypes.object) }),
34
30
  toplistHeading: PropTypes.element,
35
31
  CustomRow: PropTypes.func,
36
- page: PropTypes.shape({ template: PropTypes.string, translations: PropTypes.shape({}) }),
32
+ page: PropTypes.shape({ template: PropTypes.string }),
37
33
  };
38
34
 
39
35
  export default TopList;
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-return-assign */
1
2
  import React, { useRef } from 'react';
2
3
  import PropTypes from 'prop-types';
3
4
  import keygen from '~helpers/keygen';
@@ -13,7 +14,6 @@ export default function List({
13
14
  initItemsCount,
14
15
  loadItemsCount,
15
16
  pageTemplate,
16
- translations,
17
17
  }) {
18
18
  const initLoadItems = Number(initItemsCount) !== 0 ? Number(initItemsCount) : 10000;
19
19
  const loadingItems = Number(loadItemsCount) !== 0 ? Number(loadItemsCount) : 10000;
@@ -25,17 +25,13 @@ export default function List({
25
25
  const showLoadMoreButton = hasLoadMoreButton === '1' && Number(initItemsCount) !== 0;
26
26
 
27
27
  function handleClick() {
28
- const displayed = elRefs.current.filter((item) => {
29
- return item.classList.contains(styles.show);
30
- }).length;
28
+ const displayed = elRefs.current.filter((item) => item.classList.contains(styles.show)).length;
31
29
 
32
30
  const nextItem = loadingItems + displayed;
33
31
  const lastItem =
34
32
  nextItem > elRefs.current.length ? elRefs.current.length + 1 : displayed + loadingItems;
35
33
 
36
- elRefs.current.slice(displayed, lastItem).forEach((item) => {
37
- return item.classList.toggle(styles.show);
38
- });
34
+ elRefs.current.slice(displayed, lastItem).forEach((item) => item.classList.toggle(styles.show));
39
35
 
40
36
  if (loadingItems + displayed > elRefs.current.length) {
41
37
  loadMoreBtn.current.classList.toggle(styles.hide);
@@ -45,27 +41,24 @@ export default function List({
45
41
  return (
46
42
  <>
47
43
  <ul className={styles.list} key={keygen()}>
48
- {toplist.items.map((item, index) => {
49
- return (
50
- <li
51
- className={index + 1 <= initLoadItems ? styles.show : ''}
52
- key={keygen()}
53
- ref={(el) => (elRefs.current[index] = el)}
54
- >
55
- {CustomRow ? (
56
- <CustomRow
57
- item={item}
58
- tracker={toplist.tracker}
59
- oneliner={toplist.one_liner}
60
- isPPC={isPPCPage}
61
- translations={translations}
62
- />
63
- ) : (
64
- <Row item={item} tracker={toplist.tracker} oneliner={toplist.one_liner} />
65
- )}
66
- </li>
67
- );
68
- })}
44
+ {toplist.items.map((item, index) => (
45
+ <li
46
+ className={index + 1 <= initLoadItems ? styles.show : ''}
47
+ key={keygen()}
48
+ ref={(el) => (elRefs.current[index] = el)}
49
+ >
50
+ {CustomRow ? (
51
+ <CustomRow
52
+ item={item}
53
+ tracker={toplist.tracker}
54
+ oneliner={toplist.one_liner}
55
+ isPPC={isPPCPage}
56
+ />
57
+ ) : (
58
+ <Row item={item} tracker={toplist.tracker} oneliner={toplist.one_liner} />
59
+ )}
60
+ </li>
61
+ ))}
69
62
  </ul>
70
63
  {showLoadMoreButton && (
71
64
  <div ref={loadMoreBtn} className={styles.loadMore}>
@@ -76,6 +69,7 @@ export default function List({
76
69
  onClick={handleClick}
77
70
  invertColors
78
71
  primaryColor={false}
72
+ gtmClass="top-list-loadmore-gtm btn-cta"
79
73
  />
80
74
  </div>
81
75
  )}
@@ -98,5 +92,4 @@ List.propTypes = {
98
92
  initItemsCount: PropTypes.string,
99
93
  loadItemsCount: PropTypes.string,
100
94
  pageTemplate: PropTypes.string,
101
- translations: PropTypes.shape({}),
102
95
  };
@@ -9,9 +9,10 @@ import Navigation from '~organisms/navigation';
9
9
  import ScrollToTop from '~atoms/scroll-to-top';
10
10
  import CookieConsent from '~organisms/cookie-consent';
11
11
 
12
- function Body({ pageContext }) {
12
+ function Body({ pageContext, children }) {
13
13
  const getBodySection = (name) => getSection(name, pageContext);
14
- const template = pageContext.page.template;
14
+ const { template } = pageContext.page;
15
+ const is404 = pageContext?.page?.path?.includes('404');
15
16
 
16
17
  const main = getBodySection('main');
17
18
  const navigation = getBodySection('navigation');
@@ -19,12 +20,12 @@ function Body({ pageContext }) {
19
20
  const sidebar = getBodySection('sidebar');
20
21
 
21
22
  const Sidebar = sidebar ? loadable(() => import(`~molecules/sidebar`)) : null;
22
-
23
23
  return (
24
24
  <>
25
25
  {navigation && <Navigation template={template} section={navigation} />}
26
- <Header section={pageContext} />
27
- {main && <Main section={main} page={pageContext.page} />}
26
+ {!is404 && <Header section={pageContext} />}
27
+ {main && !children && <Main section={main} page={pageContext.page} />}
28
+ {children && <main>{children}</main>}
28
29
  {Sidebar && <Sidebar section={sidebar} />}
29
30
  <ScrollToTop />
30
31
  <Footer template={template} section={footer} />
@@ -34,9 +35,12 @@ function Body({ pageContext }) {
34
35
  }
35
36
 
36
37
  Body.propTypes = {
38
+ children: PropTypes.element,
37
39
  pageContext: PropTypes.shape({
38
40
  page: PropTypes.shape({
39
41
  id: PropTypes.number,
42
+ path: PropTypes.string,
43
+ template: PropTypes.string,
40
44
  }),
41
45
  }).isRequired,
42
46
  };
@@ -1,15 +1,37 @@
1
+ /* eslint-disable arrow-body-style */
1
2
  import React from 'react';
3
+ import PropTypes from 'prop-types';
2
4
 
3
5
  import Search from '~molecules/search';
4
6
  import Card from '~atoms/cards/default-card';
7
+ import { translate } from '~helpers/getters';
5
8
 
6
- const SearchContent = () => {
9
+ const SearchContent = ({ page }) => {
7
10
  return (
8
11
  <Search
9
12
  pageSearchOptions={{
13
+ useArchive: true,
14
+ archiveOptions: {
15
+ titles: [
16
+ { type: 'operator', title: translate(page?.translations, 'casino', 'Casino') },
17
+ { type: 'article', title: translate(page?.translations, 'news', 'News') },
18
+ ],
19
+ includeOptions: {
20
+ desktop_num_of_columns: '3',
21
+ mobile_num_of_columns: '1',
22
+ tablet_num_of_columns: '3',
23
+ },
24
+ },
10
25
  tabs: true,
11
26
  tabsOptions: { showAll: 'ShowAll', tabsAlign: 'left' },
12
27
  sort: [{ name: 'Sorting', field: 'id', type: 'number' }],
28
+ loadMore: {
29
+ label: translate(page?.translations, 'show_more', 'Show more'),
30
+ limit: 3,
31
+ increment: 6,
32
+ usePrimaryButton: false,
33
+ useInvertColors: true,
34
+ },
13
35
  }}
14
36
  >
15
37
  {(item) => (
@@ -26,4 +48,17 @@ const SearchContent = () => {
26
48
  );
27
49
  };
28
50
 
51
+ SearchContent.propTypes = {
52
+ page: PropTypes.shape({
53
+ template: PropTypes.string,
54
+ path: PropTypes.string,
55
+ updated_at: PropTypes.string,
56
+ created_at: PropTypes.string,
57
+ author: PropTypes.shape({
58
+ name: PropTypes.string,
59
+ }),
60
+ translations: PropTypes.shape({}),
61
+ }),
62
+ };
63
+
29
64
  export default SearchContent;
@@ -10,9 +10,9 @@ import styles from './tracker.module.scss';
10
10
  const Tracker = ({
11
11
  pageContext,
12
12
  path,
13
- mainText = '',
14
- redirectText = '',
15
- btnText = '',
13
+ mainText = 'One sec, while we load [operator_name] for you..',
14
+ redirectText = 'If the casino has not loaded within a few seconds',
15
+ btnText = 'Click Here!',
16
16
  bgImage = '',
17
17
  bgVideo = '',
18
18
  redirectTimer = 5000,
@@ -95,7 +95,10 @@ const Tracker = ({
95
95
  {background}
96
96
  <div className={styles.content}>
97
97
  <LazyImage alt="Site logo" src={logo} />
98
- <p className={styles.mainText}>{`${mainText} ${operator.name}`}</p>
98
+ <p className={styles.mainText}>{`${mainText.replace(
99
+ '[operator_name]',
100
+ operator.name
101
+ )}`}</p>
99
102
  <div className={styles.bar} />
100
103
  {counter ? (
101
104
  redirectText
@@ -113,6 +116,7 @@ const Tracker = ({
113
116
  to={prettyTracker(operator)}
114
117
  targetBlank={false}
115
118
  isInternalLink={false}
119
+ gtmClass="tracker-gtm btn-cta"
116
120
  />
117
121
  </div>
118
122
  </div>
@@ -62,3 +62,5 @@ export const pickRelationKeys = {
62
62
  software_provider: ['logo', 'games_count', 'name'],
63
63
  payment_method: ['logo', 'name'],
64
64
  };
65
+
66
+ export const pickHTMLSitemapPageKeys = ['title', 'path', 'template_id'];
@@ -0,0 +1,9 @@
1
+ import React, { createContext } from 'react';
2
+
3
+ export const Context = createContext();
4
+
5
+ export default (props) => {
6
+ // eslint-disable-next-line react/prop-types
7
+ const { value, children } = props;
8
+ return <Context.Provider value={value}>{children}</Context.Provider>;
9
+ };
@@ -3,15 +3,16 @@
3
3
  /* eslint-disable no-use-before-define */
4
4
  /* eslint-disable no-shadow */
5
5
 
6
- import { cloneDeep } from 'lodash';
6
+ import { cloneDeep, pick } from 'lodash';
7
7
  import chalk from 'chalk';
8
8
  import ModuleValue from '../../constants/module-value';
9
9
  import SearchTypesEnable from '../../constants/search-types-enable';
10
+ import { pickHTMLSitemapPageKeys } from '../../constants/pick-keys';
10
11
 
11
12
  // eslint-disable-next-line import/no-cycle
12
13
  import { processModule } from './modules';
13
14
  // eslint-disable-next-line import/no-cycle
14
- import { clonePageForCards } from './common';
15
+ import { clonePageForCards, groupBy } from './common';
15
16
  import { prepareSportsData, addSportsDataToPage } from './sports';
16
17
 
17
18
  const previewMode = process.env.GATSBY_PREVIEW_MODE || false;
@@ -32,7 +33,23 @@ let prefilledMarketModules = null;
32
33
  let prefilledMarketModulesRaw = null;
33
34
  let sportsData = null;
34
35
 
35
- // transform into right format
36
+ export function processSitemapPages(pages, markets) {
37
+ const pageListByMarket = [];
38
+ Object.keys(markets).forEach((market) => {
39
+ pageListByMarket[market] = [];
40
+ let pageList = [];
41
+ Object.keys(pages[market]).forEach((pageType) => {
42
+ pageList = pageList.concat(
43
+ pages[market][pageType].map((row) => pick(row, pickHTMLSitemapPageKeys))
44
+ );
45
+ });
46
+
47
+ pageListByMarket[market] = groupBy(pageList, 'template_id');
48
+ });
49
+
50
+ return pageListByMarket;
51
+ }
52
+
36
53
  function transform(response) {
37
54
  const transformed = {};
38
55
  Object.keys(response.site_markets).forEach((siteMarket) => {
@@ -0,0 +1,14 @@
1
+ import { processSitemapPages } from '.';
2
+ import getPageDataList from '~tests/factories/pages/list.factory';
3
+
4
+ describe('processor Helper', () => {
5
+ test('process sitemap', () => {
6
+ const pageList = getPageDataList(10);
7
+ const market = 'ie';
8
+ const processedSitemap = processSitemapPages(
9
+ { [market]: { type: pageList } },
10
+ { [market]: [] }
11
+ );
12
+ expect(processedSitemap[market]['5']).toHaveLength(10);
13
+ });
14
+ });
@@ -185,5 +185,6 @@ BrokenURL.story = {
185
185
  alt: 'This image has a broken URL',
186
186
  defaultImg: <FaRegFrownOpen size={250} />,
187
187
  once: false,
188
+ style: { 'border-radius': '1rem' },
188
189
  },
189
190
  };
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ // eslint-disable-next-line import/no-extraneous-dependencies
2
3
  import GatsbyLink from 'gatsby-link';
3
4
  import { navigate } from '@reach/router';
4
5
  import PropTypes from 'prop-types';
@@ -53,6 +54,7 @@ Link.propTypes = {
53
54
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.element, PropTypes.any]),
54
55
  activeClassName: PropTypes.string,
55
56
  partiallyActive: PropTypes.bool,
57
+ gtmClass: PropTypes.string,
56
58
  };
57
59
 
58
60
  export default Link;
@@ -23,6 +23,15 @@ describe('Link Component', () => {
23
23
  );
24
24
  expect(getByText('Test Content').closest('a')).toHaveAttribute('href', '/test/link');
25
25
  });
26
+
27
+ test('test GTM class', () => {
28
+ const { getByText } = render(
29
+ <Link to="test/link" className="testClassName test-gtm">
30
+ Test Content
31
+ </Link>
32
+ );
33
+ expect(getByText('Test Content').closest('a').classList.contains('test-gtm')).toBe(true);
34
+ });
26
35
  });
27
36
  afterEach(() => {
28
37
  cleanup();
@@ -1,3 +1,6 @@
1
+ /* eslint-disable jsx-a11y/click-events-have-key-events */
2
+ /* eslint-disable jsx-a11y/no-static-element-interactions */
3
+
1
4
  import React, { useContext, useRef, useEffect } from 'react';
2
5
  import PropTypes from 'prop-types';
3
6
  import { ModalContext } from './modalContext';
@@ -7,6 +10,7 @@ const ModalContent = ({ closeIcon }) => {
7
10
  const { showModal, setShowModal, modalContent, setModalContent } = useContext(ModalContext);
8
11
  const modal = useRef(null);
9
12
 
13
+ // eslint-disable-next-line react-hooks/exhaustive-deps
10
14
  const close = () => {
11
15
  setShowModal(false);
12
16
  setModalContent('');
@@ -31,7 +35,7 @@ const ModalContent = ({ closeIcon }) => {
31
35
  return () => {
32
36
  if (typeof window !== 'undefined') window.removeEventListener('keydown', handleEsc);
33
37
  };
34
- }, []);
38
+ }, [close]);
35
39
 
36
40
  // Close on outside click
37
41
  useEffect(() => {
@@ -49,14 +53,14 @@ const ModalContent = ({ closeIcon }) => {
49
53
  if (typeof window !== 'undefined')
50
54
  window.removeEventListener('mousedown', handleOutsideClick);
51
55
  };
52
- }, []);
56
+ }, [close]);
53
57
 
54
58
  return (
55
59
  <div className={styles.modalInner} ref={modal}>
56
60
  <div className={styles.modalOverlay} onClick={close} />
57
61
  <div className={styles.modalContent}>
58
62
  {closeIcon && (
59
- <button className={styles.closeIcon} onClick={close}>
63
+ <button className={`${styles.closeIcon} modal-gtm btn-cta`} type="button" onClick={close}>
60
64
  {closeIcon}
61
65
  </button>
62
66
  )}
@@ -8,9 +8,10 @@ import ModalProvider from './modalContext';
8
8
  import ModalContent from './modal-content';
9
9
 
10
10
  const setUp = () => {
11
+ React.useContext = ModalProvider;
11
12
  const { container, getAllByText } = render(
12
13
  <ModalProvider>
13
- <Modal content={'Modal opened'} >
14
+ <Modal content="Modal opened">
14
15
  <p>Click me</p>
15
16
  </Modal>
16
17
  <ModalContent closeIcon={<MdClose />} overlay />
@@ -32,7 +33,7 @@ describe('Modal Component', () => {
32
33
 
33
34
  // Toggle effect
34
35
  test('toggle modal', () => {
35
- const { container,getAllByText } = setUp();
36
+ const { container, getAllByText } = setUp();
36
37
  const toggleBtn = container.querySelector('p');
37
38
 
38
39
  fireEvent.click(toggleBtn);
@@ -10,6 +10,7 @@ const Tabs = ({
10
10
  activeTabClass = '',
11
11
  HeaderComp,
12
12
  headerClass = '',
13
+ gtmClass = '',
13
14
  }) => {
14
15
  const showAllTabId = `${showAll}_0`;
15
16
  const showTabs = children.length > 1;
@@ -35,7 +36,8 @@ const Tabs = ({
35
36
  activeTab={activeTab}
36
37
  activeTabClass={activeTabClass}
37
38
  showAll={showAll}
38
- alignRight={tabsAlign === 'right' ? true : false}
39
+ gtmClass={gtmClass}
40
+ alignRight={tabsAlign === 'right'}
39
41
  />
40
42
  )}
41
43
  {HeaderComp && <div className={styles.headerComp}>{HeaderComp}</div>}
@@ -67,6 +69,7 @@ Tabs.propTypes = {
67
69
  activeTabClass: PropTypes.string,
68
70
  HeaderComp: PropTypes.objectOf(PropTypes.any),
69
71
  headerClass: PropTypes.string,
72
+ gtmClass: PropTypes.string,
70
73
  };
71
74
 
72
75
  export default Tabs;
@@ -16,6 +16,7 @@ const TabList = ({
16
16
  activeTabClass = '',
17
17
  showAll,
18
18
  alignRight = false,
19
+ gtmClass = '',
19
20
  }) => {
20
21
  const [tabItems, setTabItems] = useState(items);
21
22
 
@@ -41,7 +42,7 @@ const TabList = ({
41
42
  <div className={`${styles.tabList} ${alignRight && styles.right}`}>
42
43
  <button
43
44
  ref={filterBtn}
44
- className={styles.select}
45
+ className={`${styles.select} ${gtmClass} btn-cta`}
45
46
  type="button"
46
47
  onClick={showDropdown}
47
48
  data-id="select-button"
@@ -62,6 +63,7 @@ const TabList = ({
62
63
  label={label}
63
64
  onClick={onClick}
64
65
  toggleDropdown={showDropdown}
66
+ gtmClass={gtmClass}
65
67
  />
66
68
  );
67
69
  })}
@@ -77,6 +79,7 @@ TabList.propTypes = {
77
79
  activeTab: PropTypes.string,
78
80
  activeTabClass: PropTypes.string,
79
81
  alignRight: PropTypes.bool,
82
+ gtmClass: PropTypes.bool,
80
83
  };
81
84
 
82
85
  export default TabList;