@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
271 lines (270 loc) • 11.4 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "Swiper", {
enumerable: true,
get: function() {
return Swiper;
}
});
var _interop_require_default = require("@swc/helpers/_/_interop_require_default");
var _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
var _define_property = require("@swc/helpers/_/_define_property");
var _object_spread = require("@swc/helpers/_/_object_spread");
var _sliced_to_array = require("@swc/helpers/_/_sliced_to_array");
var _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
var _react1 = require("@use-gesture/react");
var _web = require("@react-spring/web");
var _classnames = /*#__PURE__*/ _interop_require_default._(require("classnames"));
var _indicator = /*#__PURE__*/ _interop_require_default._(require("../indicator"));
var _userefstate = require("../../hooks/use-ref-state");
var _default = require("./effects/default");
var _focus = require("./effects/focus");
var defaultProps = {
direction: 'horizontal',
indicator: false,
loop: false,
duration: 3000,
autoPlay: false,
defaultValue: 0,
touchable: true,
effect: undefined
};
var Swiper = /*#__PURE__*/ _react.default.forwardRef(function(props, ref) {
var boundIndex = function boundIndex(current) {
var min = 0;
var max = count - 1;
if (current === max && !loop && props.slideSize) {
var slideSize = props.slideSize;
var swiperSize = getSwiperSize();
var ratio = (swiperSize - slideSize) / slideSize;
return bound(current, min, max - ratio);
}
return current;
};
var classPrefix = 'nut-swiper';
var _$_object_spread = (0, _object_spread._)({}, defaultProps, props), children = _$_object_spread.children, direction = _$_object_spread.direction, indicator = _$_object_spread.indicator, loop = _$_object_spread.loop, effect = _$_object_spread.effect, autoPlay = _$_object_spread.autoPlay, touchable = _$_object_spread.touchable, defaultValue = _$_object_spread.defaultValue, duration = _$_object_spread.duration, style = _$_object_spread.style, className = _$_object_spread.className;
var isVertical = direction === 'vertical';
var count = (0, _react.useMemo)(function() {
var c = 0;
_react.default.Children.map(children, function(child, index) {
c += 1;
});
return c;
}, [
children
]);
var getSlideSize = function getSlideSize() {
if (props.slideSize) return props.slideSize;
if (stageRef.current) {
if (isVertical) return stageRef.current.offsetHeight;
return stageRef.current.offsetWidth;
}
return 0;
};
var getSwiperSize = function getSwiperSize() {
if (swiperRef.current) {
if (isVertical) return swiperRef.current.offsetHeight;
return swiperRef.current.offsetWidth;
}
return 0;
};
var bound = function bound(v, min, max) {
if (min !== undefined) {
v = Math.max(v, min);
}
if (max !== undefined) {
v = Math.min(v, max);
}
return v;
};
var timeoutRef = (0, _react.useRef)(null);
var _useState = (0, _sliced_to_array._)((0, _react.useState)(false), 2), dragging = _useState[0], setDragging = _useState[1];
var _useRefState = (0, _sliced_to_array._)((0, _userefstate.useRefState)(defaultValue), 2), current = _useRefState[0], setCurrent = _useRefState[1];
var stageRef = (0, _react.useRef)(null);
var swiperRef = (0, _react.useRef)(null);
var _useSpring = (0, _sliced_to_array._)((0, _web.useSpring)(function() {
return {
x: !isVertical ? current.current * 100 * -1 : 0,
y: isVertical ? current.current * 100 * -1 : 0,
s: 0,
reset: function reset() {},
config: {
tension: 200,
friction: 30
}
};
}), 2), springs = _useSpring[0], api = _useSpring[1];
(0, _react.useEffect)(function() {
var _obj;
api.start((_obj = {}, (0, _define_property._)(_obj, isVertical ? 'y' : 'x', boundIndex(current.current) * -1 * 100), (0, _define_property._)(_obj, "immediate", true), _obj));
}, [
swiperRef.current
]);
var swiperDirection = (0, _react.useRef)(1);
var _useList = (0, _sliced_to_array._)((0, _focus.useList)(effect, count, current), 2), transforms = _useList[0], setTransforms = _useList[1];
// 自动播放
var runTimeSwiper = function runTimeSwiper1() {
var durationNumber = typeof duration === 'string' ? parseInt(duration) : duration;
var d = typeof autoPlay === 'number' ? autoPlay : durationNumber;
timeoutRef.current = window.setTimeout(function() {
next();
runTimeSwiper();
}, d);
};
(0, _react.useEffect)(function() {
if (!autoPlay || dragging) return;
runTimeSwiper();
return function() {
if (timeoutRef.current) window.clearTimeout(timeoutRef.current);
};
}, [
autoPlay,
duration,
dragging,
count
]);
var to = function to(index) {
var immediate = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
var _props_onChange;
var targetIndex = bound(index, 0, count - 1);
if (loop) {
var cycleIndex = index % count;
targetIndex = cycleIndex < 0 ? cycleIndex + count : cycleIndex;
}
setCurrent(targetIndex);
(_props_onChange = props.onChange) === null || _props_onChange === void 0 ? void 0 : _props_onChange.call(props, targetIndex);
if (effect) {
(0, _focus.updateTransform)(transforms, setTransforms, effect, targetIndex);
}
var _obj;
api.start((_obj = {}, (0, _define_property._)(_obj, isVertical ? 'y' : 'x', (loop ? -index : boundIndex(targetIndex) * -1) * 100), (0, _define_property._)(_obj, "s", 0), (0, _define_property._)(_obj, "immediate", immediate), _obj));
};
var getSpringsAxis = function getSpringsAxis() {
return springs[isVertical ? 'y' : 'x'];
};
var next = function next() {
to(Math.round(-getSpringsAxis().get() / 100) + 1);
};
var prev = function prev() {
to(Math.round(-getSpringsAxis().get() / 100) - 1);
};
_react.default.useImperativeHandle(ref, function() {
return {
to: to,
next: next,
prev: prev
};
});
var bind = (0, _react1.useDrag)(function(state) {
var axis = Number(isVertical);
var slideSize = getSlideSize();
var offset = state.offset[axis];
setDragging(!!state.dragging);
var distance = state.distance[axis];
swiperDirection.current = state.direction[axis];
if (state.last) {
// 计算位置
var swipeDirection = state.direction[axis];
var velocity = state.velocity[axis];
var minIndex = Math.floor(offset / slideSize);
var maxIndex = minIndex + 1;
var index = Math.round((offset + velocity * 2000 * swipeDirection) / slideSize);
to(bound(index, minIndex, maxIndex));
} else {
var _obj;
// 实时移动,换算百分比
api.start((_obj = {}, (0, _define_property._)(_obj, isVertical ? 'y' : 'x', -(offset / slideSize * 100)), (0, _define_property._)(_obj, "s", distance / slideSize), (0, _define_property._)(_obj, "immediate", true), _obj));
}
}, {
enabled: touchable,
transform: function transform(param) {
var _param = (0, _sliced_to_array._)(param, 2), x = _param[0], y = _param[1];
return [
-x,
-y
];
},
from: function from() {
// 由百分比转换到像素
var slideSize = getSlideSize();
var x = springs.x.get() / 100 * slideSize;
var y = springs.y.get() / 100 * slideSize;
return [
-x,
-y
];
},
bounds: function bounds() {
if (loop) return {};
var slideSize = getSlideSize();
if (isVertical) {
return {
top: 0,
bottom: (count - 1) * slideSize
};
}
return {
left: 0,
right: (count - 1) * slideSize
};
},
rubberband: true,
triggerAllEvents: true,
preventScroll: isVertical,
axis: isVertical ? 'y' : 'x',
pointer: {
touch: true
}
});
var renderIndicator = function renderIndicator() {
if (/*#__PURE__*/ _react.default.isValidElement(indicator)) return indicator;
if (!indicator) return null;
var _obj;
return /*#__PURE__*/ _react.default.createElement("div", {
className: (0, _classnames.default)((_obj = {}, (0, _define_property._)(_obj, "".concat(classPrefix, "-indicator"), true), (0, _define_property._)(_obj, "".concat(classPrefix, "-indicator-vertical"), isVertical), (0, _define_property._)(_obj, "".concat(classPrefix, "-indicator-horizontal"), !isVertical), _obj))
}, /*#__PURE__*/ _react.default.createElement(_indicator.default, {
current: (0, _userefstate.getRefValue)(current),
total: count,
direction: direction
}));
};
var renderEffect = function renderEffect() {
if (!effect) return (0, _default.defaultEffect)({
children: children,
getSpringsAxis: getSpringsAxis,
loop: loop,
count: count,
isVertical: isVertical
});
if (effect && effect.name === 'focus') {
return (0, _focus.focusEffect)({
children: children,
springs: springs,
loop: loop,
count: count,
isVertical: isVertical,
effect: effect,
current: current,
swiperDirection: swiperDirection,
dragging: dragging,
transforms: transforms
});
}
};
var renderSlides = function renderSlides() {
var _obj;
return /*#__PURE__*/ _react.default.createElement("div", {
ref: stageRef,
className: (0, _classnames.default)("".concat(classPrefix, "-inner"), (_obj = {}, (0, _define_property._)(_obj, "".concat(classPrefix, "-inner-vertical"), isVertical), (0, _define_property._)(_obj, "".concat(classPrefix, "-inner-horizontal"), !isVertical), _obj)),
style: (0, _object_spread._)({}, props.slideSize ? (0, _define_property._)({}, isVertical ? 'height' : 'width', "".concat(props.slideSize, "px")) : {})
}, renderEffect());
};
return /*#__PURE__*/ _react.default.createElement("div", (0, _object_spread._)({
className: (0, _classnames.default)(classPrefix, "".concat(classPrefix, "-canmove-").concat(direction), className),
style: style,
ref: swiperRef
}, bind()), renderSlides(), renderIndicator());
});
Swiper.displayName = 'NutSwiper';
;