@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
507 lines (506 loc) • 22.6 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "NoticeBar", {
enumerable: true,
get: function() {
return NoticeBar;
}
});
var _interop_require_default = require("@swc/helpers/_/_interop_require_default");
var _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
var _async_to_generator = require("@swc/helpers/_/_async_to_generator");
var _define_property = require("@swc/helpers/_/_define_property");
var _object_spread = require("@swc/helpers/_/_object_spread");
var _object_spread_props = require("@swc/helpers/_/_object_spread_props");
var _sliced_to_array = require("@swc/helpers/_/_sliced_to_array");
var _to_consumable_array = require("@swc/helpers/_/_to_consumable_array");
var _ts_generator = require("@swc/helpers/_/_ts_generator");
var _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
var _components = require("@tarojs/components");
var _iconsreacttaro = require("@nutui/icons-react-taro");
var _classnames = /*#__PURE__*/ _interop_require_default._(require("classnames"));
var _getrect = require("../../utils/taro/get-rect");
var _typings = require("../../utils/typings");
var _index = require("../configprovider/index");
var defaultProps = (0, _object_spread_props._)((0, _object_spread._)({}, _typings.ComponentDefaults), {
align: 'left',
direction: 'horizontal',
list: [],
duration: 1000,
height: 40,
content: '',
closeable: false,
wrap: false,
leftIcon: /*#__PURE__*/ _react.default.createElement(_iconsreacttaro.Notice, {
size: 16
}),
rightIcon: null,
right: null,
delay: 1,
scrollable: null,
speed: 50
});
var NoticeBar = function NoticeBar(props) {
var rtl = (0, _index.useRtl)();
var _$_object_spread = (0, _object_spread._)({}, defaultProps, props), children = _$_object_spread.children, className = _$_object_spread.className, style = _$_object_spread.style, align = _$_object_spread.align, direction = _$_object_spread.direction, list = _$_object_spread.list, duration = _$_object_spread.duration, height = _$_object_spread.height, content = _$_object_spread.content, closeable = _$_object_spread.closeable, wrap = _$_object_spread.wrap, leftIcon = _$_object_spread.leftIcon, rightIcon = _$_object_spread.rightIcon, right = _$_object_spread.right, delay = _$_object_spread.delay, scrollable = _$_object_spread.scrollable, speed = _$_object_spread.speed, close = _$_object_spread.close, click = _$_object_spread.click, onClose = _$_object_spread.onClose, onClick = _$_object_spread.onClick, onItemClick = _$_object_spread.onItemClick;
var classPrefix = 'nut-noticebar';
var wrapRef = (0, _react.useRef)(null);
var contentRef = (0, _react.useRef)(null);
var _useState = (0, _sliced_to_array._)((0, _react.useState)(true), 2), showNoticeBar = _useState[0], SetShowNoticeBar = _useState[1];
var scrollList = (0, _react.useRef)([]);
var _useState1 = (0, _sliced_to_array._)((0, _react.useState)(0), 2), wrapWidth = _useState1[0], SetWrapWidth = _useState1[1];
var _useState2 = (0, _sliced_to_array._)((0, _react.useState)(true), 2), firstRound = _useState2[0], SetFirstRound = _useState2[1];
var _useState3 = (0, _sliced_to_array._)((0, _react.useState)(0), 2), animationDuration = _useState3[0], SetAnimationDuration = _useState3[1];
var _useState4 = (0, _sliced_to_array._)((0, _react.useState)(0), 2), offsetWidth = _useState4[0], SetOffsetW = _useState4[1];
var _useState5 = (0, _sliced_to_array._)((0, _react.useState)(''), 2), animationClass = _useState5[0], SetAnimationClass = _useState5[1];
var _useState6 = (0, _sliced_to_array._)((0, _react.useState)(false), 2), animate = _useState6[0], SetAnimate = _useState6[1];
var _useState7 = (0, _sliced_to_array._)((0, _react.useState)(0), 2), timer = _useState7[0], SetTimer = _useState7[1];
var _useState8 = (0, _sliced_to_array._)((0, _react.useState)(null), 2), isCanScroll = _useState8[0], SetIsCanScroll = _useState8[1];
var isVertical = direction === 'vertical';
var _useState9 = (0, _sliced_to_array._)((0, _react.useState)(null), 2), rect = _useState9[0], setRect = _useState9[1];
var activeRef = (0, _react.useRef)(0);
var _useState10 = (0, _sliced_to_array._)((0, _react.useState)(false), 2), ready = _useState10[0], setReady = _useState10[1];
var container = (0, _react.useRef)(null);
var _useState11 = (0, _sliced_to_array._)((0, _react.useState)(false), 2), isContainerReady = _useState11[0], setIsContainerReady = _useState11[1];
var innerRef = (0, _react.useRef)(null);
var swiperRef = (0, _react.useRef)({
moving: false,
autoplayTimer: null,
width: 0,
height: 0,
offset: 0,
size: 0
});
var _useState12 = (0, _sliced_to_array._)((0, _react.useState)([]), 2), childOffset = _useState12[0], setChildOffset = _useState12[1];
var _useState13 = (0, _sliced_to_array._)((0, _react.useState)(0), 2), offset = _useState13[0], setOffset = _useState13[1];
var _useMemo = (0, _react.useMemo)(function() {
var childCount = 0;
var childs = _react.default.Children.map(children, function(child) {
if (!/*#__PURE__*/ _react.default.isValidElement(child)) return null;
childCount++;
return child;
});
return {
childs: childs,
childCount: childCount
};
}, [
children
]), childs = _useMemo.childs, childCount = _useMemo.childCount;
// 滚动消息的总高度
var trackSize = childCount * Number(height);
// 设置最小偏移量(最后一条的偏移位置)
var minOffset = function() {
if (rect) {
var base = isVertical ? rect.height : rect.width;
return base - Number(height) * childCount;
}
return 0;
}();
(0, _react.useEffect)(function() {
if (isVertical) {
if (children) {
scrollList.current = [].concat(childs);
} else {
scrollList.current = [].concat(list);
startRollEasy();
}
} else {
initScrollWrap();
}
return function() {
// 销毁事件
clearInterval(timer);
};
}, [
childs
]);
(0, _react.useEffect)(function() {
initScrollWrap();
}, [
content
]);
(0, _react.useEffect)(function() {
if (list && list.length) {
scrollList.current = [].concat(list);
}
}, [
list
]);
var initScrollWrap = function initScrollWrap() {
if (showNoticeBar === false) {
return;
}
setTimeout(function() {
return (0, _async_to_generator._)(function() {
var warpRes, contentRes, wrapW, offsetW, canScroll;
return (0, _ts_generator._)(this, function(_state) {
switch(_state.label){
case 0:
if (!wrapRef.current || !contentRef.current) {
return [
2
];
}
return [
4,
(0, _getrect.getRectInMultiPlatform)(wrapRef.current)
];
case 1:
warpRes = _state.sent();
return [
4,
(0, _getrect.getRectInMultiPlatform)(contentRef.current)
];
case 2:
contentRes = _state.sent();
if (!warpRes || !contentRes) return [
2
];
wrapW = warpRes.width;
offsetW = contentRes.width;
canScroll = align === 'left' && scrollable == null ? offsetW > wrapW : scrollable;
SetIsCanScroll(canScroll);
if (canScroll) {
SetWrapWidth(wrapW);
SetOffsetW(offsetW);
SetAnimationDuration(offsetW / speed);
SetAnimationClass('play');
} else {
SetAnimationClass('');
}
return [
2
];
}
});
})();
}, 0);
};
var handleClick = function handleClick(event) {
click && click(event);
onClick && onClick(event);
};
var onClickIcon = function onClickIcon(event) {
event.stopPropagation();
SetShowNoticeBar(!closeable);
close && close(event);
onClose && onClose(event);
};
var onAnimationEnd = function onAnimationEnd() {
SetFirstRound(false);
setTimeout(function() {
SetAnimationDuration((offsetWidth + wrapWidth) / speed);
SetAnimationClass('play-infinite');
}, 0);
};
var startRollEasy = function startRollEasy() {
showhorseLamp();
var time = height / speed / 4 < 1 ? Number((height / speed / 4).toFixed(1)) * 1000 : ~~(height / speed / 4) * 1000;
var timerCurr = window.setInterval(showhorseLamp, time + Number(duration));
SetTimer(timerCurr);
};
var showhorseLamp = function showhorseLamp() {
SetAnimate(true);
var time = height / speed / 4 < 1 ? Number((height / speed / 4).toFixed(1)) * 1000 : ~~(height / speed / 4) * 1000;
setTimeout(function() {
scrollList.current.push(scrollList.current[0]);
scrollList.current.shift();
SetAnimate(false);
}, time);
};
// 点击滚动单元
var handleClickIcon = function handleClickIcon(event) {
event.stopPropagation();
SetShowNoticeBar(!closeable);
close && close(event);
onClose && onClose(event);
};
var isEllipsis = function isEllipsis() {
if (isCanScroll == null && align === 'left') {
return wrap;
}
return !isCanScroll && !wrap;
};
var contentStyle = {
animationDelay: "".concat(firstRound ? delay : 0, "s"),
animationDuration: "".concat(animationDuration, "s"),
transform: "translateX(".concat(firstRound ? 0 : "".concat(rtl ? -wrapWidth : wrapWidth, "px"), ")")
};
var barStyle = {
height: isVertical ? "".concat(height, "px") : ''
};
var duringTime = height / speed / 4 < 1 ? Number((height / speed / 4).toFixed(1)) : ~~(height / speed / 4);
var noDuring = height / speed < 1 ? (height / speed).toFixed(1) : ~~(height / speed);
var horseLampStyle = {
transition: animate ? "all ".concat(duringTime === 0 ? noDuring : duringTime, "s") : '',
marginTop: animate ? "-".concat(height, "px") : ''
};
// 垂直自定义滚动方式
var init = function init() {
var activeIndex = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
if (!(container === null || container === void 0 ? void 0 : container.current)) return;
setTimeout(function() {
return (0, _async_to_generator._)(function() {
var rects, _active, _height, targetOffset;
return (0, _ts_generator._)(this, function(_state) {
switch(_state.label){
case 0:
return [
4,
(0, _getrect.getRectInMultiPlatform)(container === null || container === void 0 ? void 0 : container.current)
];
case 1:
rects = _state.sent();
_active = Math.max(Math.min(childCount - 1, activeIndex), 0);
_height = rects === null || rects === void 0 ? void 0 : rects.height;
trackSize = childCount * Number(_height);
targetOffset = getOffset(_active);
activeRef.current = _active;
setRect(rects);
setOffset(targetOffset);
setChildOffset(new Array(childCount).fill(0));
// 关闭动画并立即设置样式
swiperRef.current.moving = true;
setStyle(targetOffset, rects);
swiperRef.current.moving = false;
setReady(true);
return [
2
];
}
});
})();
}, 0);
};
(0, _react.useEffect)(function() {
if (ready) {
autoplay();
}
return function() {
setReady(false);
};
}, [
ready
]);
(0, _react.useEffect)(function() {
if (isVertical && children && isContainerReady) {
stopAutoPlay();
setReady(false);
init();
}
}, [
children,
isContainerReady
]);
// 清除定时器
var stopAutoPlay = function stopAutoPlay() {
clearTimeout(swiperRef.current.autoplayTimer);
swiperRef.current.moving = false;
swiperRef.current.autoplayTimer = null;
};
// 定时轮播
var autoplay = function autoplay1() {
if (childCount <= 1) return;
stopAutoPlay();
swiperRef.current.autoplayTimer = setTimeout(function() {
next();
autoplay();
}, Number(duration) + 100 * speed);
};
// 切换方法
var move = function move(param) {
var _param_pace = param.pace, pace = _param_pace === void 0 ? 0 : _param_pace, _param_offset = param.offset, offset = _param_offset === void 0 ? 0 : _param_offset;
if (childCount <= 1) return;
var targetActive = getActive(pace);
// 父级容器偏移量
var targetOffset = getOffset(targetActive, offset);
// 循环滚动,调整开头结尾图片位置
setChildOffset(function(prevChildOffset) {
var newChildOffset = (0, _to_consumable_array._)(prevChildOffset);
if (Array.isArray(children) && children[0] && targetOffset !== minOffset) {
var rightBound = targetOffset < minOffset;
newChildOffset[0] = rightBound ? trackSize : 0;
}
if (Array.isArray(children) && children[childCount - 1] && targetOffset !== 0) {
var leftBound = targetOffset > 0;
newChildOffset[childCount - 1] = leftBound ? -trackSize : 0;
}
return newChildOffset;
});
activeRef.current = targetActive;
setOffset(targetOffset);
setStyle(targetOffset);
};
// 下一页
var next = function next() {
resetPosition();
requestFrame(function() {
requestFrame(function() {
swiperRef.current.moving = false;
move({
pace: 1
});
});
});
};
var handleItemClick = function handleItemClick(event, value) {
onItemClick && onItemClick(event, value);
};
var setStyle = function setStyle() {
var moveOffset = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : offset, currentRect = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : rect;
var target = innerRef.current;
if (!target) {
return;
}
var _offset = 0;
var containerHeight = (currentRect === null || currentRect === void 0 ? void 0 : currentRect.height) || height;
var val = containerHeight - Number(height);
_offset = moveOffset + Number(activeRef.current === childCount - 1 && val / 2);
target.style.transitionDuration = "".concat(swiperRef.current.moving ? 0 : duration, "ms");
target.style.height = "".concat(Number(height) * (childCount + 1), "px");
target.style.transform = "translate3D(0,".concat(_offset, "px,0)");
};
// 无缝滚动第一个元素位移控制
var itemStyle = function itemStyle(index) {
var style = {};
if (height) {
style.height = "".concat(height, "px");
style.lineHeight = "".concat(height, "px");
}
var offset = childOffset[index];
if (offset) {
style.transform = "translate3D(0,".concat(offset, "px,0)");
}
return style;
};
// 确定当前active 元素
var getActive = function getActive(pace) {
var currentActive = activeRef.current;
if (pace) {
var _active = currentActive + pace;
return range(_active, -1, childCount);
}
return currentActive;
};
// 计算位移
var getOffset = function getOffset(active) {
var offset = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0;
var currentPosition = active * Number(height);
var targetOffset = offset - currentPosition;
return targetOffset;
};
// 浏览器 帧 事件
var requestFrame = function requestFrame(fn) {
window.requestAnimationFrame.call(window, fn);
};
// 取值 方法
var range = function range(num, min, max) {
return Math.min(Math.max(num, min), max);
};
// 重置首尾位置信息
var resetPosition = function resetPosition() {
var currentActive = activeRef.current;
swiperRef.current.moving = true;
if (currentActive <= -1) {
move({
pace: childCount
});
}
if (currentActive >= childCount) {
move({
pace: -childCount
});
}
};
var _obj;
var noticebarClass = (0, _classnames.default)((_obj = {}, (0, _define_property._)(_obj, "".concat(classPrefix, "-box"), true), (0, _define_property._)(_obj, "".concat(classPrefix, "-box-wrapable"), wrap), (0, _define_property._)(_obj, "".concat(classPrefix, "-box-").concat(align), true), _obj));
var cls = (0, _classnames.default)(classPrefix, className);
(0, _react.useEffect)(function() {
return function() {
stopAutoPlay();
};
}, []);
var hasVerticalContent = (0, _react.useMemo)(function() {
if (!isVertical) return false;
if (children) return (childs === null || childs === void 0 ? void 0 : childs.length) > 0;
return (list === null || list === void 0 ? void 0 : list.length) > 0;
}, [
isVertical,
childs,
list,
children
]);
var containerRefCallback = (0, _react.useCallback)(function(ref) {
container.current = ref;
setIsContainerReady(true);
}, []);
return /*#__PURE__*/ _react.default.createElement(_components.View, {
className: cls,
style: style
}, showNoticeBar && direction === 'horizontal' ? /*#__PURE__*/ _react.default.createElement(_components.View, {
className: noticebarClass,
style: barStyle,
onClick: handleClick
}, leftIcon ? /*#__PURE__*/ _react.default.createElement(_components.View, {
className: "nut-noticebar-box-left-icon"
}, leftIcon) : null, /*#__PURE__*/ _react.default.createElement(_components.View, {
ref: wrapRef,
className: "nut-noticebar-box-wrap"
}, /*#__PURE__*/ _react.default.createElement(_components.View, {
ref: contentRef,
className: "nut-noticebar-box-wrap-content ".concat(animationClass, " ").concat(isEllipsis() ? 'nut-ellipsis' : ''),
style: contentStyle,
onAnimationEnd: onAnimationEnd
}, children, content)), right ? /*#__PURE__*/ _react.default.createElement(_components.View, {
className: "nut-noticebar-box-right"
}, right) : null, closeable || rightIcon ? /*#__PURE__*/ _react.default.createElement(_components.View, {
className: "nut-noticebar-box-right-icon",
onClick: onClickIcon
}, rightIcon || /*#__PURE__*/ _react.default.createElement(_iconsreacttaro.Close, {
size: 12
})) : null) : null, showNoticeBar && hasVerticalContent && isVertical ? /*#__PURE__*/ _react.default.createElement(_components.View, {
className: "nut-noticebar-vertical",
style: barStyle,
ref: containerRefCallback,
onClick: handleClick
}, leftIcon ? /*#__PURE__*/ _react.default.createElement(_components.View, {
className: "nut-noticebar-box-left-icon"
}, leftIcon) : null, children ? /*#__PURE__*/ _react.default.createElement(_components.View, {
className: "nut-noticebar-box-wrap",
ref: innerRef
}, scrollList.current.map(function(item, index) {
return /*#__PURE__*/ _react.default.createElement(_components.View, {
style: itemStyle(index),
key: index,
onClick: function onClick(e) {
handleItemClick(e, item);
}
}, item);
})) : /*#__PURE__*/ _react.default.createElement(_components.View, {
className: "nut-noticebar-box-horseLamp-list",
style: horseLampStyle
}, scrollList.current.map(function(item, index) {
return(// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
/*#__PURE__*/ /*#__PURE__*/ _react.default.createElement(_components.View, {
className: "nut-noticebar-box-horseLamp-list-item",
style: {
height: height
},
key: index,
onClick: function onClick(e) {
handleItemClick(e, item);
}
}, item));
})), /*#__PURE__*/ _react.default.createElement(_components.View, {
className: "nut-noticebar-box-right-icon",
onClick: function onClick(e) {
handleClickIcon(e);
}
}, rightIcon || (closeable ? /*#__PURE__*/ _react.default.createElement(_iconsreacttaro.Close, {
size: 12
}) : null))) : null);
};
NoticeBar.displayName = 'NutNoticeBar';
;