@douyinfe/semi-ui
Version:
A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.
280 lines (279 loc) • 10.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _debounce2 = _interopRequireDefault(require("lodash/debounce"));
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _baseComponent = _interopRequireDefault(require("../_base/baseComponent"));
var _constants = require("@douyinfe/semi-foundation/lib/cjs/carousel/constants");
var _foundation = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/carousel/foundation"));
var _CarouselIndicator = _interopRequireDefault(require("./CarouselIndicator"));
var _CarouselArrow = _interopRequireDefault(require("./CarouselArrow"));
require("@douyinfe/semi-foundation/lib/cjs/carousel/carousel.css");
var _isNullOrUndefined = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/utils/isNullOrUndefined"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
class Carousel extends _baseComponent.default {
constructor(props) {
super(props);
this.play = () => {
this.foundation.setForcePlay(true);
return this.foundation.handleAutoPlay();
};
this.stop = () => {
this.foundation.setForcePlay(false);
return this.foundation.stop();
};
this.goTo = targetIndex => {
return this.foundation.goTo(targetIndex);
};
this.prev = () => {
return this.foundation.prev();
};
this.next = () => {
return this.foundation.next();
};
this.handleAutoPlay = () => {
if (!this.foundation.getIsControlledComponent()) {
this.foundation.handleAutoPlay();
}
};
this.handleMouseEnter = () => {
const {
autoPlay
} = this.props;
if (autoPlay === true || typeof autoPlay === 'object' && autoPlay.hoverToPause) {
this.foundation.stop();
}
};
this.handleMouseLeave = () => {
const {
autoPlay
} = this.props;
if ((typeof autoPlay !== 'object' || autoPlay.hoverToPause) && !this.foundation.getIsControlledComponent()) {
this.foundation.handleAutoPlay();
}
};
this.onIndicatorChange = activeIndex => {
return this.foundation.onIndicatorChange(activeIndex);
};
this.getChildren = () => {
const {
children: originChildren
} = this.props;
return _react.Children.toArray(originChildren).filter(child => {
return /*#__PURE__*/_react.default.isValidElement(child);
});
};
this.getValidIndex = activeIndex => {
return this.foundation.getValidIndex(activeIndex);
};
this.renderChildren = () => {
const {
speed,
animation
} = this.props;
const {
activeIndex,
preIndex,
isInit
} = this.state;
const children = this.getChildren();
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children.map((child, index) => {
const isCurrent = index === activeIndex;
const isPrev = index === this.getValidIndex(activeIndex - 1);
const isNext = index === this.getValidIndex(activeIndex + 1);
const animateStyle = {
transitionTimingFunction: 'ease',
transitionDuration: `${speed}ms`,
animationTimingFunction: 'ease',
animationDuration: `${speed}ms`
};
return /*#__PURE__*/_react.default.cloneElement(child, {
style: Object.assign(Object.assign({}, child.props.style), animateStyle),
className: (0, _classnames.default)(child.props.className, {
[`${_constants.cssClasses.CAROUSEL_CONTENT}-item-prev`]: isPrev,
[`${_constants.cssClasses.CAROUSEL_CONTENT}-item-next`]: isNext,
[`${_constants.cssClasses.CAROUSEL_CONTENT}-item-current`]: isCurrent,
[`${_constants.cssClasses.CAROUSEL_CONTENT}-item`]: true,
[`${_constants.cssClasses.CAROUSEL_CONTENT}-item-active`]: isCurrent,
[`${_constants.cssClasses.CAROUSEL_CONTENT}-item-slide-in`]: animation === 'slide' && !isInit && isCurrent,
[`${_constants.cssClasses.CAROUSEL_CONTENT}-item-slide-out`]: animation === 'slide' && !isInit && index === preIndex
})
});
}));
};
this.renderIndicator = () => {
const {
activeIndex
} = this.state;
const {
showIndicator,
indicatorType,
theme,
indicatorPosition,
indicatorSize,
trigger
} = this.props;
const carouselIndicatorCls = (0, _classnames.default)({
[_constants.cssClasses.CAROUSEL_INDICATOR]: true
});
const children = this.getChildren();
if (showIndicator && children.length > 1) {
return /*#__PURE__*/_react.default.createElement("div", {
className: carouselIndicatorCls
}, /*#__PURE__*/_react.default.createElement(_CarouselIndicator.default, {
type: indicatorType,
total: children.length,
activeIndex: activeIndex,
position: indicatorPosition,
trigger: trigger,
size: indicatorSize,
theme: theme,
onIndicatorChange: this.onIndicatorChange
}));
}
return null;
};
this.renderArrow = () => {
const {
showArrow,
arrowType,
theme,
arrowProps
} = this.props;
const children = this.getChildren();
if (showArrow && children.length > 1) {
return /*#__PURE__*/_react.default.createElement(_CarouselArrow.default, {
type: arrowType,
theme: theme,
prev: this.prev,
next: this.next,
arrowProps: arrowProps
});
}
return null;
};
this.foundation = new _foundation.default(this.adapter);
const defaultActiveIndex = this.foundation.getDefaultActiveIndex();
this.state = {
activeIndex: defaultActiveIndex,
preIndex: defaultActiveIndex,
isReverse: false,
isInit: true
};
}
get adapter() {
return Object.assign(Object.assign({}, super.adapter), {
notifyChange: (activeIndex, preIndex) => {
this.props.onChange(activeIndex, preIndex);
},
setNewActiveIndex: activeIndex => {
this.setState({
activeIndex
});
},
setPreActiveIndex: preIndex => {
this.setState({
preIndex
});
},
setIsReverse: isReverse => {
this.setState({
isReverse
});
},
setIsInit: isInit => {
this.setState({
isInit
});
},
getChildren: () => {
return this.getChildren();
}
});
}
static getDerivedStateFromProps(props, state) {
const states = {};
if (!(0, _isNullOrUndefined.default)(props.activeIndex) && props.activeIndex !== state.activeIndex) {
states.activeIndex = props.activeIndex;
}
return states;
}
componentDidMount() {
this.handleAutoPlay();
}
componentWillUnmount() {
this.foundation.destroy();
}
render() {
const {
animation,
className,
style,
slideDirection
} = this.props;
const {
isReverse
} = this.state;
const carouselWrapperCls = (0, _classnames.default)(className, {
[_constants.cssClasses.CAROUSEL]: true
});
return /*#__PURE__*/_react.default.createElement("div", Object.assign({
// role='listbox'
// tabIndex={0}
className: carouselWrapperCls,
style: style,
onMouseEnter: (0, _debounce2.default)(this.handleMouseEnter, 400),
onMouseLeave: (0, _debounce2.default)(this.handleMouseLeave, 400)
}, this.getDataAttr(this.props)), /*#__PURE__*/_react.default.createElement("div", {
className: (0, _classnames.default)([`${_constants.cssClasses.CAROUSEL_CONTENT}-${animation}`], {
[`${_constants.cssClasses.CAROUSEL_CONTENT}`]: true,
[`${_constants.cssClasses.CAROUSEL_CONTENT}-reverse`]: slideDirection === 'left' ? isReverse : !isReverse
}),
"x-semi-prop": "children"
}, this.renderChildren()), this.renderIndicator(), this.renderArrow());
}
}
Carousel.propTypes = {
activeIndex: _propTypes.default.number,
animation: _propTypes.default.oneOf(_constants.strings.ANIMATION_MAP),
arrowProps: _propTypes.default.object,
autoPlay: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.object]),
className: _propTypes.default.string,
defaultActiveIndex: _propTypes.default.number,
indicatorPosition: _propTypes.default.oneOf(_constants.strings.POSITION_MAP),
indicatorSize: _propTypes.default.oneOf(_constants.strings.SIZE),
indicatorType: _propTypes.default.oneOf(_constants.strings.TYPE_MAP),
theme: _propTypes.default.oneOf(_constants.strings.THEME_MAP),
onChange: _propTypes.default.func,
arrowType: _propTypes.default.oneOf(_constants.strings.ARROW_MAP),
showArrow: _propTypes.default.bool,
showIndicator: _propTypes.default.bool,
slideDirection: _propTypes.default.oneOf(_constants.strings.DIRECTION),
speed: _propTypes.default.number,
style: _propTypes.default.object,
trigger: _propTypes.default.oneOf(_constants.strings.TRIGGER)
};
Carousel.defaultProps = {
children: [],
animation: 'slide',
autoPlay: true,
arrowType: 'always',
defaultActiveIndex: _constants.numbers.DEFAULT_ACTIVE_INDEX,
indicatorPosition: 'center',
indicatorSize: 'small',
indicatorType: 'dot',
theme: 'light',
onChange: () => undefined,
showArrow: true,
showIndicator: true,
slideDirection: 'left',
speed: _constants.numbers.DEFAULT_SPEED,
trigger: 'click'
};
var _default = exports.default = Carousel;