ukelli-ui
Version:
Base on React's UI lib. Make frontend's dev simpler and faster.
204 lines (203 loc) • 8.85 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import React, { Component } from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import { Call } from 'basic-helper';
import { Icon } from '../icon';
/**
* 轮播控件
*
* @export
* @class Carousel
* @extends {Component}
*/
var Carousel = /** @class */ (function (_super) {
__extends(Carousel, _super);
function Carousel(props) {
var _this = _super.call(this, props) || this;
_this.isStarted = false;
_this.handleTouchStart = function (e) {
var touches = e.changedTouches || e;
_this.startPageX = touches[0] ? touches[0].pageX : touches.pageX;
};
_this.handleTouchEnd = function (e) {
e.preventDefault();
e.stopPropagation();
var activeIdx = _this.state.activeIdx;
var touches = e.changedTouches || e;
_this.endPageX = touches[0] ? touches[0].pageX : touches.pageX;
var touchOffset = _this.endPageX - _this.startPageX;
if (Math.abs(touchOffset) < 50) {
return _this.showDetail(activeIdx);
}
var toNext = touchOffset > 0;
return _this.setActiveIdx(activeIdx + (toNext ? -1 : 1));
};
var _a = props.carouselItems, carouselItems = _a === void 0 ? [] : _a, style = props.style;
var defaultIdx = 0;
_this.state = {
activeIdx: defaultIdx,
toNext: true,
activeItem: carouselItems[defaultIdx],
};
_this.timer = null;
_this.itemWidth = style.width;
_this.mobileEvents = {
onMouseDown: _this.handleTouchStart,
onMouseUp: _this.handleTouchEnd,
onTouchStart: _this.handleTouchStart,
onTouchEnd: _this.handleTouchEnd,
};
return _this;
}
Carousel.prototype.componentDidUpdate = function (prevProps) {
if (this.props.carouselItems.length === 0 && prevProps.carouselItems.length > 0) {
this.startLoop();
}
};
Carousel.prototype.componentDidMount = function () {
this.startLoop();
};
Carousel.prototype.componentWillUnmount = function () {
this.stopLoop();
};
Carousel.prototype.startLoop = function () {
var _this = this;
var _a = this.props.freq, freq = _a === void 0 ? 5 : _a;
if (this.timer)
this.stopLoop();
this.timer = setInterval(function () {
var carouselItems = _this.props.carouselItems;
var activeIdx = _this.state.activeIdx;
activeIdx += 1;
if (activeIdx > carouselItems.length - 1)
activeIdx = 0;
if (!document.hidden)
_this.setActiveIdx(activeIdx);
}, freq * 1000);
};
Carousel.prototype.stopLoop = function () {
clearInterval(this.timer);
this.timer = null;
};
Carousel.prototype.setActiveIdx = function (idx) {
var carouselItems = this.props.carouselItems;
var maxIdx = carouselItems.length - 1;
var nextIdx = idx;
if (idx > maxIdx)
nextIdx = 0;
if (idx < 0)
nextIdx = maxIdx;
this.setState(function (preState) {
var prevActiveIdx = preState.activeIdx;
var toNext = prevActiveIdx < nextIdx;
return {
activeIdx: nextIdx,
toNext: toNext,
activeItem: carouselItems[nextIdx] || React.createElement("span", null)
};
});
this.startLoop();
};
Carousel.prototype.genCarouselDOM = function (currItem, idx, imgStyle) {
var _a = this.props, style = _a.style, actionClass = _a.actionClass;
var _b = imgStyle || style, width = _b.width, height = _b.height;
var imgUrl = currItem.imgUrl, element = currItem.element;
var objStyle = {
width: width,
height: height,
backgroundImage: "url(" + imgUrl + ")"
};
return (React.createElement("div", { className: actionClass, key: idx }, element || (React.createElement("div", { className: "img", style: objStyle }))));
};
Carousel.prototype.showDetail = function (activeIdx) {
var activeItem = this.state.activeItem;
Call(activeItem.action, activeItem, activeIdx);
};
Carousel.prototype.getThumb = function () {
var _this = this;
var _a = this.props, isMobile = _a.isMobile, carouselItems = _a.carouselItems, style = _a.style, thumbRate = _a.thumbRate, thumbType = _a.thumbType, indicator = _a.indicator;
var activeIdx = this.state.activeIdx;
var thumbGenerator;
var _indicator = indicator || thumbType;
switch (_indicator) {
case 'thumb':
var _b = style, width = _b.width, height = _b.height;
var imgWHRate = width / height;
var thumbImgStyle_1 = {
width: width / thumbRate,
height: width / imgWHRate / thumbRate
};
thumbGenerator = function (item, idx) { return _this.genCarouselDOM(item, idx, thumbImgStyle_1); };
break;
case 'dot':
default:
thumbGenerator = function (item, idx) { return (React.createElement("span", { className: "dot-item" })); };
break;
}
var thumbDOM = !isMobile && (React.createElement("div", { className: "thumb-contaner" }, carouselItems.map(function (item, idx) {
var isActive = idx === activeIdx;
return (React.createElement("div", { className: "thumb-item" + (isActive ? ' active' : '') + " " + thumbType, key: idx },
React.createElement("div", { className: "_mark", onClick: function (e) {
_this.setActiveIdx(idx);
} }, thumbGenerator(item, idx))));
})));
return thumbDOM;
};
Carousel.prototype.render = function () {
var _this = this;
var _a = this.props, carouselItems = _a.carouselItems, style = _a.style, isMobile = _a.isMobile, transitionTimer = _a.transitionTimer, transitionName = _a.transitionName;
if (!carouselItems || carouselItems.length === 0) {
return (React.createElement("span", { className: "no-banner" }));
}
var _b = this.state, activeIdx = _b.activeIdx, toNext = _b.toNext, activeItem = _b.activeItem;
return (React.createElement("div", { className: "carousel", style: style },
React.createElement(TransitionGroup, null,
React.createElement(CSSTransition, { key: activeIdx, classNames: transitionName + "-to-" + (toNext ? 'next' : 'prev'), timeout: transitionTimer },
React.createElement("div", __assign({ className: "carousel-item" }, this.mobileEvents), this.genCarouselDOM(activeItem, activeIdx)))),
this.getThumb(),
isMobile ? null : (React.createElement(React.Fragment, null,
React.createElement("div", { className: "prev-btn func-btn", onClick: function (e) { return _this.setActiveIdx(activeIdx - 1); } },
React.createElement(Icon, { n: "arrow-left" })),
React.createElement("div", { className: "next-btn func-btn", onClick: function (e) { return _this.setActiveIdx(activeIdx + 1); } },
React.createElement(Icon, { n: "arrow-right" }))))));
};
Carousel.defaultProps = {
actionClass: 'action-area',
transitionName: 'banner',
thumbType: 'dot',
indicator: 'dot',
style: {
width: '100%',
height: 380
},
transitionTimer: 400,
freq: 5,
thumbRate: 15,
isMobile: false
};
return Carousel;
}(Component));
export default Carousel;