@comicrelief/component-library 8.2.1 → 8.3.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.
- package/dist/components/Organisms/MarketingPreferencesDS/_DefaultCopy.js +4 -2
- package/dist/components/Organisms/RichtextCarousel/RichtextCarousel.js +110 -0
- package/dist/components/Organisms/RichtextCarousel/RichtextCarousel.md +14 -0
- package/dist/components/Organisms/RichtextCarousel/RichtextCarousel.style.js +88 -0
- package/dist/components/Organisms/RichtextCarousel/RichtextCarousel.test.js +16 -0
- package/dist/index.js +8 -1
- package/dist/styleguide/data/data.js +16 -1
- package/package.json +1 -1
- package/src/components/Organisms/MarketingPreferencesDS/_DefaultCopy.js +2 -1
- package/src/components/Organisms/RichtextCarousel/RichtextCarousel.js +160 -0
- package/src/components/Organisms/RichtextCarousel/RichtextCarousel.md +14 -0
- package/src/components/Organisms/RichtextCarousel/RichtextCarousel.style.js +248 -0
- package/src/components/Organisms/RichtextCarousel/RichtextCarousel.test.js +221 -0
- package/src/index.js +1 -0
- package/src/styleguide/data/data.js +14 -1
|
@@ -29,8 +29,10 @@ const defaultCopyBottom = exports.defaultCopyBottom = /*#__PURE__*/_react.defaul
|
|
|
29
29
|
color: "grey_dark"
|
|
30
30
|
}, "Update your preferences at any time by visiting our", ' ', /*#__PURE__*/_react.default.createElement(_Link.default, {
|
|
31
31
|
type: "standard",
|
|
32
|
-
href: "https://www.comicrelief.com/update-your-preferences"
|
|
32
|
+
href: "https://www.comicrelief.com/update-your-preferences",
|
|
33
|
+
target: "blank"
|
|
33
34
|
}, "preferences centre"), ". Your details will be kept safe, see our", ' ', /*#__PURE__*/_react.default.createElement(_Link.default, {
|
|
34
35
|
type: "standard",
|
|
35
|
-
href: "https://www.comicrelief.com/privacy-policy"
|
|
36
|
+
href: "https://www.comicrelief.com/privacy-policy",
|
|
37
|
+
target: "blank"
|
|
36
38
|
}, "privacy policy"), ' ', "for more information.");
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
var _pureReactCarousel = require("pure-react-carousel");
|
|
10
|
+
require("pure-react-carousel/dist/react-carousel.es.css");
|
|
11
|
+
var _RichtextCarousel = require("./RichtextCarousel.style");
|
|
12
|
+
var _allBreakpoints = require("../../../theme/shared/allBreakpoints");
|
|
13
|
+
const RichtextCarousel = _ref => {
|
|
14
|
+
let {
|
|
15
|
+
data: {
|
|
16
|
+
contentful_id: thisID,
|
|
17
|
+
autoPlay,
|
|
18
|
+
nodes,
|
|
19
|
+
headingCopy,
|
|
20
|
+
// Set some defaults for good measure:
|
|
21
|
+
mobileHeight = 300,
|
|
22
|
+
tabletHeight = 350,
|
|
23
|
+
desktopHeight = 350,
|
|
24
|
+
carouselBackgroundColour = 'white',
|
|
25
|
+
nodeBackgroundColour = 'white',
|
|
26
|
+
nodeOutlineColour = 'grey'
|
|
27
|
+
}
|
|
28
|
+
} = _ref;
|
|
29
|
+
// Defaults to mobile config:
|
|
30
|
+
const [isMobile, setIsMobile] = (0, _react.useState)(true);
|
|
31
|
+
const [visibleSlides, setVisibleSlides] = (0, _react.useState)(1);
|
|
32
|
+
const [totalSlides, setTotalSlides] = (0, _react.useState)(null);
|
|
33
|
+
const [theseItems, setTheseItems] = (0, _react.useState)();
|
|
34
|
+
|
|
35
|
+
// Custom function to let us update the carousel config dynamically
|
|
36
|
+
const screenResize = (0, _react.useCallback)(() => {
|
|
37
|
+
const screenSize = typeof window !== 'undefined' ? window.innerWidth : null;
|
|
38
|
+
const isCurrentlyMobile = window.innerWidth < _allBreakpoints.breakpointValues.M;
|
|
39
|
+
if (screenSize !== null && isMobile !== isCurrentlyMobile) {
|
|
40
|
+
setIsMobile(isCurrentlyMobile);
|
|
41
|
+
setVisibleSlides(isCurrentlyMobile ? 1 : 3);
|
|
42
|
+
setTotalSlides(isCurrentlyMobile ? theseItems.length : theseItems.length + 2);
|
|
43
|
+
}
|
|
44
|
+
}, [isMobile, theseItems]);
|
|
45
|
+
|
|
46
|
+
// Cache our data source, using as a flag for render logic:
|
|
47
|
+
(0, _react.useEffect)(() => {
|
|
48
|
+
setTheseItems(nodes);
|
|
49
|
+
}, [setTheseItems, nodes]);
|
|
50
|
+
(0, _react.useEffect)(() => {
|
|
51
|
+
if (window !== 'undefined' && window.innerWidth >= _allBreakpoints.breakpointValues.M) {
|
|
52
|
+
// On inital render, update carousel plugin config
|
|
53
|
+
// to suit the non-mobile layout and functionality:
|
|
54
|
+
setIsMobile(false);
|
|
55
|
+
setVisibleSlides(3);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Hook into browser's own onresize event to call our custom wrapper function:
|
|
59
|
+
if (typeof window !== 'undefined') window.onresize = screenResize;
|
|
60
|
+
}, [screenResize]);
|
|
61
|
+
if (theseItems && totalSlides === null) {
|
|
62
|
+
// Reflects our two dummy/bookend slides for non-mobile/tablet views:
|
|
63
|
+
setTotalSlides(isMobile ? theseItems.length : theseItems.length + 2);
|
|
64
|
+
}
|
|
65
|
+
return /*#__PURE__*/_react.default.createElement(_RichtextCarousel.CarouselWrapper, {
|
|
66
|
+
className: "CarouselWrapper",
|
|
67
|
+
id: thisID,
|
|
68
|
+
mobileHeight: mobileHeight,
|
|
69
|
+
tabletHeight: tabletHeight,
|
|
70
|
+
desktopHeight: desktopHeight,
|
|
71
|
+
carouselBackgroundColour: carouselBackgroundColour
|
|
72
|
+
}, /*#__PURE__*/_react.default.createElement(_RichtextCarousel.HeadingCopyWrapper, null, headingCopy), theseItems && /*#__PURE__*/_react.default.createElement(_pureReactCarousel.CarouselProvider, {
|
|
73
|
+
naturalSlideWidth: 50,
|
|
74
|
+
naturalSlideHeight: 200,
|
|
75
|
+
totalSlides: totalSlides,
|
|
76
|
+
isPlaying: autoPlay,
|
|
77
|
+
interval: 5000,
|
|
78
|
+
visibleSlides: visibleSlides,
|
|
79
|
+
infinite: true
|
|
80
|
+
}, /*#__PURE__*/_react.default.createElement(_pureReactCarousel.Slider, {
|
|
81
|
+
classNameAnimation: "richtext-carousel"
|
|
82
|
+
}, isMobile === false && /*#__PURE__*/_react.default.createElement(_pureReactCarousel.Slide, {
|
|
83
|
+
index: 0,
|
|
84
|
+
key: 0
|
|
85
|
+
}), Object.keys(theseItems).map((key, index) => {
|
|
86
|
+
// Reflect that initial dummy/bookend slide shown on non-mobile/tablet views:
|
|
87
|
+
const thisOffsetIndex = index + (isMobile ? 0 : 1);
|
|
88
|
+
return (
|
|
89
|
+
/*#__PURE__*/
|
|
90
|
+
// Calculate the index offset accordingly to reflect the number of slides,
|
|
91
|
+
// but use the REAL index when determining if its the last REAL slide
|
|
92
|
+
_react.default.createElement(_pureReactCarousel.Slide, {
|
|
93
|
+
index: thisOffsetIndex,
|
|
94
|
+
className: index === theseItems.length - 1 && 'last-slide',
|
|
95
|
+
key: thisOffsetIndex
|
|
96
|
+
}, /*#__PURE__*/_react.default.createElement(_RichtextCarousel.SlideCopyWrapper, {
|
|
97
|
+
className: "slide-copy-wrapper",
|
|
98
|
+
mobileHeight: mobileHeight,
|
|
99
|
+
tabletHeight: tabletHeight,
|
|
100
|
+
desktopHeight: desktopHeight,
|
|
101
|
+
nodeBackgroundColour: nodeBackgroundColour,
|
|
102
|
+
nodeOutlineColour: nodeOutlineColour
|
|
103
|
+
}, theseItems[index].copy))
|
|
104
|
+
);
|
|
105
|
+
}), isMobile === false && /*#__PURE__*/_react.default.createElement(_pureReactCarousel.Slide, {
|
|
106
|
+
index: theseItems.length + 1,
|
|
107
|
+
key: "bookend-last"
|
|
108
|
+
})), /*#__PURE__*/_react.default.createElement(_pureReactCarousel.ButtonBack, null, "Back"), /*#__PURE__*/_react.default.createElement(_pureReactCarousel.ButtonNext, null, "Next")));
|
|
109
|
+
};
|
|
110
|
+
var _default = exports.default = RichtextCarousel;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Richtext Carousel
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
const { RichtextCarouselItems } = require('../../../styleguide/data/data');
|
|
5
|
+
|
|
6
|
+
<div>
|
|
7
|
+
<h2 style={{textAlign: 'center'}}>
|
|
8
|
+
Richtext Carousel #1
|
|
9
|
+
</h2>
|
|
10
|
+
<RichtextCarousel
|
|
11
|
+
data={RichtextCarouselItems}/>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
```
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.SlideCopyWrapper = exports.HeadingCopyWrapper = exports.CarouselWrapper = void 0;
|
|
9
|
+
var _styledComponents = _interopRequireWildcard(require("styled-components"));
|
|
10
|
+
var _spacing = _interopRequireDefault(require("../../../theme/shared/spacing"));
|
|
11
|
+
// import Text from '../../Atoms/Text/Text';
|
|
12
|
+
// Duration in seconds
|
|
13
|
+
const animationSpeed = 0.75;
|
|
14
|
+
const SlideCopyWrapper = exports.SlideCopyWrapper = _styledComponents.default.div.withConfig({
|
|
15
|
+
displayName: "RichtextCarouselstyle__SlideCopyWrapper",
|
|
16
|
+
componentId: "sc-35wlbv-0"
|
|
17
|
+
})(["background:", ";height:", "px;width:75%;display:flex;flex-direction:column;justify-content:center;padding:25px;border:1px dashed ", ";border-radius:20px;position:relative;overflow:visible;word-wrap:break-word;&:after{position:absolute;content:'';top:50%;width:34%;right:calc(-34% - 0px);height:2px;border-bottom:1px dashed ", ";}@media ", "{height:", "px;width:85%;}@media ", "{height:", "px;}"], _ref => {
|
|
18
|
+
let {
|
|
19
|
+
theme,
|
|
20
|
+
nodeBackgroundColour
|
|
21
|
+
} = _ref;
|
|
22
|
+
return theme.color(nodeBackgroundColour);
|
|
23
|
+
}, props => props.mobileHeight, _ref2 => {
|
|
24
|
+
let {
|
|
25
|
+
theme,
|
|
26
|
+
nodeOutlineColour
|
|
27
|
+
} = _ref2;
|
|
28
|
+
return theme.color(nodeOutlineColour);
|
|
29
|
+
}, _ref3 => {
|
|
30
|
+
let {
|
|
31
|
+
theme,
|
|
32
|
+
nodeOutlineColour
|
|
33
|
+
} = _ref3;
|
|
34
|
+
return theme.color(nodeOutlineColour);
|
|
35
|
+
}, _ref4 => {
|
|
36
|
+
let {
|
|
37
|
+
theme
|
|
38
|
+
} = _ref4;
|
|
39
|
+
return theme.allBreakpoints('M');
|
|
40
|
+
}, props => props.tabletHeight, _ref5 => {
|
|
41
|
+
let {
|
|
42
|
+
theme
|
|
43
|
+
} = _ref5;
|
|
44
|
+
return theme.allBreakpoints('L');
|
|
45
|
+
}, props => props.desktopHeight);
|
|
46
|
+
const HeadingCopyWrapper = exports.HeadingCopyWrapper = _styledComponents.default.div.withConfig({
|
|
47
|
+
displayName: "RichtextCarouselstyle__HeadingCopyWrapper",
|
|
48
|
+
componentId: "sc-35wlbv-1"
|
|
49
|
+
})(["text-align:center;"]);
|
|
50
|
+
|
|
51
|
+
// Unfortunately having to target plugin-created markup ye olde fashioned way:
|
|
52
|
+
const CarouselWrapper = exports.CarouselWrapper = _styledComponents.default.div.withConfig({
|
|
53
|
+
displayName: "RichtextCarouselstyle__CarouselWrapper",
|
|
54
|
+
componentId: "sc-35wlbv-2"
|
|
55
|
+
})(["height:100%;background:", ";max-width:760px;padding:2.5rem ", " 3.5rem;margin:0 auto;border-radius:20px;box-shadow:0px 0px 20px rgba(0,0,0,0.15);.carousel{position:relative;margin:0 auto;padding-top:", ";button.carousel__back-button,button.carousel__next-button{position:absolute;left:0;top:0;width:33% !important;height:100%;padding:0 !important;box-shadow:none;text-indent:-9999px;background-color:transparent;border:none;&:after{content:\"\";position:absolute;top:0;left:0;width:50%;height:100%;transition:opacity 0.2s linear;background:", ";}&:hover{&:after{opacity:0.5;}}@media ", "{width:33.3% !important;&:after{width:100%;}}}button.carousel__next-button{left:auto;right:0;&:before{transform:translate(0,-50%) rotate(-90deg);}&:after{left:auto;right:0;background:", ";}}.richtext-carousel{transition:-webkit-transform ", "s;-o-transition:transform ", "s;transition:transform ", "s;-webkit-transform:", "s;will-change:transform;.last-slide{.slide-copy-wrapper:after{content:none;}}.carousel__slide{padding-bottom:", "px !important;@media ", "{padding-bottom:", "px !important;.carousel__inner-slide{> div:first-child{transition:transform ", "s ease;transform-origin:center;transform:scale(0.8);&:after{transition:transform ", "s ease,width ", "s ease,right ", "s ease;width:100%;right:calc(-100% - 6px);transform:scale(1);}}}&.carousel__slide--visible{.carousel__inner-slide{> div:first-child{&:after{width:33%;right:calc(-33% - 3px);transform:scale(1);}}}+ .carousel__slide--visible{.carousel__inner-slide{> div:first-child{transform:scale(1);&:after{width:33%;right:calc(-33% + 3px);transform:scale(0.8);}}}+ .carousel__slide--visible{> div > div:first-child{transform:scale(0.8);&:after{width:50%;right:calc(-50% - 6px);transform:scale(1);}}}}}}@media ", "{padding-bottom:", "px !important;&.carousel__slide--visible{+ .carousel__slide--visible{+ .carousel__slide--visible{.carousel__inner-slide{> div:first-child{&:after{right:calc(-125% - 5px);width:125%;}}}}}}}.carousel__inner-slide{text-align:center;display:inline-flex;align-items:center;justify-content:flex-start;flex-direction:column;}}}}"], _ref6 => {
|
|
56
|
+
let {
|
|
57
|
+
theme,
|
|
58
|
+
carouselBackgroundColour
|
|
59
|
+
} = _ref6;
|
|
60
|
+
return theme.color(carouselBackgroundColour);
|
|
61
|
+
}, (0, _spacing.default)('l'), (0, _spacing.default)('l'), _ref7 => {
|
|
62
|
+
let {
|
|
63
|
+
theme,
|
|
64
|
+
carouselBackgroundColour
|
|
65
|
+
} = _ref7;
|
|
66
|
+
return (0, _styledComponents.css)(["linear-gradient(90deg,", ",", "7a,", "00);"], theme.color(carouselBackgroundColour), theme.color(carouselBackgroundColour), theme.color(carouselBackgroundColour));
|
|
67
|
+
}, _ref8 => {
|
|
68
|
+
let {
|
|
69
|
+
theme
|
|
70
|
+
} = _ref8;
|
|
71
|
+
return theme.allBreakpoints('M');
|
|
72
|
+
}, _ref9 => {
|
|
73
|
+
let {
|
|
74
|
+
theme,
|
|
75
|
+
carouselBackgroundColour
|
|
76
|
+
} = _ref9;
|
|
77
|
+
return (0, _styledComponents.css)(["linear-gradient(90deg,", "00,", "7a,", ");"], theme.color(carouselBackgroundColour), theme.color(carouselBackgroundColour), theme.color(carouselBackgroundColour));
|
|
78
|
+
}, animationSpeed, animationSpeed, animationSpeed, animationSpeed, props => props.mobileHeight, _ref10 => {
|
|
79
|
+
let {
|
|
80
|
+
theme
|
|
81
|
+
} = _ref10;
|
|
82
|
+
return theme.allBreakpoints('M');
|
|
83
|
+
}, props => props.tabletHeight, animationSpeed, animationSpeed, animationSpeed, animationSpeed, _ref11 => {
|
|
84
|
+
let {
|
|
85
|
+
theme
|
|
86
|
+
} = _ref11;
|
|
87
|
+
return theme.allBreakpoints('L');
|
|
88
|
+
}, props => props.desktopHeight);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
var _react = _interopRequireDefault(require("react"));
|
|
5
|
+
require("jest-styled-components");
|
|
6
|
+
var _shallowWithTheme = _interopRequireDefault(require("../../../../tests/hoc/shallowWithTheme"));
|
|
7
|
+
var _RichtextCarousel = _interopRequireDefault(require("./RichtextCarousel"));
|
|
8
|
+
const {
|
|
9
|
+
RichtextCarouselItems
|
|
10
|
+
} = require("../../../styleguide/data/data");
|
|
11
|
+
it("renders correctly", () => {
|
|
12
|
+
const tree = (0, _shallowWithTheme.default)( /*#__PURE__*/_react.default.createElement(_RichtextCarousel.default, {
|
|
13
|
+
data: RichtextCarouselItems
|
|
14
|
+
})).toJSON();
|
|
15
|
+
expect(tree).toMatchInlineSnapshot("\n .c1 {\n text-align: center;\n }\n\n .c0 {\n height: 100%;\n background: #FFFFFF;\n max-width: 760px;\n padding: 2.5rem 2rem 3.5rem;\n margin: 0 auto;\n border-radius: 20px;\n box-shadow: 0px 0px 20px rgba(0,0,0,0.15);\n }\n\n .c0 .carousel {\n position: relative;\n margin: 0 auto;\n padding-top: 2rem;\n }\n\n .c0 .carousel button.carousel__back-button,\n .c0 .carousel button.carousel__next-button {\n position: absolute;\n left: 0;\n top: 0;\n width: 33% !important;\n height: 100%;\n padding: 0 !important;\n box-shadow: none;\n text-indent: -9999px;\n background-color: transparent;\n border: none;\n }\n\n .c0 .carousel button.carousel__back-button:after,\n .c0 .carousel button.carousel__next-button:after {\n content: \"\";\n position: absolute;\n top: 0;\n left: 0;\n width: 50%;\n height: 100%;\n -webkit-transition: opacity 0.2s linear;\n transition: opacity 0.2s linear;\n background: linear-gradient(90deg,#FFFFFF,#FFFFFF7a,#FFFFFF00);\n }\n\n .c0 .carousel button.carousel__back-button:hover:after,\n .c0 .carousel button.carousel__next-button:hover:after {\n opacity: 0.5;\n }\n\n .c0 .carousel button.carousel__next-button {\n left: auto;\n right: 0;\n }\n\n .c0 .carousel button.carousel__next-button:before {\n -webkit-transform: translate(0,-50%) rotate(-90deg);\n -ms-transform: translate(0,-50%) rotate(-90deg);\n transform: translate(0,-50%) rotate(-90deg);\n }\n\n .c0 .carousel button.carousel__next-button:after {\n left: auto;\n right: 0;\n background: linear-gradient(90deg,#FFFFFF00,#FFFFFF7a,#FFFFFF);\n }\n\n .c0 .carousel .richtext-carousel {\n -webkit-transition: -webkit-transform 0.75s;\n -webkit-transition: -webkit-transform 0.75s;\n transition: -webkit-transform 0.75s;\n -o-transition: transform 0.75s;\n -webkit-transition: -webkit-transform 0.75s;\n -webkit-transition: transform 0.75s;\n transition: transform 0.75s;\n -webkit-transform: 0.75s;\n will-change: transform;\n }\n\n .c0 .carousel .richtext-carousel .last-slide .slide-copy-wrapper:after {\n content: none;\n }\n\n .c0 .carousel .richtext-carousel .carousel__slide {\n padding-bottom: 300px !important;\n }\n\n .c0 .carousel .richtext-carousel .carousel__slide .carousel__inner-slide {\n text-align: center;\n display: -webkit-inline-box;\n display: -webkit-inline-flex;\n display: -ms-inline-flexbox;\n display: inline-flex;\n -webkit-align-items: center;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: start;\n -webkit-justify-content: flex-start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n -webkit-flex-direction: column;\n -ms-flex-direction: column;\n flex-direction: column;\n }\n\n @media (min-width:740px) {\n .c0 .carousel button.carousel__back-button,\n .c0 .carousel button.carousel__next-button {\n width: 33.3% !important;\n }\n\n .c0 .carousel button.carousel__back-button:after,\n .c0 .carousel button.carousel__next-button:after {\n width: 100%;\n }\n }\n\n @media (min-width:740px) {\n .c0 .carousel .richtext-carousel .carousel__slide {\n padding-bottom: 350px !important;\n }\n\n .c0 .carousel .richtext-carousel .carousel__slide .carousel__inner-slide > div:first-child {\n -webkit-transition: -webkit-transform 0.75s ease;\n -webkit-transition: transform 0.75s ease;\n transition: transform 0.75s ease;\n -webkit-transform-origin: center;\n -ms-transform-origin: center;\n transform-origin: center;\n -webkit-transform: scale(0.8);\n -ms-transform: scale(0.8);\n transform: scale(0.8);\n }\n\n .c0 .carousel .richtext-carousel .carousel__slide .carousel__inner-slide > div:first-child:after {\n -webkit-transition: -webkit-transform 0.75s ease,width 0.75s ease,right 0.75s ease;\n -webkit-transition: transform 0.75s ease,width 0.75s ease,right 0.75s ease;\n transition: transform 0.75s ease,width 0.75s ease,right 0.75s ease;\n width: 100%;\n right: calc(-100% - 6px);\n -webkit-transform: scale(1);\n -ms-transform: scale(1);\n transform: scale(1);\n }\n\n .c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible .carousel__inner-slide > div:first-child:after {\n width: 33%;\n right: calc(-33% - 3px);\n -webkit-transform: scale(1);\n -ms-transform: scale(1);\n transform: scale(1);\n }\n\n .c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible + .carousel__slide--visible .carousel__inner-slide > div:first-child {\n -webkit-transform: scale(1);\n -ms-transform: scale(1);\n transform: scale(1);\n }\n\n .c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible + .carousel__slide--visible .carousel__inner-slide > div:first-child:after {\n width: 33%;\n right: calc(-33% + 3px);\n -webkit-transform: scale(0.8);\n -ms-transform: scale(0.8);\n transform: scale(0.8);\n }\n\n .c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible + .carousel__slide--visible + .carousel__slide--visible > div > div:first-child {\n -webkit-transform: scale(0.8);\n -ms-transform: scale(0.8);\n transform: scale(0.8);\n }\n\n .c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible + .carousel__slide--visible + .carousel__slide--visible > div > div:first-child:after {\n width: 50%;\n right: calc(-50% - 6px);\n -webkit-transform: scale(1);\n -ms-transform: scale(1);\n transform: scale(1);\n }\n }\n\n @media (min-width:1024px) {\n .c0 .carousel .richtext-carousel .carousel__slide {\n padding-bottom: 350px !important;\n }\n\n .c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible + .carousel__slide--visible + .carousel__slide--visible .carousel__inner-slide > div:first-child:after {\n right: calc(-125% - 5px);\n width: 125%;\n }\n }\n\n <div\n className=\"c0 CarouselWrapper\"\n id=\"nqIEHjiYE8Yd2A2a5cI3O\"\n >\n <div\n className=\"c1\"\n >\n Some heading copy that will be nicely constructed in-situ\n </div>\n </div>\n ");
|
|
16
|
+
});
|
package/dist/index.js
CHANGED
|
@@ -232,6 +232,12 @@ Object.defineProperty(exports, "RichText", {
|
|
|
232
232
|
return _RichText.default;
|
|
233
233
|
}
|
|
234
234
|
});
|
|
235
|
+
Object.defineProperty(exports, "RichtextCarousel", {
|
|
236
|
+
enumerable: true,
|
|
237
|
+
get: function () {
|
|
238
|
+
return _RichtextCarousel.default;
|
|
239
|
+
}
|
|
240
|
+
});
|
|
235
241
|
Object.defineProperty(exports, "SchoolLookup", {
|
|
236
242
|
enumerable: true,
|
|
237
243
|
get: function () {
|
|
@@ -454,4 +460,5 @@ var _CookieBanner = _interopRequireDefault(require("./components/Organisms/Cooki
|
|
|
454
460
|
var _Membership = _interopRequireDefault(require("./components/Organisms/Membership/Membership"));
|
|
455
461
|
var _MarketingPreferencesDS = require("./components/Organisms/MarketingPreferencesDS/_MarketingPreferencesDS");
|
|
456
462
|
var _ImpactSlider = _interopRequireDefault(require("./components/Organisms/ImpactSlider/ImpactSlider"));
|
|
457
|
-
var _WYMDCarousel = _interopRequireDefault(require("./components/Organisms/WYMDCarousel/WYMDCarousel"));
|
|
463
|
+
var _WYMDCarousel = _interopRequireDefault(require("./components/Organisms/WYMDCarousel/WYMDCarousel"));
|
|
464
|
+
var _RichtextCarousel = _interopRequireDefault(require("./components/Organisms/RichtextCarousel/RichtextCarousel"));
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.testImpactSliderItems = exports.mobileImages = exports.defaultData = exports.carouselItemsMinimal = exports.carouselItemsIncomplete = exports.carouselItemsComplete = void 0;
|
|
6
|
+
exports.testImpactSliderItems = exports.mobileImages = exports.defaultData = exports.carouselItemsMinimal = exports.carouselItemsIncomplete = exports.carouselItemsComplete = exports.RichtextCarouselItems = void 0;
|
|
7
7
|
const defaultData = exports.defaultData = {
|
|
8
8
|
title: 'What your money does',
|
|
9
9
|
text: 'When you donate to Comic Relief or Sport Relief, you’re supporting vulnerable people and communities in the UK and internationally.',
|
|
@@ -210,4 +210,19 @@ const carouselItemsMinimal = exports.carouselItemsMinimal = {
|
|
|
210
210
|
url: '//images.ctfassets.net/zsfivwzfgl3t/45yv3H0XZsvsySHtutQ8vb/1fb6d1afe4037c7dccde743a747f6b4f/Test-Carousel-Icon.png'
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
|
+
};
|
|
214
|
+
const RichtextCarouselItems = exports.RichtextCarouselItems = {
|
|
215
|
+
contentful_id: 'nqIEHjiYE8Yd2A2a5cI3O',
|
|
216
|
+
// Ugly here, but to be provided by Richtextrender function in-situ:
|
|
217
|
+
headingCopy: 'Some heading copy that will be nicely constructed in-situ',
|
|
218
|
+
nodes: [{
|
|
219
|
+
copy: 'Some other longside but not really all that long copy, who knows, it could be this long or LESS.'
|
|
220
|
+
}, {
|
|
221
|
+
copy: '140 character count limit imposed in messages to fix the design height of each container and restrict anomalies. This is based on Twitters character limit for tweets.'
|
|
222
|
+
}, {
|
|
223
|
+
copy: 'Some other longside but not really all that long copy, who knows, it could be this long or LESS'
|
|
224
|
+
}, {
|
|
225
|
+
copy: '140 character count limit imposed in messages to fix the design height of each container and restrict anomalies. This is based on Twitters character limit for tweets. ABIGLONGLINETOFORCEONTOANEWONE'
|
|
226
|
+
}],
|
|
227
|
+
autoPlay: true
|
|
213
228
|
};
|
package/package.json
CHANGED
|
@@ -24,12 +24,13 @@ const defaultCopyBottom = (
|
|
|
24
24
|
<Link
|
|
25
25
|
type="standard"
|
|
26
26
|
href="https://www.comicrelief.com/update-your-preferences"
|
|
27
|
+
target="blank"
|
|
27
28
|
>
|
|
28
29
|
preferences centre
|
|
29
30
|
</Link>
|
|
30
31
|
. Your details will be kept safe, see our
|
|
31
32
|
{' '}
|
|
32
|
-
<Link type="standard" href="https://www.comicrelief.com/privacy-policy">
|
|
33
|
+
<Link type="standard" href="https://www.comicrelief.com/privacy-policy" target="blank">
|
|
33
34
|
privacy policy
|
|
34
35
|
</Link>
|
|
35
36
|
{' '}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
useEffect, useState, useCallback
|
|
3
|
+
} from 'react';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
import {
|
|
6
|
+
CarouselProvider, Slider, Slide, ButtonBack, ButtonNext
|
|
7
|
+
} from 'pure-react-carousel';
|
|
8
|
+
import 'pure-react-carousel/dist/react-carousel.es.css';
|
|
9
|
+
import {
|
|
10
|
+
CarouselWrapper, SlideCopyWrapper, HeadingCopyWrapper
|
|
11
|
+
} from './RichtextCarousel.style';
|
|
12
|
+
import { breakpointValues } from '../../../theme/shared/allBreakpoints';
|
|
13
|
+
|
|
14
|
+
const RichtextCarousel = ({
|
|
15
|
+
data: {
|
|
16
|
+
contentful_id: thisID,
|
|
17
|
+
autoPlay,
|
|
18
|
+
nodes,
|
|
19
|
+
headingCopy,
|
|
20
|
+
// Set some defaults for good measure:
|
|
21
|
+
mobileHeight = 300,
|
|
22
|
+
tabletHeight = 350,
|
|
23
|
+
desktopHeight = 350,
|
|
24
|
+
carouselBackgroundColour = 'white',
|
|
25
|
+
nodeBackgroundColour = 'white',
|
|
26
|
+
nodeOutlineColour = 'grey'
|
|
27
|
+
}
|
|
28
|
+
}) => {
|
|
29
|
+
// Defaults to mobile config:
|
|
30
|
+
const [isMobile, setIsMobile] = useState(true);
|
|
31
|
+
const [visibleSlides, setVisibleSlides] = useState(1);
|
|
32
|
+
const [totalSlides, setTotalSlides] = useState(null);
|
|
33
|
+
const [theseItems, setTheseItems] = useState();
|
|
34
|
+
|
|
35
|
+
// Custom function to let us update the carousel config dynamically
|
|
36
|
+
const screenResize = useCallback(() => {
|
|
37
|
+
const screenSize = typeof window !== 'undefined' ? window.innerWidth : null;
|
|
38
|
+
const isCurrentlyMobile = window.innerWidth < breakpointValues.M;
|
|
39
|
+
|
|
40
|
+
if (screenSize !== null && (isMobile !== isCurrentlyMobile)) {
|
|
41
|
+
setIsMobile(isCurrentlyMobile);
|
|
42
|
+
setVisibleSlides(isCurrentlyMobile ? 1 : 3);
|
|
43
|
+
setTotalSlides(isCurrentlyMobile ? theseItems.length : theseItems.length + 2);
|
|
44
|
+
}
|
|
45
|
+
}, [isMobile, theseItems]);
|
|
46
|
+
|
|
47
|
+
// Cache our data source, using as a flag for render logic:
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
setTheseItems(nodes);
|
|
50
|
+
}, [setTheseItems, nodes]);
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (window !== 'undefined' && window.innerWidth >= breakpointValues.M) {
|
|
54
|
+
// On inital render, update carousel plugin config
|
|
55
|
+
// to suit the non-mobile layout and functionality:
|
|
56
|
+
setIsMobile(false);
|
|
57
|
+
setVisibleSlides(3);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Hook into browser's own onresize event to call our custom wrapper function:
|
|
61
|
+
if (typeof window !== 'undefined') window.onresize = screenResize;
|
|
62
|
+
}, [screenResize]);
|
|
63
|
+
|
|
64
|
+
if (theseItems && totalSlides === null) {
|
|
65
|
+
// Reflects our two dummy/bookend slides for non-mobile/tablet views:
|
|
66
|
+
setTotalSlides(isMobile ? theseItems.length : theseItems.length + 2);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<CarouselWrapper
|
|
71
|
+
className="CarouselWrapper"
|
|
72
|
+
id={thisID}
|
|
73
|
+
mobileHeight={mobileHeight}
|
|
74
|
+
tabletHeight={tabletHeight}
|
|
75
|
+
desktopHeight={desktopHeight}
|
|
76
|
+
carouselBackgroundColour={carouselBackgroundColour}
|
|
77
|
+
>
|
|
78
|
+
|
|
79
|
+
<HeadingCopyWrapper>
|
|
80
|
+
{headingCopy}
|
|
81
|
+
</HeadingCopyWrapper>
|
|
82
|
+
|
|
83
|
+
{theseItems && (
|
|
84
|
+
<CarouselProvider
|
|
85
|
+
naturalSlideWidth={50}
|
|
86
|
+
naturalSlideHeight={200}
|
|
87
|
+
totalSlides={totalSlides}
|
|
88
|
+
isPlaying={autoPlay}
|
|
89
|
+
interval={5000}
|
|
90
|
+
visibleSlides={visibleSlides}
|
|
91
|
+
infinite
|
|
92
|
+
>
|
|
93
|
+
<Slider classNameAnimation="richtext-carousel">
|
|
94
|
+
|
|
95
|
+
{/* Dummy slide for our desired non-mobile layout and functionality */}
|
|
96
|
+
{isMobile === false && (
|
|
97
|
+
<Slide index={0} key={0} />
|
|
98
|
+
)}
|
|
99
|
+
|
|
100
|
+
{Object.keys(theseItems).map((key, index) => {
|
|
101
|
+
// Reflect that initial dummy/bookend slide shown on non-mobile/tablet views:
|
|
102
|
+
const thisOffsetIndex = index + (isMobile ? 0 : 1);
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
// Calculate the index offset accordingly to reflect the number of slides,
|
|
106
|
+
// but use the REAL index when determining if its the last REAL slide
|
|
107
|
+
<Slide
|
|
108
|
+
index={thisOffsetIndex}
|
|
109
|
+
className={index === (theseItems.length - 1) && 'last-slide'}
|
|
110
|
+
key={thisOffsetIndex}
|
|
111
|
+
>
|
|
112
|
+
|
|
113
|
+
<SlideCopyWrapper
|
|
114
|
+
className="slide-copy-wrapper"
|
|
115
|
+
mobileHeight={mobileHeight}
|
|
116
|
+
tabletHeight={tabletHeight}
|
|
117
|
+
desktopHeight={desktopHeight}
|
|
118
|
+
nodeBackgroundColour={nodeBackgroundColour}
|
|
119
|
+
nodeOutlineColour={nodeOutlineColour}
|
|
120
|
+
>
|
|
121
|
+
{theseItems[index].copy}
|
|
122
|
+
</SlideCopyWrapper>
|
|
123
|
+
|
|
124
|
+
</Slide>
|
|
125
|
+
);
|
|
126
|
+
})}
|
|
127
|
+
|
|
128
|
+
{/* Dummy slide for our desired non-mobile layout and functionality */}
|
|
129
|
+
{isMobile === false && (
|
|
130
|
+
<Slide index={theseItems.length + 1} key="bookend-last" />
|
|
131
|
+
)}
|
|
132
|
+
|
|
133
|
+
</Slider>
|
|
134
|
+
<ButtonBack>Back</ButtonBack>
|
|
135
|
+
<ButtonNext>Next</ButtonNext>
|
|
136
|
+
</CarouselProvider>
|
|
137
|
+
)}
|
|
138
|
+
|
|
139
|
+
</CarouselWrapper>
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
RichtextCarousel.propTypes = {
|
|
144
|
+
data: PropTypes.shape({
|
|
145
|
+
headingCopy: PropTypes.string.isRequired,
|
|
146
|
+
nodes: PropTypes.arrayOf(PropTypes.shape({
|
|
147
|
+
copy: PropTypes.string.isRequired
|
|
148
|
+
})).isRequired,
|
|
149
|
+
autoPlay: PropTypes.bool.isRequired,
|
|
150
|
+
contentful_id: PropTypes.string.isRequired,
|
|
151
|
+
mobileHeight: PropTypes.number,
|
|
152
|
+
tabletHeight: PropTypes.number,
|
|
153
|
+
desktopHeight: PropTypes.number,
|
|
154
|
+
carouselBackgroundColour: PropTypes.string,
|
|
155
|
+
nodeBackgroundColour: PropTypes.string,
|
|
156
|
+
nodeOutlineColour: PropTypes.string
|
|
157
|
+
}).isRequired
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export default RichtextCarousel;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Richtext Carousel
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
const { RichtextCarouselItems } = require('../../../styleguide/data/data');
|
|
5
|
+
|
|
6
|
+
<div>
|
|
7
|
+
<h2 style={{textAlign: 'center'}}>
|
|
8
|
+
Richtext Carousel #1
|
|
9
|
+
</h2>
|
|
10
|
+
<RichtextCarousel
|
|
11
|
+
data={RichtextCarouselItems}/>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
```
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
|
+
import spacing from '../../../theme/shared/spacing';
|
|
3
|
+
// import Text from '../../Atoms/Text/Text';
|
|
4
|
+
|
|
5
|
+
// Duration in seconds
|
|
6
|
+
const animationSpeed = 0.75;
|
|
7
|
+
|
|
8
|
+
const SlideCopyWrapper = styled.div`
|
|
9
|
+
background: ${({ theme, nodeBackgroundColour }) => theme.color(nodeBackgroundColour)};
|
|
10
|
+
height: ${props => props.mobileHeight}px;
|
|
11
|
+
width: 75%;
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
padding: 25px;
|
|
16
|
+
border: 1px dashed ${({ theme, nodeOutlineColour }) => theme.color(nodeOutlineColour)};
|
|
17
|
+
border-radius: 20px;
|
|
18
|
+
position: relative;
|
|
19
|
+
overflow: visible;
|
|
20
|
+
word-wrap: break-word;
|
|
21
|
+
|
|
22
|
+
&:after {
|
|
23
|
+
position: absolute;
|
|
24
|
+
content: '';
|
|
25
|
+
top: 50%;
|
|
26
|
+
width: 34%;
|
|
27
|
+
right: calc(-34% - 0px);
|
|
28
|
+
height: 2px;
|
|
29
|
+
border-bottom: 1px dashed ${({ theme, nodeOutlineColour }) => theme.color(nodeOutlineColour)};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@media ${({ theme }) => theme.allBreakpoints('M')} {
|
|
33
|
+
height: ${props => props.tabletHeight}px;
|
|
34
|
+
width: 85%;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@media ${({ theme }) => theme.allBreakpoints('L')} {
|
|
38
|
+
height: ${props => props.desktopHeight}px;
|
|
39
|
+
}
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
const HeadingCopyWrapper = styled.div`
|
|
43
|
+
text-align: center;
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
// Unfortunately having to target plugin-created markup ye olde fashioned way:
|
|
47
|
+
const CarouselWrapper = styled.div`
|
|
48
|
+
height: 100%;
|
|
49
|
+
background: ${({ theme, carouselBackgroundColour }) => theme.color(carouselBackgroundColour)};
|
|
50
|
+
|
|
51
|
+
max-width: 760px;
|
|
52
|
+
padding: 2.5rem ${spacing('l')} 3.5rem;
|
|
53
|
+
margin: 0 auto;
|
|
54
|
+
|
|
55
|
+
border-radius: 20px;
|
|
56
|
+
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.15);
|
|
57
|
+
|
|
58
|
+
.carousel {
|
|
59
|
+
position: relative;
|
|
60
|
+
margin: 0 auto;
|
|
61
|
+
padding-top: ${spacing('l')};
|
|
62
|
+
|
|
63
|
+
button.carousel__back-button,
|
|
64
|
+
button.carousel__next-button {
|
|
65
|
+
position: absolute;
|
|
66
|
+
left: 0;
|
|
67
|
+
top: 0;
|
|
68
|
+
width: 33% !important;
|
|
69
|
+
height: 100%;
|
|
70
|
+
padding: 0 !important;
|
|
71
|
+
box-shadow: none;
|
|
72
|
+
text-indent: -9999px;
|
|
73
|
+
background-color: transparent;
|
|
74
|
+
border: none;
|
|
75
|
+
|
|
76
|
+
&:after {
|
|
77
|
+
content: "";
|
|
78
|
+
position: absolute;
|
|
79
|
+
top: 0;
|
|
80
|
+
left: 0;
|
|
81
|
+
width: 50%;
|
|
82
|
+
height: 100%;
|
|
83
|
+
transition: opacity 0.2s linear;
|
|
84
|
+
background: ${({ theme, carouselBackgroundColour }) => css`
|
|
85
|
+
linear-gradient(90deg, ${theme.color(carouselBackgroundColour)},
|
|
86
|
+
${theme.color(carouselBackgroundColour)}7a, ${theme.color(carouselBackgroundColour)}00);
|
|
87
|
+
`};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
&:hover {
|
|
91
|
+
&:after {
|
|
92
|
+
opacity: 0.5;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@media ${({ theme }) => theme.allBreakpoints('M')} {
|
|
97
|
+
width: 33.3% !important;
|
|
98
|
+
&:after {
|
|
99
|
+
width: 100%;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
button.carousel__next-button {
|
|
105
|
+
left: auto;
|
|
106
|
+
right: 0;
|
|
107
|
+
|
|
108
|
+
&:before {
|
|
109
|
+
transform: translate(0, -50%) rotate(-90deg);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&:after {
|
|
113
|
+
left: auto;
|
|
114
|
+
right: 0;
|
|
115
|
+
|
|
116
|
+
background: ${({ theme, carouselBackgroundColour }) => css`
|
|
117
|
+
linear-gradient(90deg, ${theme.color(carouselBackgroundColour)}00,
|
|
118
|
+
${theme.color(carouselBackgroundColour)}7a, ${theme.color(carouselBackgroundColour)});
|
|
119
|
+
`};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.richtext-carousel {
|
|
124
|
+
// Override default animations
|
|
125
|
+
transition: -webkit-transform ${animationSpeed}s;
|
|
126
|
+
-o-transition: transform ${animationSpeed}s;
|
|
127
|
+
transition: transform ${animationSpeed}s;
|
|
128
|
+
-webkit-transform: ${animationSpeed}s;
|
|
129
|
+
will-change: transform;
|
|
130
|
+
|
|
131
|
+
.last-slide {
|
|
132
|
+
.slide-copy-wrapper:after {
|
|
133
|
+
content: none;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.carousel__slide {
|
|
138
|
+
// 'Mobile'
|
|
139
|
+
padding-bottom: ${props => props.mobileHeight}px !important;
|
|
140
|
+
|
|
141
|
+
// 'Tablet' (and up) tweaks for the 3-visible layout
|
|
142
|
+
@media ${({ theme }) => theme.allBreakpoints('M')} {
|
|
143
|
+
|
|
144
|
+
padding-bottom: ${props => props.tabletHeight}px !important;
|
|
145
|
+
|
|
146
|
+
// All slides:
|
|
147
|
+
.carousel__inner-slide {
|
|
148
|
+
|
|
149
|
+
// All 'SlideCopyWrapper's:
|
|
150
|
+
> div:first-child {
|
|
151
|
+
transition: transform ${animationSpeed}s ease;
|
|
152
|
+
transform-origin: center;
|
|
153
|
+
transform: scale(0.8);
|
|
154
|
+
|
|
155
|
+
&:after {
|
|
156
|
+
transition: transform ${animationSpeed}s ease,
|
|
157
|
+
width ${animationSpeed}s ease,
|
|
158
|
+
right ${animationSpeed}s ease;
|
|
159
|
+
width: 100%;
|
|
160
|
+
right: calc(-100% - 6px);
|
|
161
|
+
transform: scale(1);
|
|
162
|
+
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Our 'first' slide of the three:
|
|
168
|
+
&.carousel__slide--visible {
|
|
169
|
+
.carousel__inner-slide {
|
|
170
|
+
> div:first-child {
|
|
171
|
+
&:after {
|
|
172
|
+
width: 33%;
|
|
173
|
+
right: calc(-33% - 3px);
|
|
174
|
+
transform: scale(1);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 2nd and 3rd:
|
|
180
|
+
+ .carousel__slide--visible {
|
|
181
|
+
.carousel__inner-slide {
|
|
182
|
+
> div:first-child {
|
|
183
|
+
transform: scale(1);
|
|
184
|
+
&:after {
|
|
185
|
+
width: 33%;
|
|
186
|
+
right: calc(-33% + 3px);
|
|
187
|
+
transform: scale(0.8);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Resets the 3rd slide:
|
|
193
|
+
+ .carousel__slide--visible {
|
|
194
|
+
> div > div:first-child {
|
|
195
|
+
transform: scale(0.8);
|
|
196
|
+
&:after {
|
|
197
|
+
width: 50%;
|
|
198
|
+
right: calc(-50% - 6px);
|
|
199
|
+
transform: scale(1);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// 'Desktop'
|
|
208
|
+
@media ${({ theme }) => theme.allBreakpoints('L')} {
|
|
209
|
+
padding-bottom: ${props => props.desktopHeight}px !important;
|
|
210
|
+
|
|
211
|
+
// First
|
|
212
|
+
&.carousel__slide--visible {
|
|
213
|
+
|
|
214
|
+
// 2nd and 3rd
|
|
215
|
+
+ .carousel__slide--visible {
|
|
216
|
+
|
|
217
|
+
// 3rd only
|
|
218
|
+
+ .carousel__slide--visible {
|
|
219
|
+
.carousel__inner-slide {
|
|
220
|
+
> div:first-child {
|
|
221
|
+
&:after {
|
|
222
|
+
right: calc(-125% - 5px);
|
|
223
|
+
width: 125%;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// END OF DESKTOP
|
|
232
|
+
|
|
233
|
+
.carousel__inner-slide {
|
|
234
|
+
text-align: center;
|
|
235
|
+
display: inline-flex;
|
|
236
|
+
align-items: center;
|
|
237
|
+
justify-content: flex-start;
|
|
238
|
+
flex-direction: column;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
`;
|
|
244
|
+
|
|
245
|
+
export {
|
|
246
|
+
CarouselWrapper, SlideCopyWrapper,
|
|
247
|
+
HeadingCopyWrapper
|
|
248
|
+
};
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import "jest-styled-components";
|
|
3
|
+
|
|
4
|
+
import renderWithTheme from "../../../../tests/hoc/shallowWithTheme";
|
|
5
|
+
import RichtextCarousel from "./RichtextCarousel";
|
|
6
|
+
const { RichtextCarouselItems } = require("../../../styleguide/data/data");
|
|
7
|
+
|
|
8
|
+
it("renders correctly", () => {
|
|
9
|
+
const tree = renderWithTheme(
|
|
10
|
+
<RichtextCarousel data={RichtextCarouselItems} />
|
|
11
|
+
).toJSON();
|
|
12
|
+
|
|
13
|
+
expect(tree).toMatchInlineSnapshot(`
|
|
14
|
+
.c1 {
|
|
15
|
+
text-align: center;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.c0 {
|
|
19
|
+
height: 100%;
|
|
20
|
+
background: #FFFFFF;
|
|
21
|
+
max-width: 760px;
|
|
22
|
+
padding: 2.5rem 2rem 3.5rem;
|
|
23
|
+
margin: 0 auto;
|
|
24
|
+
border-radius: 20px;
|
|
25
|
+
box-shadow: 0px 0px 20px rgba(0,0,0,0.15);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.c0 .carousel {
|
|
29
|
+
position: relative;
|
|
30
|
+
margin: 0 auto;
|
|
31
|
+
padding-top: 2rem;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.c0 .carousel button.carousel__back-button,
|
|
35
|
+
.c0 .carousel button.carousel__next-button {
|
|
36
|
+
position: absolute;
|
|
37
|
+
left: 0;
|
|
38
|
+
top: 0;
|
|
39
|
+
width: 33% !important;
|
|
40
|
+
height: 100%;
|
|
41
|
+
padding: 0 !important;
|
|
42
|
+
box-shadow: none;
|
|
43
|
+
text-indent: -9999px;
|
|
44
|
+
background-color: transparent;
|
|
45
|
+
border: none;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.c0 .carousel button.carousel__back-button:after,
|
|
49
|
+
.c0 .carousel button.carousel__next-button:after {
|
|
50
|
+
content: "";
|
|
51
|
+
position: absolute;
|
|
52
|
+
top: 0;
|
|
53
|
+
left: 0;
|
|
54
|
+
width: 50%;
|
|
55
|
+
height: 100%;
|
|
56
|
+
-webkit-transition: opacity 0.2s linear;
|
|
57
|
+
transition: opacity 0.2s linear;
|
|
58
|
+
background: linear-gradient(90deg,#FFFFFF,#FFFFFF7a,#FFFFFF00);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.c0 .carousel button.carousel__back-button:hover:after,
|
|
62
|
+
.c0 .carousel button.carousel__next-button:hover:after {
|
|
63
|
+
opacity: 0.5;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.c0 .carousel button.carousel__next-button {
|
|
67
|
+
left: auto;
|
|
68
|
+
right: 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.c0 .carousel button.carousel__next-button:before {
|
|
72
|
+
-webkit-transform: translate(0,-50%) rotate(-90deg);
|
|
73
|
+
-ms-transform: translate(0,-50%) rotate(-90deg);
|
|
74
|
+
transform: translate(0,-50%) rotate(-90deg);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.c0 .carousel button.carousel__next-button:after {
|
|
78
|
+
left: auto;
|
|
79
|
+
right: 0;
|
|
80
|
+
background: linear-gradient(90deg,#FFFFFF00,#FFFFFF7a,#FFFFFF);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.c0 .carousel .richtext-carousel {
|
|
84
|
+
-webkit-transition: -webkit-transform 0.75s;
|
|
85
|
+
-webkit-transition: -webkit-transform 0.75s;
|
|
86
|
+
transition: -webkit-transform 0.75s;
|
|
87
|
+
-o-transition: transform 0.75s;
|
|
88
|
+
-webkit-transition: -webkit-transform 0.75s;
|
|
89
|
+
-webkit-transition: transform 0.75s;
|
|
90
|
+
transition: transform 0.75s;
|
|
91
|
+
-webkit-transform: 0.75s;
|
|
92
|
+
will-change: transform;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.c0 .carousel .richtext-carousel .last-slide .slide-copy-wrapper:after {
|
|
96
|
+
content: none;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.c0 .carousel .richtext-carousel .carousel__slide {
|
|
100
|
+
padding-bottom: 300px !important;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.c0 .carousel .richtext-carousel .carousel__slide .carousel__inner-slide {
|
|
104
|
+
text-align: center;
|
|
105
|
+
display: -webkit-inline-box;
|
|
106
|
+
display: -webkit-inline-flex;
|
|
107
|
+
display: -ms-inline-flexbox;
|
|
108
|
+
display: inline-flex;
|
|
109
|
+
-webkit-align-items: center;
|
|
110
|
+
-webkit-box-align: center;
|
|
111
|
+
-ms-flex-align: center;
|
|
112
|
+
align-items: center;
|
|
113
|
+
-webkit-box-pack: start;
|
|
114
|
+
-webkit-justify-content: flex-start;
|
|
115
|
+
-ms-flex-pack: start;
|
|
116
|
+
justify-content: flex-start;
|
|
117
|
+
-webkit-flex-direction: column;
|
|
118
|
+
-ms-flex-direction: column;
|
|
119
|
+
flex-direction: column;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@media (min-width:740px) {
|
|
123
|
+
.c0 .carousel button.carousel__back-button,
|
|
124
|
+
.c0 .carousel button.carousel__next-button {
|
|
125
|
+
width: 33.3% !important;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.c0 .carousel button.carousel__back-button:after,
|
|
129
|
+
.c0 .carousel button.carousel__next-button:after {
|
|
130
|
+
width: 100%;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@media (min-width:740px) {
|
|
135
|
+
.c0 .carousel .richtext-carousel .carousel__slide {
|
|
136
|
+
padding-bottom: 350px !important;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.c0 .carousel .richtext-carousel .carousel__slide .carousel__inner-slide > div:first-child {
|
|
140
|
+
-webkit-transition: -webkit-transform 0.75s ease;
|
|
141
|
+
-webkit-transition: transform 0.75s ease;
|
|
142
|
+
transition: transform 0.75s ease;
|
|
143
|
+
-webkit-transform-origin: center;
|
|
144
|
+
-ms-transform-origin: center;
|
|
145
|
+
transform-origin: center;
|
|
146
|
+
-webkit-transform: scale(0.8);
|
|
147
|
+
-ms-transform: scale(0.8);
|
|
148
|
+
transform: scale(0.8);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.c0 .carousel .richtext-carousel .carousel__slide .carousel__inner-slide > div:first-child:after {
|
|
152
|
+
-webkit-transition: -webkit-transform 0.75s ease,width 0.75s ease,right 0.75s ease;
|
|
153
|
+
-webkit-transition: transform 0.75s ease,width 0.75s ease,right 0.75s ease;
|
|
154
|
+
transition: transform 0.75s ease,width 0.75s ease,right 0.75s ease;
|
|
155
|
+
width: 100%;
|
|
156
|
+
right: calc(-100% - 6px);
|
|
157
|
+
-webkit-transform: scale(1);
|
|
158
|
+
-ms-transform: scale(1);
|
|
159
|
+
transform: scale(1);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible .carousel__inner-slide > div:first-child:after {
|
|
163
|
+
width: 33%;
|
|
164
|
+
right: calc(-33% - 3px);
|
|
165
|
+
-webkit-transform: scale(1);
|
|
166
|
+
-ms-transform: scale(1);
|
|
167
|
+
transform: scale(1);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible + .carousel__slide--visible .carousel__inner-slide > div:first-child {
|
|
171
|
+
-webkit-transform: scale(1);
|
|
172
|
+
-ms-transform: scale(1);
|
|
173
|
+
transform: scale(1);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible + .carousel__slide--visible .carousel__inner-slide > div:first-child:after {
|
|
177
|
+
width: 33%;
|
|
178
|
+
right: calc(-33% + 3px);
|
|
179
|
+
-webkit-transform: scale(0.8);
|
|
180
|
+
-ms-transform: scale(0.8);
|
|
181
|
+
transform: scale(0.8);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible + .carousel__slide--visible + .carousel__slide--visible > div > div:first-child {
|
|
185
|
+
-webkit-transform: scale(0.8);
|
|
186
|
+
-ms-transform: scale(0.8);
|
|
187
|
+
transform: scale(0.8);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible + .carousel__slide--visible + .carousel__slide--visible > div > div:first-child:after {
|
|
191
|
+
width: 50%;
|
|
192
|
+
right: calc(-50% - 6px);
|
|
193
|
+
-webkit-transform: scale(1);
|
|
194
|
+
-ms-transform: scale(1);
|
|
195
|
+
transform: scale(1);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@media (min-width:1024px) {
|
|
200
|
+
.c0 .carousel .richtext-carousel .carousel__slide {
|
|
201
|
+
padding-bottom: 350px !important;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.c0 .carousel .richtext-carousel .carousel__slide.carousel__slide--visible + .carousel__slide--visible + .carousel__slide--visible .carousel__inner-slide > div:first-child:after {
|
|
205
|
+
right: calc(-125% - 5px);
|
|
206
|
+
width: 125%;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
<div
|
|
211
|
+
className="c0 CarouselWrapper"
|
|
212
|
+
id="nqIEHjiYE8Yd2A2a5cI3O"
|
|
213
|
+
>
|
|
214
|
+
<div
|
|
215
|
+
className="c1"
|
|
216
|
+
>
|
|
217
|
+
Some heading copy that will be nicely constructed in-situ
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
`);
|
|
221
|
+
});
|
package/src/index.js
CHANGED
|
@@ -76,3 +76,4 @@ export {
|
|
|
76
76
|
} from './components/Organisms/MarketingPreferencesDS/_MarketingPreferencesDS';
|
|
77
77
|
export { default as ImpactSlider } from './components/Organisms/ImpactSlider/ImpactSlider';
|
|
78
78
|
export { default as WYMDCarousel } from './components/Organisms/WYMDCarousel/WYMDCarousel';
|
|
79
|
+
export { default as RichtextCarousel } from './components/Organisms/RichtextCarousel/RichtextCarousel';
|
|
@@ -223,7 +223,20 @@ const carouselItemsMinimal = {
|
|
|
223
223
|
}
|
|
224
224
|
};
|
|
225
225
|
|
|
226
|
+
const RichtextCarouselItems = {
|
|
227
|
+
contentful_id: 'nqIEHjiYE8Yd2A2a5cI3O',
|
|
228
|
+
// Ugly here, but to be provided by Richtextrender function in-situ:
|
|
229
|
+
headingCopy: 'Some heading copy that will be nicely constructed in-situ',
|
|
230
|
+
nodes: [
|
|
231
|
+
{ copy: 'Some other longside but not really all that long copy, who knows, it could be this long or LESS.' },
|
|
232
|
+
{ copy: '140 character count limit imposed in messages to fix the design height of each container and restrict anomalies. This is based on Twitters character limit for tweets.' },
|
|
233
|
+
{ copy: 'Some other longside but not really all that long copy, who knows, it could be this long or LESS' },
|
|
234
|
+
{ copy: '140 character count limit imposed in messages to fix the design height of each container and restrict anomalies. This is based on Twitters character limit for tweets. ABIGLONGLINETOFORCEONTOANEWONE' }
|
|
235
|
+
],
|
|
236
|
+
autoPlay: true
|
|
237
|
+
};
|
|
238
|
+
|
|
226
239
|
export {
|
|
227
240
|
defaultData, mobileImages, testImpactSliderItems,
|
|
228
|
-
carouselItemsComplete, carouselItemsIncomplete, carouselItemsMinimal
|
|
241
|
+
carouselItemsComplete, carouselItemsIncomplete, carouselItemsMinimal, RichtextCarouselItems
|
|
229
242
|
};
|