react-id-swiper
Version:
ReactJs component for iDangerous Swiper
459 lines (407 loc) • 12.9 kB
JavaScript
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Swiper from 'swiper/dist/js/swiper';
import objectAssign from 'object-assign';
import PropTypes from 'prop-types';
import { cn } from './utils';
export default class ReactIdSwiper extends Component {
// Default props
static defaultProps = {
containerClass: 'swiper-container',
wrapperClass: 'swiper-wrapper',
slideClass: 'swiper-slide',
ContainerEl: 'div',
WrapperEl: 'div',
renderScrollbar: ({ scrollbar }) => <div className={cn(scrollbar.el)} />,
renderPagination: ({ pagination }) => <div className={cn(pagination.el)} />,
renderPrevButton: ({ navigation }) => <div className={cn(navigation.prevEl)} />,
renderNextButton: ({ navigation }) => <div className={cn(navigation.nextEl)} />,
renderParallax: ({ parallaxEl }) => (
<div className={cn(parallaxEl.el)} data-swiper-parallax={parallaxEl.value} />
)
};
// Proptypes
static propTypes = {
// react-id-swiper original parameters
ContainerEl: PropTypes.string,
WrapperEl: PropTypes.string,
containerClass: PropTypes.string,
wrapperClass: PropTypes.string,
children: PropTypes.any,
rebuildOnUpdate: PropTypes.bool,
shouldSwiperUpdate: PropTypes.bool,
activeSlideKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
renderScrollbar: PropTypes.func,
renderPagination: PropTypes.func,
renderPrevButton: PropTypes.func,
renderNextButton: PropTypes.func,
renderParallax: PropTypes.func,
// parallax
parallax: PropTypes.bool,
parallaxEl: PropTypes.shape({
el: PropTypes.string,
value: PropTypes.string
}),
// swiper parameter
init: PropTypes.bool,
initialSlide: PropTypes.number,
direction: PropTypes.string,
rtl: PropTypes.bool,
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
})
]),
// 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.buildSwiper();
}
componentDidUpdate() {
if (typeof this.swiper !== 'undefined') {
const { rebuildOnUpdate, shouldSwiperUpdate, activeSlideKey } = this.props;
if (rebuildOnUpdate) {
this.rebuildSwiper();
} else if (shouldSwiperUpdate) {
this.updateSwiper();
const numSlides = this.swiper.slides.length;
if (numSlides <= this.swiper.activeIndex) {
const index = Math.max(numSlides - 1, 0);
this.swiper.slideTo(index);
}
}
if (activeSlideKey) {
let activeSlideId = null;
let id = 0;
React.Children.forEach(this.props.children, child => {
if (child) {
if (child.key === activeSlideKey) {
activeSlideId = id;
}
id += 1;
}
});
if (activeSlideId !== null) {
this.swiper.slideTo(activeSlideId);
}
}
}
}
componentWillUnmount() {
if (typeof this.swiper !== 'undefined') this.swiper.destroy(true, true);
delete this.swiper;
}
buildSwiper() {
this.swiper = new Swiper(ReactDOM.findDOMNode(this), objectAssign({}, this.props));
}
rebuildSwiper() {
this.swiper.destroy(true, true);
this.buildSwiper();
}
updateSwiper() {
if (typeof this.swiper !== 'undefined') this.swiper.update();
}
renderContent(e) {
if (!e) return false;
const { slideClass, noSwiping } = this.props;
const slideClassNames = [slideClass, e.props.className];
if (noSwiping) slideClassNames.push('swiper-no-swiping');
return React.cloneElement(e, {
...e.props,
className: slideClassNames.join(' ').trim()
});
}
render() {
const {
ContainerEl,
WrapperEl,
containerClass,
wrapperClass,
children,
rtl,
scrollbar,
renderScrollbar,
pagination,
renderPagination,
navigation,
renderPrevButton,
renderNextButton,
parallax,
parallaxEl,
renderParallax
} = this.props;
return (
<ContainerEl className={containerClass} dir={rtl && 'rtl'}>
{parallax && parallaxEl && renderParallax(this.props)}
<WrapperEl className={wrapperClass}>
{React.Children.map(children, this.renderContent)}
</WrapperEl>
{pagination && pagination.el && renderPagination(this.props)}
{scrollbar && scrollbar.el && renderScrollbar(this.props)}
{navigation && navigation.nextEl && renderNextButton(this.props)}
{navigation && navigation.prevEl && renderPrevButton(this.props)}
</ContainerEl>
);
}
}