UNPKG

@antmjs/vantui

Version:

一套适用于Taro3及React的vantui组件库

301 lines (299 loc) 14.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.IndexBar = IndexBar; exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _components = require("@tarojs/components"); var _react = require("react"); var _taro = require("@tarojs/taro"); var _toArray = _interopRequireDefault(require("rc-util/lib/Children/toArray")); var utils = _interopRequireWildcard(require("../wxs/utils")); var _utils2 = require("../common/utils"); var _color = require("../common/color"); var _defaultProps = require("../default-props"); var _pageScroll = require("./../mixins/page-scroll"); var _jsxRuntime = require("react/jsx-runtime"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function IndexBar(props) { var _useState = (0, _react.useState)((0, _defaultProps.get)().IndexBar), _useState2 = (0, _slicedToArray2.default)(_useState, 1), d = _useState2[0]; var _d$props = _objectSpread(_objectSpread({}, d), props), _d$props$sticky = _d$props.sticky, sticky = _d$props$sticky === void 0 ? true : _d$props$sticky, _d$props$zIndex = _d$props.zIndex, zIndex = _d$props$zIndex === void 0 ? 1 : _d$props$zIndex, _d$props$highlightCol = _d$props.highlightColor, highlightColor = _d$props$highlightCol === void 0 ? _color.GREEN : _d$props$highlightCol, _d$props$stickyOffset = _d$props.stickyOffsetTop, stickyOffsetTop = _d$props$stickyOffset === void 0 ? 0 : _d$props$stickyOffset, _d$props$indexList = _d$props.indexList, indexList = _d$props$indexList === void 0 ? genIndexList() : _d$props$indexList, onSelect = _d$props.onSelect, children = _d$props.children, className = _d$props.className, style = _d$props.style, _d$props$rectWrapper = _d$props.rectWrapper, rectWrapper = _d$props$rectWrapper === void 0 ? '' : _d$props$rectWrapper; var _useState3 = (0, _react.useState)(null), _useState4 = (0, _slicedToArray2.default)(_useState3, 2), activeAnchorIndex = _useState4[0], setActiveAnchorIndex = _useState4[1]; var _useState5 = (0, _react.useState)([]), _useState6 = (0, _slicedToArray2.default)(_useState5, 2), changeData = _useState6[0], setChangeData = _useState6[1]; var timerRef = (0, _react.useRef)(null); var scrollTopRef = (0, _react.useRef)(0); var sidebarRef = (0, _react.useRef)(null); var scrollToAnchorIndexRef = (0, _react.useRef)(null); var rectRef = (0, _react.useRef)({}); var realAnchor = (0, _react.useRef)([]); var _children = (0, _react.useMemo)(function () { var anchorIndex = 0; return parseIndexAnchor(children).map(function (anchor, index) { var _anchor$node, _anchor$node$type; // index 可能没有 他会用到children if (((_anchor$node = anchor.node) === null || _anchor$node === void 0 ? void 0 : (_anchor$node$type = _anchor$node.type) === null || _anchor$node$type === void 0 ? void 0 : _anchor$node$type.displayName) === 'IndexAnchor') { var _realAnchor$current$a, _anchor$node2, _anchor$node2$props; realAnchor.current[anchorIndex] = _objectSpread(_objectSpread({}, (_realAnchor$current$a = realAnchor.current[anchorIndex]) !== null && _realAnchor$current$a !== void 0 ? _realAnchor$current$a : { top: 0, height: 0 }), {}, { childIndex: index, index: (_anchor$node2 = anchor.node) === null || _anchor$node2 === void 0 ? void 0 : (_anchor$node2$props = _anchor$node2.props) === null || _anchor$node2$props === void 0 ? void 0 : _anchor$node2$props.index }); anchorIndex += 1; } var data = changeData[index]; var defaultProps = { key: index, id: "index-bar-item_".concat(anchorIndex - 1) }; var props = data ? _objectSpread(_objectSpread({}, defaultProps), data) : defaultProps; return /*#__PURE__*/(0, _react.cloneElement)(anchor.node, props); }); }, [changeData, children]); // 应该在 子组件中调用 var _setAnchorsRect = (0, _react.useCallback)(function () { return (0, _utils2.getAllRect)(null, '.van-index-anchor-wrapper').then(function (rects) { realAnchor.current = rects.map(function (e, index) { var _realAnchor$current$i; return _objectSpread(_objectSpread({}, (_realAnchor$current$i = realAnchor.current[index]) !== null && _realAnchor$current$i !== void 0 ? _realAnchor$current$i : {}), {}, { top: e.top, height: e.height }); }); }); }, []); var _scrollIntoView = (0, _react.useCallback)(function (top) { (0, _taro.pageScrollTo)({ duration: 0, scrollTop: top - stickyOffsetTop }); }, [stickyOffsetTop]); var _setListRect = (0, _react.useCallback)(function () { return (0, _utils2.getRect)(null, '.van-index-bar', rectWrapper).then(function (rect) { if (!(0, _utils2.isDef)(rect)) { return; } rectRef.current = { height: rect.height, top: rect.top + scrollTopRef.current }; }); }, []); var _setSiderbarRect = (0, _react.useCallback)(function () { return (0, _utils2.getRect)(null, '.van-index-bar__sidebar', rectWrapper).then(function (res) { if (!(0, _utils2.isDef)(res)) { return; } sidebarRef.current = { height: res.height, top: res.top }; }); }, []); var _getActiveAnchorIndex = (0, _react.useCallback)(function () { var child = realAnchor.current; for (var i = child.length - 1; i >= 0; i--) { var _child; var rect = child[i]; if (!rect) continue; var preAnchorHeight = i > 0 ? (_child = child[i - 1]) === null || _child === void 0 ? void 0 : _child.height : 0; var reachTop = sticky ? preAnchorHeight + stickyOffsetTop : 0; if (reachTop + scrollTopRef.current >= rect.top) { return i; } } return -1; }, [sticky, stickyOffsetTop]); var _setRect = (0, _react.useCallback)(function () { return Promise.all([_setAnchorsRect(), _setListRect(), _setSiderbarRect()]); }, [_setAnchorsRect, _setListRect, _setSiderbarRect]); var _onScroll = (0, _react.useCallback)(function () { if (!(_children !== null && _children !== void 0 && _children.length)) { return; } var child = realAnchor.current; var active = _getActiveAnchorIndex(); setActiveAnchorIndex(active); var updateStyle = []; if (sticky) { var isActiveAnchorSticky = false; if (active !== -1) { var _child$active; isActiveAnchorSticky = (((_child$active = child[active]) === null || _child$active === void 0 ? void 0 : _child$active.top) || 0) <= stickyOffsetTop + scrollTopRef.current; } realAnchor.current.forEach(function (item, index) { if (index === active) { var wrapperStyle = ''; var anchorStyle = "\n color: ".concat(highlightColor, ";\n "); if (isActiveAnchorSticky) { wrapperStyle = "\n height: ".concat(item.height, "px;\n "); anchorStyle = "\n position: fixed;\n top: ".concat(stickyOffsetTop, "px;\n z-index: ").concat(zIndex, ";\n color: ").concat(highlightColor, ";\n "); } updateStyle[item.childIndex] = { active: true, anchorStyle: anchorStyle, wrapperStyle: wrapperStyle }; } else if (index === active - 1) { var _realAnchor$current; var currentAnchor = item; // 自己距离顶部 的位置 var currentOffsetTop = (currentAnchor === null || currentAnchor === void 0 ? void 0 : currentAnchor.top) || 0; var targetOffsetTop = index === _children.length - 1 ? rectRef.current.top : (_realAnchor$current = realAnchor.current[index + 1]) === null || _realAnchor$current === void 0 ? void 0 : _realAnchor$current.top; var parentOffsetHeight = targetOffsetTop - currentOffsetTop; var translateY = parentOffsetHeight - ((currentAnchor === null || currentAnchor === void 0 ? void 0 : currentAnchor.height) || 0); var _anchorStyle = "\n position: relative;\n transform: translate3d(0, ".concat(translateY, "px, 0);\n z-index: ").concat(zIndex, ";\n color: ").concat(highlightColor, ";\n "); updateStyle[item.childIndex] = { active: true, anchorStyle: _anchorStyle }; } else { updateStyle[item.childIndex] = { active: false, anchorStyle: '', wrapperStyle: '' }; } }); setChangeData(updateStyle); } }, [_children.length, _getActiveAnchorIndex, highlightColor, sticky, stickyOffsetTop, zIndex]); var _scrollToAnchor = (0, _react.useCallback)(function (index) { if (typeof index !== 'number' || scrollToAnchorIndexRef.current === index) { return; } scrollToAnchorIndexRef.current = index; var currentItem = realAnchor.current[index]; if (currentItem) { _scrollIntoView(currentItem.top); onSelect === null || onSelect === void 0 ? void 0 : onSelect({ detail: currentItem.index }); } }, [_scrollIntoView, onSelect]); var _onTouchMove = (0, _react.useCallback)(function (event) { event.stopPropagation(); event.preventDefault(); var sidebarLength = realAnchor.current.length || 0; var touch = event.touches[0]; var itemHeight = sidebarRef.current.height / sidebarLength; var index = Math.floor((touch.clientY - sidebarRef.current.top) / itemHeight); if (index < 0) { index = 0; } else if (index > sidebarLength - 1) { index = sidebarLength - 1; } _scrollToAnchor(index); }, [_scrollToAnchor]); var _onTouchStop = (0, _react.useCallback)(function () { scrollToAnchorIndexRef.current = null; }, []); var _updateData = (0, _react.useCallback)(function () { (0, _taro.nextTick)(function () { if (timerRef.current !== null) { clearTimeout(timerRef.current); } timerRef.current = setTimeout(function () { _setRect().then(function () { _onScroll(); }); }, 100); }); }, [_onScroll, _setRect]); var _onClick = (0, _react.useCallback)(function (event) { var targetIndex = Number(event.target.dataset.index); _scrollToAnchor(targetIndex); }, [_scrollToAnchor]); var scroller = (0, _react.useCallback)(function (event) { scrollTopRef.current = (event === null || event === void 0 ? void 0 : event.scrollTop) || 0; (0, _taro.nextTick)(function () { _onScroll(); }); }, [_onScroll]); (0, _pageScroll.usePageScroll)(scroller); (0, _react.useEffect)(function () { _updateData(); }, [_updateData]); return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.View, { className: "van-index-bar-wrapper", children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.View, { className: "van-index-bar ".concat(className || ''), style: utils.style([style]), children: [_children, /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.View // @ts-ignore , { catchMove: true, className: "van-index-bar__sidebar", onClick: _onClick, onTouchMove: _onTouchMove, onTouchEnd: _onTouchStop, onTouchCancel: _onTouchStop, children: indexList.map(function (item, index) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.View, { className: "van-index-bar__index", style: 'z-index: ' + (zIndex + 1) + '; color: ' + (activeAnchorIndex === index ? highlightColor : ''), "data-index": index, children: item }, index); }) })] }) }); } var _default = IndexBar; exports.default = _default; var genIndexList = function genIndexList() { var indexList = []; var charCodeOfA = 'A'.charCodeAt(0); for (var i = 0; i < 26; i++) { indexList.push(String.fromCharCode(charCodeOfA + i)); } return indexList; }; function parseIndexAnchor(children) { return (0, _toArray.default)(children).map(function (node, index) { if ( /*#__PURE__*/(0, _react.isValidElement)(node)) { var key = node.key !== undefined ? String(node.key) : index; return _objectSpread(_objectSpread({ key: key }, node.props), {}, { node: node }); } return null; }).filter(function (indexAnchor) { return !!indexAnchor; }); }