gatsby-core-theme 44.5.0-poc.2 → 44.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.ci.yml +2 -28
  2. package/CHANGELOG.md +233 -29
  3. package/gatsby-browser.js +48 -100
  4. package/gatsby-node.mjs +25 -21
  5. package/package.json +1 -1
  6. package/release.config.js +0 -5
  7. package/src/components/atoms/admin/button/index.js +1 -1
  8. package/src/components/atoms/author/index.js +6 -5
  9. package/src/components/atoms/collapse/collapse.test.js +113 -26
  10. package/src/components/atoms/collapse/index.js +23 -1
  11. package/src/components/atoms/comment-votes/comment-votes.module.scss +34 -0
  12. package/src/components/atoms/comment-votes/index.js +93 -0
  13. package/src/components/atoms/ratings/index.js +7 -0
  14. package/src/components/atoms/ratings/rating.test.js +1 -1
  15. package/src/components/molecules/comment/comment.module.scss +42 -74
  16. package/src/components/molecules/comment/index.js +108 -134
  17. package/src/components/molecules/header/variants/operator/template-one-two/index.js +4 -3
  18. package/src/components/molecules/header/variants/operator/template-one-two/template-one-two.stories.js +4 -3
  19. package/src/components/molecules/header/variants/operator/template-one-two/template-one-two.test.js +8 -8
  20. package/src/components/molecules/header/variants/slot/template-one/index.js +4 -3
  21. package/src/components/molecules/header/variants/slot/template-one/template-one.stories.js +4 -3
  22. package/src/components/molecules/leave-comment-form/index.js +25 -19
  23. package/src/components/molecules/spotlights_v2/icon/template-one/index.js +1 -1
  24. package/src/components/organisms/anchor/template-one/anchor.module.scss +19 -11
  25. package/src/components/organisms/archive/index.js +5 -2
  26. package/src/components/organisms/comments/comment-tree/comment-tree.module.scss +47 -0
  27. package/src/components/organisms/comments/comment-tree/index.js +8 -7
  28. package/src/components/organisms/comments/index.js +14 -26
  29. package/src/components/organisms/cookie-consent/index.js +48 -34
  30. package/src/components/organisms/form/fields/fields.module.scss +7 -4
  31. package/src/components/organisms/form/fields/index.js +101 -56
  32. package/src/components/organisms/form/form.module.scss +131 -39
  33. package/src/components/organisms/form/form.test.js +28 -33
  34. package/src/components/organisms/form/index.js +138 -78
  35. package/src/constants/forms.js +65 -14
  36. package/src/constants/ratings-constant.js +5 -0
  37. package/src/constants/schema.js +1 -0
  38. package/src/constants/settings.mjs +0 -1
  39. package/src/context/VotesProvider.js +49 -0
  40. package/src/helpers/replaceMedia.js +44 -1
  41. package/src/helpers/schema.js +32 -0
  42. package/src/helpers/tracker.mjs +2 -2
  43. package/src/resolver/index.mjs +8 -4
  44. package/src/resolver/modules.mjs +9 -6
  45. package/src/resolver/modules.test.js +1 -1
  46. package/src/resolver/redirect.mjs +23 -0
  47. package/src/resolver/redirect.test.js +65 -1
@@ -0,0 +1,47 @@
1
+ .comment_0{
2
+ margin-left: 0;
3
+
4
+ >div>div{
5
+ z-index: 1;
6
+ }
7
+ }
8
+
9
+ .comment_1{
10
+ @include min(tablet){
11
+ margin-left: 5.6rem;
12
+ }
13
+
14
+ margin-left: 2.4rem;
15
+ }
16
+
17
+ .comment_2{
18
+ @include min(tablet){
19
+ margin-left: 11.2rem;
20
+ }
21
+
22
+ margin-left: 4rem;
23
+ }
24
+
25
+ .isReply{
26
+ position: relative;
27
+
28
+ &::before{
29
+ content: "";
30
+ position: absolute;
31
+ right: 100%;
32
+ border-left: var(--comment-tree-border, .1rem solid #CFC7C0);
33
+ border-bottom: var(--comment-tree-border, .1rem solid #CFC7C0);
34
+ border-bottom-left-radius: var(--comment-tree-border-radius, 2rem);
35
+ bottom: 50%;
36
+ height: calc(50% + 8.5rem);
37
+ width: 1.1rem;
38
+
39
+ @include min(tablet){
40
+ width: 3rem;
41
+ }
42
+ }
43
+
44
+ + .isReply::before{
45
+ height: calc(50% + 25.5rem);
46
+ }
47
+ }
@@ -1,15 +1,16 @@
1
1
  import React from "react";
2
2
 
3
3
  import PropTypes, { arrayOf } from 'prop-types';
4
- import keygen from '~helpers/keygen';
5
4
  import Comment from "../../../molecules/comment";
6
5
 
7
- const CommentTree = React.memo(({ pageContext, comment, authors, depth = 0, cookieComments }) =>
8
- <div key={keygen()} style={{ marginLeft: depth * 56 }}>
9
- <Comment pageContext={pageContext} comment={comment} authors={authors} isReply={depth > 0} userInteractions={cookieComments} />
6
+ import styles from './comment-tree.module.scss';
7
+
8
+ const CommentTree = React.memo(({ pageContext, comment, authors, depth = 0 }) =>
9
+ <div key={comment.comment_id} className={`${styles?.[`comment_${depth}`]} ${depth > 0 && styles.isReply}`}>
10
+ <Comment pageContext={pageContext} comment={comment} authors={authors} isReply={depth > 0} />
10
11
  {comment.replies?.map(reply => (
11
12
  <CommentTree
12
- key={keygen()}
13
+ key={reply.comment_id}
13
14
  comment={reply}
14
15
  authors={authors}
15
16
  depth={depth + 1}
@@ -22,11 +23,11 @@ const CommentTree = React.memo(({ pageContext, comment, authors, depth = 0, cook
22
23
  CommentTree.propTypes = {
23
24
  pageContext: PropTypes.shape({}),
24
25
  comment: PropTypes.shape({
25
- replies: arrayOf(PropTypes.shape({}))
26
+ replies: arrayOf(PropTypes.shape({})),
27
+ comment_id: PropTypes.number
26
28
  }),
27
29
  authors: PropTypes.shape({}),
28
30
  depth: PropTypes.number,
29
- cookieComments: PropTypes.arrayOf(PropTypes.string)
30
31
  };
31
32
 
32
33
  export default CommentTree;
@@ -1,39 +1,27 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import CommentTree from './comment-tree';
4
4
  import LeaveCommentForm from '../../molecules/leave-comment-form';
5
+ import { VotesProvider } from '../../../context/VotesProvider';
5
6
 
6
7
  const Comments = ({ pageContext }) => {
7
8
  const { comments, authors } = pageContext;
8
- const [cookieComments, setCookieComments] = useState([]);
9
-
10
- useEffect(() => {
11
- const storedVotes =
12
- document.cookie
13
- .split('; ')
14
- .find((row) => row.startsWith('comments='))
15
- ?.split('=')[1]
16
- ?.split(',')
17
- .filter(Boolean) || [];
18
-
19
- setCookieComments(storedVotes);
20
- }, []);
21
-
22
- if (!comments) return null;
23
9
 
24
10
  return (
25
11
  <div>
26
12
  <LeaveCommentForm page={pageContext.page} />
27
- {comments.map((comment) => (
28
- <CommentTree
29
- key={comment.comment_id}
30
- pageContext={pageContext}
31
- comment={comment}
32
- authors={authors?.authors}
33
- depth={0}
34
- cookieComments={cookieComments}
35
- />
36
- ))}
13
+ {comments && <VotesProvider>
14
+ {comments.map((comment) => (
15
+ <CommentTree
16
+ key={comment.comment_id}
17
+ pageContext={pageContext}
18
+ comment={comment}
19
+ authors={authors?.authors}
20
+ depth={0}
21
+ />
22
+ ))}
23
+ </VotesProvider>
24
+ }
37
25
  </div>
38
26
  );
39
27
  };
@@ -1,70 +1,78 @@
1
1
  /* eslint-disable react-hooks/exhaustive-deps */
2
2
  /* eslint-disable jsx-a11y/click-events-have-key-events */
3
3
  /* eslint-disable import/no-extraneous-dependencies */
4
- import React, { useState, useEffect } from 'react';
5
- import PropTypes from 'prop-types';
4
+ import React, { useState, useEffect, lazy, Suspense } from "react";
5
+ import PropTypes from "prop-types";
6
6
 
7
- import useTranslate from '~hooks/useTranslate/useTranslate';
8
- import { setCookie, getCookie } from '~helpers/cookies';
9
- import CookieModal from '../../molecules/cookie-modal';
10
- import styles from './cookie-consent.module.scss';
7
+ import useTranslate from "~hooks/useTranslate/useTranslate";
8
+ import { setCookie, getCookie } from "~helpers/cookies";
9
+ import styles from "./cookie-consent.module.scss";
11
10
 
12
11
  const CookieConsent = ({
13
- acceptText = 'Accept',
14
- rejectText = 'Reject',
12
+ acceptText = "Accept",
13
+ rejectText = "Reject",
15
14
  settingsCookie,
16
15
  children,
17
- cookieName = 'CookieConsent',
18
- logo = '/images/logo.svg',
16
+ cookieName = "CookieConsent",
17
+ logo = "/images/logo.svg",
19
18
  icon = null,
20
- showRejectButton=false
19
+ showRejectButton = false,
21
20
  }) => {
22
21
  const [showModal, setShowModal] = useState(false);
23
22
 
24
23
  const [showCookieConsent, setShowCookieConsent] = useState(false);
25
24
 
25
+ const CookieModal = lazy(() => import("../../molecules/cookie-modal"));
26
+
26
27
  // when user declines
27
28
  const handleDecline = () => {
28
- setCookie(cookieName, false, 365, '/');
29
- setCookie('showCookie', false, 365, '/');
29
+ setCookie(cookieName, false, 365, "/");
30
+ setCookie("showCookie", false, 365, "/");
30
31
  setShowCookieConsent(false);
31
32
  setShowModal(false);
32
- document.body.style.overflow = 'auto';
33
+ document.body.style.overflow = "auto";
33
34
  };
34
35
 
35
36
  // when user accepts
36
37
  const handleAccept = () => {
37
- setCookie(cookieName, true, 365, '/');
38
- setCookie('showCookie', false, 365, '/');
38
+ setCookie(cookieName, true, 365, "/");
39
+ setCookie("showCookie", false, 365, "/");
39
40
  setShowCookieConsent(false);
40
41
  setShowModal(false);
41
- document.body.style.overflow = 'auto';
42
+ document.body.style.overflow = "auto";
42
43
  };
43
44
 
44
45
  const handleShowModalClick = () => {
45
46
  setShowModal(!showModal);
46
- document.body.style.overflow = 'hidden';
47
+ document.body.style.overflow = "hidden";
47
48
  };
48
49
 
49
50
  const closeModal = () => {
50
51
  setShowModal(false);
51
- document.body.style.overflow = 'auto';
52
+ document.body.style.overflow = "auto";
52
53
  };
53
54
 
54
55
  useEffect(() => {
55
- if (typeof window !== `undefined` && getCookie('showCookie') !== "false") {
56
+ if (typeof window !== `undefined` && getCookie("showCookie") !== "false") {
56
57
  setShowCookieConsent(true);
57
58
  }
58
59
  }, []);
59
60
 
60
- const settingCookieText = useTranslate('cookie_setting_button', 'Cookie Setting');
61
+ const settingCookieText = useTranslate(
62
+ "cookie_setting_button",
63
+ "Cookie Setting"
64
+ );
61
65
 
62
66
  return (
63
67
  <>
64
- <div className={`${styles.cookieConsent} ${(showCookieConsent && styles.show) || ''}`}>
65
- <div className={`${styles?.consent || ''}`}>
66
- <div className={styles?.content || ''}>{children}</div>
67
- <div className={styles?.buttonsContainer || ''}>
68
+ <div
69
+ className={`${styles.cookieConsent} ${
70
+ (showCookieConsent && styles.show) || ""
71
+ }`}
72
+ >
73
+ <div className={`${styles?.consent || ""}`}>
74
+ <div className={styles?.content || ""}>{children}</div>
75
+ <div className={styles?.buttonsContainer || ""}>
68
76
  {settingsCookie && (
69
77
  <button
70
78
  onClick={handleShowModalClick}
@@ -90,20 +98,22 @@ const CookieConsent = ({
90
98
  className="cookie-consent-gtm btn-cta"
91
99
  type="button"
92
100
  >
93
- {useTranslate('cookie_accept_button', acceptText)}
101
+ {useTranslate("cookie_accept_button", acceptText)}
94
102
  {icon && icon}
95
103
  </button>
96
104
  </div>
97
105
  </div>
98
106
  </div>
99
107
  {settingsCookie && showModal && (
100
- <CookieModal
101
- logo={logo}
102
- hide={!showModal}
103
- handleAcceptCookies={handleAccept}
104
- handleDeclineCookies={handleDecline}
105
- closeModal={closeModal}
106
- />
108
+ <Suspense fallback={null}>
109
+ <CookieModal
110
+ logo={logo}
111
+ hide={!showModal}
112
+ handleAcceptCookies={handleAccept}
113
+ handleDeclineCookies={handleDecline}
114
+ closeModal={closeModal}
115
+ />
116
+ </Suspense>
107
117
  )}
108
118
  </>
109
119
  );
@@ -116,7 +126,11 @@ CookieConsent.propTypes = {
116
126
  settingsCookie: PropTypes.bool,
117
127
  cookieName: PropTypes.string,
118
128
  logo: PropTypes.string,
119
- children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node, PropTypes.any]),
129
+ children: PropTypes.oneOfType([
130
+ PropTypes.arrayOf(PropTypes.node),
131
+ PropTypes.node,
132
+ PropTypes.any,
133
+ ]),
120
134
  icon: PropTypes.node,
121
135
  };
122
136
 
@@ -29,7 +29,7 @@
29
29
  @include flex-align(flex-end, flex-start);
30
30
 
31
31
  > span {
32
- font-size: 1.4rem;
32
+ font-size: 1.2rem;
33
33
  font-weight: 400;
34
34
  line-height: 2.2rem;
35
35
  }
@@ -105,7 +105,7 @@
105
105
  cursor: pointer;
106
106
  width: 4.8rem;
107
107
  inset: 0;
108
- background-color: #ccc;
108
+ background-color: #AFAFB0;
109
109
  transition: 0.4s;
110
110
  border-radius: 3.4rem;
111
111
  height: 2.4rem;
@@ -137,11 +137,14 @@ input:checked + .slider::before {
137
137
 
138
138
  .switchLabel{
139
139
  margin-left: 4.5rem;
140
+ font-size: 1.6rem;
141
+ font-weight: 400;
142
+ color: var(--switch-bg, #3C3C40);
140
143
  }
141
144
 
142
145
  .errorMsg {
143
146
  font-size: 1.2rem;
144
- color: #DD4B39;
147
+ color: var(--comment-error-color, #DD4B39);;
145
148
  font-weight: 400;
146
149
  line-height: 1.8rem;
147
150
  grid-column: 1/-1;
@@ -154,7 +157,7 @@ input:checked + .slider::before {
154
157
  bottom: 3.5rem;
155
158
  right: 1.5rem;
156
159
  font-size: 1.2rem;
157
- color: #DD4B39;
160
+ color: var(--comment-length-warning-color, #DD4B39);
158
161
  font-weight: 400;
159
162
  line-height: 1.8rem;
160
163
  }
@@ -5,13 +5,21 @@
5
5
  /* eslint-disable import/prefer-default-export */
6
6
  /* eslint-disable react/react-in-jsx-scope */
7
7
  /* eslint-disable no-undef */
8
- import React, {useState} from 'react';
9
- import styles from './fields.module.scss';
10
- import { generatePlaceholderString } from '../../../../helpers/generators.mjs';
11
- import useTranslate from '~hooks/useTranslate/useTranslate';
8
+ import React, { useState } from "react";
9
+ import styles from "./fields.module.scss";
10
+ import { generatePlaceholderString } from "../../../../helpers/generators.mjs";
11
+ import useTranslate from "~hooks/useTranslate/useTranslate";
12
12
 
13
13
  const getField = (field, handleChange, elements, state) => {
14
- const { type, id, translationKey, label, placeholder, icon = null, ...props } = field;
14
+ const {
15
+ type,
16
+ id,
17
+ translationKey,
18
+ label,
19
+ placeholder,
20
+ icon = null,
21
+ ...props
22
+ } = field;
15
23
  const [rating, setRating] = useState(3);
16
24
  const { errorMsg, ...restProps } = props;
17
25
 
@@ -37,38 +45,33 @@ const getField = (field, handleChange, elements, state) => {
37
45
  <span>{`${elements[id].length}/${field.maxLength}`}</span>
38
46
  )}
39
47
  {field.minlength && (
40
- <span className={styles.lengthWarning}>{`Minimum ${field.minlength} words`}</span>
48
+ <span className={styles.lengthWarning}>
49
+ {useTranslate(
50
+ "minimum_chars",
51
+ `Minimum ${field.minlength} chars`
52
+ )}
53
+ </span>
54
+ )}
55
+ {field?.error?.errorMsg && (
56
+ <span className={styles.errorMsg}>
57
+ {useTranslate(
58
+ field?.error?.translationKey,
59
+ field?.error?.errorMsg
60
+ )}
61
+ </span>
41
62
  )}
42
- {field.errorMsg && <span className={styles.errorMsg}>{field.errorMsg}</span>}
43
63
  </div>
44
64
  );
45
65
  case "checkbox":
46
66
  return (
47
- <div className={styles.checkboxGroup || ''}>
48
- {field.options.map((option) => field.switch ? (
49
- <label key={option.id} className={styles.switch} htmlFor={option.id}>
50
- <input
51
- id={option.id}
52
- name={option.id}
53
- type={type}
54
- checked={elements[option.id] === 'true'}
55
- onChange={(e) => handleChange(e.target.name, e.target.checked.toString())}
56
- required={!!option?.required}
57
- />
58
- <span
59
- className={`${styles.checkboxLabel || ''} ${styles.slider} ${
60
- (!state.isValid && !elements[option.id].length && styles.invalid) || ''
61
- }`}
62
- />
63
- <span className={styles.switchLabel}>{generatePlaceholderString(
64
- useTranslate(option.translationKey, option.label),
65
- null,
66
- option?.link
67
- )}</span>
68
- </label>
69
- ) : (
70
- <>
71
- <div key={option.id}>
67
+ <div className={styles.checkboxGroup || ""}>
68
+ {field.options.map((option) =>
69
+ field.switch ? (
70
+ <label
71
+ key={option.id}
72
+ className={styles.switch}
73
+ htmlFor={option.id}
74
+ >
72
75
  <input
73
76
  id={option.id}
74
77
  name={option.id}
@@ -79,26 +82,58 @@ const getField = (field, handleChange, elements, state) => {
79
82
  }
80
83
  required={!!option?.required}
81
84
  />
82
- <label
83
- htmlFor={option.id}
84
- className={`${
85
- (!state.isValid &&
86
- !elements[option.id].length &&
87
- styles.invalid) ||
88
- ""
89
- }`}
90
- dangerouslySetInnerHTML={{
91
- __html: generatePlaceholderString(
92
- useTranslate(option.translationKey, option.label),
93
- null,
94
- option?.link
95
- ),
96
- }}
85
+ <span
86
+ className={`${styles.checkboxLabel || ""} ${styles.slider}`}
97
87
  />
98
- {field.errorMsg && <span className={styles.errorMsg}>{field.errorMsg}</span>}
99
- </div>
100
- </>
101
- ))}
88
+ <span className={styles.switchLabel}>
89
+ {generatePlaceholderString(
90
+ useTranslate(option.translationKey, option.label),
91
+ null,
92
+ option?.link
93
+ )}
94
+ </span>
95
+ </label>
96
+ ) : (
97
+ <>
98
+ <div key={option.id}>
99
+ <input
100
+ id={option.id}
101
+ name={option.id}
102
+ type={type}
103
+ checked={elements[option.id] === "true"}
104
+ onChange={(e) =>
105
+ handleChange(e.target.name, e.target.checked.toString())
106
+ }
107
+ required={!!option?.required}
108
+ />
109
+ <label
110
+ htmlFor={option.id}
111
+ className={`${
112
+ (!state.isValid &&
113
+ !elements[option.id].length &&
114
+ styles.invalid) ||
115
+ ""
116
+ }`}
117
+ dangerouslySetInnerHTML={{
118
+ __html: generatePlaceholderString(
119
+ useTranslate(option.translationKey, option.label),
120
+ null,
121
+ option?.link
122
+ ),
123
+ }}
124
+ />
125
+ {field?.error?.errorMsg && (
126
+ <span className={styles.errorMsg}>
127
+ {useTranslate(
128
+ field?.error?.translationKey,
129
+ field?.error?.errorMsg
130
+ )}
131
+ </span>
132
+ )}
133
+ </div>
134
+ </>
135
+ )
136
+ )}
102
137
  </div>
103
138
  );
104
139
  case "radio":
@@ -152,7 +187,7 @@ const getField = (field, handleChange, elements, state) => {
152
187
  ))}
153
188
  </select>
154
189
  );
155
- case 'range':
190
+ case "range":
156
191
  return field?.starRating ? (
157
192
  <>
158
193
  <label className={styles.ratingLabel}>
@@ -168,10 +203,12 @@ const getField = (field, handleChange, elements, state) => {
168
203
  onChange={e => setRating(e.target.value)}
169
204
  value={rating} />
170
205
  </label>
171
- {field.errorMsg && rating === '0' && <span className={styles.errorMsg}>{field.errorMsg}</span>}
206
+ {field.errorMsg && rating === "0" && (
207
+ <span className={styles.errorMsg}>{field.errorMsg}</span>
208
+ )}
172
209
  </>
173
210
  ) : (
174
- <div className={styles.radioGroup || ''}>
211
+ <div className={styles.radioGroup || ""}>
175
212
  <input
176
213
  name={id}
177
214
  id={id}
@@ -220,12 +257,20 @@ const getField = (field, handleChange, elements, state) => {
220
257
  <div className={styles.inputGroup || ""}>
221
258
  {icon}
222
259
  {inputElement}
223
- {field.errorMsg && <span className={styles.errorMsg}>{field.errorMsg}</span>}
260
+ {field.error.errorMsg && (
261
+ <span className={styles.errorMsg}>
262
+ {useTranslate(field.error?.translationKey, field.error?.errorMsg)}
263
+ </span>
264
+ )}
224
265
  </div>
225
266
  ) : (
226
267
  <>
227
268
  {inputElement}
228
- {field.errorMsg && <span className={styles.errorMsg}>{field.errorMsg}</span>}
269
+ {field.error?.errorMsg && (
270
+ <span className={styles.errorMsg}>
271
+ {useTranslate(field.error?.translationKey, field.error?.errorMsg)}
272
+ </span>
273
+ )}
229
274
  </>
230
275
  );
231
276
  }