diff --git a/package-lock.json b/package-lock.json
index af041a863..111861af3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1221,7 +1221,7 @@
"babel-loader": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz",
- "integrity": "sha1-9svhInEPGqKvTYgcbVtUNYyiQSY=",
+ "integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==",
"dev": true,
"requires": {
"find-cache-dir": "1.0.0",
@@ -3003,7 +3003,7 @@
},
"conventional-changelog-angular": {
"version": "1.6.6",
- "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz",
+ "resolved": "http://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz",
"integrity": "sha512-suQnFSqCxRwyBxY68pYTsFkG0taIdinHLNEAX5ivtw8bCRnIgnpvcHmlR/yjUyZIrNPYAoXlY1WiEKWgSE4BNg==",
"dev": true,
"requires": {
@@ -3013,7 +3013,7 @@
},
"conventional-commits-parser": {
"version": "2.1.7",
- "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz",
+ "resolved": "http://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz",
"integrity": "sha512-BoMaddIEJ6B4QVMSDu9IkVImlGOSGA1I2BQyOZHeLQ6qVOJLcLKn97+fL6dGbzWEiqDzfH4OkcveULmeq2MHFQ==",
"dev": true,
"requires": {
@@ -3253,17 +3253,6 @@
"sha.js": "2.4.9"
}
},
- "create-react-class": {
- "version": "15.6.3",
- "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz",
- "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==",
- "dev": true,
- "requires": {
- "fbjs": "0.8.16",
- "loose-envify": "1.3.1",
- "object-assign": "4.1.1"
- }
- },
"cross-spawn": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
@@ -3613,6 +3602,33 @@
"es5-ext": "0.10.37"
}
},
+ "d3-color": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.3.tgz",
+ "integrity": "sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw==",
+ "dev": true
+ },
+ "d3-ease": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.5.tgz",
+ "integrity": "sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ==",
+ "dev": true
+ },
+ "d3-interpolate": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.3.2.tgz",
+ "integrity": "sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==",
+ "dev": true,
+ "requires": {
+ "d3-color": "1.2.3"
+ }
+ },
+ "d3-timer": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.9.tgz",
+ "integrity": "sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg==",
+ "dev": true
+ },
"damerau-levenshtein": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz",
@@ -4582,7 +4598,7 @@
"eslint-loader": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-1.9.0.tgz",
- "integrity": "sha1-fhvp/t3KMo09z67xrUnVvv/oOhM=",
+ "integrity": "sha512-40aN976qSNPyb9ejTqjEthZITpls1SVKtwguahmH1dzGCwQU/vySE+xX33VZmD8csU0ahVNCtFlsPgKqRBiqgg==",
"dev": true,
"requires": {
"loader-fs-cache": "1.0.1",
@@ -6250,7 +6266,7 @@
},
"git-raw-commits": {
"version": "1.3.6",
- "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.6.tgz",
+ "resolved": "http://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.6.tgz",
"integrity": "sha512-svsK26tQ8vEKnMshTDatSIQSMDdz8CxIIqKsvPqbtV23Etmw6VNaFAitu8zwZ0VrOne7FztwPyRLxK7/DIUTQg==",
"dev": true,
"requires": {
@@ -8019,7 +8035,7 @@
"json-loader": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
- "integrity": "sha1-3KFKcCNf+C8KyaOr62DTN6NlGF0=",
+ "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==",
"dev": true
},
"json-parse-better-errors": {
@@ -10163,14 +10179,15 @@
}
},
"nuka-carousel": {
- "version": "github:Adslot/nuka-carousel#3c7154d9331b0d54eddfd00fe4ff18fd9432ede7",
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/nuka-carousel/-/nuka-carousel-4.4.3.tgz",
+ "integrity": "sha512-MkPZm4Mx/OUAu0zUmDxJ36CGudOTd7x++bBxMB+/t1GffyUArUZYi+GICKkw2q2/owzqdVAtZs0pNfPOimtSwA==",
"dev": true,
"requires": {
- "create-react-class": "15.6.3",
+ "d3-ease": "1.0.5",
"exenv": "1.2.2",
- "object-assign": "4.1.1",
"prop-types": "15.6.1",
- "react-tween-state": "0.1.5"
+ "react-move": "2.8.0"
}
},
"null-check": {
@@ -13332,6 +13349,16 @@
"integrity": "sha512-hSl7E6l25GTjNEZATqZIuWOgSnpXb3kD0DVCujmg46K5zLxsbiKaaT6VO9slkSBDPZfYs30lwfJwbOFOnoEnKQ==",
"dev": true
},
+ "react-move": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/react-move/-/react-move-2.8.0.tgz",
+ "integrity": "sha512-pqH9m6k0dOkEHRFQSJC7gK8sPABgY69h8BoriSxdv1SXYSWaOHWxUWgfeEaeQ76od32qKMFj+EztKGqtrcUGPg==",
+ "dev": true,
+ "requires": {
+ "d3-interpolate": "1.3.2",
+ "d3-timer": "1.0.9"
+ }
+ },
"react-onclickoutside": {
"version": "6.7.1",
"resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.7.1.tgz",
@@ -13428,16 +13455,6 @@
}
}
},
- "react-tween-state": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/react-tween-state/-/react-tween-state-0.1.5.tgz",
- "integrity": "sha1-6YsGZVHvuTy5LdG+FJlcLj3q4zk=",
- "dev": true,
- "requires": {
- "raf": "3.4.0",
- "tween-functions": "1.2.0"
- }
- },
"read-pkg": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
@@ -14486,7 +14503,7 @@
"sass-loader": {
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.6.tgz",
- "integrity": "sha1-6dXmwfFV+qMqSybXqbcQfCJeQPk=",
+ "integrity": "sha512-c3/Zc+iW+qqDip6kXPYLEgsAu2lf4xz0EZDplB7EmSUMda12U1sGJPetH55B/j9eu0bTtKzKlNPWWyYC7wFNyQ==",
"dev": true,
"requires": {
"async": "2.6.0",
@@ -16049,12 +16066,6 @@
"integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
"dev": true
},
- "tween-functions": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/tween-functions/-/tween-functions-1.2.0.tgz",
- "integrity": "sha1-GuOlDnxguz3vd06scHrLynO7w/8=",
- "dev": true
- },
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
diff --git a/package.json b/package.json
index a34f819c4..952de492e 100644
--- a/package.json
+++ b/package.json
@@ -110,7 +110,7 @@
"mocha": "^5.2.0",
"moment": "^2.20.1",
"node-sass": "^4.9.4",
- "nuka-carousel": "github:Adslot/nuka-carousel#3c7154d9331b0d54eddfd00fe4ff18fd9432ede7",
+ "nuka-carousel": "^4.4.3",
"null-loader": "^0.1.1",
"object-assign": "^4.1.1",
"postcss-loader": "^2.1.0",
diff --git a/src/components/adslot-ui/Carousel/index.jsx b/src/components/adslot-ui/Carousel/index.jsx
index 731219fde..fcc4ba67a 100644
--- a/src/components/adslot-ui/Carousel/index.jsx
+++ b/src/components/adslot-ui/Carousel/index.jsx
@@ -1,58 +1,25 @@
-import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Carousel from 'nuka-carousel';
-
-require('./styles.scss');
+import './styles.scss';
const baseClass = 'carousel-component';
-const navigationDelay = 600;
-const decoratorStyles = {
- bottom: 0,
- width: '30px',
-};
-
-export const getPrevDecorator = () => {
- let previousSlideThrottled;
- const component = ({ previousSlide }) => {
- if (!previousSlideThrottled) {
- previousSlideThrottled = _.throttle(previousSlide, navigationDelay);
- }
- return ;
- };
- component.propTypes = { previousSlide: PropTypes.func.isRequired };
-
- return {
- component,
- position: 'TopLeft',
- style: decoratorStyles,
- };
-};
-export const getNextDecorator = () => {
- let nextSlideThrottled;
- const component = ({ nextSlide }) => {
- if (!nextSlideThrottled) {
- nextSlideThrottled = _.throttle(nextSlide, navigationDelay);
- }
- return ;
- };
- component.propTypes = { nextSlide: PropTypes.func.isRequired };
+export const PrevButton = ({ previousSlide }) => ;
- return {
- component,
- position: 'TopRight',
- style: decoratorStyles,
- };
-};
+export const NextButton = ({ nextSlide }) => ;
const CarouselComponent = props => {
const { className, children } = props;
- const decorators = [getPrevDecorator(), getNextDecorator()];
return (
-
+
{children}
);
@@ -63,6 +30,14 @@ CarouselComponent.propTypes = {
children: PropTypes.node,
};
+PrevButton.propTypes = {
+ previousSlide: PropTypes.func.isRequired,
+};
+
+NextButton.propTypes = {
+ nextSlide: PropTypes.func.isRequired,
+};
+
// See Nuka Carousel docs for other options:
// https://github.com/FormidableLabs/nuka-carousel
CarouselComponent.defaultProps = {
diff --git a/src/components/adslot-ui/Carousel/index.spec.jsx b/src/components/adslot-ui/Carousel/index.spec.jsx
index 98e36018d..cfa652055 100644
--- a/src/components/adslot-ui/Carousel/index.spec.jsx
+++ b/src/components/adslot-ui/Carousel/index.spec.jsx
@@ -1,82 +1,79 @@
import _ from 'lodash';
import React from 'react';
-import { shallow } from 'enzyme';
-import Carousel, { getPrevDecorator, getNextDecorator } from 'adslot-ui/Carousel';
+import { shallow, mount } from 'enzyme';
+import Carousel, { PrevButton, NextButton } from 'adslot-ui/Carousel';
describe('CarouselComponent', () => {
- describe('render()', () => {
- it('should render with defaults', () => {
- const component = shallow();
- expect(component.prop('decorators')).to.be.an('array');
- expect(component.prop('decorators')).to.have.length(2);
- expect(component.prop('className')).to.equal('carousel-component');
- expect(component.children()).to.have.length(0);
- });
+ it('should render with defaults', () => {
+ const wrapper = shallow();
+ expect(wrapper.prop('className')).to.equal('carousel-component');
+ expect(wrapper.children()).to.have.length(0);
+ });
- it('should render with slides', () => {
- const component = shallow(
-
-
-
-
- );
- expect(component.children()).to.have.length(2);
+ it('should render with slides', () => {
+ const wrapper = shallow(
+
+
+
+
+ );
+ expect(wrapper.children()).to.have.length(2);
- const firstSlide = component.childAt(0);
- expect(firstSlide.prop('src')).to.equal('path/to/image-1.jpg');
+ const firstSlide = wrapper.childAt(0);
+ expect(firstSlide.prop('src')).to.equal('path/to/image-1.jpg');
- const secondSlide = component.childAt(1);
- expect(secondSlide.prop('src')).to.equal('path/to/image-2.jpg');
- });
+ const secondSlide = wrapper.childAt(1);
+ expect(secondSlide.prop('src')).to.equal('path/to/image-2.jpg');
});
- describe('getPrevDecorator()', () => {
- it('should get decorator for Previous button', () => {
- const decorator = getPrevDecorator();
- expect(decorator.component).to.be.a('function');
- expect(decorator.position).to.equal('TopLeft');
- expect(decorator.style).to.eql({
- bottom: 0,
- width: '30px',
- });
-
- const component = shallow(decorator.component({ previousSlide: _.noop }));
- expect(component.prop('className')).to.equal('carousel-component-prev');
- expect(component.prop('onClick')).to.be.a('function');
- });
+ it('should be able to navigate to the next image', () => {
+ const wrapper = mount(
+
+ {_.map(new Array(5), (value, index) => (
+
+ ))}
+
+ );
+ expect(wrapper.find('.carousel-component-next').length).to.equal(1);
+ expect(wrapper.find('.slide-visible img').prop('id')).to.equal('img-0');
+ wrapper.find('.carousel-component-next').simulate('click');
+ expect(wrapper.find('.slide-visible img').prop('id')).to.equal('img-1');
+ });
- it('should call the same throttled function for each onClick event', () => {
- const decorator = getPrevDecorator();
- const componentA = shallow(decorator.component({ previousSlide: _.noop }));
- const onClickA = componentA.prop('onClick');
- const componentB = shallow(decorator.component({ previousSlide: _.noop }));
- const onClickB = componentB.prop('onClick');
- expect(onClickA).to.equal(onClickB);
- });
+ it('should be able to navigate to the previous image', () => {
+ const wrapper = mount(
+
+ {_.map(new Array(5), (value, index) => (
+
+ ))}
+
+ );
+ expect(wrapper.find('.carousel-component-prev').length).to.equal(1);
+ expect(wrapper.find('.slide-visible img').prop('id')).to.equal('img-0');
+ wrapper.find('.carousel-component-prev').simulate('click');
+ expect(wrapper.find('.slide-visible img').prop('id')).to.equal('img-4');
});
+});
- describe('getNextDecorator()', () => {
- it('should get decorator for Next button', () => {
- const decorator = getNextDecorator();
- expect(decorator.component).to.be.a('function');
- expect(decorator.position).to.equal('TopRight');
- expect(decorator.style).to.eql({
- bottom: 0,
- width: '30px',
- });
+describe('Navigation buttons', () => {
+ const props = {
+ previousSlide: _.noop,
+ nextSlide: _.noop,
+ };
- const component = shallow(decorator.component({ nextSlide: _.noop }));
- expect(component.prop('className')).to.equal('carousel-component-next');
- expect(component.prop('onClick')).to.be.a('function');
+ describe('PrevButton component', () => {
+ it('should render the component without errors', () => {
+ const wrapper = shallow();
+ expect(wrapper.prop('className')).to.equal('carousel-component-prev');
+ expect(wrapper.prop('onClick')).to.be.a('function');
});
+ });
- it('should call the same throttled function for each onClick event', () => {
- const decorator = getNextDecorator();
- const componentA = shallow(decorator.component({ nextSlide: _.noop }));
- const onClickA = componentA.prop('onClick');
- const componentB = shallow(decorator.component({ nextSlide: _.noop }));
- const onClickB = componentB.prop('onClick');
- expect(onClickA).to.equal(onClickB);
+ describe('NextButton component', () => {
+ it('should render the component without errors', () => {
+ const wrapper = shallow();
+ expect(wrapper.prop('className')).to.equal('carousel-component-next');
+ expect(wrapper.prop('onClick')).to.be.a('function');
});
});
});
diff --git a/src/components/adslot-ui/Carousel/styles.scss b/src/components/adslot-ui/Carousel/styles.scss
index 9baa6f414..9c3279973 100644
--- a/src/components/adslot-ui/Carousel/styles.scss
+++ b/src/components/adslot-ui/Carousel/styles.scss
@@ -1,34 +1,45 @@
@import '~styles/color';
@import '~styles/icon';
+@mixin button-style {
+ background-color: $color-carousel-button;
+ border: 0;
+ height: 100%;
+ padding: 0;
+ width: 100%;
+
+ &::before {
+ background: $icon-chevron-white 50% no-repeat;
+ content: '';
+ display: block;
+ height: $icon-size-large;
+ margin: 0 auto;
+ width: $icon-size-large;
+ }
+}
+
.carousel-component {
- &-prev,
- &-next {
- background-color: $color-carousel-button;
- border: 0;
+ .slider-control-centerleft {
height: 100%;
- padding: 0;
- width: 100%;
-
- &::before {
- background: $icon-chevron-white 50% no-repeat;
- content: '';
- display: block;
- height: $icon-size-large;
- margin: 0 auto;
- width: $icon-size-large;
- }
- }
- &-prev {
- &::before {
- transform: rotate(-90deg);
+ .carousel-component-prev {
+ @include button-style;
+
+ &::before {
+ transform: rotate(-90deg);
+ }
}
}
- &-next {
- &::before {
- transform: rotate(90deg);
+ .slider-control-centerright {
+ height: 100%;
+
+ .carousel-component-next {
+ @include button-style;
+
+ &::before {
+ transform: rotate(90deg);
+ }
}
}
}