UNPKG

react-id-swiper

Version:

ReactJs component for iDangerous Swiper

457 lines (398 loc) 13.4 kB
import React from 'react'; import ReactDOM from 'react-dom'; import Swiper from 'swiper/dist/js/swiper.js'; import objectAssign from 'object-assign'; import PropTypes from 'prop-types'; export default class ReactIdSwiper extends React.Component { // Default props static defaultProps = { containerClass: 'swiper-container', wrapperClass: 'swiper-wrapper', slideClass: 'swiper-slide' } // Proptypes static propTypes = { // react-id-swiper original parameter containerClass: PropTypes.string, wrapperClass: PropTypes.string, children: PropTypes.oneOfType([ PropTypes.node, PropTypes.element ]), rebuildOnUpdate: PropTypes.bool, shouldSwiperUpdate: PropTypes.bool, prevButtonCustomizedClass: PropTypes.string, nextButtonCustomizedClass: PropTypes.string, paginationCustomizedClass: PropTypes.string, scrollbarCustomizedClass: PropTypes.string, activeSlideKey: PropTypes.string, // swiper parameter init: PropTypes.bool, initialSlide: PropTypes.number, direction: PropTypes.string, speed: PropTypes.number, setWrapperSize: PropTypes.bool, virtualTranslate: PropTypes.bool, width: PropTypes.number, height: PropTypes.number, autoHeight: PropTypes.bool, roundLengths: PropTypes.bool, nested: PropTypes.bool, uniqueNavElements: PropTypes.bool, effect: PropTypes.string, runCallbacksOnInit: PropTypes.bool, // slides grid spaceBetween: PropTypes.number, slidesPerView: PropTypes.any, slidesPerColumn: PropTypes.number, slidesPerColumnFill: PropTypes.string, slidesPerGroup: PropTypes.number, centeredSlides: PropTypes.bool, slidesOffsetBefore: PropTypes.number, slidesOffsetAfter: PropTypes.number, normalizeSlideIndex: PropTypes.bool, // grab cursor grabCursor: PropTypes.bool, // touches touchEventsTarget: PropTypes.string, touchRatio: PropTypes.number, touchAngle: PropTypes.number, simulateTouch: PropTypes.bool, shortSwipes: PropTypes.bool, longSwipes: PropTypes.bool, longSwipesRatio: PropTypes.number, longSwipesMs: PropTypes.number, followFinger: PropTypes.bool, allowTouchMove: PropTypes.bool, threshold: PropTypes.number, touchMoveStopPropagation: PropTypes.bool, iOSEdgeSwipeDetection: PropTypes.bool, iOSEdgeSwipeThreshold: PropTypes.number, touchReleaseOnEdges: PropTypes.bool, passiveListeners: PropTypes.bool, // touch resistance resistance: PropTypes.bool, resistanceRatio: PropTypes.number, // swiping / no swiping allowSlidePrev: PropTypes.bool, allowSlideNext: PropTypes.bool, noSwiping: PropTypes.bool, noSwipingClass: PropTypes.string, swipeHandler: PropTypes.any, // clicks preventClicks: PropTypes.bool, preventClicksPropagation: PropTypes.bool, slideToClickedSlide: PropTypes.bool, // freemode freeMode: PropTypes.bool, freeModeMomentum: PropTypes.bool, freeModeMomentumRatio: PropTypes.number, freeModeMomentumVelocityRatio: PropTypes.number, freeModeMomentumBounce: PropTypes.bool, freeModeMomentumBounceRatio: PropTypes.number, freeModeMinimumVelocity: PropTypes.number, freeModeSticky: PropTypes.bool, // progress watchSlidesProgress: PropTypes.bool, watchSlidesVisibility: PropTypes.bool, // images preloadImages: PropTypes.bool, updateOnImagesReady: PropTypes.bool, // loop loop: PropTypes.bool, loopAdditionalSlides: PropTypes.number, loopedSlides: PropTypes.number, loopFillGroupWithBlank: PropTypes.bool, // breakpoints breakpoints: PropTypes.object, // observer observer: PropTypes.bool, observeParents: PropTypes.bool, // namespace containerModifierClass: PropTypes.string, slideClass: PropTypes.string, slideActiveClass: PropTypes.string, slideDuplicatedActiveClass: PropTypes.string, slideVisibleClass: PropTypes.string, slideDuplicateClass: PropTypes.string, slideNextClass: PropTypes.string, slideDuplicatedNextClass: PropTypes.string, slidePrevClass: PropTypes.string, slideDuplicatedPrevClass: PropTypes.string, // autoplay autoplay: PropTypes.oneOfType([ PropTypes.bool, PropTypes.shape({ delay: PropTypes.number, stopOnLast: PropTypes.bool, disableOnInteraction: PropTypes.bool, }) ]), // pagination pagination: PropTypes.shape({ el: PropTypes.string, type: PropTypes.string, bulletElement: PropTypes.string, dynamicBullets: PropTypes.bool, hideOnClick: PropTypes.bool, clickable: PropTypes.bool, renderBullet: PropTypes.func, renderFraction: PropTypes.func, renderProgressbar: PropTypes.func, renderCustom: PropTypes.func, bulletClass: PropTypes.string, bulletActiveClass: PropTypes.string, modifierClass: PropTypes.string, currentClass: PropTypes.string, totalClass: PropTypes.string, hiddenClass: PropTypes.string, progressbarFillClass: PropTypes.string, clickableClass: PropTypes.string, }), // scrollbar scrollbar: PropTypes.shape({ el: PropTypes.any, hide: PropTypes.bool, draggable: PropTypes.bool, snapOnRelease: PropTypes.bool, dragSize: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), }), // navigation navigation: PropTypes.shape({ nextEl: PropTypes.string, prevEl: PropTypes.string, hideOnClick: PropTypes.bool, disabledClass: PropTypes.string, hiddenClass: PropTypes.string, }), // a11y a11y: PropTypes.oneOfType([ PropTypes.bool, PropTypes.shape({ prevSlideMessage: PropTypes.string, nextSlideMessage: PropTypes.string, firstSlideMessage: PropTypes.string, lastSlideMessage: PropTypes.string, paginationBulletMessage: PropTypes.string, notificationClass: PropTypes.string, }) ]), // zoom zoom: PropTypes.oneOfType([ PropTypes.bool, PropTypes.shape({ maxRatio: PropTypes.number, minRatio: PropTypes.number, toggle: PropTypes.bool, containerClass: PropTypes.string, zoomedSlideClass: PropTypes.string, }) ]), // keyboard keyboard: PropTypes.bool, // mousewheel mousewheel: PropTypes.oneOfType([ PropTypes.bool, PropTypes.shape({ forceToAxis: PropTypes.bool, releaseOnEdges: PropTypes.bool, invert: PropTypes.bool, sensitivity: PropTypes.number, eventsTarged: PropTypes.string, }) ]), // hashNavigation hashNavigation: PropTypes.oneOfType([ PropTypes.bool, PropTypes.shape({ watchState: PropTypes.bool, replaceState: PropTypes.bool, }) ]), // history history: PropTypes.oneOfType([ PropTypes.bool, PropTypes.shape({ key: PropTypes.string, replaceState: PropTypes.bool, }) ]), // lazy lazy: PropTypes.oneOfType([ PropTypes.bool, PropTypes.shape({ loadPrevNext: PropTypes.bool, loadPrevNextAmount: PropTypes.number, loadOnTransitionStart: PropTypes.bool, elementClass: PropTypes.string, loadingClass: PropTypes.string, loadedClass: PropTypes.string, preloaderClass: PropTypes.string, }) ]), // fadeEffect fadeEffect: PropTypes.shape({ crossFade: PropTypes.bool }), // coverflowEffect coverflowEffect: PropTypes.shape({ slideShadows: PropTypes.bool, rotate: PropTypes.number, stretch: PropTypes.number, depth: PropTypes.number, modifier: PropTypes.number, }), // flipEffect flipEffect: PropTypes.shape({ slideShadows: PropTypes.bool, limitRotation: PropTypes.bool, }), // cubeEffect cubeEffect: PropTypes.shape({ slideShadows: PropTypes.bool, shadow: PropTypes.bool, shadowOffset: PropTypes.number, shadowScale: PropTypes.number, }), // controller controller: PropTypes.oneOfType([ PropTypes.bool, PropTypes.shape({ control: PropTypes.any, inverse: PropTypes.bool, by: PropTypes.string, }) ]), // parallax parallax: PropTypes.bool, // events on: PropTypes.shape({ init: PropTypes.func, beforeDestroy: PropTypes.func, slideChange: PropTypes.func, slideChangeTransitionStart: PropTypes.func, slideChangeTransitionEnd: PropTypes.func, slideNextTransitionStart: PropTypes.func, slideNextTransitionEnd: PropTypes.func, slidePrevTransitionStart: PropTypes.func, slidePrevTransitionEnd: PropTypes.func, transitionStart: PropTypes.func, onTransitionEnd: PropTypes.func, touchStart: PropTypes.func, touchMove: PropTypes.func, touchMoveOpposite: PropTypes.func, sliderMove: PropTypes.func, touchEnd: PropTypes.func, click: PropTypes.func, tap: PropTypes.func, doubleTap: PropTypes.func, imagesReady: PropTypes.func, progress: PropTypes.func, reachBeginning: PropTypes.func, reachEnd: PropTypes.func, fromEdge: PropTypes.func, setTranslate: PropTypes.func, setTransition: PropTypes.func, resize: PropTypes.func, }), } constructor(props) { super(props); this.renderContent = this.renderContent.bind(this); } componentDidMount() { this.swiper = new Swiper(ReactDOM.findDOMNode(this), objectAssign({}, this.props)); } componentWillReceiveProps(nextProps) { if (this.props.rebuildOnUpdate && typeof this.swiper !== 'undefined') { this.swiper.destroy(true, true); this.swiper = new Swiper(ReactDOM.findDOMNode(this), objectAssign({}, nextProps)); } } shouldComponentUpdate(nextProps) { return nextProps.children !== this.props.children; } componentDidUpdate() { if (this.props.rebuildOnUpdate && typeof this.swiper !== 'undefined') { this.swiper.destroy(true, true); this.swiper = new Swiper(ReactDOM.findDOMNode(this), objectAssign({}, this.props)); } else if (this.props.shouldSwiperUpdate && typeof this.swiper !== 'undefined') { this.swiper.update(); this.swiper.reLoop(); const numSlides = this.swiper.slides.length; if (numSlides <= this.swiper.activeIndex) { const index = Math.max(numSlides - 1, 0); this.swiper.slideTo(index); } } if (this.props.activeSlideKey) { let activeSlideId = null; let id = 0; React.Children.forEach(this.props.children, child => { if (child) { if (child.key === this.props.activeSlideKey) { activeSlideId = id; } id++; } }); if (activeSlideId) { this.swiper.slideTo(activeSlideId); } } } componentWillUnmount() { if (typeof this.swiper !== 'undefined') this.swiper.destroy(true, true); delete this.swiper; } validateClass(className) { if (typeof className !== 'string') return ''; return className.replace(/\.|#/g, ' ').trim(); } renderScrollBar() { if (!this.props.scrollbar || !this.props.scrollbar.el) return false; const scrollbarCustomizedClass = this.validateClass(this.props.scrollbarCustomizedClass); const scrollbarClass = this.validateClass(this.props.scrollbar.el); return <div className={[scrollbarClass, scrollbarCustomizedClass].join(' ')} />; } renderPagination() { if (!this.props.pagination || !this.props.pagination.el) return false; const paginationCustomizedClass = this.validateClass(this.props.paginationCustomizedClass); const paginationClass = this.validateClass(this.props.pagination.el); return <div className={[paginationClass, paginationCustomizedClass].join(' ')} />; } renderNextButton() { if (!this.props.navigation || !this.props.navigation.nextEl) return false; const nextButtonCustomizedClass = this.validateClass(this.props.nextButtonCustomizedClass); const nextButtonClass = this.validateClass(this.props.navigation.nextEl); return <div className={[nextButtonClass, nextButtonCustomizedClass].join(' ')} />; } renderPrevButton() { if (!this.props.navigation || !this.props.navigation.prevEl) return false; const prevButtonCustomizedClass = this.validateClass(this.props.prevButtonCustomizedClass); const prevButtonClass = this.validateClass(this.props.navigation.prevEl); return <div className={[prevButtonClass, prevButtonCustomizedClass].join(' ')} />; } renderContent(e) { if (!e) { return null; } const { slideClass, noSwiping } = this.props; const noSwipingClass = noSwiping ? 'swiper-no-swiping' : ''; return React.cloneElement(e, { className: [slideClass, e.props.className, noSwipingClass].join(' ') }); } render() { const { containerClass, wrapperClass, children } = this.props; return ( <div className={containerClass}> <div className={wrapperClass}> {React.Children.map(children, this.renderContent)} </div> {this.renderPagination()} {this.renderScrollBar()} {this.renderNextButton()} {this.renderPrevButton()} </div> ) } }