Skip to content

Commit

Permalink
feat: Add Carousel touch support via Hammer.js
Browse files Browse the repository at this point in the history
Touch support should be provided for our Carousel components, as
per the upstream docs for Carousel (as of Bootstrap v4.2).
  • Loading branch information
bpas247 committed Jul 9, 2019
1 parent db5ac1a commit 0b6a4fa
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -119,6 +119,7 @@
"@restart/hooks": "^0.3.0", "@restart/hooks": "^0.3.0",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"dom-helpers": "^3.4.0", "dom-helpers": "^3.4.0",
"hammerjs": "^2.0.8",
"invariant": "^2.2.4", "invariant": "^2.2.4",
"keycode": "^2.2.0", "keycode": "^2.2.0",
"popper.js": "^1.14.7", "popper.js": "^1.14.7",
Expand Down
34 changes: 34 additions & 0 deletions src/Carousel.js
@@ -1,6 +1,7 @@
import classNames from 'classnames'; import classNames from 'classnames';
import styles from 'dom-helpers/style'; import styles from 'dom-helpers/style';
import transition from 'dom-helpers/transition'; import transition from 'dom-helpers/transition';
import Hammer from 'hammerjs';
import React, { cloneElement } from 'react'; import React, { cloneElement } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { uncontrollable } from 'uncontrollable'; import { uncontrollable } from 'uncontrollable';
Expand Down Expand Up @@ -99,6 +100,11 @@ const propTypes = {
* Set to null to deactivate. * Set to null to deactivate.
*/ */
nextLabel: PropTypes.string, nextLabel: PropTypes.string,

/**
* Whether the carousel should support left/right swipe interactions on touchscreen devices.
*/
touch: PropTypes.bool,
}; };


const defaultProps = { const defaultProps = {
Expand All @@ -117,6 +123,7 @@ const defaultProps = {


nextIcon: <span aria-hidden="true" className="carousel-control-next-icon" />, nextIcon: <span aria-hidden="true" className="carousel-control-next-icon" />,
nextLabel: 'Next', nextLabel: 'Next',
touch: true,
}; };


class Carousel extends React.Component { class Carousel extends React.Component {
Expand All @@ -131,6 +138,27 @@ class Carousel extends React.Component {


componentDidMount() { componentDidMount() {
this.cycle(); this.cycle();
if (this.carousel && this.props.touch) {
this.hammer = new Hammer(this.carousel.current);
this.hammer.on('swipe', ev => {
const lastPossibleIndex = countChildren(this.props.children) - 1;
if (ev.direction === Hammer.DIRECTION_LEFT) {
this.to(
this.state.activeIndex === lastPossibleIndex
? 0
: this.state.activeIndex + 1,
ev,
);
} else if (ev.direction === Hammer.DIRECTION_RIGHT) {
this.to(
this.state.activeIndex === 0
? lastPossibleIndex
: this.state.activeIndex - 1,
ev,
);
}
});
}
} }


static getDerivedStateFromProps( static getDerivedStateFromProps(
Expand Down Expand Up @@ -219,6 +247,10 @@ class Carousel extends React.Component {
componentWillUnmount() { componentWillUnmount() {
clearTimeout(this.timeout); clearTimeout(this.timeout);
this.isUnmounted = true; this.isUnmounted = true;
if (this.hammer) {
this.hammer.stop();
this.hammer.destroy();
}
} }


handleSlideEnd = () => { handleSlideEnd = () => {
Expand Down Expand Up @@ -427,6 +459,8 @@ class Carousel extends React.Component {
indicators, indicators,
controls, controls,
wrap, wrap,
// eslint-disable-next-line no-unused-vars
touch,
prevIcon, prevIcon,
prevLabel, prevLabel,
nextIcon, nextIcon,
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Expand Up @@ -4113,6 +4113,11 @@ gud@^1.0.0:
resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0"
integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==


hammerjs@^2.0.8:
version "2.0.8"
resolved "https://registry.yarnpkg.com/hammerjs/-/hammerjs-2.0.8.tgz#04ef77862cff2bb79d30f7692095930222bf60f1"
integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=

handlebars@^4.0.1, handlebars@^4.1.0: handlebars@^4.0.1, handlebars@^4.1.0:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.1.tgz#6e4e41c18ebe7719ae4d38e5aca3d32fa3dd23d3" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.1.tgz#6e4e41c18ebe7719ae4d38e5aca3d32fa3dd23d3"
Expand Down

0 comments on commit 0b6a4fa

Please sign in to comment.