@comicrelief/component-library 8.24.2 → 8.25.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 (21) hide show
  1. package/dist/components/Organisms/EmailSignUp/EmailSignUp.md +3 -3
  2. package/dist/components/Organisms/EmailSignUp/EmailSignUp.style.js +34 -26
  3. package/dist/components/Organisms/EmailSignUp/EmailSignUpForm.js +3 -0
  4. package/dist/components/Organisms/EmailSignUp/_EmailSignUp.js +13 -3
  5. package/dist/components/Organisms/Header/HeaderNav/HeaderNav.style.js +1 -1
  6. package/dist/components/Organisms/Header/annoying.css +1 -1
  7. package/dist/components/Organisms/Header2025/HeaderNav2025/HeaderNav2025.style.js +1 -1
  8. package/dist/components/Organisms/Header2025/annoying.css +1 -1
  9. package/dist/components/Organisms/MarketingPreferencesDS/MarketingPreferencesDS.style.js +5 -4
  10. package/dist/components/Organisms/MarketingPreferencesDS/_MarketingPreferencesDS.js +14 -4
  11. package/package.json +1 -1
  12. package/src/components/Organisms/EmailSignUp/EmailSignUp.md +3 -3
  13. package/src/components/Organisms/EmailSignUp/EmailSignUp.style.js +4 -4
  14. package/src/components/Organisms/EmailSignUp/EmailSignUpForm.js +2 -0
  15. package/src/components/Organisms/EmailSignUp/_EmailSignUp.js +20 -4
  16. package/src/components/Organisms/Header/HeaderNav/HeaderNav.style.js +6 -6
  17. package/src/components/Organisms/Header/annoying.css +1 -1
  18. package/src/components/Organisms/Header2025/HeaderNav2025/HeaderNav2025.style.js +11 -11
  19. package/src/components/Organisms/Header2025/annoying.css +1 -1
  20. package/src/components/Organisms/MarketingPreferencesDS/MarketingPreferencesDS.style.js +18 -29
  21. package/src/components/Organisms/MarketingPreferencesDS/_MarketingPreferencesDS.js +23 -4
@@ -1,5 +1,6 @@
1
1
  # Email SignUp Form
2
-
2
+ ### EmailSignUpForm.js is just a wrapper for viewing in the CL
3
+ ### The email sign up component that is used/exported is _EmailSignUp.js
3
4
 
4
5
  ```js
5
6
  import EmailSignUpForm from './EmailSignUpForm';
@@ -7,8 +8,7 @@ import Text from '../../Atoms/Text/Text';
7
8
 
8
9
  <>
9
10
  <Text tag="p">This EmailSignUpForm component exists purely to show the EmailSignUp component functioning within the Component Library; applications are to provide their own react-hook-form form and validation, based on these.</Text>
10
-
11
+
11
12
  <EmailSignUpForm />
12
13
  </>
13
-
14
14
  ```
@@ -19,16 +19,22 @@ const ESUWrapper = exports.ESUWrapper = _styledComponents.default.div.withConfig
19
19
  return theme.fontSize('s');
20
20
  }, _ref2 => {
21
21
  let {
22
- theme
22
+ theme,
23
+ textColour
23
24
  } = _ref2;
24
- return theme.color('white');
25
+ return theme.color(textColour);
25
26
  }, _ref3 => {
26
27
  let {
27
28
  theme,
28
29
  backgroundColour
29
30
  } = _ref3;
30
31
  return theme.color(backgroundColour);
31
- }, (0, _spacing.default)('m'));
32
+ }, _ref4 => {
33
+ let {
34
+ containerPadding
35
+ } = _ref4;
36
+ return containerPadding ? (0, _spacing.default)('m') : 0;
37
+ });
32
38
  const TopCopyWrapper = exports.TopCopyWrapper = _styledComponents.default.div.withConfig({
33
39
  displayName: "EmailSignUpstyle__TopCopyWrapper",
34
40
  componentId: "sc-w2b8yk-1"
@@ -36,36 +42,37 @@ const TopCopyWrapper = exports.TopCopyWrapper = _styledComponents.default.div.wi
36
42
  const ButtonWrapper = exports.ButtonWrapper = _styledComponents.default.div.withConfig({
37
43
  displayName: "EmailSignUpstyle__ButtonWrapper",
38
44
  componentId: "sc-w2b8yk-2"
39
- })(["margin-top:", ";button{background-color:", ";}"], (0, _spacing.default)('md'), _ref4 => {
45
+ })(["margin-top:", ";button{background-color:", ";}"], (0, _spacing.default)('md'), _ref5 => {
40
46
  let {
41
47
  theme,
42
48
  buttonColour
43
- } = _ref4;
49
+ } = _ref5;
44
50
  return theme.color(buttonColour);
45
51
  });
46
52
  const PrivacyCopyWrapper = exports.PrivacyCopyWrapper = _styledComponents.default.div.withConfig({
47
53
  displayName: "EmailSignUpstyle__PrivacyCopyWrapper",
48
54
  componentId: "sc-w2b8yk-3"
49
- })(["display:flex;flex-direction:column;margin-top:", ";p{font-size:", ";line-height:", ";a{font-size:", ";color:", ";}}"], (0, _spacing.default)('md'), _ref5 => {
50
- let {
51
- theme
52
- } = _ref5;
53
- return theme.fontSize('s');
54
- }, _ref6 => {
55
+ })(["display:flex;flex-direction:column;margin-top:", ";p{font-size:", ";line-height:", ";a{font-size:", ";color:", ";}}"], (0, _spacing.default)('md'), _ref6 => {
55
56
  let {
56
57
  theme
57
58
  } = _ref6;
58
- return theme.fontSize('xl');
59
+ return theme.fontSize('s');
59
60
  }, _ref7 => {
60
61
  let {
61
62
  theme
62
63
  } = _ref7;
63
- return theme.fontSize('s');
64
+ return theme.fontSize('xl');
64
65
  }, _ref8 => {
65
66
  let {
66
67
  theme
67
68
  } = _ref8;
68
- return theme.color('white');
69
+ return theme.fontSize('s');
70
+ }, _ref9 => {
71
+ let {
72
+ theme,
73
+ textColour
74
+ } = _ref9;
75
+ return theme.color(textColour);
69
76
  });
70
77
  const FormInner = exports.FormInner = _styledComponents.default.div.withConfig({
71
78
  displayName: "EmailSignUpstyle__FormInner",
@@ -74,34 +81,35 @@ const FormInner = exports.FormInner = _styledComponents.default.div.withConfig({
74
81
  const NameWrapper = exports.NameWrapper = _styledComponents.default.div.withConfig({
75
82
  displayName: "EmailSignUpstyle__NameWrapper",
76
83
  componentId: "sc-w2b8yk-5"
77
- })(["display:flex;flex-direction:column;gap:0;@media ", "{justify-content:start;flex-direction:", ";gap:", ";)};}"], _ref9 => {
84
+ })(["display:flex;flex-direction:column;gap:0;@media ", "{justify-content:start;flex-direction:", ";gap:", ";)};}"], _ref10 => {
78
85
  let {
79
86
  theme
80
- } = _ref9;
87
+ } = _ref10;
81
88
  return theme.allBreakpoints('L');
82
- }, _ref10 => {
89
+ }, _ref11 => {
83
90
  let {
84
91
  columnLayout
85
- } = _ref10;
92
+ } = _ref11;
86
93
  return columnLayout ? 'column' : 'row';
87
- }, _ref11 => {
94
+ }, _ref12 => {
88
95
  let {
89
96
  columnLayout
90
- } = _ref11;
97
+ } = _ref12;
91
98
  return columnLayout ? 0 : (0, _spacing.default)('md');
92
99
  });
93
100
  const InputField = exports.InputField = (0, _styledComponents.default)(_TextInput.default).withConfig({
94
101
  displayName: "EmailSignUpstyle__InputField",
95
102
  componentId: "sc-w2b8yk-6"
96
- })(["width:100%;margin-bottom:", ";& > span:first-child{color:", ";}@media ", "{max-width:290px;}"], (0, _spacing.default)('md'), _ref12 => {
103
+ })(["width:100%;margin-bottom:", ";& > span:first-child{color:", ";}@media ", "{max-width:290px;}"], (0, _spacing.default)('md'), _ref13 => {
97
104
  let {
98
- theme
99
- } = _ref12;
100
- return theme.color('white');
101
- }, _ref13 => {
105
+ theme,
106
+ textColour
107
+ } = _ref13;
108
+ return theme.color(textColour);
109
+ }, _ref14 => {
102
110
  let {
103
111
  theme
104
- } = _ref13;
112
+ } = _ref14;
105
113
  return theme.allBreakpoints('L');
106
114
  });
107
115
  const Title = exports.Title = (0, _styledComponents.default)(_Text.default).withConfig({
@@ -10,6 +10,9 @@ var _reactHookForm = require("react-hook-form");
10
10
  var _yup = require("@hookform/resolvers/yup");
11
11
  var _RichText = _interopRequireDefault(require("../../Atoms/RichText/RichText"));
12
12
  var _EmailSignUp = require("./_EmailSignUp");
13
+ // EmailSignUpForm.js is just a wrapper for viewing in the CL
14
+ // The email sign up component that is used/exported is _EmailSignUp.js
15
+
13
16
  const EmailSignUpForm = () => {
14
17
  const validationSchema = (0, _EmailSignUp.buildEsuValidationSchema)({});
15
18
  const formMethods = (0, _reactHookForm.useForm)({
@@ -32,9 +32,11 @@ const EmailSignUp = _ref => {
32
32
  privacyCopy,
33
33
  backgroundColour = 'deep_violet_dark',
34
34
  buttonColour = 'red',
35
- buttonText = 'Subscribe',
35
+ buttonText,
36
+ containerPadding = true,
36
37
  formContext,
37
38
  columnLayout = false,
39
+ textColour = 'white',
38
40
  ...rest
39
41
  } = _ref;
40
42
  const {
@@ -46,8 +48,11 @@ const EmailSignUp = _ref => {
46
48
  errors
47
49
  }
48
50
  } = formContext;
51
+ const normalisedButtonText = buttonText || 'Subscribe';
49
52
  return /*#__PURE__*/_react.default.createElement(_EmailSignUp.ESUWrapper, Object.assign({
50
- backgroundColour: backgroundColour
53
+ backgroundColour: backgroundColour,
54
+ textColour: textColour,
55
+ containerPadding: containerPadding
51
56
  }, rest), /*#__PURE__*/_react.default.createElement(_EmailSignUp.Title, {
52
57
  tag: "h2",
53
58
  size: "xxl",
@@ -59,6 +64,7 @@ const EmailSignUp = _ref => {
59
64
  }), /*#__PURE__*/_react.default.createElement(_EmailSignUp.TopCopyWrapper, null, /*#__PURE__*/_react.default.createElement(_Text.default, null, successCopy))), !isSubmitSuccessful && /*#__PURE__*/_react.default.createElement(_EmailSignUp.FormInner, null, /*#__PURE__*/_react.default.createElement(_EmailSignUp.NameWrapper, {
60
65
  columnLayout: columnLayout
61
66
  }, /*#__PURE__*/_react.default.createElement(_EmailSignUp.InputField, {
67
+ textColour: textColour,
62
68
  fieldName: _EmailSignUpConfig.ESU_FIELDS.FIRST_NAME,
63
69
  id: "first-name",
64
70
  type: "text",
@@ -66,6 +72,7 @@ const EmailSignUp = _ref => {
66
72
  placeholder: "Enter your first name",
67
73
  formContext: formContext
68
74
  }), /*#__PURE__*/_react.default.createElement(_EmailSignUp.InputField, {
75
+ textColour: textColour,
69
76
  fieldName: _EmailSignUpConfig.ESU_FIELDS.LAST_NAME,
70
77
  id: "last-name",
71
78
  type: "text",
@@ -73,6 +80,7 @@ const EmailSignUp = _ref => {
73
80
  placeholder: "Enter your last name",
74
81
  formContext: formContext
75
82
  })), /*#__PURE__*/_react.default.createElement(_EmailSignUp.InputField, {
83
+ textColour: textColour,
76
84
  fieldName: _EmailSignUpConfig.ESU_FIELDS.EMAIL,
77
85
  id: "email",
78
86
  type: "email",
@@ -87,6 +95,8 @@ const EmailSignUp = _ref => {
87
95
  loading: isSubmitting,
88
96
  loadingText: "Submitting...",
89
97
  "data-test": "subscribe-button"
90
- }, /*#__PURE__*/_react.default.createElement(_Text.default, null, buttonText)))), isSubmitted && !isSubmitSuccessful && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, errors.formError !== undefined && /*#__PURE__*/_react.default.createElement(_ErrorText.default, null, errors.formError.message)), /*#__PURE__*/_react.default.createElement(_EmailSignUp.PrivacyCopyWrapper, null, /*#__PURE__*/_react.default.createElement(_Text.default, null, privacyCopy)));
98
+ }, /*#__PURE__*/_react.default.createElement(_Text.default, null, normalisedButtonText)))), isSubmitted && !isSubmitSuccessful && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, errors.formError !== undefined && /*#__PURE__*/_react.default.createElement(_ErrorText.default, null, errors.formError.message)), /*#__PURE__*/_react.default.createElement(_EmailSignUp.PrivacyCopyWrapper, {
99
+ textColour: textColour
100
+ }, /*#__PURE__*/_react.default.createElement(_Text.default, null, privacyCopy)));
91
101
  };
92
102
  exports.EmailSignUp = EmailSignUp;
@@ -98,7 +98,7 @@ const SubNavMenu = exports.SubNavMenu = _styledComponents.default.ul.withConfig(
98
98
  const SubNavItem = exports.SubNavItem = _styledComponents.default.li.withConfig({
99
99
  displayName: "HeaderNavstyle__SubNavItem",
100
100
  componentId: "sc-1eihosl-3"
101
- })(["padding:0;height:100%;width:100%;border-top:1px solid ", ";;position:relative;transition:background-color ", "s ease;&:first-of-type{border-top:none;}span{font-weight:100;}:hover,:focus,:focus-within{background-color:", ";+ span{border-bottom:0;padding-bottom:2px;color:", ";}}"], _ref13 => {
101
+ })(["padding:0;height:100%;width:100%;border-top:1px solid ", ";position:relative;transition:background-color ", "s ease;&:first-of-type{border-top:none;}span{font-weight:100;}:hover,:focus,:focus-within{background-color:", ";+ span{border-bottom:0;padding-bottom:2px;color:", ";}}"], _ref13 => {
102
102
  let {
103
103
  theme
104
104
  } = _ref13;
@@ -10,5 +10,5 @@
10
10
 
11
11
  .rsg--header-11,
12
12
  .rsg--tabs-12 {
13
- display: none !important;;
13
+ display: none !important;
14
14
  }
@@ -125,7 +125,7 @@ const SubNavMenu = exports.SubNavMenu = _styledComponents.default.ul.withConfig(
125
125
  const SubNavItem = exports.SubNavItem = _styledComponents.default.li.withConfig({
126
126
  displayName: "HeaderNav2025style__SubNavItem",
127
127
  componentId: "sc-xflhtq-3"
128
- })(["padding:0;height:100%;width:100%;border-top:1px solid ", ";;position:relative;transition:background-color ", "s ease;&:first-of-type{border-top:none;}span{font-weight:100;}"], _ref18 => {
128
+ })(["padding:0;height:100%;width:100%;border-top:1px solid ", ";position:relative;transition:background-color ", "s ease;&:first-of-type{border-top:none;}span{font-weight:100;}"], _ref18 => {
129
129
  let {
130
130
  theme
131
131
  } = _ref18;
@@ -10,5 +10,5 @@
10
10
 
11
11
  .rsg--header-11,
12
12
  .rsg--tabs-12 {
13
- display: none !important;;
13
+ display: none !important;
14
14
  }
@@ -48,9 +48,10 @@ const FormField = exports.FormField = _styledComponents.default.div.withConfig({
48
48
  componentId: "sc-68n85q-5"
49
49
  })(["", ""], _ref2 => {
50
50
  let {
51
- theme
51
+ theme,
52
+ isError
52
53
  } = _ref2;
53
- return (0, _styledComponents.css)(["position:relative;margin-bottom:", ";width:100%;display:flex;flex-direction:column;padding:", ";border:1px solid ", ";;border-radius:10px;background-color:", ";transition:background-color 0.3s,color 0.3s;&:hover{background-color:", ";}&.selected{background-color:", ";span.icon-mp_permissionEmail{background-image:url(", ");}span.icon-mp_permissionPhone{background-image:url(", ");}span.icon-mp_permissionPost{background-image:url(", ");}span.icon-mp_permissionSMS{background-image:url(", ");}> div{label,> span{color:", ";}}&:hover{background-color:#161a85;}}label{position:relative;margin-bottom:0;width:100%;color:", ";font-weight:600;display:flex;justify-content:space-between;}h3{position:relative;margin-bottom:", ";&:before{position:absolute;top:0;left:0;width:24px;height:24px;content:'';}}"], (0, _spacing.default)('md'), (0, _spacing.default)('m'), theme.color('grey'), theme.color('grey_light'), theme.color('grey_medium'), theme.color('blue_donate'), _EmailWhite.default, _PhoneWhite.default, _PostWhite.default, _TextWhite.default, theme.color('white'), theme.color('black'), (0, _spacing.default)('md'));
54
+ return (0, _styledComponents.css)(["position:relative;margin-bottom:", ";width:100%;display:flex;flex-direction:column;padding:", ";background-color:", ";transition:background-color 0.3s,color 0.3s;border-radius:10px;border:1px solid ", ";&.selected{background-color:", ";&:hover{background-color:", ";border-color:", ";}span.icon-mp_permissionEmail{background-image:url(", ");}span.icon-mp_permissionPhone{background-image:url(", ");}span.icon-mp_permissionPost{background-image:url(", ");}span.icon-mp_permissionSMS{background-image:url(", ");}> div{label,> span{color:", ";}}}label{position:relative;margin-bottom:0;width:100%;color:", ";font-weight:600;display:flex;justify-content:space-between;}h3{position:relative;margin-bottom:", ";&:before{position:absolute;top:0;left:0;width:24px;height:24px;content:'';}}"], (0, _spacing.default)('md'), (0, _spacing.default)('m'), theme.color('grey_light'), theme.color('grey'), isError ? theme.color('red') : theme.color('blue_donate'), isError ? theme.color('red_dark') : theme.color('blue_donate'), theme.color('grey_4'), _EmailWhite.default, _PhoneWhite.default, _PostWhite.default, _TextWhite.default, theme.color('white'), theme.color('black'), (0, _spacing.default)('md'));
54
55
  });
55
56
  const CheckContainer = exports.CheckContainer = _styledComponents.default.div.withConfig({
56
57
  displayName: "MarketingPreferencesDSstyle__CheckContainer",
@@ -73,7 +74,7 @@ const CheckLabel = exports.CheckLabel = _styledComponents.default.label.withConf
73
74
  const CheckInput = exports.CheckInput = _styledComponents.default.input.withConfig({
74
75
  displayName: "MarketingPreferencesDSstyle__CheckInput",
75
76
  componentId: "sc-68n85q-8"
76
- })(["font-size:", ";display:block;box-sizing:border-box;opacity:0;position:absolute;width:100%;height:100%;left:0;top:0;margin:0;border:1px solid ", ";+ span{width:30px;height:30px;background-color:", ";border:1px solid ", ";float:left;border-radius:8px;}:checked + span{background:url(", ") no-repeat center ", ";;background-size:contain;}"], _ref5 => {
77
+ })(["font-size:", ";display:block;box-sizing:border-box;opacity:0;position:absolute;width:100%;height:100%;left:0;top:0;margin:0;border:1px solid ", ";+ span{width:30px;height:30px;background-color:", ";border:1px solid ", ";float:left;border-radius:8px;}:checked + span{background:url(", ") no-repeat center ", ";background-size:contain;}"], _ref5 => {
77
78
  let {
78
79
  theme
79
80
  } = _ref5;
@@ -120,7 +121,7 @@ const ExtraInfo = exports.ExtraInfo = _styledComponents.default.span.withConfig(
120
121
  const MPTextInput = exports.MPTextInput = (0, _styledComponents.default)(_TextInput.default).withConfig({
121
122
  displayName: "MarketingPreferencesDSstyle__MPTextInput",
122
123
  componentId: "sc-68n85q-11"
123
- })(["> div + span span{margin-top:-20px;}> span{margin-bottom:.5rem;}input{border:1px solid ", ";background-color:", ";margin-bottom:10px;@media ", "{max-width:none;}}"], _ref12 => {
124
+ })(["input{border:1px solid ", ";background-color:", ";@media ", "{max-width:none;}}span{color:white;}"], _ref12 => {
124
125
  let {
125
126
  theme
126
127
  } = _ref12;
@@ -90,10 +90,17 @@ const MarketingPreferencesDS = _ref => {
90
90
  const showPhoneField = !mp_permissionPhone.hideInput && (phoneChoice || errors.mp_phone);
91
91
  const showPostFields = !mp_permissionPost.hideInput && (postChoice || isAddressErroring());
92
92
  const customId = id ? "marketing-preferences--".concat(id) : 'marketing-preferences';
93
+
94
+ // Check for field-specific errors
95
+ const hasEmailError = Boolean(errors.mp_permissionEmail || errors.mp_email);
96
+ const hasPostError = Boolean(errors.mp_permissionPost || errors.mp_address1 || errors.mp_address2 || errors.mp_address3 || errors.mp_town || errors.mp_country || errors.mp_postcode);
97
+ const hasSMSError = Boolean(errors.mp_permissionSMS || errors.mp_mobile);
98
+ const hasPhoneError = Boolean(errors.mp_permissionPhone || errors.mp_phone);
93
99
  return /*#__PURE__*/_react.default.createElement(_MarketingPreferencesDS.OuterWrapper, Object.assign({
94
100
  id: customId
95
101
  }, rest), copyTop && /*#__PURE__*/_react.default.createElement(_MarketingPreferencesDS.TopCopyWrapper, null, copyTop), !mp_permissionEmail.disableOption && /*#__PURE__*/_react.default.createElement(_MarketingPreferencesDS.FormField, {
96
- className: "field-email ".concat(emailChoice && 'selected')
102
+ className: "field-email ".concat(emailChoice && 'selected'),
103
+ isError: hasEmailError
97
104
  }, /*#__PURE__*/_react.default.createElement(_MarketingPreferencesDS.CheckboxWrapper, null, /*#__PURE__*/_react.default.createElement(_OptInCheckbox.default, {
98
105
  mpValidationOptions: mpValidationOptions,
99
106
  name: "mp_permissionEmail",
@@ -115,7 +122,8 @@ const MarketingPreferencesDS = _ref => {
115
122
  id: "mp_email",
116
123
  formContext: formContext
117
124
  })))), !mp_permissionPost.disableOption && /*#__PURE__*/_react.default.createElement(_MarketingPreferencesDS.FormField, {
118
- className: "field-post ".concat(postChoice && 'selected')
125
+ className: "field-post ".concat(postChoice && 'selected'),
126
+ isError: hasPostError
119
127
  }, /*#__PURE__*/_react.default.createElement(_MarketingPreferencesDS.CheckboxWrapper, null, /*#__PURE__*/_react.default.createElement(_OptInCheckbox.default, {
120
128
  name: "mp_permissionPost",
121
129
  mpValidationOptions: mpValidationOptions,
@@ -169,7 +177,8 @@ const MarketingPreferencesDS = _ref => {
169
177
  id: "mp_country",
170
178
  formContext: formContext
171
179
  })))), !mp_permissionSMS.disableOption && /*#__PURE__*/_react.default.createElement(_MarketingPreferencesDS.FormField, {
172
- className: "field-sms ".concat(smsChoice && 'selected')
180
+ className: "field-sms ".concat(smsChoice && 'selected'),
181
+ isError: hasSMSError
173
182
  }, /*#__PURE__*/_react.default.createElement(_MarketingPreferencesDS.CheckboxWrapper, null, /*#__PURE__*/_react.default.createElement(_OptInCheckbox.default, {
174
183
  name: "mp_permissionSMS",
175
184
  id: "mp_permissionSMS",
@@ -188,7 +197,8 @@ const MarketingPreferencesDS = _ref => {
188
197
  id: "mp_mobile",
189
198
  formContext: formContext
190
199
  })))), !mp_permissionPhone.disableOption && /*#__PURE__*/_react.default.createElement(_MarketingPreferencesDS.FormField, {
191
- className: "field-phone ".concat(phoneChoice && 'selected')
200
+ className: "field-phone ".concat(phoneChoice && 'selected'),
201
+ isError: hasPhoneError
192
202
  }, /*#__PURE__*/_react.default.createElement(_MarketingPreferencesDS.CheckboxWrapper, null, /*#__PURE__*/_react.default.createElement(_OptInCheckbox.default, {
193
203
  name: "mp_permissionPhone",
194
204
  mpValidationOptions: mpValidationOptions,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comicrelief/component-library",
3
3
  "author": "Comic Relief Engineering Team",
4
- "version": "8.24.2",
4
+ "version": "8.25.1",
5
5
  "main": "dist/index.js",
6
6
  "license": "ISC",
7
7
  "jest": {
@@ -1,5 +1,6 @@
1
1
  # Email SignUp Form
2
-
2
+ ### EmailSignUpForm.js is just a wrapper for viewing in the CL
3
+ ### The email sign up component that is used/exported is _EmailSignUp.js
3
4
 
4
5
  ```js
5
6
  import EmailSignUpForm from './EmailSignUpForm';
@@ -7,8 +8,7 @@ import Text from '../../Atoms/Text/Text';
7
8
 
8
9
  <>
9
10
  <Text tag="p">This EmailSignUpForm component exists purely to show the EmailSignUp component functioning within the Component Library; applications are to provide their own react-hook-form form and validation, based on these.</Text>
10
-
11
+
11
12
  <EmailSignUpForm />
12
13
  </>
13
-
14
14
  ```
@@ -8,9 +8,9 @@ const ESUWrapper = styled.div`
8
8
  display: flex;
9
9
  flex-direction: column;
10
10
  font-size: ${({ theme }) => theme.fontSize('s')};
11
- color: ${({ theme }) => theme.color('white')};
11
+ color: ${({ theme, textColour }) => theme.color(textColour)};
12
12
  background-color: ${({ theme, backgroundColour }) => theme.color(backgroundColour)};
13
- padding: ${spacing('m')};
13
+ padding: ${({ containerPadding }) => (containerPadding ? spacing('m') : 0)};
14
14
  `;
15
15
 
16
16
  const TopCopyWrapper = styled.div`
@@ -35,7 +35,7 @@ const PrivacyCopyWrapper = styled.div`
35
35
  line-height: ${({ theme }) => theme.fontSize('xl')};
36
36
  a {
37
37
  font-size: ${({ theme }) => theme.fontSize('s')};
38
- color: ${({ theme }) => theme.color('white')};
38
+ color: ${({ theme, textColour }) => theme.color(textColour)};
39
39
  }
40
40
  }
41
41
  `;
@@ -65,7 +65,7 @@ const InputField = styled(TextInput)`
65
65
  margin-bottom: ${spacing('md')};
66
66
 
67
67
  & > span:first-child {
68
- color: ${({ theme }) => theme.color('white')};
68
+ color: ${({ theme, textColour }) => theme.color(textColour)};
69
69
  }
70
70
 
71
71
  @media ${({ theme }) => theme.allBreakpoints('L')} {
@@ -1,3 +1,5 @@
1
+ // EmailSignUpForm.js is just a wrapper for viewing in the CL
2
+ // The email sign up component that is used/exported is _EmailSignUp.js
1
3
  import React from 'react';
2
4
  import { useForm, FormProvider } from 'react-hook-form';
3
5
  import { yupResolver } from '@hookform/resolvers/yup';
@@ -24,9 +24,11 @@ const EmailSignUp = ({
24
24
  privacyCopy,
25
25
  backgroundColour = 'deep_violet_dark',
26
26
  buttonColour = 'red',
27
- buttonText = 'Subscribe',
27
+ buttonText,
28
+ containerPadding = true,
28
29
  formContext,
29
30
  columnLayout = false,
31
+ textColour = 'white',
30
32
  ...rest
31
33
  }) => {
32
34
  const {
@@ -39,8 +41,15 @@ const EmailSignUp = ({
39
41
  }
40
42
  } = formContext;
41
43
 
44
+ const normalisedButtonText = buttonText || 'Subscribe';
45
+
42
46
  return (
43
- <ESUWrapper backgroundColour={backgroundColour} {...rest}>
47
+ <ESUWrapper
48
+ backgroundColour={backgroundColour}
49
+ textColour={textColour}
50
+ containerPadding={containerPadding}
51
+ {...rest}
52
+ >
44
53
  <Title tag="h2" size="xxl" weight="400" family="Anton" uppercase>
45
54
  {title}
46
55
  </Title>
@@ -62,6 +71,7 @@ const EmailSignUp = ({
62
71
  <FormInner>
63
72
  <NameWrapper columnLayout={columnLayout}>
64
73
  <InputField
74
+ textColour={textColour}
65
75
  fieldName={ESU_FIELDS.FIRST_NAME}
66
76
  id="first-name"
67
77
  type="text"
@@ -70,6 +80,7 @@ const EmailSignUp = ({
70
80
  formContext={formContext}
71
81
  />
72
82
  <InputField
83
+ textColour={textColour}
73
84
  fieldName={ESU_FIELDS.LAST_NAME}
74
85
  id="last-name"
75
86
  type="text"
@@ -79,6 +90,7 @@ const EmailSignUp = ({
79
90
  />
80
91
  </NameWrapper>
81
92
  <InputField
93
+ textColour={textColour}
82
94
  fieldName={ESU_FIELDS.EMAIL}
83
95
  id="email"
84
96
  type="email"
@@ -94,7 +106,7 @@ const EmailSignUp = ({
94
106
  loadingText="Submitting..."
95
107
  data-test="subscribe-button"
96
108
  >
97
- <Text>{buttonText}</Text>
109
+ <Text>{normalisedButtonText}</Text>
98
110
  </ButtonWithStates>
99
111
  </ButtonWrapper>
100
112
  </FormInner>
@@ -109,7 +121,9 @@ const EmailSignUp = ({
109
121
  </>
110
122
  )}
111
123
 
112
- <PrivacyCopyWrapper>
124
+ <PrivacyCopyWrapper
125
+ textColour={textColour}
126
+ >
113
127
  <Text>{privacyCopy}</Text>
114
128
  </PrivacyCopyWrapper>
115
129
  </ESUWrapper>
@@ -124,6 +138,8 @@ EmailSignUp.propTypes = {
124
138
  backgroundColour: PropTypes.string,
125
139
  buttonColour: PropTypes.string,
126
140
  buttonText: PropTypes.string,
141
+ textColour: PropTypes.string,
142
+ containerPadding: PropTypes.bool,
127
143
  formContext: PropTypes.shape().isRequired,
128
144
  columnLayout: PropTypes.bool
129
145
  };
@@ -80,7 +80,7 @@ const SubNavMenu = styled.ul`
80
80
  overflow: hidden;
81
81
  border: 1px solid ${({ theme }) => theme.color('grey_medium')};
82
82
 
83
- // DESKTOP:
83
+ // DESKTOP:
84
84
  @media ${({ theme }) => theme.allBreakpoints('Nav')} {
85
85
  display: flex;
86
86
  visibility: ${({ isFocussed }) => (isFocussed ? 'visible' : 'hidden')};
@@ -104,7 +104,7 @@ const SubNavItem = styled.li`
104
104
  padding: 0;
105
105
  height: 100%;
106
106
  width: 100%;
107
- border-top: 1px solid ${({ theme }) => theme.color('grey_medium')};;
107
+ border-top: 1px solid ${({ theme }) => theme.color('grey_medium')};
108
108
  position: relative;
109
109
  transition: background-color ${transitionDuration}s ease;
110
110
 
@@ -230,8 +230,8 @@ const NavItem = styled.li`
230
230
  }
231
231
  }
232
232
  }
233
-
234
-
233
+
234
+
235
235
  @media ${({ theme }) => theme.allBreakpoints('Nav')} {
236
236
  margin: 0 4px;
237
237
  padding: 25px 5px;
@@ -364,12 +364,12 @@ const DonateButtonWrapperBottom = styled.div`
364
364
  transition: width 0.35s cubic-bezier(0.5, 1.5, 0.5, 0.9);
365
365
 
366
366
  &:hover,
367
- &:focus {
367
+ &:focus {
368
368
  width: 100%;
369
369
  box-shadow: rgba(0, 0, 0, 0.1) 0 0 20px 0;
370
370
  }
371
371
  }
372
-
372
+
373
373
  // Hide the 'Nav'-embedded version of the button when the nav
374
374
  // goes FULL DESKTOP, leaving just the 'Header'-embedded example
375
375
  @media ${({ theme }) => theme.allBreakpoints('Nav')} {
@@ -10,5 +10,5 @@
10
10
 
11
11
  .rsg--header-11,
12
12
  .rsg--tabs-12 {
13
- display: none !important;;
13
+ display: none !important;
14
14
  }
@@ -24,7 +24,7 @@ const NavLinkClass = styled(Link)`
24
24
  :focus-within {
25
25
  border: 0;
26
26
  }
27
-
27
+
28
28
  // No hover state for mobile, so targetting Medium+:
29
29
  @media ${({ theme }) => theme.allBreakpoints('M')} {
30
30
  :hover,
@@ -44,7 +44,7 @@ const NavLinkClass = styled(Link)`
44
44
  }
45
45
  }
46
46
  }
47
-
47
+
48
48
  // Chevron icon:
49
49
  > div {
50
50
  height: auto;
@@ -113,7 +113,7 @@ const SubNavMenu = styled.ul`
113
113
  overflow: hidden;
114
114
  border-top: 1px solid ${({ theme }) => theme.color('grey_medium')};
115
115
 
116
- // DESKTOP:
116
+ // DESKTOP:
117
117
  @media ${({ theme }) => theme.allBreakpoints('Nav')} {
118
118
  display: flex;
119
119
  width: 330px;
@@ -136,7 +136,7 @@ const SubNavItem = styled.li`
136
136
  padding: 0;
137
137
  height: 100%;
138
138
  width: 100%;
139
- border-top: 1px solid ${({ theme }) => theme.color('grey_medium')};;
139
+ border-top: 1px solid ${({ theme }) => theme.color('grey_medium')};
140
140
  position: relative;
141
141
  transition: background-color ${transitionDuration}s ease;
142
142
 
@@ -208,7 +208,7 @@ const NavLink = styled(NavLinkClass)`
208
208
  ${({ hasSubMenu }) => (hasSubMenu && css`
209
209
  padding: 10px 14px 10px 0;
210
210
  `)}
211
-
211
+
212
212
  :hover,
213
213
  :focus-within,
214
214
  :focus {
@@ -217,7 +217,7 @@ const NavLink = styled(NavLinkClass)`
217
217
  opacity: 1;
218
218
  }}
219
219
  }
220
-
220
+
221
221
  @media ${({ theme }) => theme.allBreakpoints('NavWide')} {
222
222
  ${({ hasSubMenu }) => (hasSubMenu && css`
223
223
  padding: 10px 16px 10px 0;
@@ -286,8 +286,8 @@ const NavItem = styled.li`
286
286
  }
287
287
  }
288
288
  }
289
-
290
-
289
+
290
+
291
291
  @media ${({ theme }) => theme.allBreakpoints('Nav')} {
292
292
  margin: 0 22px 0 0;
293
293
  padding: 25px 0px;
@@ -399,7 +399,7 @@ const NavMetaIcons = styled.div`
399
399
  &:hover {
400
400
  span {
401
401
  color: ${({ theme }) => theme.color('red')};
402
- }
402
+ }
403
403
  }
404
404
  }
405
405
  }
@@ -438,12 +438,12 @@ const DonateButtonWrapperBottom = styled.div`
438
438
  transition: width 0.35s cubic-bezier(0.5, 1.5, 0.5, 0.9);
439
439
 
440
440
  &:hover,
441
- &:focus {
441
+ &:focus {
442
442
  width: 100%;
443
443
  box-shadow: rgba(0, 0, 0, 0.1) 0 0 20px 0;
444
444
  }
445
445
  }
446
-
446
+
447
447
  // Hide the 'Nav'-embedded version of the button when the nav
448
448
  // goes FULL DESKTOP, leaving just the 'Header'-embedded example
449
449
  @media ${({ theme }) => theme.allBreakpoints('Nav')} {
@@ -10,5 +10,5 @@
10
10
 
11
11
  .rsg--header-11,
12
12
  .rsg--tabs-12 {
13
- display: none !important;;
13
+ display: none !important;
14
14
  }
@@ -16,7 +16,7 @@ const OuterWrapper = styled.div`
16
16
  display: flex;
17
17
  flex-direction: column;
18
18
 
19
- // Preload 'selected' icons
19
+ /* Preload 'selected' icons */
20
20
  &:after {
21
21
  position:absolute;
22
22
  width: 0;
@@ -75,24 +75,24 @@ const AssociatedFieldsName = styled.span`
75
75
  }
76
76
  `;
77
77
 
78
- const FormField = styled.div`${({ theme }) => css`
78
+ const FormField = styled.div`${({ theme, isError }) => css`
79
79
  position: relative;
80
80
  margin-bottom: ${spacing('md')};
81
81
  width: 100%;
82
82
  display: flex;
83
83
  flex-direction: column;
84
84
  padding: ${spacing('m')};
85
- border: 1px solid ${theme.color('grey')};;
86
- border-radius: 10px;
87
85
  background-color: ${theme.color('grey_light')};
88
86
  transition: background-color 0.3s, color 0.3s;
89
-
90
- &:hover {
91
- background-color: ${theme.color('grey_medium')};
92
- }
87
+ border-radius: 10px;
88
+ border: 1px solid ${theme.color('grey')};
93
89
 
94
90
  &.selected {
95
- background-color: ${theme.color('blue_donate')};
91
+ background-color: ${isError ? theme.color('red') : theme.color('blue_donate')};
92
+ &:hover {
93
+ background-color: ${isError ? theme.color('red_dark') : theme.color('blue_donate')};
94
+ border-color: ${theme.color('grey_4')};
95
+ }
96
96
 
97
97
  span.icon-mp_permissionEmail {
98
98
  background-image: url(${EmailIconWhite});
@@ -115,14 +115,9 @@ const FormField = styled.div`${({ theme }) => css`
115
115
  color: ${theme.color('white')};
116
116
  }
117
117
  }
118
-
119
- &:hover {
120
- // No fancy functions yet to darken preexisting colours..
121
- background-color: #161a85;
122
- }
123
118
  }
124
119
 
125
- // All labels; input AND checkbox
120
+ /* All labels; input AND checkbox */
126
121
  label {
127
122
  position: relative;
128
123
  margin-bottom: 0;
@@ -187,7 +182,7 @@ const CheckInput = styled.input`
187
182
  border-radius: 8px;
188
183
  }
189
184
  :checked + span {
190
- background: url(${checkBoxIcon}) no-repeat center ${({ theme }) => theme.color('white')};;
185
+ background: url(${checkBoxIcon}) no-repeat center ${({ theme }) => theme.color('white')};
191
186
  background-size: contain;
192
187
  }
193
188
  `;
@@ -219,9 +214,9 @@ const ExtraInfo = styled.span`
219
214
  margin-top: ${spacing('md')};
220
215
  margin-bottom: 0;
221
216
 
222
- // Visually hide the actual field label for the
223
- // non-multifield options, as we have the
224
- // more chatty 'extra info' language
217
+ /* Visually hide the actual field label for the */
218
+ /* non-multifield options, as we have the */
219
+ /* more chatty 'extra info' language */
225
220
  &[for="mp_email"],
226
221
  &[for="mp_mobile"],
227
222
  &[for="mp_phone"] {
@@ -240,23 +235,17 @@ const ExtraInfo = styled.span`
240
235
  `;
241
236
 
242
237
  const MPTextInput = styled(TextInput)`
243
- // Correct the ErrorMsg offset for this context
244
- > div + span span {
245
- margin-top: -20px;
246
- }
247
-
248
- > span {
249
- margin-bottom: .5rem;
250
- }
251
-
252
238
  input {
253
239
  border: 1px solid ${({ theme }) => theme.color('black')};
254
240
  background-color: ${({ theme }) => theme.color('white')};
255
- margin-bottom: 10px;
256
241
  @media ${({ theme }) => theme.allBreakpoints('M')} {
257
242
  max-width: none;
258
243
  }
259
244
  }
245
+ /* error message text colour */
246
+ span {
247
+ color: white;
248
+ }
260
249
  `;
261
250
 
262
251
  export {
@@ -61,13 +61,23 @@ const MarketingPreferencesDS = ({
61
61
 
62
62
  const customId = id ? `marketing-preferences--${id}` : 'marketing-preferences';
63
63
 
64
+ // Check for field-specific errors
65
+ const hasEmailError = Boolean(errors.mp_permissionEmail || errors.mp_email);
66
+ const hasPostError = Boolean(errors.mp_permissionPost || errors.mp_address1 || errors.mp_address2
67
+ || errors.mp_address3 || errors.mp_town || errors.mp_country || errors.mp_postcode);
68
+ const hasSMSError = Boolean(errors.mp_permissionSMS || errors.mp_mobile);
69
+ const hasPhoneError = Boolean(errors.mp_permissionPhone || errors.mp_phone);
70
+
64
71
  return (
65
72
  <OuterWrapper id={customId} {...rest}>
66
73
  {copyTop && <TopCopyWrapper>{copyTop}</TopCopyWrapper>}
67
74
 
68
75
  {/* Render Email checkboxes and input if not removed in config */}
69
76
  {!mp_permissionEmail.disableOption && (
70
- <FormField className={`field-email ${emailChoice && 'selected'}`}>
77
+ <FormField
78
+ className={`field-email ${emailChoice && 'selected'}`}
79
+ isError={hasEmailError}
80
+ >
71
81
  <CheckboxWrapper>
72
82
  <OptInCheckbox
73
83
  mpValidationOptions={mpValidationOptions}
@@ -102,7 +112,10 @@ const MarketingPreferencesDS = ({
102
112
 
103
113
  {/* Render Post checkboxes and inputs if not removed in config */}
104
114
  {!mp_permissionPost.disableOption && (
105
- <FormField className={`field-post ${postChoice && 'selected'}`}>
115
+ <FormField
116
+ className={`field-post ${postChoice && 'selected'}`}
117
+ isError={hasPostError}
118
+ >
106
119
  <CheckboxWrapper>
107
120
  <OptInCheckbox
108
121
  name="mp_permissionPost"
@@ -174,7 +187,10 @@ const MarketingPreferencesDS = ({
174
187
 
175
188
  {/* Render SMS checkboxes and inputs if not removed in config */}
176
189
  {!mp_permissionSMS.disableOption && (
177
- <FormField className={`field-sms ${smsChoice && 'selected'}`}>
190
+ <FormField
191
+ className={`field-sms ${smsChoice && 'selected'}`}
192
+ isError={hasSMSError}
193
+ >
178
194
  <CheckboxWrapper>
179
195
  <OptInCheckbox
180
196
  name="mp_permissionSMS"
@@ -206,7 +222,10 @@ const MarketingPreferencesDS = ({
206
222
 
207
223
  {/* Render Phone checkboxes and input if not removed in config */}
208
224
  {!mp_permissionPhone.disableOption && (
209
- <FormField className={`field-phone ${phoneChoice && 'selected'}`}>
225
+ <FormField
226
+ className={`field-phone ${phoneChoice && 'selected'}`}
227
+ isError={hasPhoneError}
228
+ >
210
229
  <CheckboxWrapper>
211
230
  <OptInCheckbox
212
231
  name="mp_permissionPhone"