UNPKG

@nutui/nutui-react-taro

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

507 lines (506 loc) 22.6 kB
"use strict"; 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';