gatsby-core-theme 1.6.20 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/gatsby-node.esm.js +23 -14
  3. package/package.json +2 -2
  4. package/src/components/app.js +4 -0
  5. package/src/components/atoms/iframe/index.js +15 -9
  6. package/src/components/atoms/selling-points/index.js +1 -2
  7. package/src/components/atoms/selling-points/selling-points.module.scss +12 -5
  8. package/src/components/atoms/selling-points/selling-points.test.js +1 -1
  9. package/src/components/molecules/content/index.js +5 -1
  10. package/src/components/molecules/footer/footer.test.js +22 -22
  11. package/src/components/molecules/footer/index.js +3 -1
  12. package/src/components/molecules/header/index.js +7 -2
  13. package/src/components/molecules/link-list/index.js +9 -12
  14. package/src/components/molecules/operator-banner/operator-banner.test.js +0 -1
  15. package/src/components/molecules/search/index.js +5 -3
  16. package/src/components/molecules/slider/index.js +6 -2
  17. package/src/components/molecules/slider/slider.test.js +30 -23
  18. package/src/components/molecules/star-rating/index.js +8 -24
  19. package/src/components/molecules/star-rating/star-rating.module.scss +13 -1
  20. package/src/components/molecules/star-rating/star-rating.test.js +4 -2
  21. package/src/components/molecules/tnc/index.js +2 -3
  22. package/src/components/molecules/tnc/tnc.test.js +0 -1
  23. package/src/components/molecules/toplist/default-row/index.js +22 -20
  24. package/src/components/pages/search/index.js +3 -2
  25. package/src/helpers/device-detect.js +5 -6
  26. package/src/helpers/events.js +91 -0
  27. package/src/helpers/generators.js +11 -3
  28. package/src/helpers/generators.test.js +34 -12
  29. package/src/helpers/processor/sports.js +0 -2
  30. package/src/helpers/rating.js +2 -0
  31. package/src/helpers/schedule.js +0 -36
  32. package/src/hooks/lazy-image/index.js +30 -44
  33. package/src/hooks/tabs/index.js +4 -2
  34. package/src/hooks/tabs/tabs.test.js +32 -15
  35. package/src/styles/utils/_mixins.scss +42 -0
  36. package/src/styles/utils/variables/_main.scss +8 -0
@@ -1,20 +1,11 @@
1
1
  import React from 'react';
2
- import { FaStar, FaStarHalfAlt, FaRegStar } from 'react-icons/fa';
3
2
  import PropTypes from 'prop-types';
4
- import LazyLoad from 'react-lazyload';
5
3
 
6
4
  import styles from './star-rating.module.scss';
7
5
  import keygen from '~helpers/keygen';
8
6
  import { getRating } from '~helpers/rating';
9
7
 
10
- const StarRating = ({
11
- numOfStars,
12
- iconEmpty = <FaRegStar />,
13
- iconHalf = <FaStarHalfAlt />,
14
- iconFull = <FaStar />,
15
- rating,
16
- halfStars = true,
17
- }) => {
8
+ const StarRating = ({ numOfStars, rating, halfStars = true }) => {
18
9
  const renderFarm = () => {
19
10
  const output = [];
20
11
  const rate = getRating(rating);
@@ -22,38 +13,31 @@ const StarRating = ({
22
13
  for (let i = 1; i < numOfStars + 1; i += 1) {
23
14
  if (i <= rate) {
24
15
  output.push(
25
- <span className={`${styles.starItem} ${styles.starFull}`} key={keygen()}>
26
- {iconFull}
16
+ <span className={styles.fullStar} key={keygen()}>
17
+ {' '}
27
18
  </span>
28
19
  );
29
20
  } else if (halfStars && i - 0.5 === rate) {
30
21
  output.push(
31
- <span className={`${styles.starItem} ${styles.starHalf}`} key={keygen()}>
32
- {iconHalf}
22
+ <span className={styles.halfStar} key={keygen()}>
23
+ {' '}
33
24
  </span>
34
25
  );
35
26
  } else {
36
27
  output.push(
37
- <span className={`${styles.starItem} ${styles.starEmpty}`} key={keygen()}>
38
- {iconEmpty}
28
+ <span className={styles.emptyStar} key={keygen()}>
29
+ {' '}
39
30
  </span>
40
31
  );
41
32
  }
42
33
  }
43
34
  return output;
44
35
  };
45
- return (
46
- <LazyLoad once>
47
- <div className={styles.starRatingContainer}>{renderFarm()}</div>
48
- </LazyLoad>
49
- );
36
+ return <div className={styles.starRatingContainer}>{renderFarm()}</div>;
50
37
  };
51
38
 
52
39
  StarRating.propTypes = {
53
40
  numOfStars: PropTypes.oneOf([5, 10]).isRequired,
54
- iconEmpty: PropTypes.element,
55
- iconHalf: PropTypes.element,
56
- iconFull: PropTypes.element,
57
41
  rating: PropTypes.oneOfType([PropTypes.array, PropTypes.number, PropTypes.string]).isRequired,
58
42
  halfStars: PropTypes.bool,
59
43
  };
@@ -7,4 +7,16 @@
7
7
  fill: var(--star-rating-color);
8
8
  }
9
9
  }
10
- }
10
+
11
+ .fullStar{
12
+ @include star(var(--full-star-fill-color), var(--full-star-border-color))
13
+ }
14
+
15
+ .halfStar{
16
+ @include half-star(var(--half-star-border-color), var(--halfFull-star-fill-color), var(--halfEmpty-star-fill-color))
17
+ }
18
+
19
+ .emptyStar{
20
+ @include star(var(--empty-star-border-color), var(--empty-star-fill-color))
21
+ }
22
+ }
@@ -7,8 +7,10 @@ import StarRating from '.';
7
7
  describe('StarRating Component', () => {
8
8
  test('render container with lazyload', () => {
9
9
  const { container } = render(<StarRating numOfStars={10} rating={6.5} />);
10
- expect(container).toBeTruthy();
11
- expect(container.querySelectorAll('.lazyload-placeholder')).toHaveLength(1);
10
+
11
+ expect(container.querySelectorAll('.fullStar')).toHaveLength(6);
12
+ expect(container.querySelectorAll('.halfStar')).toHaveLength(1);
13
+ expect(container.querySelectorAll('.emptyStar')).toHaveLength(3);
12
14
  });
13
15
  });
14
16
  afterEach(() => {
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import LazyLoad from 'react-lazyload';
4
3
 
5
4
  import Collapse from '~atoms/collapse';
6
5
 
@@ -13,7 +12,7 @@ const Tnc = ({
13
12
  initOpen = false,
14
13
  operator,
15
14
  }) => (
16
- <LazyLoad once>
15
+ <>
17
16
  {hasCollapse ? (
18
17
  <Collapse
19
18
  onlyMobile={onlyMobile}
@@ -26,7 +25,7 @@ const Tnc = ({
26
25
  ) : (
27
26
  contentText
28
27
  )}
29
- </LazyLoad>
28
+ </>
30
29
  );
31
30
 
32
31
  Tnc.propTypes = {
@@ -8,7 +8,6 @@ describe('Tnc Component', () => {
8
8
  test('render component', () => {
9
9
  const { container } = render(<Tnc />);
10
10
  expect(container).toBeTruthy();
11
- expect(container.querySelectorAll('.lazyload-placeholder')).toHaveLength(1);
12
11
  });
13
12
  });
14
13
  afterEach(() => {
@@ -1,18 +1,21 @@
1
- import React from 'react';
1
+ import React, { useContext } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { MdCheck } from 'react-icons/md';
4
-
5
- import Button from '~atoms/button';
6
4
  import Bonus from '~atoms/bonus';
5
+ import { Context } from '~context/TranslationsProvider';
7
6
  import SellingPoints from '~atoms/selling-points';
8
-
9
- import { prettyTracker, imagePrettyUrl } from '~helpers/getters';
7
+ import StarRating from '~molecules/star-rating';
8
+ import Link from '~hooks/link';
9
+ import OperatorCta from '~atoms/operator-cta';
10
+ import { prettyTracker, imagePrettyUrl, translate } from '~helpers/getters';
10
11
  import LazyImage from '~hooks/lazy-image';
11
12
 
12
13
  import styles from './default-row.module.scss';
13
14
 
14
- const Row = ({ item, oneliner = 'main', layout = 'list' }) => {
15
+ const Row = ({ item, oneliner = 'main', layout = 'list', tracker = 'main' }) => {
15
16
  const prettyLink = prettyTracker(item);
17
+ const itemRating = item.rating;
18
+ const { translations } = useContext(Context) || {};
16
19
 
17
20
  return (
18
21
  <div className={`${styles.row} ${styles[layout]}`}>
@@ -33,26 +36,23 @@ const Row = ({ item, oneliner = 'main', layout = 'list' }) => {
33
36
  rel="noreferrer"
34
37
  aria-label={`${item.name} Link`}
35
38
  >
36
- <LazyImage alt={item.name} src={imagePrettyUrl(item.logo_url, 100)} />
39
+ <LazyImage
40
+ alt={item.name}
41
+ src={imagePrettyUrl(item.logo_url, 100)}
42
+ width={150}
43
+ height={40}
44
+ />
37
45
  </a>
38
46
  <Bonus item={item} tracker={oneliner} />
47
+ <StarRating numOfStars={5} rating={itemRating} />
39
48
  <SellingPoints icon={<MdCheck />} sellingPoints={item.selling_points} />
40
49
  <div>
41
- <Button
42
- to={`/${item.review_link}`}
43
- primaryColor={false}
44
- gtmClass="casinos-top-list-gtm btn-cta"
45
- btnText="Omtale"
46
- />
50
+ <Link className={`${styles.reviewLink} toplist-variant-one-gtm`} to={item.review_link}>
51
+ {`${translate(translations, 'read_review', 'Review')}`}
52
+ </Link>
47
53
  </div>
48
54
  <div>
49
- <Button
50
- to={prettyLink}
51
- btnText="Spill nå!"
52
- gtmClass="casinos-top-list-gtm btn-cta"
53
- primaryColor
54
- isInternalLink={false}
55
- />
55
+ <OperatorCta operator={item} tracker={tracker} gtmClass="toplist-operator-cta-gtm" />
56
56
  </div>
57
57
  </div>
58
58
  );
@@ -61,11 +61,13 @@ const Row = ({ item, oneliner = 'main', layout = 'list' }) => {
61
61
  Row.propTypes = {
62
62
  oneliner: PropTypes.string,
63
63
  layout: PropTypes.string,
64
+ tracker: PropTypes.string,
64
65
  item: PropTypes.shape({
65
66
  name: PropTypes.string,
66
67
  logo_url: PropTypes.string,
67
68
  selling_points: PropTypes.arrayOf(PropTypes.string),
68
69
  review_link: PropTypes.string,
70
+ rating: PropTypes.string,
69
71
  one_liners: PropTypes.shape({
70
72
  main: PropTypes.shape({
71
73
  one_liner: PropTypes.string,
@@ -1,12 +1,13 @@
1
1
  /* eslint-disable arrow-body-style */
2
2
  import React from 'react';
3
3
  import PropTypes from 'prop-types';
4
-
5
- import Search from '~molecules/search';
4
+ import loadable from '@loadable/component';
6
5
  import Card from '~atoms/cards/default-card';
7
6
  import { translate } from '~helpers/getters';
8
7
 
9
8
  const SearchContent = ({ page }) => {
9
+ const Search = loadable(() => import('~molecules/search'));
10
+
10
11
  return (
11
12
  <Search
12
13
  pageSearchOptions={{
@@ -14,12 +14,11 @@ export function isMobileDevice() {
14
14
  const isIos = () => Boolean(userAgent.match(/iPhone|iPad|iPod/i));
15
15
  const isOpera = () => Boolean(userAgent.match(/Opera Mini/i));
16
16
  const isWindows = () => Boolean(userAgent.match(/IEMobile/i));
17
- const isIos13 = () =>
18
- Boolean(
19
- platform === 'MacIntel' &&
20
- maxTouchPoints &&
21
- maxTouchPoints === 5
22
- );
17
+ const isIos13 = () => Boolean(platform === 'MacIntel' && maxTouchPoints && maxTouchPoints === 5);
23
18
 
24
19
  return Boolean(isAndroid() || isIos() || isOpera() || isWindows() || isIos13());
25
20
  }
21
+
22
+ export function isNativeImageLazyLoadingSupported() {
23
+ return typeof HTMLImageElement !== 'undefined' && 'loading' in HTMLImageElement.prototype;
24
+ }
@@ -0,0 +1,91 @@
1
+ /* eslint-disable camelcase */
2
+ /* eslint-disable import/prefer-default-export */
3
+ import { zeroPadding } from './schedule';
4
+
5
+ function isValidDate(d) {
6
+ return d instanceof Date && !Number.isNaN(d);
7
+ }
8
+
9
+ export function convertTimeZone(event) {
10
+ if (!event || !event.date || !event.date.time) {
11
+ return event;
12
+ }
13
+ const timeArr = event.date.time.split(':');
14
+
15
+ // ecmascript has month ranges between 0 - 11, that's why we do -1 to month_number
16
+ const currentTimeZoneDate = new Date(
17
+ Date.UTC(
18
+ event.date.year_number,
19
+ zeroPadding(event.date.month_number - 1, 2),
20
+ zeroPadding(event.date.day_number, 2),
21
+ timeArr[0],
22
+ timeArr[1]
23
+ )
24
+ );
25
+
26
+ if (!isValidDate(currentTimeZoneDate)) return event;
27
+
28
+ const time = `${zeroPadding(currentTimeZoneDate.getHours(), 2)}:${zeroPadding(
29
+ currentTimeZoneDate.getMinutes(),
30
+ 2
31
+ )}`;
32
+
33
+ // in case the utc is 23:00, but user's timezone can get 00:00 so update the date object.
34
+ const day_number = zeroPadding(currentTimeZoneDate.getDate(), 2);
35
+ const month_number = zeroPadding(currentTimeZoneDate.getMonth() + 1, 2);
36
+ const date = `${day_number}-${month_number}-${zeroPadding(currentTimeZoneDate.getFullYear(), 2)}`;
37
+
38
+ const dateAttrs = {
39
+ date: {
40
+ ...event.date,
41
+ time,
42
+ month_number,
43
+ day_number,
44
+ date,
45
+ },
46
+ };
47
+
48
+ return { ...event, ...dateAttrs };
49
+ }
50
+
51
+ export function updateAllTimezones(relation) {
52
+ const relationSchedule = relation?.schedule;
53
+ const relationFeaturedEvents = relation?.featured_events;
54
+ const relationShowcasedEvents = relation?.showcased_events;
55
+
56
+ // formated timezone schedule
57
+ const schedule = relationSchedule
58
+ ? Object.keys(relationSchedule).reduce((acc, dateKey) => {
59
+ const { tournaments } = relationSchedule[dateKey] || {};
60
+
61
+ const formattedTournaments = Object.keys(tournaments).reduce(
62
+ (tournamentAcc, currentTournamentKey) => {
63
+ const league = tournaments[currentTournamentKey];
64
+ const formattedEvents = league.events.map((event) => convertTimeZone(event));
65
+ tournamentAcc[currentTournamentKey] = { ...league, events: formattedEvents };
66
+ return tournamentAcc;
67
+ },
68
+ {}
69
+ );
70
+
71
+ acc[dateKey] = { ...relation.schedule[dateKey], tournaments: formattedTournaments };
72
+ return acc;
73
+ }, {})
74
+ : {};
75
+
76
+ // formated timezone featured events
77
+ const featured_events = relationFeaturedEvents?.map((event) => convertTimeZone(event)) || [];
78
+
79
+ // formated timezone showcased events
80
+ const showcased_events = relationShowcasedEvents?.map((event) => convertTimeZone(event)) || [];
81
+
82
+ // format timezone for relation.event
83
+ const event = convertTimeZone(relation?.event);
84
+
85
+ const updatedObject = { ...relation, schedule, featured_events, showcased_events };
86
+ if (event) {
87
+ updatedObject.event = event;
88
+ }
89
+
90
+ return updatedObject;
91
+ }
@@ -21,17 +21,25 @@ export function generateTrackerLink(operator, trackerType) {
21
21
  }
22
22
  }
23
23
 
24
- export function generateMetaTitle(metaTitle, translations) {
24
+ export function generateMetaString(metaString, translations, props) {
25
25
  const date = new Date();
26
+ const day = date.getDate();
26
27
  const month = months[date.getMonth()];
27
28
  const year = date.getFullYear();
29
+ const regex =
30
+ /\[MONTH\]|\[YEAR\]|\[currentyear\]|\[sitename\]|\[currentmonth\]|\[title\]|\[currentdate\]/gi;
28
31
 
29
- return metaTitle.replace(
30
- /\[MONTH\]|\[YEAR\]/gi,
32
+ return metaString.replace(
33
+ regex,
31
34
  (match) =>
32
35
  ({
33
36
  '[MONTH]': (translations && translations[month]) || month,
34
37
  '[YEAR]': year,
38
+ '[currentdate]': `${(translations && translations[month]) || month} ${day}, ${year}`,
39
+ '[currentmonth]': (translations && translations[month]) || month,
40
+ '[currentyear]': year,
41
+ '[sitename]': (props && props.siteName) || '',
42
+ '[title]': (props && props.siteTitle) || '',
35
43
  }[match])
36
44
  );
37
45
  }
@@ -1,4 +1,4 @@
1
- import { generateTrackerLink, generateMetaTitle } from './generators';
1
+ import { generateTrackerLink, generateMetaString } from './generators';
2
2
  import { months } from '~constants/common';
3
3
 
4
4
  describe('Generate Tracker Link Helper', () => {
@@ -17,24 +17,46 @@ describe('Generate Tracker Link Helper', () => {
17
17
  });
18
18
 
19
19
  describe('Generate Meta Title Helper', () => {
20
- test('generateMetaTitle main', () => {
21
- const metaTitle = generateMetaTitle('meta title [MONTH] [YEAR]');
20
+ test('generateMetaString uppercase', () => {
21
+ const metaString = generateMetaString('meta title [MONTH] [YEAR]');
22
22
  const date = new Date();
23
- expect(metaTitle).not.toContain('[MONTH]');
24
- expect(metaTitle).not.toContain('[YEAR]');
25
- expect(metaTitle).toContain(date.getFullYear());
26
- expect(metaTitle).toContain(months[date.getMonth()]);
23
+
24
+ expect(metaString).not.toContain('[MONTH]');
25
+ expect(metaString).not.toContain('[YEAR]');
26
+ expect(metaString).toContain(date.getFullYear());
27
+ expect(metaString).toContain(months[date.getMonth()]);
28
+ });
29
+ test('generateMetaString lowercase', () => {
30
+ const metaString = generateMetaString(
31
+ 'meta title [currentdate] [currentmonth] [currentyear] [sitename] [title]',
32
+ null,
33
+ {
34
+ siteName: 'Site Name',
35
+ siteTitle: 'Site Title',
36
+ }
37
+ );
38
+ const date = new Date();
39
+
40
+ expect(metaString).not.toContain('[currentdate]');
41
+ expect(metaString).not.toContain('[currentmonth]');
42
+ expect(metaString).not.toContain('[currentyear]');
43
+ expect(metaString).not.toContain('[sitename]');
44
+ expect(metaString).not.toContain('[title]');
45
+ expect(metaString).toContain(date.getDate());
46
+ expect(metaString).toContain(months[date.getMonth()]);
47
+ expect(metaString).toContain(date.getFullYear());
48
+ expect(metaString).toContain('Site Name');
49
+ expect(metaString).toContain('Site Title');
27
50
  });
28
- test('generateMetaTitle translated', () => {
51
+ test('generateMetaString translated', () => {
29
52
  const translateMonths = months.reduce(
30
53
  (translated, month) => ({ ...translated, [month]: `translate${month.substring(0, 1)}` }),
31
54
  {}
32
55
  );
33
- const metaTitle = generateMetaTitle('meta title [MONTH] [YEAR]', translateMonths);
56
+ const metaString = generateMetaString('meta title [MONTH]', translateMonths);
34
57
  const date = new Date();
35
58
 
36
- expect(metaTitle).not.toContain('[MONTH]');
37
- expect(metaTitle).not.toContain('[YEAR]');
38
- expect(metaTitle).toContain(translateMonths[months[date.getMonth()]]);
59
+ expect(metaString).not.toContain('[MONTH]');
60
+ expect(metaString).toContain(translateMonths[months[date.getMonth()]]);
39
61
  });
40
62
  });
@@ -6,11 +6,9 @@ import {
6
6
  filterEvents,
7
7
  findTournaments,
8
8
  getSortedEvents,
9
- formatEvents,
10
9
  } from '../schedule';
11
10
 
12
11
  export function prepareSportsData(sportsData) {
13
- sportsData.events = formatEvents(sportsData.events);
14
12
  Object.keys(sportsData.tournaments).forEach((key) => {
15
13
  if (sportsData.tournaments[key].events) {
16
14
  sportsData.tournaments[key].events = filterEvents(
@@ -1,3 +1,5 @@
1
+ /* eslint-disable arrow-body-style */
2
+ /* eslint-disable no-unused-expressions */
1
3
  export const roundHalf = (num) => {
2
4
  return Math.round(num * 2) / 2;
3
5
  };
@@ -120,39 +120,3 @@ export function filterEvents(tournamentEvents, events) {
120
120
 
121
121
  return futureEvents;
122
122
  }
123
-
124
- export function changeEventHour(event, hour = 1) {
125
- if (!event || !event.date || !event.date.time) {
126
- return event;
127
- }
128
-
129
- const timeArr = event.date.time.split(':');
130
- timeArr[0] = Number(timeArr[0]) - hour;
131
- event.date.time = timeArr.join(':');
132
-
133
- return event;
134
- }
135
-
136
- export function formatEvents(events) {
137
- const eventsArr = Object.values(events);
138
- const siteName = process.env.GATSBY_SITE_NAME;
139
- let prefix = '0';
140
-
141
- switch (siteName) {
142
- case 'sefodbold.dk':
143
- case 'sesport.dk':
144
- case 'watchfooty.co.uk':
145
- case 'bekijksport.nl':
146
- case 'livestreamsvoetbal.nl':
147
- prefix = 1;
148
- break;
149
- default:
150
- prefix = 0;
151
- }
152
-
153
- return eventsArr.reduce((acc, current) => {
154
- const event = changeEventHour(current, prefix);
155
- acc[event.id] = event;
156
- return acc;
157
- }, {});
158
- }
@@ -1,39 +1,29 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  // eslint-disable-next-line import/no-extraneous-dependencies
3
- // import LazyLoad from 'react-lazyload';
4
3
  import PropTypes from 'prop-types';
4
+ import loadable from '@loadable/component';
5
+ import { isNativeImageLazyLoadingSupported } from '~helpers/device-detect';
5
6
 
6
- // When to use this component:
7
- // 1. If you have 1 image to lazyload
8
- // 2. If you have images for different breakpoints and want the browser to decide when to serve the images based on the device, bandwidth, etc.
9
7
  export default function LazyImage({
10
8
  height,
11
9
  width,
12
- // offset = 200,
13
10
  style = {},
14
11
  className,
15
12
  src = '#',
16
- // srcSet = '',
17
13
  alt = '',
18
- // sizes,
19
- // defaultImg,
20
- // once = false,
14
+ defaultImg,
15
+ loading = 'lazy',
21
16
  }) {
22
- // const [errorImage, setErrorImage] = useState(false);
17
+ const [errorImage, setErrorImage] = useState(false);
23
18
 
24
- // if ((defaultImg && !src) || errorImage === true) {
25
- // return defaultImg;
26
- // }
19
+ if ((defaultImg && !src) || errorImage === true) {
20
+ return defaultImg;
21
+ }
27
22
 
28
- return (
29
- <>
30
- {/* <LazyLoad
31
- height={`${height}px`}
32
- width={`${width}px`}
33
- offset={offset}
34
- debounce={0}
35
- once={once}
36
- >
23
+ if (!isNativeImageLazyLoadingSupported()) {
24
+ const LazyLoad = loadable(() => import(`react-lazyload`));
25
+ return (
26
+ <LazyLoad height={`${height}px`} width={`${width}px`} debounce={0}>
37
27
  <img
38
28
  src={src}
39
29
  className={className}
@@ -41,36 +31,32 @@ export default function LazyImage({
41
31
  width={width}
42
32
  alt={alt}
43
33
  style={style}
44
- srcSet={srcSet}
45
- sizes={sizes}
46
- onError={() => setErrorImage(true)}
47
34
  />
48
- </LazyLoad> */}
49
- {/* <noscript> */}
50
- <img
51
- src={src}
52
- loading="lazy"
53
- className={className}
54
- height={height}
55
- width={width}
56
- alt={alt}
57
- style={style}
58
- />
59
- {/* </noscript> */}
60
- </>
35
+ </LazyLoad>
36
+ );
37
+ }
38
+
39
+ return (
40
+ <img
41
+ src={src}
42
+ loading={loading}
43
+ className={className}
44
+ height={height}
45
+ width={width}
46
+ alt={alt}
47
+ style={style}
48
+ onError={() => setErrorImage(true)}
49
+ />
61
50
  );
62
51
  }
63
52
 
64
53
  LazyImage.propTypes = {
65
54
  width: PropTypes.number,
66
55
  height: PropTypes.number,
67
- // offset: PropTypes.number,
68
56
  style: PropTypes.shape({}),
69
57
  className: PropTypes.string,
70
58
  src: PropTypes.string,
71
59
  alt: PropTypes.string,
72
- // sizes: PropTypes.string,
73
- // srcSet: PropTypes.string,
74
- // defaultImg: PropTypes.element,
75
- // once: PropTypes.bool,
60
+ defaultImg: PropTypes.element,
61
+ loading: PropTypes.string,
76
62
  };
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { forceCheck } from 'react-lazyload';
4
- import TabList from './tab/tab-list';
4
+ import loadable from '@loadable/component';
5
5
  import styles from './tabs.module.scss';
6
6
 
7
7
  const Tabs = ({
@@ -19,6 +19,8 @@ const Tabs = ({
19
19
  showAll ? showAllTabId : `${children[0].props.label}_0`
20
20
  );
21
21
 
22
+ const TabList = showTabs ? loadable(() => import('./tab/tab-list')) : null;
23
+
22
24
  const tabHeaderClass = `${styles.tabsHeader} ${!HeaderComp && styles.tabsOnly} ${
23
25
  styles[headerClass]
24
26
  } ${tabsAlign === 'right' && styles.invertOrder}`;
@@ -31,7 +33,7 @@ const Tabs = ({
31
33
  return (
32
34
  <>
33
35
  <div className={tabHeaderClass}>
34
- {showTabs && (
36
+ {TabList && (
35
37
  <TabList
36
38
  onClick={onClickTabItem}
37
39
  items={children}