gatsby-core-theme 41.1.25 → 41.1.27

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,31 @@
1
+ ## [41.1.27](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v41.1.26...v41.1.27) (2025-01-20)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * sports team kits data ([44e6164](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/44e6164b119c29a5e7c2d67bbb1c71228a85dc5e))
7
+
8
+
9
+ ### Code Refactoring
10
+
11
+ * complete changes to anchor module to move it into build ([f327cc5](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/f327cc56e91e1e16fc5aca77e6242e564eb659d5))
12
+ * refactor strings module ([70f5e39](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/70f5e3908aca3eafd70e20052704124ffee89f63))
13
+
14
+
15
+ * Merge branch 'anchor-fix' into 'master' ([7c15bc3](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/7c15bc31352ce00ee333f1921e9f455fef9989e9))
16
+
17
+
18
+ ### Tests
19
+
20
+ * add test for operator name ([271ef7b](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/271ef7b1c4e615ef447650630c7e986b75dc7faf))
21
+
22
+ ## [41.1.26](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v41.1.25...v41.1.26) (2025-01-15)
23
+
24
+
25
+ ### Code Refactoring
26
+
27
+ * add game categories ([42ce2dd](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/42ce2dd726453307d0f433d12c350659930c5480))
28
+
1
29
  ## [41.1.25](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v41.1.24...v41.1.25) (2025-01-15)
2
30
 
3
31
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-core-theme",
3
- "version": "41.1.25",
3
+ "version": "41.1.27",
4
4
  "description": "Gatsby Theme NPM Package",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -12,6 +12,27 @@ import getNavigation from '~tests/factories/sections/navigationStatic.factory';
12
12
  import siteLogo from '../../../../../static/images/logo.svg';
13
13
  import Anchor from '.';
14
14
  import Navigation from '~organisms/navigation';
15
+ import { processAnchor } from '../../../../helpers/processor/modules.mjs';
16
+ import getPageData from '~tests/factories/pages/default.factory';
17
+
18
+ const page = getPageData();
19
+ const module = {
20
+ items: [
21
+ { slug: 'section-one-year', label: 'Section one [YEAR]' },
22
+ { slug: 'section-two-operator_name', label: 'Section two [operator_name]' },
23
+ { slug: 'section-three', label: 'Section three' },
24
+ { slug: 'section-four', label: 'Section four' },
25
+ { slug: 'section-five', label: 'Section five' },
26
+ { slug: 'section-six', label: 'Section six' },
27
+ { slug: 'section-seven', label: 'Section seven' },
28
+ { slug: 'section-eight', label: 'Section eight' },
29
+ { slug: 'section-nine', label: 'Section nine' },
30
+ { slug: 'section-ten', label: 'Section ten' },
31
+ { slug: 'section-eleven', label: 'Section eleven' },
32
+ { slug: 'section-twelve', label: 'Section twelve' },
33
+ ]
34
+ };
35
+ const processedAnchor = processAnchor(module, page?.relation);
15
36
 
16
37
  export default {
17
38
  title: 'Theme/Modules/Anchor/Template One',
@@ -20,34 +41,13 @@ export default {
20
41
  module: {
21
42
  name: 'module',
22
43
  type: { name: 'object', required: false },
23
- defaultValue: '',
44
+ defaultValue: processedAnchor,
24
45
  description: 'The module data object including list of sections.',
25
46
  table: {
26
47
  type: { summary: 'object' },
27
48
  defaultValue: { summary: null },
28
49
  },
29
50
  },
30
- headerOffset: {
31
- name: 'headerOffset',
32
- type: { name: 'number', required: false },
33
- defaultValue: 0,
34
- description: 'The space between the header and target section in pixels.',
35
- table: {
36
- type: { summary: 'number' },
37
- defaultValue: { summary: 0 },
38
- },
39
- },
40
- sliderGap: {
41
- name: 'sliderGap',
42
- type: { name: 'number', required: false },
43
- defaultValue: 0,
44
- description: 'The space between navigation buttons in pixels.',
45
- table: {
46
- type: { summary: 'number' },
47
- defaultValue: { summary: 0 },
48
- },
49
- control: null,
50
- },
51
51
  },
52
52
  parameters: {
53
53
  docs: {
@@ -75,21 +75,6 @@ const navigationData = {
75
75
  logo: siteLogo,
76
76
  };
77
77
 
78
- const sections = [
79
- 'section-one',
80
- 'section-two',
81
- 'section-three',
82
- 'section-four',
83
- 'section-five',
84
- 'section-six',
85
- 'section-seven',
86
- 'section-eight',
87
- 'section-nine',
88
- 'section-ten',
89
- 'section-eleven',
90
- 'section-twelf',
91
- ];
92
-
93
78
  const Template = (args) => (
94
79
  <>
95
80
  <Navigation {...navigationData} />
@@ -101,9 +86,9 @@ const Template = (args) => (
101
86
  }}
102
87
  >
103
88
  <Anchor {...args} />
104
- {sections?.map((sec) => (
105
- <div id={sec}>
106
- <h2>{sec}</h2>
89
+ {processedAnchor?.items?.map((sec) => (
90
+ <div id={sec.id}>
91
+ <h2>{sec.label}</h2>
107
92
  <p>
108
93
  {`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum
109
94
  has been the industry's standard dummy text ever since the 1500s, when an unknown
@@ -121,50 +106,10 @@ const Template = (args) => (
121
106
 
122
107
  export const Default = Template.bind({});
123
108
  Default.args = {
124
- width: ' 100%',
125
- module: {
126
- items: [
127
- { label: 'section-one' },
128
- { label: 'section-two' },
129
- { label: 'section-three' },
130
- { label: 'section-four' },
131
- { label: 'section-five' },
132
- { label: 'section-six' },
133
- { label: 'section-seven' },
134
- { label: 'section-eight' },
135
- { label: 'section-nine' },
136
- { label: 'section-ten' },
137
- { label: 'section-eleven' },
138
- { label: 'section-twelf' },
139
- ],
140
- },
141
- fullScrollWidth: false,
142
109
  setShowButtons: false,
143
- sliderGap: 10,
144
- headerOffset: 20,
145
110
  };
146
111
 
147
112
  export const FullWidth = Template.bind({});
148
113
  FullWidth.args = {
149
- width: '100%',
150
- module: {
151
- items: [
152
- { label: 'section-one' },
153
- { label: 'section-two' },
154
- { label: 'section-three' },
155
- { label: 'section-four' },
156
- { label: 'section-five' },
157
- { label: 'section-six' },
158
- { label: 'section-seven' },
159
- { label: 'section-eight' },
160
- { label: 'section-nine' },
161
- { label: 'section-ten' },
162
- { label: 'section-eleven' },
163
- { label: 'section-twelf' },
164
- ],
165
- },
166
- fullScrollWidth: true,
167
114
  setShowButtons: true,
168
- sliderGap: 10,
169
- headerOffset: 80,
170
115
  };
@@ -1,48 +1,66 @@
1
1
  import React from 'react';
2
2
  import { render, cleanup, fireEvent } from '@testing-library/react';
3
3
  import '@testing-library/jest-dom/extend-expect';
4
-
4
+ import { processAnchor } from '../../../../helpers/processor/modules.mjs';
5
5
  import '~tests/helpers/match-media.mock';
6
- import { getListCarouselItem } from '~tests/factories/modules/carousel.factory';
7
6
  import Anchor from '.';
7
+ import getPageData from '~tests/factories/pages/default.factory';
8
+
9
+ const page = getPageData();
10
+
11
+ const module = {
12
+ items: [
13
+ { slug: 'section-one-year', label: 'Section one [YEAR]' },
14
+ { slug: 'section-two-operator_name', label: 'Section two [operator_name]' },
15
+ { slug: 'section-three', label: 'Section three' },
16
+ { slug: 'section-four', label: 'Section four' },
17
+ { slug: 'section-five', label: 'Section five' },
18
+ { slug: 'section-six', label: 'Section six' },
19
+ { slug: 'section-seven', label: 'Section seven' },
20
+ { slug: 'section-eight', label: 'Section eight' },
21
+ { slug: 'section-nine', label: 'Section nine' },
22
+ { slug: 'section-ten', label: 'Section ten' },
23
+ { slug: 'section-eleven', label: 'Section eleven' },
24
+ { slug: 'section-twelve', label: 'Section twelve' },
25
+ ]
26
+ };
27
+ const processedAnchor = processAnchor(module, page?.relation)
8
28
 
9
29
  describe('Anchor Component', () => {
10
- test('render with props', () => {
11
- const module = getListCarouselItem(2);
12
- const { container, getByText } = render(<Anchor module={module} headerOffset={90} />);
13
- expect(container.querySelectorAll('a')).toHaveLength(2);
14
- expect(getByText('label-1')).toBeTruthy();
15
- expect(getByText('label-2')).toBeTruthy();
16
- expect(getByText('label-2').getAttribute('href')).toEqual('#label2');
30
+ test('render with props', () => {
31
+ const { container, getByText } = render(<Anchor module={processedAnchor} headerOffset={90} />);
32
+ expect(container.querySelectorAll('a')).toHaveLength(12);
33
+ expect(getByText('Section five')).toBeInTheDocument();
34
+ expect(getByText('Section four')).toBeInTheDocument();
35
+ expect(getByText('Section six').getAttribute('href')).toEqual('#section-six');
17
36
  });
18
37
  test('on click', async () => {
19
- const module = getListCarouselItem(4);
38
+
20
39
  const { getByText } = render(
21
40
  <>
22
- <Anchor module={module} headerOffset={90} />
23
- <div id="label-1" style={{ marginTop: '1000px' }}>
41
+ <Anchor module={processedAnchor} headerOffset={90} />
42
+ <div id="section-three" style={{ marginTop: '1000px' }}>
24
43
  hjbihi
25
44
  </div>
26
45
  </>
27
46
  );
28
47
  const scrollToSpy = jest.fn();
29
48
  window.scrollTo = scrollToSpy;
30
- expect(getByText('label-1')).toBeTruthy();
31
- fireEvent.mouseDown(getByText('label-1'));
32
- fireEvent.click(getByText('label-1'));
49
+ expect(getByText('Section three')).toBeInTheDocument();
50
+ fireEvent.mouseDown(getByText('Section three'));
51
+ fireEvent.click(getByText('Section three'));
33
52
  });
34
53
  test('renders correctly with default props', () => {
35
- const items = getListCarouselItem(4);
36
- const { getByText } = render(<Anchor module={items} />);
54
+ const { getByText } = render(<Anchor module={processedAnchor} />);
37
55
 
38
- expect(getByText('label-1')).toBeInTheDocument();
39
- expect(getByText('label-2')).toBeInTheDocument();
40
- expect(getByText('label-3')).toBeInTheDocument();
56
+ expect(getByText('Section four')).toBeInTheDocument();
57
+ expect(getByText('Section five')).toBeInTheDocument();
58
+ expect(getByText('Section ten')).toBeInTheDocument();
41
59
  });
42
60
  test('renders navigation buttons when conditions are met', () => {
43
- const module = getListCarouselItem(4);
61
+
44
62
  const { container } = render(
45
- <Anchor module={module} minCharactersForButtons={10} setShowButtons={true} />
63
+ <Anchor module={processedAnchor} minCharactersForButtons={10} setShowButtons />
46
64
  );
47
65
  const buttons = container.querySelectorAll('button');
48
66
 
@@ -57,6 +75,13 @@ describe('Anchor Component', () => {
57
75
  expect(buttons[0]).toBeInTheDocument();
58
76
  expect(buttons[1]).toBeInTheDocument();
59
77
  });
78
+ test('Test with shortcodes', () => {
79
+ const { getByText } = render(<Anchor module={processedAnchor} headerOffset={90} />);
80
+ expect(getByText('Section one 2025')).toBeInTheDocument();
81
+ expect(getByText('Section one 2025').getAttribute('href')).toEqual('#section-one-2025');
82
+ expect(getByText('Section two Wildz')).toBeInTheDocument();
83
+ expect(getByText('Section two Wildz').getAttribute('href')).toEqual('#section-two-wildz');
84
+ });
60
85
  });
61
86
  afterEach(() => {
62
87
  cleanup();
@@ -1,17 +1,10 @@
1
1
  /* eslint-disable react-hooks/rules-of-hooks */
2
- /* eslint-disable no-nested-ternary */
3
- /* eslint-disable import/no-extraneous-dependencies */
4
- /* eslint-disable no-unused-expressions */
5
- /* eslint-disable prefer-destructuring */
6
- /* eslint-disable react-hooks/exhaustive-deps */
7
2
  import React, { useRef, useState } from "react";
8
3
  import PropTypes from "prop-types";
9
4
  import { IoIosArrowBack } from "@react-icons/all-files/io/IoIosArrowBack";
10
5
  import { IoIosArrowForward } from "@react-icons/all-files/io/IoIosArrowForward";
11
6
  import isSticky from "~hooks/stickyOnScroll";
12
7
  import keygen from "~helpers/keygen";
13
- import { anchorLink, removeSymbols } from "~helpers/strings";
14
- import { generatePlaceholderString } from "~helpers/generators";
15
8
 
16
9
  import useTranslate from "~hooks/useTranslate/useTranslate";
17
10
  import styles from "./anchor.module.scss";
@@ -28,7 +21,6 @@ function Anchor({
28
21
  buttonScroll = 200,
29
22
  leftButtonIcon = <IoIosArrowBack />,
30
23
  rightButtonIcon = <IoIosArrowForward />,
31
- page
32
24
  }) {
33
25
  const [scrollX, setScrollX] = useState(0);
34
26
  const [scrollEnd, setScrollEnd] = useState(false);
@@ -39,20 +31,9 @@ function Anchor({
39
31
  const progressBar = useRef(null);
40
32
 
41
33
  let numberOfCharacters = 0;
42
- const anchorList = items.map((anchor) => {
34
+
35
+ items.forEach((anchor) => {
43
36
  numberOfCharacters += anchor?.label?.length;
44
- const generatedLabel = generatePlaceholderString(anchor?.label?.trim(),null, page?.relation);
45
-
46
- return {
47
- id: `${
48
- anchor.label &&
49
- removeSymbols(anchorLink(generatedLabel))
50
- }`,
51
- label: generatedLabel,
52
- slug: `${
53
- anchor.label && anchorLink(generatedLabel)
54
- }`,
55
- };
56
37
  });
57
38
  const showButtons =
58
39
  numberOfCharacters > minCharactersForButtons && setShowButtons;
@@ -78,7 +59,7 @@ function Anchor({
78
59
  const setActiveAnchor = () => {
79
60
  const elements = document.querySelectorAll("[data-track='true'], [data-anchor-label]");
80
61
  const { innerHeight, scrollY } = window;
81
- const scrollHeight = document.body.scrollHeight;
62
+ const { scrollHeight } = document.body;
82
63
 
83
64
  // Update progress bar
84
65
  const calcPercent = (scrollY * 100) / (scrollHeight - innerHeight);
@@ -119,7 +100,7 @@ function Anchor({
119
100
  const sticky =
120
101
  isFixed && isSticky(stickyOffset, setActiveAnchor, anchorContainerRef);
121
102
 
122
- const anchorItems = anchorList?.map((item, index) => (
103
+ const anchorItems = items?.map((item, index) => (
123
104
  // eslint-disable-next-line react/no-array-index-key
124
105
  <li key={index} className={styles.anchorItem || ""}>
125
106
  <a
@@ -130,7 +111,7 @@ function Anchor({
130
111
  ref={(el) => (itemsRef.current[index] = el)}
131
112
  href={`#${item?.id && item.id}`}
132
113
  >
133
- {generatePlaceholderString(useTranslate(item.slug, item.label),null, page?.relation)}
114
+ {useTranslate(item.slug, item.label)}
134
115
  {icon}
135
116
  </a>
136
117
  </li>
@@ -204,9 +185,6 @@ Anchor.propTypes = {
204
185
  rightButtonIcon: PropTypes.shape({}),
205
186
  minCharactersForButtons: PropTypes.number,
206
187
  setShowButtons: PropTypes.bool,
207
- page: PropTypes.shape({
208
- relation:PropTypes.shape({})
209
- })
210
188
  };
211
189
 
212
190
  export default Anchor;
@@ -9,7 +9,6 @@ import PropTypes from 'prop-types';
9
9
 
10
10
  import ScollX from 'gatsby-core-theme/src/hooks/scroll-x';
11
11
  import keygen from '~helpers/keygen';
12
- import { anchorLink, removeSymbols } from '~helpers/strings';
13
12
  import useTranslate from '~hooks/useTranslate/useTranslate';
14
13
  import { generatePlaceholderString } from "~helpers/generators";
15
14
 
@@ -20,12 +19,6 @@ function Anchor({ module: { items }, icon = null, showTitle = true, exclOperator
20
19
  const anchorContainerRef = useRef(null);
21
20
  const anchorListRef = useRef(null);
22
21
 
23
- const anchorList = items.map((anchor) => ({
24
- id: `${anchor.label && removeSymbols(anchorLink(anchor?.label?.toLowerCase().trim()))}`,
25
- label: anchor.label,
26
- slug: `${anchor.label && anchorLink(anchor?.label?.toLowerCase().trim())}`,
27
- }));
28
-
29
22
  return (
30
23
  <div className={styles.containerAnchor || ''} ref={anchorContainerRef}>
31
24
  {showTitle ? (
@@ -42,7 +35,7 @@ function Anchor({ module: { items }, icon = null, showTitle = true, exclOperator
42
35
  >
43
36
  <ScollX refTag={anchorListRef}>
44
37
  <ul ref={anchorListRef} className={`${styles.anchor || ''}`}>
45
- {anchorList?.map((item, index) => (
38
+ {items?.map((item, index) => (
46
39
  <li className={styles.anchorItem || ''}>
47
40
  <a
48
41
  className={`${styles.link || ''} anchor-carousel-gtm anchor-menu-gtm`}
@@ -10,6 +10,28 @@ import {
10
10
  } from '@storybook/addon-docs/blocks';
11
11
 
12
12
  import Anchor from '.';
13
+ import { processAnchor } from '../../../../helpers/processor/modules.mjs';
14
+ import getPageData from '~tests/factories/pages/default.factory';
15
+
16
+ const page = getPageData();
17
+
18
+ const module = {
19
+ items: [
20
+ { slug: 'section-one-year', label: 'Section one [YEAR]' },
21
+ { slug: 'section-two-operator_name', label: 'Section two [operator_name]' },
22
+ { slug: 'section-three', label: 'Section three' },
23
+ { slug: 'section-four', label: 'Section four' },
24
+ { slug: 'section-five', label: 'Section five' },
25
+ { slug: 'section-six', label: 'Section six' },
26
+ { slug: 'section-seven', label: 'Section seven' },
27
+ { slug: 'section-eight', label: 'Section eight' },
28
+ { slug: 'section-nine', label: 'Section nine' },
29
+ { slug: 'section-ten', label: 'Section ten' },
30
+ { slug: 'section-eleven', label: 'Section eleven' },
31
+ { slug: 'section-twelve', label: 'Section twelve' },
32
+ ]
33
+ };
34
+ const processedAnchor = processAnchor(module, page?.relation);
13
35
 
14
36
  export default {
15
37
  title: 'Theme/Modules/Anchor/Template Two',
@@ -18,7 +40,7 @@ export default {
18
40
  module: {
19
41
  name: 'module',
20
42
  type: { name: 'object', required: false },
21
- defaultValue: '',
43
+ defaultValue: processedAnchor,
22
44
  description: 'The module data object including list of sections.',
23
45
  table: {
24
46
  type: { summary: 'object' },
@@ -55,30 +77,15 @@ export default {
55
77
  },
56
78
  };
57
79
 
58
- const sections = [
59
- 'section-one',
60
- 'section-two',
61
- 'section-three',
62
- 'section-four',
63
- 'section-five',
64
- 'section-six',
65
- 'section-seven',
66
- 'section-eight',
67
- 'section-nine',
68
- 'section-ten',
69
- 'section-eleven',
70
- 'section-twelf',
71
- ];
72
-
73
80
  const Template = (args) => (
74
81
  <>
75
82
  <Anchor {...args} />
76
- {sections?.map((sec) => (
77
- <div id={sec}>
78
- <h2>{sec}</h2>
83
+ {processedAnchor?.items?.map((sec) => (
84
+ <div id={sec.id}>
85
+ <h2>{sec.label}</h2>
79
86
  <p>
80
87
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has
81
- been the industry's standard dummy text ever since the 1500s, when an unknown printer took
88
+ been the industry standard dummy text ever since the 1500s, when an unknown printer took
82
89
  a galley of type and scrambled it to make a type specimen book. It has survived not only
83
90
  five centuries, but also the leap into electronic typesetting, remaining essentially
84
91
  unchanged. It was popularised in the 1960s with the release of Letraset sheets containing
@@ -91,23 +98,4 @@ const Template = (args) => (
91
98
  );
92
99
 
93
100
  export const Default = Template.bind({});
94
- Default.args = {
95
- module: {
96
- items: [
97
- { label: 'section-one' },
98
- { label: 'section-two' },
99
- { label: 'section-three' },
100
- { label: 'section-four' },
101
- { label: 'section-five' },
102
- { label: 'section-six' },
103
- { label: 'section-seven' },
104
- { label: 'section-eight' },
105
- { label: 'section-nine' },
106
- { label: 'section-ten' },
107
- { label: 'section-eleven' },
108
- { label: 'section-twelf' },
109
- ],
110
- },
111
- sliderGap: 10,
112
- headerOffset: 0,
113
- };
101
+ Default.args = {};
@@ -1,35 +1,60 @@
1
1
  import React from 'react';
2
2
  import { render, cleanup, fireEvent } from '@testing-library/react';
3
3
  import '@testing-library/jest-dom/extend-expect';
4
-
5
4
  import '~tests/helpers/match-media.mock';
6
- import { getListCarouselItem } from '~tests/factories/modules/carousel.factory';
7
5
  import Anchor from '.';
6
+ import { processAnchor } from '../../../../helpers/processor/modules.mjs';
7
+ import getPageData from '~tests/factories/pages/default.factory';
8
+
9
+ const page = getPageData();
10
+
11
+ const module = {
12
+ items: [
13
+ { slug: 'section-one-year', label: 'Section one [YEAR]' },
14
+ { slug: 'section-two-operator_name', label: 'Section two [operator_name]' },
15
+ { slug: 'section-three', label: 'Section three' },
16
+ { slug: 'section-four', label: 'Section four' },
17
+ { slug: 'section-five', label: 'Section five' },
18
+ { slug: 'section-six', label: 'Section six' },
19
+ { slug: 'section-seven', label: 'Section seven' },
20
+ { slug: 'section-eight', label: 'Section eight' },
21
+ { slug: 'section-nine', label: 'Section nine' },
22
+ { slug: 'section-ten', label: 'Section ten' },
23
+ { slug: 'section-eleven', label: 'Section eleven' },
24
+ { slug: 'section-twelve', label: 'Section twelve' },
25
+ ]
26
+ };
27
+ const processedAnchor = processAnchor(module, page?.relation)
8
28
 
9
29
  describe('Anchor Component', () => {
10
30
  test('render with props', () => {
11
- const module = getListCarouselItem(2);
12
- const { container, getByText } = render(<Anchor module={module} headerOffset={90} />);
13
- expect(container.querySelectorAll('a')).toHaveLength(2);
14
- expect(getByText('label-1')).toBeTruthy();
15
- expect(getByText('label-2')).toBeTruthy();
16
- expect(getByText('label-2').getAttribute('href')).toEqual('#label2');
31
+ const { container, getByText } = render(<Anchor module={processedAnchor} headerOffset={90} />);
32
+ expect(container.querySelectorAll('a')).toHaveLength(12);
33
+ expect(getByText('Section five')).toBeInTheDocument();
34
+ expect(getByText('Section four')).toBeInTheDocument();
35
+ expect(getByText('Section ten').getAttribute('href')).toEqual('#section-ten');
17
36
  });
18
37
  test('on click', async () => {
19
- const module = getListCarouselItem(4);
20
38
  const { getByText } = render(
21
39
  <>
22
- <Anchor module={module} headerOffset={90} />
23
- <div id="label-1" style={{ marginTop: '1000px' }}>
40
+ <Anchor module={processedAnchor} headerOffset={90} />
41
+ <div id="section-three" style={{ marginTop: '1000px' }}>
24
42
  hjbihi
25
43
  </div>
26
44
  </>
27
45
  );
28
46
  const scrollToSpy = jest.fn();
29
47
  window.scrollTo = scrollToSpy;
30
- expect(getByText('label-1')).toBeTruthy();
31
- fireEvent.mouseDown(getByText('label-1'));
32
- fireEvent.click(getByText('label-1'));
48
+ expect(getByText('Section three')).toBeInTheDocument();
49
+ fireEvent.mouseDown(getByText('Section three'));
50
+ fireEvent.click(getByText('Section three'));
51
+ });
52
+ test('Test with shortcodes', () => {
53
+ const { getByText } = render(<Anchor module={processedAnchor} headerOffset={90} />);
54
+ expect(getByText('Section one 2025')).toBeInTheDocument();
55
+ expect(getByText('Section one 2025').getAttribute('href')).toEqual('#section-one-2025');
56
+ expect(getByText('Section two Wildz')).toBeInTheDocument();
57
+ expect(getByText('Section two Wildz').getAttribute('href')).toEqual('#section-two-wildz');
33
58
  });
34
59
  });
35
60
  afterEach(() => {
@@ -150,6 +150,7 @@ export const pickRelationKeys = {
150
150
  "logo",
151
151
  "game_thumbnail",
152
152
  "extra_fields",
153
+ "game_categories",
153
154
  ],
154
155
  software_provider: [
155
156
  "logo_filename_object",
@@ -3,6 +3,7 @@
3
3
  /* eslint-disable import/no-extraneous-dependencies */
4
4
  import loadash from "lodash/index.js";
5
5
  import { generatePlaceholderString } from "../generators.mjs";
6
+ import { anchorLink, removeSymbols } from "../strings.mjs";
6
7
  import {
7
8
  clonePageForCards,
8
9
  groupBy,
@@ -295,7 +296,6 @@ export function processTopListModule(
295
296
  markets,
296
297
  data,
297
298
  toplists,
298
- translations
299
299
  ) {
300
300
  module.items = module.items.map((listItem) => {
301
301
  const { type } = listItem;
@@ -426,6 +426,21 @@ export function processFaq(module = {}, content, relationData) {
426
426
  });
427
427
  }
428
428
 
429
+ export function processAnchor(module = {}, relationData) {
430
+ // eslint-disable-next-line no-unused-expressions
431
+ module.items &&
432
+ module.items.forEach((anchor) => {
433
+
434
+ const generatedLabel = generatePlaceholderString(anchor?.label?.trim(),null, relationData);
435
+ const anchorLinkText = anchorLink(generatedLabel);
436
+
437
+ anchor.id = `${anchor.label && removeSymbols(anchorLinkText)}`;
438
+ anchor.label = generatedLabel;
439
+ anchor.slug = `${anchor.label && anchorLinkText}`;
440
+ });
441
+ return module;
442
+ }
443
+
429
444
  export function processModule(
430
445
  module,
431
446
  pages,
@@ -477,6 +492,8 @@ export function processModule(
477
492
  );
478
493
  } else if (module.name === "faq") {
479
494
  processFaq(module, content, relationData);
495
+ } else if (module.name === "anchor") {
496
+ processAnchor(module, relationData);
480
497
  } else if (module.name === "spotlights") {
481
498
  processSpotlightModule(module, content);
482
499
  } else if (module.name === "menu" && menus && menus[module.menu_id]) {
@@ -21,7 +21,8 @@ import {
21
21
  relationData,
22
22
  singleToplistItemData,
23
23
  } from "../../../tests/factories/modules/toplist.factory";
24
- import { processContentModule } from "./modules.mjs";
24
+ import { processContentModule, processAnchor } from "./modules.mjs";
25
+ import getPageData from '~tests/factories/pages/default.factory';
25
26
 
26
27
  const { cloneDeep } = loadash;
27
28
 
@@ -259,4 +260,40 @@ describe("Modules Helper", () => {
259
260
  expect(module.value).toContain(new Date().getFullYear().toString());
260
261
  expect(module.show_more_content).toContain(new Date().getFullYear().toString());
261
262
  });
263
+
264
+ test("Process Anchor module", () => {
265
+ const module = {
266
+ items: [
267
+ { slug: 'section-one-year', label: 'Section one [YEAR]' },
268
+ { slug: 'section-two-operator_name', label: 'Section two [operator_name]' },
269
+ { slug: 'section-three', label: 'Section three' },
270
+ { slug: 'section-four', label: 'Section four' },
271
+ ]
272
+ };
273
+ const processedAnchor = processAnchor(module)
274
+
275
+ expect(processedAnchor.items[2].slug).toBe('section-three');
276
+ expect(processedAnchor.items[3].id).toBe('section-four');
277
+ });
278
+ test("Process Anchor module with shortcodes", () => {
279
+ const module = {
280
+ items: [
281
+ { slug: 'section-one-year', label: 'Section one [YEAR]' },
282
+ { slug: 'section-two-operator_name', label: 'Section two [operator_name]' },
283
+ { slug: 'section-three', label: 'Section three' },
284
+ { slug: 'section-four', label: 'Section four' },
285
+ ]
286
+ };
287
+ const page = getPageData();
288
+ const text0 = module.items[0].label;
289
+ const text1 = module.items[1].label;
290
+ const processedAnchor = processAnchor(module, page?.relation);
291
+ const date = new Date();
292
+ const year = date.getFullYear();
293
+
294
+ expect(processedAnchor.items[0].slug).toBe('section-one-2025');
295
+ expect(processedAnchor.items[1].id).toBe('section-two-wildz');
296
+ expect(processedAnchor.items[0].label).toBe(text0.replace('[YEAR]', year));
297
+ expect(processedAnchor.items[1].label).toBe(text1.replace('[operator_name]', page?.relation.name));
298
+ });
262
299
  });
@@ -75,7 +75,7 @@ export const processSportsRelations = (
75
75
  teams[team] &&
76
76
  teams[team].livegoals_v2_id in data.relations.sports_data.team_kits
77
77
  ) {
78
- teamKits[team] = cloneDeep(
78
+ teamKits[teams[team].livegoals_v2_id] = cloneDeep(
79
79
  data.relations.sports_data.team_kits[teams[team].livegoals_v2_id]
80
80
  );
81
81
  eventTeams[team] = cloneDeep(teams[team]);
@@ -1,4 +1,4 @@
1
- import { imagePrettyUrl } from './getters';
1
+ import { imagePrettyUrl } from './getters.mjs';
2
2
 
3
3
  export function capitalize(string) {
4
4
  return string.replace(/^\w/, (c) => c.toUpperCase());