@alibsp/elevator
Version:
117 lines (103 loc) • 3.55 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import React, { useEffect, useState, useRef } from "react";
import { Tab, Affix } from "@alifd/next";
import "./index.scss";
var findNode = function findNode(target, param) {
if (!target) {
if (param) return param;
return null;
}
if (typeof target === "function") {
try {
target = target();
} catch (err) {
target = null;
}
}
return target;
};
export default function Elevator(props) {
var _ref = props || {},
_ref$className = _ref.className,
className = _ref$className === void 0 ? "" : _ref$className,
activeKey = _ref.activeKey,
dataSource = _ref.dataSource,
_ref$offset = _ref.offset,
offset = _ref$offset === void 0 ? 0 : _ref$offset,
container = _ref.container,
children = _ref.children,
_ref$useAbsolute = _ref.useAbsolute,
useAbsolute = _ref$useAbsolute === void 0 ? false : _ref$useAbsolute,
_ref$hasMargin = _ref.hasMargin,
hasMargin = _ref$hasMargin === void 0 ? false : _ref$hasMargin,
_ref$tabProps = _ref.tabProps,
tabProps = _ref$tabProps === void 0 ? {} : _ref$tabProps;
var scrolling = useRef(false);
var _useState = useState(activeKey || (dataSource.length ? dataSource[0].id : "")),
active = _useState[0],
setActive = _useState[1];
var _useState2 = useState(findNode(container)),
target = _useState2[0],
setTarget = _useState2[1];
var clickHandler = function clickHandler(id) {
setActive(id);
scrolling.current = true;
var currentTop = document.querySelector("#" + id).offsetTop + offset;
target.scrollTo(0, currentTop);
setTimeout(function () {
scrolling.current = false;
}, 100);
};
var scrollListener = function scrollListener() {
requestAnimationFrame(function () {
if (scrolling.current) return;
if (!dataSource.length) {
return;
}
var scrollTop = target.scrollY || target.scrollTop;
for (var i = 0; i < dataSource.length; i++) {
// 当前区块将消失,下一区块的offsetTop与scrollTop相同时
if (dataSource[i + 1] && document.querySelector("#" + dataSource[i + 1].id).offsetTop > scrollTop) {
setActive(dataSource[i].id);
return;
}
}
if (active !== dataSource[dataSource.length - 1].id) {
setActive(dataSource[dataSource.length - 1].id);
}
});
};
useEffect(function () {
setTimeout(function () {
setTarget(findNode(props.container, window));
});
}, []);
useEffect(function () {
target && target.addEventListener("scroll", scrollListener);
return function () {
target && target.removeEventListener("scroll", scrollListener);
};
}, [target]);
return /*#__PURE__*/React.createElement("div", {
className: "mod-bsp-eleavtor " + className
}, /*#__PURE__*/React.createElement(Affix, {
useAbsolute: useAbsolute,
container: function container() {
return target;
},
className: "mod-bsp-eleavtor-affix " + (hasMargin ? "mod-bsp-eleavtor-affix-hasMargin" : "")
}, /*#__PURE__*/React.createElement(Tab, _extends({
size: "medium",
shape: "text",
activeKey: active,
className: "mod-bsp-eleavtor-tab"
}, tabProps), dataSource.map(function (item) {
return /*#__PURE__*/React.createElement(Tab.Item, {
key: item.id,
title: item.title,
onClick: function onClick() {
return clickHandler(item.id);
}
});
}))), children);
}