gatsby-matrix-theme 8.0.1 → 8.0.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ ## [8.0.2](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/compare/v8.0.1...v8.0.2) (2022-10-21)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * aligned with master and fixes ([6966281](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/69662815a0359cec2f0973613899d4f2eb80a41a))
7
+ * fixed conflict ([c9609b2](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/c9609b2b1fbf2684614a59dee7d61f3f1914a5e3))
8
+ * tests ([5340d2c](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/5340d2ce4da606f949e6849aae83ae8a138cf543))
9
+
10
+
11
+ ### Code Refactoring
12
+
13
+ * update tabs loading in search and toplist ([ba81a0b](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/ba81a0b9b3c5f2338f4bf82d61f1b0f73aeb8ed5))
14
+ * update toplist code splitting ([f4e73eb](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/f4e73eb0dfc63dd16081bdc6a677f90ad7e95926))
15
+ * update toplist title contex import ([552339c](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/552339c82bb7ad4bb944496f32a5822b5fa97768))
16
+
17
+
18
+ * Merge branch 'tm-3076-pagespeed-improvements-toplist-tabs' into 'master' ([b1067ea](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/commit/b1067ea6318efb077ee98463bde0cd4988f0edf7))
19
+
1
20
  ## [8.0.1](https://git.ilcd.rocks/team-floyd/themes/matrix-theme/compare/v8.0.0...v8.0.1) (2022-10-19)
2
21
 
3
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-matrix-theme",
3
- "version": "8.0.1",
3
+ "version": "8.0.2",
4
4
  "main": "index.js",
5
5
  "description": "Matrix Theme NPM Package",
6
6
  "author": "",
@@ -23,7 +23,7 @@ const Author = ({
23
23
  dateFormat = 'DD.MM.YYYY',
24
24
  isCardsAuthor = false,
25
25
  reviewer,
26
- clock = '../../../images/clock.svg'
26
+ clock = '../../../images/clock.svg',
27
27
  }) => {
28
28
  const { translations } = useContext(Context) || {};
29
29
  const prefixstyle = !link || !authorImg;
@@ -33,7 +33,11 @@ const Author = ({
33
33
  : translate(translations, 'written_by', 'Written by');
34
34
 
35
35
  return (
36
- <div className={`${styles.authorWraper} ${isCardsAuthor && styles.authorCard} ${styles.authorSeparator}`}>
36
+ <div
37
+ className={`${styles.authorWraper} ${isCardsAuthor && styles.authorCard} ${
38
+ styles.authorSeparator
39
+ }`}
40
+ >
37
41
  {name && (
38
42
  <div className={`${styles.infoContainer} ${isCardsAuthor && styles.infoCardContainer}`}>
39
43
  <p className={`${styles.prefixStyle} ${prefixstyle && styles.prefixCardText}`}>
@@ -65,8 +69,10 @@ const Author = ({
65
69
  )}
66
70
  {readingTime && !isCardsAuthor && (
67
71
  <div className={date && styles.readingWithBorder}>
68
- <img className={styles.clock} src={clock} alt='clock' />
69
- <span className={styles.readingTimeText}>{translate(translations, 'reading_time', 'Reading time')}</span>
72
+ <img className={styles.clock} src={clock} alt="clock" />
73
+ <span className={styles.readingTimeText}>
74
+ {translate(translations, 'reading_time', 'Reading time')}
75
+ </span>
70
76
  {` ${readingTime} ${translate(translations, 'minutes', 'min')}`}
71
77
  <span className={styles.readText}>{translate(translations, 'read', 'read')}</span>
72
78
  </div>
@@ -75,9 +81,7 @@ const Author = ({
75
81
  <div className={styles.dateTimeWrapper}>
76
82
  {!isCardsAuthor && <span>{translate(translations, 'published_on', 'Published on')}</span>}
77
83
  {` `}
78
- <a
79
- href='#authorbox'
80
- className={!isCardsAuthor && styles.dateLink}>
84
+ <a href="#authorbox" className={!isCardsAuthor && styles.dateLink}>
81
85
  {formatDate(date, dateFormat, splitDateFormat, 'en-GB')}
82
86
  </a>
83
87
  </div>
@@ -105,4 +109,4 @@ Author.propTypes = {
105
109
  clock: PropTypes.string,
106
110
  };
107
111
 
108
- export default Author;
112
+ export default Author;
@@ -10,7 +10,7 @@ import styles from 'gatsby-core-theme/src/components/molecules/main/main.module.
10
10
  import keygen from 'gatsby-core-theme/src/helpers/keygen';
11
11
  import settings from '../../../../constants/settings/newsletter';
12
12
 
13
- const Main = ({ section = {}, pageContext = {}, showAuthor = true, }) => {
13
+ const Main = ({ section = {}, pageContext = {}, showAuthor = true }) => {
14
14
  const { page } = pageContext;
15
15
  const siteName = process.env.GATSBY_SITE_NAME;
16
16
  const showNewsletter = !(
@@ -38,7 +38,11 @@ const Main = ({ section = {}, pageContext = {}, showAuthor = true, }) => {
38
38
  : null;
39
39
  const AuthorBox = page.author_id ? loadable(() => import(`~atoms/author-box`)) : null;
40
40
  const Author =
41
- page.path !== '/' && page.path !== 'contact-us' && page.path !== 'news' && page.author && showAuthor
41
+ page.path !== '/' &&
42
+ page.path !== 'contact-us' &&
43
+ page.path !== 'news' &&
44
+ page.author &&
45
+ showAuthor
42
46
  ? loadable(() => import('~atoms/author'))
43
47
  : null;
44
48
  const Feedback =
@@ -72,14 +76,15 @@ const Main = ({ section = {}, pageContext = {}, showAuthor = true, }) => {
72
76
  />
73
77
  ))}
74
78
  {SearchPage && <SearchPage page={page} />}
75
- {AuthorBox &&
76
- <AuthorBox
77
- author={page.author}
79
+ {AuthorBox && (
80
+ <AuthorBox
81
+ author={page.author}
78
82
  page={page}
79
83
  date={page.updated_at ? page.updated_at : page.created_at}
80
84
  readingTime={page.reading_time}
81
- reviewer={page.reviewer_id && page?.reviewer} />
82
- }
85
+ reviewer={page.reviewer_id && page?.reviewer}
86
+ />
87
+ )}
83
88
  {Feedback && (
84
89
  <Feedback
85
90
  trueVotes={page?.true_votes}
@@ -4,7 +4,6 @@ import PropTypes from 'prop-types';
4
4
  import { navigate } from 'gatsby';
5
5
  import { FaSearch } from '@react-icons/all-files/fa/FaSearch';
6
6
  import loadable from '@loadable/component';
7
- import Tabs from 'gatsby-matrix-theme/src/hooks/tabs';
8
7
  import { translate } from 'gatsby-core-theme/src/helpers/getters';
9
8
  import { Context } from 'gatsby-core-theme/src/context/TranslationsProvider';
10
9
 
@@ -256,6 +255,11 @@ const Search = ({
256
255
  </button>
257
256
  );
258
257
  }
258
+
259
+ const Tabs =
260
+ searchResultsRef.current.length !== 0 &&
261
+ loadable(() => import('gatsby-core-theme/src/hooks/tabs'));
262
+
259
263
  return (
260
264
  <>
261
265
  {formSearchOptionsCopy !== null && (
@@ -1,48 +1,73 @@
1
1
  /* eslint-disable react/forbid-prop-types */
2
+ /* eslint-disable import/no-extraneous-dependencies */
2
3
  import React from 'react';
3
- // eslint-disable-next-line import/no-extraneous-dependencies
4
4
  import PropTypes from 'prop-types';
5
- // eslint-disable-next-line import/no-extraneous-dependencies
5
+ import loadable from '@loadable/component';
6
6
  import keygen from '~helpers/keygen';
7
7
  import List from './list';
8
- import Tabs from '~hooks/tabs';
9
8
  import Row from '../../../../components/molecules/toplist/row/variant-one';
9
+ import styles from './toplist.module.scss';
10
10
 
11
- // eslint-disable-next-line no-unused-vars
12
- const TopList = ({ module, toplistHeading, CustomRow, page, isHomepageFirstModule = false }) => {
13
- const template = page?.template;
11
+ const TopList = ({
12
+ module,
13
+ toplistHeading,
14
+ CustomRow = Row,
15
+ page,
16
+ isHomepageFirstModule = false,
17
+ }) => {
18
+ const showTabs = module.items.length > 1;
19
+ const content = module.items.map((toplist) => (
20
+ <div label={toplist.title} key={keygen()}>
21
+ {toplistHeading}
22
+ <List
23
+ pagePath={page.path}
24
+ toplist={toplist}
25
+ CustomRow={CustomRow}
26
+ modulestyle={module?.style}
27
+ hasLoadMoreButton={toplist.show_load_more}
28
+ initItemsCount={toplist.num_items_initial_load}
29
+ loadItemsCount={toplist.num_items_load_more}
30
+ pageTemplate={page?.template}
31
+ />
32
+ </div>
33
+ ));
14
34
 
15
- return (
35
+ const Tabs = showTabs && loadable(() => import('~hooks/tabs'));
36
+ const Title =
37
+ !showTabs &&
38
+ (module.title || module.module_title) &&
39
+ loadable(() => import('gatsby-matrix-theme/src/gatsby-core-theme/hooks/tabs/title'));
40
+ const ModuleIntro =
41
+ !showTabs && module.module_introduction && loadable(() => import('~molecules/content'));
42
+
43
+ return showTabs ? (
16
44
  <Tabs
17
- title={module.title}
18
45
  module={module}
19
46
  tabsAlign="right"
20
47
  gtmClass="toplist-tabs-menu-gtm"
21
48
  isHomepageFirstModule={isHomepageFirstModule}
22
49
  >
23
- {module.items.map((toplist) => (
24
- <div label={toplist.title} key={keygen()}>
25
- {toplistHeading}
26
- <List
27
- pagePath={page.path}
28
- toplist={toplist}
29
- CustomRow={Row}
30
- modulestyle={module?.style}
31
- hasLoadMoreButton={toplist.show_load_more}
32
- initItemsCount={toplist.num_items_initial_load}
33
- loadItemsCount={toplist.num_items_load_more}
34
- pageTemplate={template}
35
- />
36
- </div>
37
- ))}
50
+ {content}
38
51
  </Tabs>
52
+ ) : (
53
+ <>
54
+ {Title && (
55
+ <div className={`${styles.tabsHeader} ${styles.titleAndTab}`}>
56
+ <Title module={module} />
57
+ </div>
58
+ )}
59
+ {ModuleIntro && <ModuleIntro module={{ value: module.module_introduction }} />}
60
+ {content}
61
+ </>
39
62
  );
40
63
  };
41
64
 
42
65
  TopList.propTypes = {
43
66
  module: PropTypes.shape({
44
- items: PropTypes.arrayOf(PropTypes.object),
67
+ items: PropTypes.arrayOf(PropTypes.shape({})),
45
68
  title: PropTypes.string,
69
+ module_title: PropTypes.string,
70
+ module_introduction: PropTypes.string,
46
71
  style: PropTypes.string,
47
72
  }),
48
73
  isHomepageFirstModule: PropTypes.bool,
@@ -0,0 +1,18 @@
1
+ .tabsHeader {
2
+ margin-bottom: 2rem !important;
3
+ display: grid;
4
+ grid-template-columns: auto;
5
+ @include min(tablet) {
6
+ grid-template-columns: 1fr;
7
+ }
8
+ h2 {
9
+ margin: 0;
10
+ }
11
+ }
12
+
13
+ .titleAndTab {
14
+ width: 100%;
15
+ display: flex;
16
+ justify-content: space-between;
17
+ flex-direction: column;
18
+ }
@@ -1,6 +1,90 @@
1
- import React from 'react';
2
- import TabListMatrix from '../../../hooks/tabs/index';
1
+ /* eslint-disable react/forbid-prop-types */
2
+ /* eslint-disable react/jsx-no-bind */
3
+ /* eslint-disable import/no-extraneous-dependencies */
4
+ import React, { useState } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import loadable from '@loadable/component';
7
+ import styles from './tabs.module.scss';
3
8
 
4
- const TabList = (props) => <TabListMatrix {...props} />;
9
+ const Tabs = ({
10
+ module = {},
11
+ siteName = '',
12
+ children,
13
+ showAll,
14
+ tabsAlign,
15
+ activeTabClass = '',
16
+ HeaderComp,
17
+ headerClass = '',
18
+ gtmClass = '',
19
+ }) => {
20
+ const showAllTabId = `${showAll}_0`;
21
+ const [activeTab, setActiveTab] = useState(
22
+ showAll ? showAllTabId : `${children[0].props.label}_0`
23
+ );
24
+ const Title =
25
+ module?.name === 'top_list' &&
26
+ (module?.title || module?.module_title) &&
27
+ loadable(() => import('./title'));
28
+ const TabList = children.length > 1 && loadable(() => import('./tab/tab-list'));
29
+ const { forceCheck } = TabList && loadable(() => import('react-lazyload'));
30
+ const ModuleIntro = module.module_introduction && loadable(() => import('~molecules/content'));
31
+ const tabHeaderClass = `${styles.tabsHeader} ${!HeaderComp && styles.tabsOnly} ${
32
+ styles[headerClass]
33
+ } ${tabsAlign === 'right' && styles.invertOrder}`;
5
34
 
6
- export default TabList;
35
+ return (
36
+ <>
37
+ <div className={tabHeaderClass}>
38
+ <div className={styles.titleAndTab}>
39
+ {Title && <Title module={module} />}
40
+ {TabList && (
41
+ <TabList
42
+ siteName={siteName}
43
+ title={module.title}
44
+ onClick={(tabId) => {
45
+ setActiveTab(tabId);
46
+ setTimeout(forceCheck);
47
+ }}
48
+ items={children}
49
+ activeTab={activeTab}
50
+ activeTabClass={activeTabClass}
51
+ showAll={showAll}
52
+ alignRight={tabsAlign === 'right'}
53
+ module={module}
54
+ gtmClass={gtmClass}
55
+ />
56
+ )}
57
+ </div>
58
+ {HeaderComp && <div className={styles.headerComp}>{HeaderComp}</div>}
59
+ </div>
60
+ {ModuleIntro && <ModuleIntro module={{ value: module.module_introduction }} />}
61
+ <div className="tab-content">
62
+ {children.map(
63
+ (child, index) =>
64
+ child !== null &&
65
+ (`${child.props.label}_${showAll ? index + 1 : index}` === activeTab ||
66
+ activeTab === showAllTabId) &&
67
+ child.props.children
68
+ )}
69
+ </div>
70
+ </>
71
+ );
72
+ };
73
+
74
+ Tabs.defaultProps = {
75
+ showAll: null,
76
+ };
77
+
78
+ Tabs.propTypes = {
79
+ children: PropTypes.arrayOf(PropTypes.any).isRequired,
80
+ showAll: PropTypes.string,
81
+ tabsAlign: PropTypes.string,
82
+ activeTabClass: PropTypes.string,
83
+ HeaderComp: PropTypes.objectOf(PropTypes.any),
84
+ headerClass: PropTypes.string,
85
+ module: PropTypes.shape({}),
86
+ siteName: PropTypes.string,
87
+ gtmClass: PropTypes.string,
88
+ };
89
+
90
+ export default Tabs;
@@ -1,7 +1,9 @@
1
+ /* eslint-disable react/forbid-prop-types */
2
+ /* eslint-disable react/jsx-no-bind */
3
+ /* eslint-disable import/no-extraneous-dependencies */
1
4
  import React, { useState, useEffect, useRef } from 'react';
2
5
  import PropTypes from 'prop-types';
3
- // eslint-disable-next-line import/no-extraneous-dependencies
4
- import Tab from 'gatsby-matrix-theme/src/hooks/tabs/tab/tab';
6
+ import Tab from 'gatsby-core-theme/src/hooks/tabs/tab/tab';
5
7
  import styles from './tab-list.module.scss';
6
8
  import keygen from '~helpers/keygen';
7
9
  import useWindowSize from '~hooks/useWindowSize';
@@ -1,3 +1,5 @@
1
+ /* eslint-disable react/forbid-prop-types */
2
+ /* eslint-disable import/no-extraneous-dependencies */
1
3
  import React from 'react';
2
4
  import PropTypes from 'prop-types';
3
5
  import styles from './tab.module.scss';
@@ -5,18 +5,6 @@
5
5
  grid-template-columns: max-content;
6
6
  margin-bottom: 2rem;
7
7
  }
8
- .noTag {
9
- display: block;
10
- color: var(--heading-base-color);
11
- margin: 1rem 0.3rem 0 0;
12
- font: {
13
- weight: bold;
14
- size: var(--h2-mobile-size);
15
- }
16
- @include min(tablet) {
17
- font-size: var(--h2-size);
18
- }
19
- }
20
8
  @include min(tablet) {
21
9
  grid-template-columns: 1fr 0.4fr;
22
10
  &.tabsonly {
@@ -28,21 +16,6 @@
28
16
  margin-bottom: 2rem;
29
17
  }
30
18
  }
31
- .toplistDate {
32
- color: var(--color-6);
33
- font-weight: 300;
34
- font-size: 1.4rem;
35
- padding-left: 0.5rem;
36
- display: inline-block;
37
- position: relative;
38
- top: -4px;
39
- small {
40
- padding-right: 0.5rem;
41
- font-size: 1.2rem;
42
- font-weight: 400;
43
- }
44
- }
45
-
46
19
  &.invertOrder {
47
20
  display: flex;
48
21
  justify-content: space-between;
@@ -85,10 +58,6 @@
85
58
  flex-direction: column;
86
59
  }
87
60
 
88
- .title {
89
- margin: 2rem 0;
90
- }
91
-
92
61
  .headerComp {
93
62
  select {
94
63
  margin: 2rem 0;
@@ -107,4 +76,4 @@
107
76
 
108
77
  .titleContainer {
109
78
  @include flex-align(center, center);
110
- }
79
+ }
@@ -0,0 +1,47 @@
1
+ /* eslint-disable no-nested-ternary */
2
+ /* eslint-disable react/jsx-no-bind */
3
+ /* eslint-disable react/forbid-prop-types */
4
+ /* eslint-disable import/no-extraneous-dependencies */
5
+ import React, { useContext } from 'react';
6
+ import PropTypes from 'prop-types';
7
+ import loadable from '@loadable/component';
8
+ import styles from './title.module.scss';
9
+
10
+ const TabsTitle = ({ module }) => {
11
+ const TitleTag = module?.module_title_tag
12
+ ? `${module?.module_title_tag}`
13
+ : module?.module_title
14
+ ? 'span'
15
+ : 'h2';
16
+ const showDate = module?.show_last_updated_date;
17
+ const { Context = {} } =
18
+ showDate && loadable(() => import('gatsby-core-theme/src/context/TranslationsProvider'));
19
+ const { translations } = useContext(Context) || {};
20
+ const { translate } = showDate && loadable(() => import('gatsby-core-theme/src/helpers/getters'));
21
+ const { getDate } = showDate && loadable(() => import('../../../../helpers/strings'));
22
+ const { month, year } = showDate && getDate();
23
+ const titleText = module?.module_title || module?.title;
24
+
25
+ return (
26
+ <TitleTag className={styles.noTag}>
27
+ {module?.module_title_tag ? <div className={styles.title}>{titleText}</div> : titleText}
28
+ {showDate && (
29
+ <span className={styles.toplistDate}>
30
+ <small>•</small>
31
+ {`${translate(translations, month, month)} ${year}`}
32
+ </span>
33
+ )}
34
+ </TitleTag>
35
+ );
36
+ };
37
+
38
+ TabsTitle.propTypes = {
39
+ module: PropTypes.shape({
40
+ title: PropTypes.string,
41
+ module_title: PropTypes.string,
42
+ module_title_tag: PropTypes.string,
43
+ show_last_updated_date: PropTypes.string,
44
+ }),
45
+ };
46
+
47
+ export default TabsTitle;
@@ -0,0 +1,29 @@
1
+ .title {
2
+ margin: 2rem 0;
3
+ }
4
+ .noTag {
5
+ display: block;
6
+ color: var(--heading-base-color);
7
+ margin: 1rem 0.3rem 0 0;
8
+ font: {
9
+ weight: bold;
10
+ size: var(--h2-mobile-size);
11
+ }
12
+ @include min(tablet) {
13
+ font-size: var(--h2-size);
14
+ }
15
+ }
16
+ .toplistDate {
17
+ color: var(--color-6);
18
+ font-weight: 300;
19
+ font-size: 1.4rem;
20
+ padding-left: 0.5rem;
21
+ display: inline-block;
22
+ position: relative;
23
+ top: -4px;
24
+ small {
25
+ padding-right: 0.5rem;
26
+ font-size: 1.2rem;
27
+ font-weight: 400;
28
+ }
29
+ }
@@ -72,3 +72,31 @@ export function transformMetaTitle(relation, metaTitle, type) {
72
72
  return metaTitle;
73
73
  }
74
74
  }
75
+
76
+ const monthNames = [
77
+ 'January',
78
+ 'February',
79
+ 'March',
80
+ 'April',
81
+ 'May',
82
+ 'June',
83
+ 'July',
84
+ 'August',
85
+ 'September',
86
+ 'October',
87
+ 'November',
88
+ 'December',
89
+ ];
90
+
91
+ export const getDate = () => {
92
+ const dateTime = new Date();
93
+ const date = dateTime.getDate();
94
+ const month = monthNames[dateTime.getMonth()];
95
+ const year = dateTime.getFullYear();
96
+
97
+ return {
98
+ date,
99
+ month,
100
+ year,
101
+ };
102
+ };
@@ -7,6 +7,7 @@ import {
7
7
  getTwitterUsername,
8
8
  getLaunchDate,
9
9
  transformMetaTitle,
10
+ getDate,
10
11
  } from './strings';
11
12
 
12
13
  describe('String helper component', () => {
@@ -53,4 +54,8 @@ describe('String helper component', () => {
53
54
  test('Meta title other types', () => {
54
55
  expect(transformMetaTitle(singleToplistData.items[0].items[0], 'Page', 'page')).toBe('Page');
55
56
  });
57
+
58
+ test('Get date', () => {
59
+ expect(getDate()).toBeTruthy();
60
+ });
56
61
  });
@@ -1,174 +0,0 @@
1
- /* eslint-disable react/forbid-prop-types */
2
- /* eslint-disable react/jsx-no-bind */
3
- /* eslint-disable import/no-extraneous-dependencies */
4
- import React, { useContext, useState } from 'react';
5
- import PropTypes from 'prop-types';
6
- import { forceCheck } from 'react-lazyload';
7
- import loadable from '@loadable/component';
8
- import { translate } from 'gatsby-core-theme/src/helpers/getters';
9
- import { Context } from 'gatsby-core-theme/src/context/TranslationsProvider';
10
- import styles from './tabs.module.scss';
11
-
12
- const Tabs = ({
13
- title = '',
14
- module = {},
15
- siteName = '',
16
- children,
17
- showAll,
18
- tabsAlign,
19
- activeTabClass = '',
20
- HeaderComp,
21
- headerClass = '',
22
- gtmClass = '',
23
- isHomepageFirstModule = false,
24
- }) => {
25
- const showAllTabId = `${showAll}_0`;
26
- const showTabs = children.length > 1;
27
- const [activeTab, setActiveTab] = useState(
28
- showAll ? showAllTabId : `${children[0].props.label}_0`
29
- );
30
-
31
- const TabList = showTabs ? loadable(() => import('./tab/tab-list')) : null;
32
- const CustomTag = `${module?.module_title_tag}`;
33
- const { translations } = useContext(Context) || {};
34
- const monthNames = [
35
- 'January',
36
- 'February',
37
- 'March',
38
- 'April',
39
- 'May',
40
- 'June',
41
- 'July',
42
- 'August',
43
- 'September',
44
- 'October',
45
- 'November',
46
- 'December',
47
- ];
48
- const d = new Date();
49
- const year = d.getFullYear();
50
- const month = monthNames[d.getMonth()];
51
- const currentMonth = module?.show_last_updated_date
52
- ? translate(translations, month, month)
53
- : false;
54
-
55
- const tabHeaderClass = `${styles.tabsHeader} ${!HeaderComp && styles.tabsOnly} ${
56
- styles[headerClass]
57
- } ${tabsAlign === 'right' && styles.invertOrder} ${
58
- isHomepageFirstModule && styles.tabsHeaderFirstModule
59
- }`;
60
- const getTitle = () => {
61
- if (!module?.module_title && !module?.title) {
62
- return null;
63
- }
64
-
65
- if (!module?.module_title) {
66
- return (
67
- <h2 className={styles.noTag}>
68
- {module.title}
69
- {currentMonth ? (
70
- <span className={styles.toplistDate}>
71
- <small>•</small>
72
- {`${currentMonth} ${year}`}
73
- </span>
74
- ) : null}
75
- </h2>
76
- );
77
- }
78
-
79
- if (module?.module_title_tag)
80
- return (
81
- <CustomTag className={styles.titleContainer}>
82
- <div className={styles.title}>{module.module_title}</div>
83
- {currentMonth ? (
84
- <span className={styles.toplistDate}>
85
- <small>•</small>
86
- {`${currentMonth} ${year}`}
87
- </span>
88
- ) : null}
89
- </CustomTag>
90
- );
91
- return (
92
- <span className={styles.noTag}>
93
- {module.module_title}
94
- {currentMonth ? (
95
- <span className={styles.toplistDate}>
96
- <small>•</small>
97
- {`${currentMonth} ${year}`}
98
- </span>
99
- ) : null}
100
- </span>
101
- );
102
- };
103
-
104
- function onClickTabItem(tabId) {
105
- setActiveTab(tabId);
106
- setTimeout(forceCheck);
107
- }
108
-
109
- const ModuleIntro = module.module_introduction && loadable(() => import('~molecules/content'));
110
-
111
- return (
112
- <>
113
- <div className={tabHeaderClass}>
114
- <div className={styles.titleAndTab}>
115
- {module.name === 'top_list' && getTitle(module)}
116
- {TabList ? (
117
- <TabList
118
- siteName={siteName}
119
- title={title}
120
- onClick={onClickTabItem}
121
- items={children}
122
- activeTab={activeTab}
123
- activeTabClass={activeTabClass}
124
- showAll={showAll}
125
- alignRight={tabsAlign === 'right'}
126
- module={module}
127
- gtmClass={gtmClass}
128
- />
129
- ) : (
130
- <></>
131
- )}
132
- </div>
133
- {HeaderComp && <div className={styles.headerComp}>{HeaderComp}</div>}
134
- </div>
135
- {ModuleIntro && (
136
- <ModuleIntro
137
- module={{ value: module.module_introduction }}
138
- isHomepageFirstModule={isHomepageFirstModule}
139
- />
140
- )}
141
- <div className="tab-content">
142
- {children.map((child, index) => {
143
- if (
144
- child === null ||
145
- (`${child.props.label}_${showAll ? index + 1 : index}` !== activeTab &&
146
- activeTab !== showAllTabId)
147
- )
148
- return undefined;
149
- return child.props.children;
150
- })}
151
- </div>
152
- </>
153
- );
154
- };
155
-
156
- Tabs.defaultProps = {
157
- showAll: null,
158
- };
159
-
160
- Tabs.propTypes = {
161
- children: PropTypes.arrayOf(PropTypes.any).isRequired,
162
- showAll: PropTypes.string,
163
- isHomepageFirstModule: PropTypes.bool,
164
- tabsAlign: PropTypes.string,
165
- activeTabClass: PropTypes.string,
166
- HeaderComp: PropTypes.objectOf(PropTypes.any),
167
- headerClass: PropTypes.string,
168
- title: PropTypes.string,
169
- module: PropTypes.shape({}),
170
- siteName: PropTypes.string,
171
- gtmClass: PropTypes.string,
172
- };
173
-
174
- export default Tabs;