UNPKG

fastlion-amis

Version:

一种MIS页面生成工具

172 lines (171 loc) 7.91 kB
"use strict"; /** * @file AnchorNav * @description 锚点导航 * @author hsm-lv */ Object.defineProperty(exports, "__esModule", { value: true }); exports.AnchorNav = exports.AnchorNavSection = void 0; var tslib_1 = require("tslib"); var react_1 = (0, tslib_1.__importDefault)(require("react")); var theme_1 = require("../theme"); var helper_1 = require("../utils/helper"); var uncontrollable_1 = require("uncontrollable"); var find_1 = (0, tslib_1.__importDefault)(require("lodash/find")); var AnchorNavSectionComponent = /** @class */ (function (_super) { (0, tslib_1.__extends)(AnchorNavSectionComponent, _super); function AnchorNavSectionComponent() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.contentRef = function (ref) { return (_this.contentDom = ref); }; return _this; } AnchorNavSectionComponent.prototype.render = function () { var _a = this.props, cx = _a.classnames, children = _a.children, className = _a.className; return (react_1.default.createElement("div", { ref: this.contentRef, className: cx('AnchorNav-section', className) }, children)); }; return AnchorNavSectionComponent; }(react_1.default.PureComponent)); exports.AnchorNavSection = (0, theme_1.themeable)(AnchorNavSectionComponent); var AnchorNav = /** @class */ (function (_super) { (0, tslib_1.__extends)(AnchorNav, _super); function AnchorNav() { var _this = _super !== null && _super.apply(this, arguments) || this; // 滚动区域DOM _this.contentDom = react_1.default.createRef(); return _this; } AnchorNav.prototype.componentDidMount = function () { var _this = this; // 初始化滚动标识 this.setState({ fromSelect: false }); // add scroll event var sectionRootDom = this.contentDom && this.contentDom.current; sectionRootDom.addEventListener('scroll', this.scrollToNav); var offsetArr = []; var _a = this.props, children = _a.children, active = _a.active; // 收集段落区域offsetTop children && react_1.default.Children.forEach(children, function (section, index) { offsetArr.push({ key: section.props.name, offsetTop: sectionRootDom.children[index].offsetTop }); }); this.setState({ offsetArr: offsetArr }, function () { return active && _this.scrollToSection(active); }); }; AnchorNav.prototype.scrollToNav = function (e) { var _this = this; if (this.state.fromSelect) { return; } // 获取滚动的scrollTop var scrollTop = e.target.scrollTop; // 判断scrollTop所在区域 var offsetArr = this.state.offsetArr; var firstSection = offsetArr[0]; var lastSection = offsetArr[offsetArr.length - 1]; // 首层偏移 var offset = scrollTop + firstSection.offsetTop; // 首层 if (offset <= firstSection.offsetTop) { this.fireSelect(firstSection.key); } // 最后一层 else if (offset >= lastSection.offsetTop) { this.fireSelect(lastSection.key); } else { // 段落区间判断 offsetArr.forEach(function (item, index) { if (offset >= item.offsetTop && offset < offsetArr[index + 1].offsetTop) { _this.fireSelect(item.key); } }); } }; AnchorNav.prototype.scrollToSection = function (key) { // 获取指定段落的offsettop var offsetArr = this.state.offsetArr; var section = (0, find_1.default)(offsetArr, function (item) { return item.key === key; }); var sectionRootDom = this.contentDom && this.contentDom.current; // 滚动到指定段落 section && (sectionRootDom.scrollTop = section.offsetTop - offsetArr[0].offsetTop); }; AnchorNav.prototype.handleSelect = function (key) { // 标记滚动来自导航选择 this.setState({ fromSelect: true }); // 滚动到对应段落 this.scrollToSection(key); var sectionRootDom = this.contentDom && this.contentDom.current; // 如果已经滚到底就不去更新导航选中了 if (sectionRootDom.scrollHeight - sectionRootDom.scrollTop < sectionRootDom.clientHeight) { // fire event this.fireSelect(key); } // 取消标记 this.setState({ fromSelect: false }); }; AnchorNav.prototype.fireSelect = function (key) { var onSelect = this.props.onSelect; onSelect && onSelect(key); }; AnchorNav.prototype.renderLink = function (link, index) { var _this = this; if (!link) { return; } var _a = this.props, cx = _a.classnames, activeProp = _a.active; var _b = link.props, title = _b.title, name = _b.name; var active = activeProp === undefined && index === 0 ? name : activeProp; return (react_1.default.createElement("li", { className: cx('AnchorNav-link', active === name ? 'is-active' : ''), key: index, onClick: function () { return _this.handleSelect(name); } }, react_1.default.createElement("a", null, title))); }; AnchorNav.prototype.renderSection = function (section, index) { if (!section) { return; } var _a = this.props, activeProp = _a.active, classnames = _a.classnames; var name = section.props.name; var active = activeProp === undefined && index === 0 ? name : activeProp; return react_1.default.cloneElement(section, (0, tslib_1.__assign)((0, tslib_1.__assign)({}, section.props), { key: index, classnames: classnames, active: active })); }; AnchorNav.prototype.render = function () { var _a; var _this = this; var _b = this.props, cx = _b.classnames, className = _b.className, linkClassName = _b.linkClassName, sectionClassName = _b.sectionClassName, children = _b.children, direction = _b.direction; if (!Array.isArray(children)) { return null; } return (react_1.default.createElement("div", { className: cx('AnchorNav', (_a = {}, _a["AnchorNav--" + direction] = direction, _a), className) }, react_1.default.createElement("ul", { className: cx('AnchorNav-link-wrap', linkClassName), role: "anchorlist" }, children.map(function (link, index) { return _this.renderLink(link, index); })), react_1.default.createElement("div", { className: cx('AnchorNav-section-wrap', sectionClassName), ref: this.contentDom }, children.map(function (section, index) { return _this.renderSection(section, index); })))); }; var _a; AnchorNav.defaultProps = { linkClassName: '', sectionClassName: '', direction: 'vertical' }; (0, tslib_1.__decorate)([ helper_1.autobind, (0, tslib_1.__metadata)("design:type", Function), (0, tslib_1.__metadata)("design:paramtypes", [typeof (_a = typeof Event !== "undefined" && Event) === "function" ? _a : Object]), (0, tslib_1.__metadata)("design:returntype", void 0) ], AnchorNav.prototype, "scrollToNav", null); return AnchorNav; }(react_1.default.Component)); exports.AnchorNav = AnchorNav; var ThemedAnchorNav = (0, theme_1.themeable)((0, uncontrollable_1.uncontrollable)(AnchorNav, { active: 'onSelect' })); exports.default = ThemedAnchorNav; //# sourceMappingURL=./components/AnchorNav.js.map