mobile-more
Version:
基于 antd-mobile v5 扩展移动端 UI 组件
146 lines (142 loc) • 6.75 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.AnchorTabs = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _react = _interopRequireWildcard(require("react"));
var _ut = require("ut2");
var _antdMobile = require("antd-mobile");
var _useCompatId = _interopRequireDefault(require("../../hooks/useCompatId"));
var _rcHooks = require("rc-hooks");
var _dom = require("../../utils/dom");
var _classnames = _interopRequireDefault(require("classnames"));
var _config = require("../../config");
require("./index.css");
var _excluded = ["items", "renderItems", "tabsProps", "className", "headerStyle", "headerClassName", "contentStyle", "contentClassName"];
var prefixCls = "".concat(_config.prefixClass, "-anchor-tabs");
var BizAnchorTabs = function BizAnchorTabs(_ref) {
var items = _ref.items,
renderItems = _ref.renderItems,
tabsProps = _ref.tabsProps,
className = _ref.className,
headerStyle = _ref.headerStyle,
headerClassName = _ref.headerClassName,
contentStyle = _ref.contentStyle,
contentClassName = _ref.contentClassName,
restProps = (0, _objectWithoutProperties2.default)(_ref, _excluded);
var uid = (0, _useCompatId.default)('__anchor_tabs');
var ref = (0, _react.useRef)(null);
var tabContainerRef = (0, _react.useRef)(null);
var _useState = (0, _react.useState)(items[0].key),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
activeKey = _useState2[0],
setActiveKey = _useState2[1];
var _useThrottleFn = (0, _rcHooks.useThrottleFn)(function () {
var _tabContainerRef$curr;
var currentKey = items[0].key;
var tabContainerRect = (_tabContainerRef$curr = tabContainerRef.current) === null || _tabContainerRef$curr === void 0 ? void 0 : _tabContainerRef$curr.getBoundingClientRect();
var tabTop = tabContainerRect ? tabContainerRect.top + tabContainerRect.height : 0;
var _iterator = (0, _createForOfIteratorHelper2.default)(items),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var item = _step.value;
var element = document.getElementById(uid + item.key);
if (!element) continue;
var rect = element.getBoundingClientRect();
if (rect.top <= tabTop) {
currentKey = item.key;
} else {
break;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
setActiveKey(currentKey);
}, 100),
handleScroll = _useThrottleFn.run;
(0, _react.useEffect)(function () {
handleScroll();
var scrollContainer = (0, _dom.getScrollParent)(ref.current);
scrollContainer === null || scrollContainer === void 0 || scrollContainer.addEventListener('scroll', handleScroll);
return function () {
scrollContainer === null || scrollContainer === void 0 || scrollContainer.removeEventListener('scroll', handleScroll);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
var itemsDom = items.map(function (item) {
var id = uid + item.key;
if (typeof item.content === 'function') {
return /*#__PURE__*/_react.default.createElement(_react.Fragment, {
key: item.key
}, item.content(id));
}
return /*#__PURE__*/_react.default.createElement("div", {
key: item.key,
id: id
}, item.content);
});
var customItemsDom = typeof renderItems === 'function' ? renderItems(itemsDom) : itemsDom;
return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({
className: (0, _classnames.default)(prefixCls, className)
}, restProps, {
ref: ref
}), /*#__PURE__*/_react.default.createElement("div", {
className: (0, _classnames.default)("".concat(prefixCls, "-header"), headerClassName),
style: headerStyle,
ref: tabContainerRef
}, /*#__PURE__*/_react.default.createElement(_antdMobile.Tabs, (0, _extends2.default)({}, tabsProps, {
activeKey: activeKey,
onChange: function onChange(key) {
var _tabsProps$onChange;
var id = uid + key;
var currentContent = document.getElementById(id);
currentContent === null || currentContent === void 0 || currentContent.scrollIntoView();
var scrollContainer = (0, _dom.getScrollParent)(ref.current);
if (scrollContainer && tabContainerRef.current) {
var tabRect = tabContainerRef.current.getBoundingClientRect();
// scrollIntoView 存在的问题:不一定滚动至顶部,会留有 0.015xxx 左右的误差
var contentRectTop = (currentContent === null || currentContent === void 0 ? void 0 : currentContent.getBoundingClientRect().top) || 0;
var offsetTop = (0, _ut.ceil)(contentRectTop - tabRect.top);
// 如果已滚动至顶部,不需要再处理减去tab高度
// if (
// getScrollTop(scrollContainer) + getClientHeight(scrollContainer) <
// getScrollHeight(scrollContainer)
// ) {
// 此处使用偏差小于tab高度进行判断
if (offsetTop < tabRect.height) {
// scrollTo 存在的问题:如果滚动不是整数或0.5倍数会有偏差,例如 400.9121 => 400.5
scrollContainer.scrollTo({
top: (0, _dom.getScrollTop)(scrollContainer) - tabRect.height + offsetTop
});
}
}
tabsProps === null || tabsProps === void 0 || (_tabsProps$onChange = tabsProps.onChange) === null || _tabsProps$onChange === void 0 || _tabsProps$onChange.call(tabsProps, key);
}
}), items.map(function (item) {
return /*#__PURE__*/_react.default.createElement(_antdMobile.Tabs.Tab, {
title: item.title,
key: item.key
});
}))), /*#__PURE__*/_react.default.createElement("div", {
className: (0, _classnames.default)("".concat(prefixCls, "-content"), contentClassName),
style: contentStyle
}, customItemsDom));
};
/**
* @deprecated 即将废弃,请使用 `BizAnchorTabs` 替代。
*/
var AnchorTabs = exports.AnchorTabs = BizAnchorTabs;
/**
* @deprecated 即将废弃,请使用 `BizAnchorTabsProps` 替代。
*/
var _default = exports.default = BizAnchorTabs;