@comicrelief/component-library 8.44.4 → 8.45.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.
- package/dist/components/Atoms/SocialIcons/Icon/Icon.js +39 -14
- package/dist/components/Atoms/SocialIcons/SocialIcons.js +91 -22
- package/dist/components/Atoms/SocialIcons/Utils/Icons.js +26 -7
- package/dist/components/Atoms/SocialIcons/Utils/Links.js +10 -0
- package/dist/components/Atoms/SocialIcons/__snapshots__/SocialIcons.test.js.snap +63 -48
- package/{src/components/Atoms/SocialIcons/assets → dist/components/Atoms/SocialIcons/assets/circled}/facebook.svg +1 -1
- package/{src/components/Atoms/SocialIcons/assets → dist/components/Atoms/SocialIcons/assets/circled}/twitter.svg +1 -1
- package/dist/components/Atoms/SocialIcons/assets/{youtube.svg → circled/youtube.svg} +1 -1
- package/dist/components/Atoms/SocialIcons/assets/standard/facebook.svg +3 -0
- package/dist/components/Atoms/SocialIcons/assets/standard/instagram.svg +3 -0
- package/dist/components/Atoms/SocialIcons/assets/standard/tiktok.svg +3 -0
- package/dist/components/Atoms/SocialIcons/assets/standard/x.svg +3 -0
- package/dist/components/Atoms/SocialIcons/assets/standard/youtube.svg +3 -0
- package/dist/components/Molecules/EmailSignUp/EmailSignUp.js +38 -0
- package/dist/components/Molecules/EmailSignUp/EmailSignUp.style.js +113 -0
- package/dist/components/Molecules/LogoLinked/LogoLinked.js +6 -6
- package/dist/components/Organisms/Footer/Footer.md +12 -11
- package/dist/components/Organisms/Footer/FundraisingRegulatorLogo/FundraisingRegulatorLogo.js +36 -16
- package/dist/components/Organisms/Footer/Nav/Nav.style.js +8 -8
- package/dist/components/Organisms/Footer/__snapshots__/Footer.test.js.snap +188 -183
- package/dist/components/Organisms/FooterNew/FooterNew.js +136 -0
- package/dist/components/Organisms/FooterNew/FooterNew.md +47 -0
- package/dist/components/Organisms/FooterNew/FooterNew.style.js +312 -0
- package/dist/components/Organisms/FooterNew/FooterNew.test.js +20 -0
- package/dist/components/Organisms/FooterNew/Nav/PrimaryNav.js +32 -0
- package/dist/components/Organisms/FooterNew/Nav/SecondaryNav.js +32 -0
- package/dist/components/Organisms/FooterNew/__snapshots__/FooterNew.test.js.snap +1490 -0
- package/dist/components/Organisms/FooterNew/dev-data/data.js +106 -0
- package/dist/index.js +20 -0
- package/dist/theme/crTheme/colors.js +12 -7
- package/dist/theme/shared/animations.js +46 -0
- package/package.json +1 -1
- package/src/components/Atoms/SocialIcons/Icon/Icon.js +47 -11
- package/src/components/Atoms/SocialIcons/SocialIcons.js +99 -25
- package/src/components/Atoms/SocialIcons/Utils/Icons.js +29 -10
- package/src/components/Atoms/SocialIcons/Utils/Links.js +10 -0
- package/src/components/Atoms/SocialIcons/__snapshots__/SocialIcons.test.js.snap +63 -48
- package/{dist/components/Atoms/SocialIcons/assets → src/components/Atoms/SocialIcons/assets/circled}/facebook.svg +1 -1
- package/{dist/components/Atoms/SocialIcons/assets → src/components/Atoms/SocialIcons/assets/circled}/twitter.svg +1 -1
- package/src/components/Atoms/SocialIcons/assets/{youtube.svg → circled/youtube.svg} +1 -1
- package/src/components/Atoms/SocialIcons/assets/standard/facebook.svg +3 -0
- package/src/components/Atoms/SocialIcons/assets/standard/instagram.svg +3 -0
- package/src/components/Atoms/SocialIcons/assets/standard/tiktok.svg +3 -0
- package/src/components/Atoms/SocialIcons/assets/standard/x.svg +3 -0
- package/src/components/Atoms/SocialIcons/assets/standard/youtube.svg +3 -0
- package/src/components/Molecules/EmailSignUp/EmailSignUp.js +55 -0
- package/src/components/Molecules/EmailSignUp/EmailSignUp.style.js +107 -0
- package/src/components/Molecules/LogoLinked/LogoLinked.js +5 -14
- package/src/components/Organisms/Footer/Footer.md +12 -11
- package/src/components/Organisms/Footer/FundraisingRegulatorLogo/FundraisingRegulatorLogo.js +14 -3
- package/src/components/Organisms/Footer/Nav/Nav.style.js +8 -8
- package/src/components/Organisms/Footer/__snapshots__/Footer.test.js.snap +188 -183
- package/src/components/Organisms/FooterNew/FooterNew.js +211 -0
- package/src/components/Organisms/FooterNew/FooterNew.md +47 -0
- package/src/components/Organisms/FooterNew/FooterNew.style.js +294 -0
- package/src/components/Organisms/FooterNew/FooterNew.test.js +24 -0
- package/src/components/Organisms/FooterNew/Nav/PrimaryNav.js +54 -0
- package/src/components/Organisms/FooterNew/Nav/SecondaryNav.js +54 -0
- package/src/components/Organisms/FooterNew/__snapshots__/FooterNew.test.js.snap +1490 -0
- package/src/components/Organisms/FooterNew/dev-data/data.js +123 -0
- package/src/index.js +2 -0
- package/src/theme/crTheme/colors.js +13 -7
- package/src/theme/shared/animations.js +60 -0
- /package/dist/components/Atoms/SocialIcons/assets/{X-white-Subtract.svg → circled/X-white-Subtract.svg} +0 -0
- /package/dist/components/Atoms/SocialIcons/assets/{instagram.svg → circled/instagram.svg} +0 -0
- /package/src/components/Atoms/SocialIcons/assets/{X-white-Subtract.svg → circled/X-white-Subtract.svg} +0 -0
- /package/src/components/Atoms/SocialIcons/assets/{instagram.svg → circled/instagram.svg} +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.testSecondaryLinksList = exports.testPrimaryLinksList = exports.secondaryLinksList = exports.primaryLinksList = void 0;
|
|
7
|
+
const primaryLinksList = exports.primaryLinksList = [{
|
|
8
|
+
title: 'Contact us',
|
|
9
|
+
path: 'contact-us',
|
|
10
|
+
internal: {
|
|
11
|
+
type: 'ContentfulPageLandingPage'
|
|
12
|
+
}
|
|
13
|
+
}, {
|
|
14
|
+
title: 'Update your preferences',
|
|
15
|
+
path: 'https://www.comicrelief.com/update-your-preferences',
|
|
16
|
+
internal: {
|
|
17
|
+
type: 'ContentfulPageLandingPage'
|
|
18
|
+
}
|
|
19
|
+
}, {
|
|
20
|
+
title: 'Your Gift Aid',
|
|
21
|
+
path: 'https://giftaid.comicrelief.com/update',
|
|
22
|
+
internal: {
|
|
23
|
+
type: 'ContentfulPageLandingPage'
|
|
24
|
+
}
|
|
25
|
+
}, {
|
|
26
|
+
title: 'Reporting complaints and concerns',
|
|
27
|
+
path: 'https://www.comicrelief.com/reporting-complaints',
|
|
28
|
+
internal: {
|
|
29
|
+
type: 'ContentfulPageLandingPage'
|
|
30
|
+
}
|
|
31
|
+
}, {
|
|
32
|
+
title: 'FAQs',
|
|
33
|
+
path: 'https://www.comicrelief.com/frequently-asked-questions',
|
|
34
|
+
internal: {
|
|
35
|
+
type: 'ContentfulPageLandingPage'
|
|
36
|
+
}
|
|
37
|
+
}];
|
|
38
|
+
const secondaryLinksList = exports.secondaryLinksList = [{
|
|
39
|
+
title: 'Terms of use',
|
|
40
|
+
path: 'https://www.comicrelief.com/terms-of-use',
|
|
41
|
+
internal: {
|
|
42
|
+
type: 'ContentfulPageLandingPage'
|
|
43
|
+
}
|
|
44
|
+
}, {
|
|
45
|
+
title: 'Privacy notice',
|
|
46
|
+
path: 'https://www.comicrelief.com/privacy-notice',
|
|
47
|
+
internal: {
|
|
48
|
+
type: 'ContentfulPageLandingPage'
|
|
49
|
+
}
|
|
50
|
+
}, {
|
|
51
|
+
title: 'Cookies',
|
|
52
|
+
path: 'https://www.comicrelief.com/cookies',
|
|
53
|
+
internal: {
|
|
54
|
+
type: 'ContentfulPageLandingPage'
|
|
55
|
+
}
|
|
56
|
+
}, {
|
|
57
|
+
title: 'Text to donate terms',
|
|
58
|
+
path: 'https://www.comicrelief.com/text-to-donate-terms',
|
|
59
|
+
internal: {
|
|
60
|
+
type: 'ContentfulPageLandingPage'
|
|
61
|
+
}
|
|
62
|
+
}, {
|
|
63
|
+
title: 'Prize draw terms',
|
|
64
|
+
path: 'https://www.comicrelief.com/prize-draw-terms',
|
|
65
|
+
internal: {
|
|
66
|
+
type: 'ContentfulPageLandingPage'
|
|
67
|
+
}
|
|
68
|
+
}, {
|
|
69
|
+
title: 'Modern Slavery and Human Trafficking Statement',
|
|
70
|
+
path: 'https://www.comicrelief.com/modern-slavery-statement',
|
|
71
|
+
internal: {
|
|
72
|
+
type: 'ContentfulPageLandingPage'
|
|
73
|
+
}
|
|
74
|
+
}, {
|
|
75
|
+
title: 'Positive Practices',
|
|
76
|
+
path: 'https://www.comicrelief.com/positive-practices',
|
|
77
|
+
internal: {
|
|
78
|
+
type: 'ContentfulPageLandingPage'
|
|
79
|
+
}
|
|
80
|
+
}];
|
|
81
|
+
const testPrimaryLinksList = exports.testPrimaryLinksList = [{
|
|
82
|
+
title: 'Contact us',
|
|
83
|
+
path: 'contact-us',
|
|
84
|
+
internal: {
|
|
85
|
+
type: 'ContentfulPageLandingPage'
|
|
86
|
+
}
|
|
87
|
+
}, {
|
|
88
|
+
title: 'FAQs',
|
|
89
|
+
path: 'https://www.comicrelief.com/frequently-asked-questions',
|
|
90
|
+
internal: {
|
|
91
|
+
type: 'ContentfulPageLandingPage'
|
|
92
|
+
}
|
|
93
|
+
}];
|
|
94
|
+
const testSecondaryLinksList = exports.testSecondaryLinksList = [{
|
|
95
|
+
title: 'Terms of use',
|
|
96
|
+
path: 'https://www.comicrelief.com/terms-of-use',
|
|
97
|
+
internal: {
|
|
98
|
+
type: 'ContentfulPageLandingPage'
|
|
99
|
+
}
|
|
100
|
+
}, {
|
|
101
|
+
title: 'Privacy notice',
|
|
102
|
+
path: 'https://www.comicrelief.com/privacy-notice',
|
|
103
|
+
internal: {
|
|
104
|
+
type: 'ContentfulPageLandingPage'
|
|
105
|
+
}
|
|
106
|
+
}];
|
package/dist/index.js
CHANGED
|
@@ -130,6 +130,12 @@ Object.defineProperty(exports, "Footer", {
|
|
|
130
130
|
return _Footer.default;
|
|
131
131
|
}
|
|
132
132
|
});
|
|
133
|
+
Object.defineProperty(exports, "FooterNew", {
|
|
134
|
+
enumerable: true,
|
|
135
|
+
get: function () {
|
|
136
|
+
return _FooterNew.default;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
133
139
|
Object.defineProperty(exports, "Header", {
|
|
134
140
|
enumerable: true,
|
|
135
141
|
get: function () {
|
|
@@ -400,6 +406,12 @@ Object.defineProperty(exports, "hideVisually", {
|
|
|
400
406
|
return _hideVisually.default;
|
|
401
407
|
}
|
|
402
408
|
});
|
|
409
|
+
Object.defineProperty(exports, "logoRotateAnimation", {
|
|
410
|
+
enumerable: true,
|
|
411
|
+
get: function () {
|
|
412
|
+
return _animations.logoRotateAnimation;
|
|
413
|
+
}
|
|
414
|
+
});
|
|
403
415
|
Object.defineProperty(exports, "setInitialValues", {
|
|
404
416
|
enumerable: true,
|
|
405
417
|
get: function () {
|
|
@@ -412,6 +424,12 @@ Object.defineProperty(exports, "spacing", {
|
|
|
412
424
|
return _spacing.default;
|
|
413
425
|
}
|
|
414
426
|
});
|
|
427
|
+
Object.defineProperty(exports, "springScaleAnimation", {
|
|
428
|
+
enumerable: true,
|
|
429
|
+
get: function () {
|
|
430
|
+
return _animations.springScaleAnimation;
|
|
431
|
+
}
|
|
432
|
+
});
|
|
415
433
|
Object.defineProperty(exports, "zIndex", {
|
|
416
434
|
enumerable: true,
|
|
417
435
|
get: function () {
|
|
@@ -426,6 +444,7 @@ var _allowListed = _interopRequireDefault(require("./utils/allowListed"));
|
|
|
426
444
|
var _spacing = _interopRequireDefault(require("./theme/shared/spacing"));
|
|
427
445
|
var _allBreakpoints = _interopRequireDefault(require("./theme/shared/allBreakpoints"));
|
|
428
446
|
var _containers = _interopRequireDefault(require("./theme/shared/containers"));
|
|
447
|
+
var _animations = require("./theme/shared/animations");
|
|
429
448
|
var _Text = _interopRequireDefault(require("./components/Atoms/Text/Text"));
|
|
430
449
|
var _Logo = _interopRequireDefault(require("./components/Atoms/Logo/Logo"));
|
|
431
450
|
var _Picture = _interopRequireDefault(require("./components/Atoms/Picture/Picture"));
|
|
@@ -459,6 +478,7 @@ var _Donate = _interopRequireDefault(require("./components/Organisms/Donate/Dona
|
|
|
459
478
|
var _DoubleCopy = _interopRequireDefault(require("./components/Molecules/DoubleCopy/DoubleCopy"));
|
|
460
479
|
var _PartnerLink = _interopRequireDefault(require("./components/Molecules/PartnerLink/PartnerLink"));
|
|
461
480
|
var _Footer = _interopRequireDefault(require("./components/Organisms/Footer/Footer"));
|
|
481
|
+
var _FooterNew = _interopRequireDefault(require("./components/Organisms/FooterNew/FooterNew"));
|
|
462
482
|
var _SearchResult = _interopRequireDefault(require("./components/Molecules/SearchResult/SearchResult"));
|
|
463
483
|
var _SearchInput = _interopRequireDefault(require("./components/Molecules/SearchInput/SearchInput"));
|
|
464
484
|
var _ShareButton = _interopRequireDefault(require("./components/Molecules/ShareButton/ShareButton"));
|
|
@@ -33,17 +33,22 @@ const colors = {
|
|
|
33
33
|
grey_extra_light: '#f0f0f0',
|
|
34
34
|
grey_for_forms: '#666',
|
|
35
35
|
grey_label: '#5C5C5E',
|
|
36
|
-
|
|
37
|
-
// grey_1
|
|
36
|
+
grey_1: '#FFFFFF',
|
|
38
37
|
grey_light: '#F4F3F5',
|
|
39
|
-
// grey_2
|
|
40
38
|
grey_medium: '#E1E2E3',
|
|
41
|
-
|
|
39
|
+
grey_2: '#E1E2E3',
|
|
40
|
+
// TODO: 'grey' is actually 'grey_3'. It is referenced in many places.
|
|
41
|
+
// We need to rename it to 'grey_3' across all references.
|
|
42
|
+
// Until then, we need to keep both names for backwards compatibility.
|
|
43
|
+
// Same story with 'grey_medium' - it should be grey_2, and
|
|
44
|
+
// grey_dark, should be grey_4.
|
|
45
|
+
// For the time being we need both of each. I will provision a separate PR.
|
|
42
46
|
grey: '#969598',
|
|
43
|
-
|
|
44
|
-
grey_4: '#6E6E6E',
|
|
45
|
-
// grey_5
|
|
47
|
+
grey_3: '#969598',
|
|
46
48
|
grey_dark: '#222222',
|
|
49
|
+
grey_4: '#222222',
|
|
50
|
+
grey_4_hover: '#3A3A3A',
|
|
51
|
+
grey_5: '#18181A',
|
|
47
52
|
/* GENERAL COLOURS */
|
|
48
53
|
blue: '#0565D1',
|
|
49
54
|
blue_dark: '#274084',
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.springScaleAnimation = exports.logoRotateAnimation = void 0;
|
|
7
|
+
var _styledComponents = require("styled-components");
|
|
8
|
+
/**
|
|
9
|
+
* Logo rotation animation on hover
|
|
10
|
+
* Applies a rotation transition that rotates the logo (or whatever else)
|
|
11
|
+
* -14deg on hover/focus
|
|
12
|
+
* @param {boolean} animateRotate - Whether to enable the rotation animation
|
|
13
|
+
* @returns {css} template literal for the animation
|
|
14
|
+
*/
|
|
15
|
+
const logoRotateAnimation = animateRotate => {
|
|
16
|
+
if (!animateRotate) {
|
|
17
|
+
return (0, _styledComponents.css)([""]);
|
|
18
|
+
}
|
|
19
|
+
return (0, _styledComponents.css)(["img{transition:transform 0.6s cubic-bezier(0.41,1.64,0.41,0.8);}&:hover,&:focus{img{transform:rotate(-14deg);}}"]);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Spring scale animation on hover
|
|
24
|
+
* Applies a smooth spring-like scale transition that expands the element on hover/focus
|
|
25
|
+
* @param {boolean} animateScale - Whether to enable the scale animation
|
|
26
|
+
* @param {number} scaleFactor - Scale factor to apply on hover (default 8%)
|
|
27
|
+
* @param {number} bounceIntensity - Intensity of the springy bounce effect (0-3, default: 1)
|
|
28
|
+
* @returns {css} template literal for the animation
|
|
29
|
+
*/
|
|
30
|
+
exports.logoRotateAnimation = logoRotateAnimation;
|
|
31
|
+
const springScaleAnimation = function (animateScale) {
|
|
32
|
+
let scaleFactor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1.08;
|
|
33
|
+
let bounceIntensity = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
|
34
|
+
if (!animateScale) {
|
|
35
|
+
return (0, _styledComponents.css)([""]);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// More negative pull-back and higher overshoot = more bounce
|
|
39
|
+
// Default intensity (1) gives: cubic-bezier(0.68, -0.85, 0.265, 1.95)
|
|
40
|
+
// Higher intensity = more pronounced bounce effect
|
|
41
|
+
const pullBack = -0.55 - bounceIntensity * 0.3;
|
|
42
|
+
const overshoot = 1.55 + bounceIntensity * 0.4;
|
|
43
|
+
const duration = 0.2 + bounceIntensity * 0.1;
|
|
44
|
+
return (0, _styledComponents.css)(["transition:transform ", "s cubic-bezier(0.68,", ",0.265,", ");transform-origin:center;&:hover,&:focus{transform:scale(", ");}"], duration, pullBack, overshoot, scaleFactor);
|
|
45
|
+
};
|
|
46
|
+
exports.springScaleAnimation = springScaleAnimation;
|
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@ import styled, { css } from 'styled-components';
|
|
|
4
4
|
import { kebabCase } from 'lodash';
|
|
5
5
|
import hideVisually from '../../../../theme/shared/hideVisually';
|
|
6
6
|
import Text from '../../Text/Text';
|
|
7
|
+
import { springScaleAnimation } from '../../../../theme/shared/animations';
|
|
7
8
|
|
|
8
9
|
const RevealTextWidth = 55;
|
|
9
10
|
const RevealTextSpeed = 0.35;
|
|
@@ -30,11 +31,11 @@ const StyledLink = styled.a`
|
|
|
30
31
|
&:focus {
|
|
31
32
|
opacity: 1;
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
|
|
34
35
|
// No hover state for mobile, so targetting Medium+:
|
|
35
|
-
@media ${({ theme }) => theme.
|
|
36
|
+
@media ${({ theme }) => theme.breakpoints2026('M')} {
|
|
36
37
|
&:hover,
|
|
37
|
-
&:focus {
|
|
38
|
+
&:focus {
|
|
38
39
|
img {
|
|
39
40
|
filter: invert(0.5) sepia(1) saturate(100) hue-rotate(20deg);
|
|
40
41
|
}
|
|
@@ -46,24 +47,46 @@ const StyledLink = styled.a`
|
|
|
46
47
|
&:focus {
|
|
47
48
|
// Default
|
|
48
49
|
padding-right: ${RevealTextWidth}px;
|
|
49
|
-
|
|
50
|
+
|
|
50
51
|
// Tweak for ESU's longer text:
|
|
51
52
|
&[data-test="header-esu"] {
|
|
52
53
|
padding-right: 92px;
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
+
|
|
55
56
|
// Tweak for Shop's shorter text:
|
|
56
57
|
&[data-test="header-shop"] {
|
|
57
58
|
padding-right: 48px;
|
|
58
59
|
}
|
|
59
|
-
|
|
60
|
-
// Show the Reveal text
|
|
60
|
+
|
|
61
|
+
// Show the Reveal text
|
|
61
62
|
img + span {
|
|
62
63
|
display: block;
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
`}
|
|
66
67
|
};
|
|
68
|
+
|
|
69
|
+
// New style is rounded square buttons with dark grey background, and animation.
|
|
70
|
+
// When we've moved fully to the new design,
|
|
71
|
+
// this prop and the old styles can be removed.
|
|
72
|
+
${({ newStyle }) => newStyle && css`
|
|
73
|
+
background-color: ${({ theme }) => theme.color('grey_4')};
|
|
74
|
+
border-radius: 0.5rem;
|
|
75
|
+
padding: 0.5rem;
|
|
76
|
+
display: flex;
|
|
77
|
+
align-items: center;
|
|
78
|
+
justify-content: center;
|
|
79
|
+
width: 100%;
|
|
80
|
+
height: 100%;
|
|
81
|
+
|
|
82
|
+
${springScaleAnimation(true, 1.15, 2)}
|
|
83
|
+
|
|
84
|
+
&:hover,
|
|
85
|
+
&:focus {
|
|
86
|
+
background-color: ${({ theme }) => theme.color('grey_4_hover')};
|
|
87
|
+
opacity: 1;
|
|
88
|
+
}
|
|
89
|
+
`}
|
|
67
90
|
`;
|
|
68
91
|
|
|
69
92
|
const RevealText = styled(Text)`
|
|
@@ -88,6 +111,9 @@ const RevealText = styled(Text)`
|
|
|
88
111
|
|
|
89
112
|
const StyledImage = styled.img`
|
|
90
113
|
width: 100%;
|
|
114
|
+
${({ invertColor }) => invertColor && css`
|
|
115
|
+
filter: brightness(0) invert(1);
|
|
116
|
+
`}
|
|
91
117
|
`;
|
|
92
118
|
|
|
93
119
|
const HelperText = styled.span`
|
|
@@ -95,7 +121,8 @@ const HelperText = styled.span`
|
|
|
95
121
|
`;
|
|
96
122
|
|
|
97
123
|
const Icon = ({
|
|
98
|
-
href, target, icon, brand, title,
|
|
124
|
+
href, target, icon, brand, title, id,
|
|
125
|
+
isHeader = false, newStyle = false, invertColor = false, ...restProps
|
|
99
126
|
}) => (
|
|
100
127
|
<StyledLink
|
|
101
128
|
href={href}
|
|
@@ -105,9 +132,9 @@ const Icon = ({
|
|
|
105
132
|
rel="noopener noreferrer"
|
|
106
133
|
data-test={`${isHeader ? 'header' : 'icon'}-${kebabCase(id)}`}
|
|
107
134
|
isHeader={isHeader}
|
|
135
|
+
newStyle={newStyle}
|
|
108
136
|
>
|
|
109
|
-
<StyledImage src={icon} alt={brand} />
|
|
110
|
-
|
|
137
|
+
<StyledImage src={icon} alt={brand} invertColor={invertColor} />
|
|
111
138
|
{ isHeader && (
|
|
112
139
|
<RevealText>{title}</RevealText>
|
|
113
140
|
)}
|
|
@@ -125,7 +152,16 @@ Icon.propTypes = {
|
|
|
125
152
|
icon: PropTypes.string.isRequired,
|
|
126
153
|
title: PropTypes.string.isRequired,
|
|
127
154
|
isHeader: PropTypes.bool,
|
|
128
|
-
id: PropTypes.string.isRequired
|
|
155
|
+
id: PropTypes.string.isRequired,
|
|
156
|
+
/** This applies the newer style, fitting with the new footer design for our pre-RND 2026
|
|
157
|
+
* website redesign.
|
|
158
|
+
* Currently only in use in the new footer. Once we have moved fully to the new design,
|
|
159
|
+
* this prop and the old styles can be removed. */
|
|
160
|
+
newStyle: PropTypes.bool,
|
|
161
|
+
/** Invert the color of the svg icon, e.g. for if you're using a dark background
|
|
162
|
+
* (currently only in use in the new footer)
|
|
163
|
+
*/
|
|
164
|
+
invertColor: PropTypes.bool
|
|
129
165
|
};
|
|
130
166
|
|
|
131
167
|
export default Icon;
|
|
@@ -2,50 +2,107 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import styled from 'styled-components';
|
|
4
4
|
import getLinks from './Utils/Links';
|
|
5
|
-
import
|
|
5
|
+
import { circledIcons, standardIcons } from './Utils/Icons';
|
|
6
6
|
import Icon from './Icon/Icon';
|
|
7
7
|
import spacing from '../../../theme/shared/spacing';
|
|
8
8
|
|
|
9
9
|
const StyledList = styled.ul`
|
|
10
10
|
display: flex;
|
|
11
11
|
list-style-type: none;
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
justify-content: ${newStyle => (newStyle ? 'space-around' : 'center')};
|
|
13
|
+
margin: ${({ newStyle }) => (newStyle ? `${spacing('lg')} 0` : '0 auto 0 0')};
|
|
14
14
|
padding: 0;
|
|
15
15
|
align-items: center;
|
|
16
16
|
|
|
17
|
-
@media ${({ theme }) => theme.
|
|
17
|
+
@media ${({ theme }) => theme.breakpoints2026('M')} {
|
|
18
18
|
justify-content: start;
|
|
19
|
+
margin: ${({ newStyle }) => (newStyle ? `${spacing('sm')} 0` : '0 auto 0 0')};
|
|
19
20
|
}
|
|
20
21
|
`;
|
|
21
22
|
|
|
22
23
|
const StyledItem = styled.li`
|
|
23
|
-
width:
|
|
24
|
-
margin-right: ${spacing('m')};
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
width: 48px;
|
|
25
|
+
margin-right: ${({ newStyle }) => (newStyle ? '0' : spacing('m'))};
|
|
26
|
+
|
|
27
|
+
@media ${({ theme }) => theme.breakpoints2026('M')} {
|
|
28
|
+
margin-right: ${({ newStyle }) => (newStyle ? spacing('md') : spacing('m'))};
|
|
27
29
|
}
|
|
28
30
|
`;
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
const StyledIcon = styled(Icon)`
|
|
33
|
+
width: auto;
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
const SocialIcons = ({
|
|
37
|
+
campaign,
|
|
38
|
+
showFacebookSocialIcon,
|
|
39
|
+
showInstagramSocialIcon,
|
|
40
|
+
showXSocialIcon,
|
|
41
|
+
showTikTokSocialIcon,
|
|
42
|
+
showYouTubeSocialIcon,
|
|
43
|
+
target = 'blank',
|
|
44
|
+
newStyle = false,
|
|
45
|
+
invertColor = false,
|
|
46
|
+
...restProps
|
|
47
|
+
}) => {
|
|
32
48
|
const links = getLinks(campaign);
|
|
33
49
|
|
|
50
|
+
// We've got two sets now - one better suited to the new footer design,
|
|
51
|
+
// and one for the legacy footer.
|
|
52
|
+
const iconSet = newStyle ? standardIcons : circledIcons;
|
|
53
|
+
|
|
54
|
+
// Map brand names to their show props
|
|
55
|
+
const brandVisibilityMap = {
|
|
56
|
+
facebook: showFacebookSocialIcon,
|
|
57
|
+
instagram: showInstagramSocialIcon,
|
|
58
|
+
twitter: showXSocialIcon,
|
|
59
|
+
x: showXSocialIcon,
|
|
60
|
+
tiktok: showTikTokSocialIcon,
|
|
61
|
+
youtube: showYouTubeSocialIcon
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// If prop is explicitly false, hide; otherwise show
|
|
65
|
+
// (for backward compatibility with the 'old' footer)
|
|
66
|
+
const shouldShowIcon = brand => {
|
|
67
|
+
const visibilityProp = brandVisibilityMap[brand];
|
|
68
|
+
return visibilityProp !== false;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// Get the list of brands to display
|
|
72
|
+
// For newStyle, include tiktok and use 'x' instead of twitter
|
|
73
|
+
const brandsToShow = newStyle
|
|
74
|
+
? ['facebook', 'instagram', 'x', 'tiktok', 'youtube']
|
|
75
|
+
: ['facebook', 'instagram', 'twitter', 'youtube'];
|
|
76
|
+
|
|
34
77
|
return (
|
|
35
|
-
<StyledList>
|
|
36
|
-
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
78
|
+
<StyledList newStyle={newStyle}>
|
|
79
|
+
{brandsToShow
|
|
80
|
+
.filter(brand => shouldShowIcon(brand))
|
|
81
|
+
.map(brand => {
|
|
82
|
+
const linkData = links[brand];
|
|
83
|
+
if (!linkData) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const icon = iconSet[brand];
|
|
87
|
+
if (!icon) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
return (
|
|
91
|
+
<StyledItem key={brand} newStyle={newStyle}>
|
|
92
|
+
<StyledIcon
|
|
93
|
+
target={target}
|
|
94
|
+
icon={icon}
|
|
95
|
+
href={linkData.url}
|
|
96
|
+
title={linkData.title}
|
|
97
|
+
brand={brand}
|
|
98
|
+
id={linkData.id}
|
|
99
|
+
newStyle={newStyle}
|
|
100
|
+
invertColor={invertColor}
|
|
101
|
+
{...restProps}
|
|
102
|
+
/>
|
|
103
|
+
</StyledItem>
|
|
104
|
+
);
|
|
105
|
+
})}
|
|
49
106
|
</StyledList>
|
|
50
107
|
);
|
|
51
108
|
};
|
|
@@ -54,7 +111,24 @@ SocialIcons.propTypes = {
|
|
|
54
111
|
/** Campaign, used to get social media accounts' links */
|
|
55
112
|
campaign: PropTypes.string.isRequired,
|
|
56
113
|
/** Social media account link target */
|
|
57
|
-
target: PropTypes.string
|
|
114
|
+
target: PropTypes.string,
|
|
115
|
+
/** This applies the newer style, fitting with the new footer design for
|
|
116
|
+
* our pre-RND 2026 website redesign.
|
|
117
|
+
Currently only in use in the new footer. Once we have moved fully to
|
|
118
|
+
the new design, this prop and the old styles can be removed. */
|
|
119
|
+
newStyle: PropTypes.bool,
|
|
120
|
+
/** Show/hide Facebook social icon */
|
|
121
|
+
showFacebookSocialIcon: PropTypes.bool,
|
|
122
|
+
/** Show/hide Instagram social icon */
|
|
123
|
+
showInstagramSocialIcon: PropTypes.bool,
|
|
124
|
+
/** Show/hide X (Twitter) social icon */
|
|
125
|
+
showXSocialIcon: PropTypes.bool,
|
|
126
|
+
/** Show/hide TikTok social icon */
|
|
127
|
+
showTikTokSocialIcon: PropTypes.bool,
|
|
128
|
+
/** Show/hide YouTube social icon */
|
|
129
|
+
showYouTubeSocialIcon: PropTypes.bool,
|
|
130
|
+
/** Invert the color of the svg icon, e.g. for if you're using a dark background */
|
|
131
|
+
invertColor: PropTypes.bool
|
|
58
132
|
};
|
|
59
133
|
|
|
60
134
|
export default SocialIcons;
|
|
@@ -1,11 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
// Icons with drawn circular border (old style)
|
|
2
|
+
import facebookCircled from '../assets/circled/facebook.svg';
|
|
3
|
+
import twitterCircled from '../assets/circled/X-white-Subtract.svg';
|
|
4
|
+
import youtubeCircled from '../assets/circled/youtube.svg';
|
|
5
|
+
import instagramCircled from '../assets/circled/instagram.svg';
|
|
6
|
+
|
|
7
|
+
// Standard icons without drawn border (new style)
|
|
8
|
+
import facebookStandard from '../assets/standard/facebook.svg';
|
|
9
|
+
import xStandard from '../assets/standard/x.svg';
|
|
10
|
+
import youtubeStandard from '../assets/standard/youtube.svg';
|
|
11
|
+
import instagramStandard from '../assets/standard/instagram.svg';
|
|
12
|
+
import tiktokStandard from '../assets/standard/tiktok.svg';
|
|
13
|
+
|
|
14
|
+
export const circledIcons = {
|
|
15
|
+
facebook: facebookCircled,
|
|
16
|
+
instagram: instagramCircled,
|
|
17
|
+
twitter: twitterCircled,
|
|
18
|
+
youtube: youtubeCircled
|
|
11
19
|
};
|
|
20
|
+
|
|
21
|
+
export const standardIcons = {
|
|
22
|
+
facebook: facebookStandard,
|
|
23
|
+
instagram: instagramStandard,
|
|
24
|
+
x: xStandard,
|
|
25
|
+
youtube: youtubeStandard,
|
|
26
|
+
tiktok: tiktokStandard
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// Default export for backward compatibility (circled icons)
|
|
30
|
+
export default circledIcons;
|
|
@@ -14,6 +14,11 @@ export default campaign => ({
|
|
|
14
14
|
title: 'Check out our Twitter account',
|
|
15
15
|
id: 'twitter'
|
|
16
16
|
},
|
|
17
|
+
x: {
|
|
18
|
+
url: `https://x.com/${campaign}`,
|
|
19
|
+
title: 'Check out our X account',
|
|
20
|
+
id: 'x'
|
|
21
|
+
},
|
|
17
22
|
youtube: {
|
|
18
23
|
url: 'https://www.youtube.com/channel/UCdF5u0ggeSETozc8fsprjcw',
|
|
19
24
|
title: 'Check out our YouTube channel',
|
|
@@ -23,5 +28,10 @@ export default campaign => ({
|
|
|
23
28
|
url: `https://www.instagram.com/${campaign}`,
|
|
24
29
|
title: 'Check out our Instagram account',
|
|
25
30
|
id: 'instagram'
|
|
31
|
+
},
|
|
32
|
+
tiktok: {
|
|
33
|
+
url: `https://www.tiktok.com/@${campaign}`,
|
|
34
|
+
title: 'Check out our TikTok account',
|
|
35
|
+
id: 'tiktok'
|
|
26
36
|
}
|
|
27
37
|
});
|