├── .babelrc ├── .gitignore ├── README.md ├── example ├── index.html ├── index.js ├── screenshot.gif └── webpack.config.js ├── lib ├── Swipe.js ├── __mocks__ │ ├── fileMock.js │ └── styleMock.js ├── __tests__ │ └── Swipe.spec.js └── swipe.css ├── package.json ├── src ├── Swipe.js ├── __mocks__ │ ├── fileMock.js │ └── styleMock.js ├── __tests__ │ ├── Swipe.spec.js │ └── __snapshots__ │ │ └── Swipe.spec.js.snap └── swipe.css └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env" 5 | ], 6 | "@babel/preset-react" 7 | ], 8 | "plugins": [ 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | .node-version 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## react-swipe 2 | 3 | [![npm version](https://badge.fury.io/js/react-swipr.svg)](https://badge.fury.io/js/react-z-swipe) 4 | 5 | ![](https://raw.githubusercontent.com/react-z/react-swipe/master/example/screenshot.gif) 6 | 7 | A simple react swipe component 8 | 9 | ## Install 10 | 11 | ``` js 12 | yarn add react-z-swipe 13 | ``` 14 | 15 | ## Use 16 | 17 | ``` js 18 | import Swipe from 'react-z-swipe' 19 | import ReactDOM from 'react-dom' 20 | import React, { Component } from 'react' 21 | 22 | class TestComponent extends Component { 23 | render () { 24 | return ( 25 |
26 | 27 |
  • 28 | 29 |
  • 30 |
  • 31 | 32 |
  • 33 |
  • 34 | 35 |
  • 36 |
    37 | 38 |
  • 39 | 40 |
  • 41 |
  • 42 | 43 |
  • 44 |
  • 45 | 46 |
  • 47 |
    48 |
    49 | ) 50 | } 51 | } 52 | 53 | ReactDOM.render( 54 | , 55 | document.getElementById('root') 56 | ) 57 | ``` 58 | 59 | ## Development 60 | yarn 61 | yarn run dev 62 | 63 | ## Test 64 | yarn run test 65 | 66 | ## Build 67 | yarn 68 | yarn run build 69 | 70 | ## Publish 71 | npm login 72 | npm version patch 73 | git add -A 74 | git push origin master 75 | npm publish 76 | 77 | ## License 78 | 79 | [MIT](http://isekivacenz.mit-license.org/) 80 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Example 5 | 6 | 7 |
    8 | 9 | 10 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import Swipe from '../lib/Swipe' // 'react-z-swipe' 2 | import ReactDOM from 'react-dom' 3 | import React, { Component } from 'react' 4 | 5 | class TestComponent extends Component { 6 | render () { 7 | return ( 8 |
    9 | 10 |
  • 11 | 12 |
  • 13 |
  • 14 | 15 |
  • 16 |
  • 17 | 18 |
  • 19 |
    20 | 21 |
  • 22 | 23 |
  • 24 |
  • 25 | 26 |
  • 27 |
  • 28 | 29 |
  • 30 |
    31 |
    32 | ) 33 | } 34 | } 35 | 36 | ReactDOM.render( 37 | , 38 | document.getElementById('root') 39 | ) 40 | -------------------------------------------------------------------------------- /example/screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-z/react-swipe/9c8f660e1b6784cc59ec1bacbcb793c8c86590fd/example/screenshot.gif -------------------------------------------------------------------------------- /example/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin') 2 | 3 | module.exports = { 4 | entry: ['./example/index.js'], 5 | devtool: 'inline-source-map', 6 | output: { filename: 'bundle.js', publicPath: '' }, 7 | module: { 8 | rules: [ 9 | { 10 | test: /\.js$/, 11 | use: [ { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/react'] } } ], 12 | exclude: /node_modules/, 13 | }, 14 | { 15 | test: /\.css$/, 16 | use: [ 17 | { loader: 'style-loader' }, 18 | { loader: 'css-loader' } 19 | ] 20 | } 21 | ] 22 | }, 23 | plugins: [ 24 | new HtmlWebpackPlugin({ title: 'example', template: './example/index.html' }) 25 | ], 26 | } 27 | -------------------------------------------------------------------------------- /lib/Swipe.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = _interopRequireWildcard(require("react")); 9 | 10 | var _propTypes = _interopRequireDefault(require("prop-types")); 11 | 12 | var _swipr = _interopRequireDefault(require("swipr")); 13 | 14 | var _swipe = _interopRequireDefault(require("./swipe.css")); 15 | 16 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 17 | 18 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } 19 | 20 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 21 | 22 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 23 | 24 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 25 | 26 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 27 | 28 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 29 | 30 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 31 | 32 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 33 | 34 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 35 | 36 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 37 | 38 | /** 39 | * React Swipe component 40 | **/ 41 | var Swipe = 42 | /*#__PURE__*/ 43 | function (_Component) { 44 | _inherits(Swipe, _Component); 45 | 46 | function Swipe() { 47 | _classCallCheck(this, Swipe); 48 | 49 | return _possibleConstructorReturn(this, _getPrototypeOf(Swipe).apply(this, arguments)); 50 | } 51 | 52 | _createClass(Swipe, [{ 53 | key: "componentDidMount", 54 | value: function componentDidMount() { 55 | var elementId = this.props.elementId; 56 | document.addEventListener('DOMContentLoaded', function () { 57 | var $elem = document.getElementById(elementId); 58 | (0, _swipr.default)($elem); 59 | }); 60 | } 61 | }, { 62 | key: "render", 63 | value: function render() { 64 | var _this$props = this.props, 65 | navigation = _this$props.navigation, 66 | elementId = _this$props.elementId; 67 | return _react.default.createElement("div", { 68 | className: "react-swipe", 69 | id: elementId 70 | }, _react.default.createElement("div", { 71 | className: "swipr" 72 | }, _react.default.createElement("ul", { 73 | className: "swipr_slides" 74 | }, this.props.children)), navigation && _react.default.createElement(_react.default.Fragment, null, _react.default.createElement("span", { 75 | className: "swipr_prev" 76 | }, _react.default.createElement("svg", { 77 | width: "50", 78 | height: "50", 79 | viewBox: "0 0 501.5 501.5" 80 | }, _react.default.createElement("g", null, _react.default.createElement("path", { 81 | fill: "currentColor", 82 | d: "M302.67 90.877l55.77 55.508L254.575 250.75 358.44 355.116l-55.77 55.506L143.56 250.75z" 83 | })))), _react.default.createElement("span", { 84 | className: "swipr_next" 85 | }, _react.default.createElement("svg", { 86 | width: "50", 87 | height: "50", 88 | viewBox: "0 0 501.5 501.5" 89 | }, _react.default.createElement("g", null, _react.default.createElement("path", { 90 | fill: "currentColor", 91 | d: "M199.33 410.622l-55.77-55.508L247.425 250.75 143.56 146.384l55.77-55.507L358.44 250.75z" 92 | })))))); 93 | } 94 | }], [{ 95 | key: "propTypes", 96 | get: function get() { 97 | return { 98 | elementId: _propTypes.default.string.isRequired, 99 | navigation: _propTypes.default.bool 100 | }; 101 | } 102 | }]); 103 | 104 | return Swipe; 105 | }(_react.Component); 106 | 107 | exports.default = Swipe; -------------------------------------------------------------------------------- /lib/__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = 'test-file-stub'; -------------------------------------------------------------------------------- /lib/__mocks__/styleMock.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = {}; -------------------------------------------------------------------------------- /lib/__tests__/Swipe.spec.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var _enzyme = require("enzyme"); 4 | 5 | var _enzymeAdapterReact = _interopRequireDefault(require("enzyme-adapter-react-16")); 6 | 7 | var _react = _interopRequireDefault(require("react")); 8 | 9 | var _reactTestRenderer = _interopRequireDefault(require("react-test-renderer")); 10 | 11 | var _Swipe = _interopRequireDefault(require("../Swipe")); 12 | 13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 14 | 15 | /* setup enzyme */ 16 | (0, _enzyme.configure)({ 17 | adapter: new _enzymeAdapterReact.default() 18 | }); 19 | /* setup jsdom */ 20 | 21 | var jsdom = require('jsdom'); 22 | 23 | var JSDOM = jsdom.JSDOM; 24 | var window = new JSDOM('').window; 25 | global.window = window; 26 | global.document = window.document; 27 | test('Swipe renders correctly and matches snapshot', function () { 28 | var component = _reactTestRenderer.default.create(_react.default.createElement(_Swipe.default, { 29 | elementId: "react-swipe-1", 30 | navigation: false 31 | }, _react.default.createElement("li", null, _react.default.createElement("p", null, "swiping...")), _react.default.createElement("li", null, _react.default.createElement("p", null, "more swiping...")), _react.default.createElement("li", null, _react.default.createElement("p", null, "more more swiping...")))); 32 | 33 | var tree = component.toJSON(); 34 | expect(tree).toMatchSnapshot(); 35 | }); 36 | test('Swipe renders the correct elements', function () { 37 | var wrapper = (0, _enzyme.shallow)(_react.default.createElement(_Swipe.default, { 38 | elementId: "react-swipe-2", 39 | navigation: true 40 | }, _react.default.createElement("li", null, _react.default.createElement("p", null, "swiping...")), _react.default.createElement("li", null, _react.default.createElement("p", null, "more swiping...")), _react.default.createElement("li", null, _react.default.createElement("p", null, "more more swiping...")))); 41 | expect(wrapper.find('.react-swipe').length).toEqual(1); 42 | expect(wrapper.find('.swipr_slides').length).toEqual(1); 43 | expect(wrapper.find('#react-swipe-2').length).toEqual(1); 44 | expect(wrapper.find('li').length).toEqual(3); 45 | expect(wrapper.find('p').first().text()).toEqual('swiping...'); 46 | expect(wrapper.find('svg').length).toEqual(2); 47 | expect(wrapper.find('.swipr_next').length).toEqual(1); 48 | expect(wrapper.find('.swipr_prev').length).toEqual(1); 49 | wrapper.setProps({ 50 | navigation: false 51 | }); 52 | expect(wrapper.find('svg').length).toEqual(0); 53 | expect(wrapper.find('.swipr_next').length).toEqual(0); 54 | expect(wrapper.find('.swipr_prev').length).toEqual(0); 55 | }); -------------------------------------------------------------------------------- /lib/swipe.css: -------------------------------------------------------------------------------- 1 | img { 2 | display: block; 3 | margin: 0 auto; 4 | } 5 | 6 | .swipr_example { 7 | margin: 0 auto; 8 | border: 1px solid; 9 | width: 800px; 10 | } 11 | 12 | .swipr { 13 | position: relative; 14 | overflow: hidden; 15 | white-space: nowrap; 16 | user-select: none; 17 | width: 800px; 18 | } 19 | 20 | .swipr li { 21 | position: relative; 22 | display: inline-block; 23 | pointer-events: none; 24 | width: 800px; 25 | } 26 | 27 | .swipr_slides { 28 | display: inline-block; 29 | } 30 | 31 | .swipr_prev, .swipr_next { 32 | display: inline-block; 33 | cursor: pointer; 34 | } 35 | 36 | .swipr_next svg, .swipr_prev svg { 37 | width: 25px; 38 | } 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-z-swipe", 3 | "version": "1.1.1", 4 | "description": "A react component for swipr the minimal touch swiper", 5 | "main": "lib/ReactSwipr.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/react-z/react-swipe.git" 9 | }, 10 | "author": "svnm", 11 | "license": "MIT", 12 | "homepage": "https://github.com/react-z/react-swipe.git", 13 | "peerDependencies": { 14 | "react": "^16.0.0" 15 | }, 16 | "dependencies": { 17 | "hammerjs": "2.0.4", 18 | "prop-types": "^15.6.0", 19 | "swipr": "^2.1.0" 20 | }, 21 | "devDependencies": { 22 | "@babel/cli": "^7.2.3", 23 | "@babel/core": "7.3.3", 24 | "@babel/preset-env": "7.3.1", 25 | "@babel/preset-react": "7.0.0", 26 | "babel-jest": "^24.7.1", 27 | "babel-loader": "8.0.5", 28 | "css-loader": "^2.1.1", 29 | "enzyme": "3.9.0", 30 | "enzyme-adapter-react-16": "^1.9.1", 31 | "html-webpack-plugin": "3.2.0", 32 | "jest": "^24.7.1", 33 | "jsdom": "13.2.0", 34 | "react": "^16.0.0", 35 | "react-dom": "^16.0.0", 36 | "react-test-renderer": "^16.8.6", 37 | "style-loader": "^0.23.1", 38 | "webpack": "4.29.4", 39 | "webpack-cli": "3.2.3", 40 | "webpack-dev-server": "3.1.14" 41 | }, 42 | "scripts": { 43 | "build": "babel src --out-dir lib", 44 | "dev": "webpack-dev-server --mode=development --port 3000 --inline --hot --config example/webpack.config", 45 | "test": "jest" 46 | }, 47 | "jest": { 48 | "moduleNameMapper": { 49 | "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/src/__mocks__/fileMock.js", 50 | "\\.(css|less)$": "/src/__mocks__/styleMock.js" 51 | } 52 | }, 53 | "keywords": [ 54 | "react", 55 | "react-component", 56 | "react-swipr", 57 | "react swiper", 58 | "react-swipe", 59 | "react-slide", 60 | "react-slider", 61 | "react slide", 62 | "react slider", 63 | "react-carousel", 64 | "react carousel", 65 | "swiper", 66 | "swipe", 67 | "slider", 68 | "slide", 69 | "carousel", 70 | "touch-slider", 71 | "touch enabled", 72 | "minimal", 73 | "simple slider", 74 | "minimal slider" 75 | ] 76 | } 77 | -------------------------------------------------------------------------------- /src/Swipe.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import PropTypes from 'prop-types' 3 | import swipr from 'swipr' 4 | import style from './swipe.css' 5 | 6 | /** 7 | * React Swipe component 8 | **/ 9 | export default class Swipe extends Component { 10 | static get propTypes() { 11 | return { 12 | elementId: PropTypes.string.isRequired, 13 | navigation: PropTypes.bool 14 | } 15 | } 16 | 17 | componentDidMount() { 18 | const { elementId } = this.props 19 | 20 | document.addEventListener('DOMContentLoaded', function() { 21 | const $elem = document.getElementById(elementId) 22 | swipr($elem) 23 | }) 24 | } 25 | 26 | render() { 27 | const { navigation, elementId } = this.props 28 | 29 | return ( 30 |
    31 |
    32 |
      {this.props.children}
    33 |
    34 | {navigation && ( 35 | 36 | 37 | 38 | 39 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 53 | 54 | 55 | 56 | 57 | )} 58 |
    59 | ) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | module.exports = 'test-file-stub'; -------------------------------------------------------------------------------- /src/__mocks__/styleMock.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; -------------------------------------------------------------------------------- /src/__tests__/Swipe.spec.js: -------------------------------------------------------------------------------- 1 | /* setup enzyme */ 2 | import { configure } from 'enzyme' 3 | import Adapter from 'enzyme-adapter-react-16' 4 | configure({ adapter: new Adapter() }) 5 | 6 | /* setup jsdom */ 7 | var jsdom = require('jsdom') 8 | const { JSDOM } = jsdom 9 | const window = new JSDOM('').window 10 | global.window = window 11 | global.document = window.document 12 | 13 | import React from 'react' 14 | import renderer from 'react-test-renderer' 15 | import { shallow } from 'enzyme' 16 | import Swipe from '../Swipe' 17 | 18 | test('Swipe renders correctly and matches snapshot', () => { 19 | const component = renderer.create( 20 | 21 |
  • 22 |

    swiping...

    23 |
  • 24 |
  • 25 |

    more swiping...

    26 |
  • 27 |
  • 28 |

    more more swiping...

    29 |
  • 30 |
    31 | ) 32 | 33 | let tree = component.toJSON() 34 | expect(tree).toMatchSnapshot() 35 | }) 36 | 37 | test('Swipe renders the correct elements', () => { 38 | const wrapper = shallow( 39 | 40 |
  • 41 |

    swiping...

    42 |
  • 43 |
  • 44 |

    more swiping...

    45 |
  • 46 |
  • 47 |

    more more swiping...

    48 |
  • 49 |
    50 | ) 51 | 52 | expect(wrapper.find('.react-swipe').length).toEqual(1) 53 | expect(wrapper.find('.swipr_slides').length).toEqual(1) 54 | expect(wrapper.find('#react-swipe-2').length).toEqual(1) 55 | 56 | expect(wrapper.find('li').length).toEqual(3) 57 | expect( 58 | wrapper 59 | .find('p') 60 | .first() 61 | .text() 62 | ).toEqual('swiping...') 63 | 64 | expect(wrapper.find('svg').length).toEqual(2) 65 | expect(wrapper.find('.swipr_next').length).toEqual(1) 66 | expect(wrapper.find('.swipr_prev').length).toEqual(1) 67 | 68 | wrapper.setProps({ navigation: false }) 69 | expect(wrapper.find('svg').length).toEqual(0) 70 | expect(wrapper.find('.swipr_next').length).toEqual(0) 71 | expect(wrapper.find('.swipr_prev').length).toEqual(0) 72 | }) 73 | -------------------------------------------------------------------------------- /src/__tests__/__snapshots__/Swipe.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Swipe renders correctly and matches snapshot 1`] = ` 4 |
    8 |
    11 |
      14 |
    • 15 |

      16 | swiping... 17 |

      18 |
    • 19 |
    • 20 |

      21 | more swiping... 22 |

      23 |
    • 24 |
    • 25 |

      26 | more more swiping... 27 |

      28 |
    • 29 |
    30 |
    31 |
    32 | `; 33 | -------------------------------------------------------------------------------- /src/swipe.css: -------------------------------------------------------------------------------- 1 | img { 2 | display: block; 3 | margin: 0 auto; 4 | } 5 | 6 | .swipr_example { 7 | margin: 0 auto; 8 | border: 1px solid; 9 | width: 800px; 10 | } 11 | 12 | .swipr { 13 | position: relative; 14 | overflow: hidden; 15 | white-space: nowrap; 16 | user-select: none; 17 | width: 800px; 18 | } 19 | 20 | .swipr li { 21 | position: relative; 22 | display: inline-block; 23 | pointer-events: none; 24 | width: 800px; 25 | } 26 | 27 | .swipr_slides { 28 | display: inline-block; 29 | } 30 | 31 | .swipr_prev, .swipr_next { 32 | display: inline-block; 33 | cursor: pointer; 34 | } 35 | 36 | .swipr_next svg, .swipr_prev svg { 37 | width: 25px; 38 | } 39 | --------------------------------------------------------------------------------