zent
Version:
一套前端设计语言和基于React的实现
208 lines (207 loc) • 11 kB
JavaScript
import { __assign, __extends } from "tslib";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import cn from 'classnames';
import { Component, createRef } from 'react';
import AnchorOperation from '../operation/AnchorOperation';
import SlideOperation from '../operation/SlideOperation';
import { WindowResizeHandler } from '../../../utils/component/WindowResizeHandler';
import memorizeOne from '../../../utils/memorize-one';
import Icon from '../../../icon';
import { runOnceInNextFrame } from '../../../utils/nextFrame';
var classNamePrefix = 'zent-tabs-nav-tabs-content';
var OperationTabs = (function (_super) {
__extends(OperationTabs, _super);
function OperationTabs() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.tabsWrapperRef = createRef();
_this.tabsMainRef = createRef();
_this.state = {
startIndex: 0,
endIndex: 0,
translateX: 0,
};
_this.getTargetIndex = function (translateX, tabsInfo, isEnd) {
if (isEnd === void 0) { isEnd = false; }
var list = tabsInfo.list, tabsTotalWidth = tabsInfo.tabsTotalWidth;
var targetIndex = isEnd ? list.length - 1 : 0;
var indexOffset = isEnd ? -1 : 1;
if (translateX <= 0) {
return 0;
}
if (translateX >= tabsTotalWidth) {
return list.length - 1;
}
for (var index = 0; index < list.length; index++) {
var _a = list[index], width = _a.width, accumWidth = _a.accumWidth;
if (accumWidth + width >= translateX && accumWidth < translateX) {
return index + indexOffset;
}
}
return targetIndex;
};
_this.getHiddenTabs = memorizeOne(function (tabDataList, startIndex, endIndex) {
return tabDataList.reduce(function (hiddenTabs, tab, index) {
if (index < startIndex || index > endIndex) {
hiddenTabs.push(tab);
}
return hiddenTabs;
}, []);
});
_this.onStartChange = function (startIndex, tabsInfo) {
var list = tabsInfo.list, tabsTotalWidth = tabsInfo.tabsTotalWidth;
var tabsWrapperWidth = _this.tabsWrapperWidth;
var currentIndexTranslateX = list[startIndex].accumWidth + tabsWrapperWidth;
var availableTranslateX = Math.min(currentIndexTranslateX, tabsTotalWidth);
if (currentIndexTranslateX > tabsTotalWidth) {
startIndex = _this.getTargetIndex(tabsTotalWidth - tabsWrapperWidth, tabsInfo);
}
var endIndex = _this.getTargetIndex(availableTranslateX, tabsInfo, true);
var translateX = availableTranslateX - tabsWrapperWidth;
_this.setState({
startIndex: startIndex,
endIndex: endIndex,
translateX: translateX,
});
};
_this.onEndChange = function (endIndex, tabsInfo) {
var list = tabsInfo.list;
var tabsWrapperWidth = _this.tabsWrapperWidth;
var _a = list[endIndex], accumWidth = _a.accumWidth, width = _a.width;
var currentIndexTranslateX = accumWidth + width - tabsWrapperWidth;
var availableTranslateX = Math.max(currentIndexTranslateX, 0);
if (currentIndexTranslateX < 0) {
endIndex = _this.getTargetIndex(tabsWrapperWidth, tabsInfo, true);
}
var startIndex = _this.getTargetIndex(availableTranslateX, tabsInfo);
_this.setState({
startIndex: startIndex,
endIndex: endIndex,
translateX: availableTranslateX,
});
};
_this.handlePageScroll = function (tab) {
var tabsInfo = _this.getTabsInfo();
var targetIndex = tabsInfo.list.findIndex(function (item) { return item.id === tab.key; });
var _a = _this.state, startIndex = _a.startIndex, endIndex = _a.endIndex;
if (targetIndex <= startIndex) {
_this.onStartChange(targetIndex, tabsInfo);
}
if (targetIndex >= endIndex) {
_this.onEndChange(targetIndex, tabsInfo);
}
};
_this.onAnchorPageChange = function (tab) {
var _a, _b;
if (tab.disabled)
return;
if (!_this.isControlled) {
_this.handlePageScroll(tab);
}
(_b = (_a = _this.props).onChange) === null || _b === void 0 ? void 0 : _b.call(_a, tab.key);
};
_this.onSlidePageChange = function (isPrev, disabled) {
if (disabled === void 0) { disabled = false; }
if (disabled)
return;
var _a = _this.state, startIndex = _a.startIndex, endIndex = _a.endIndex;
var tabsInfo = _this.getTabsInfo();
if (isPrev) {
_this.onEndChange(startIndex - 1, tabsInfo);
}
else {
_this.onStartChange(endIndex + 1, tabsInfo);
}
};
_this.onResize = runOnceInNextFrame(function () {
_this.onStartChange(_this.state.startIndex, _this.getTabsInfo());
});
_this.componentDidUpdate = function (prevProps) {
var _a = _this.props, activeId = _a.activeId, tabDataList = _a.tabDataList;
if (prevProps.tabDataList.length !== _this.props.tabDataList.length) {
_this.onResize();
}
if (prevProps.activeId === activeId)
return;
var _b = _this.state, startIndex = _b.startIndex, endIndex = _b.endIndex;
var currentTabIndex = tabDataList.findIndex(function (tab) { return tab.key === activeId; });
if (currentTabIndex === -1)
return;
if (currentTabIndex < startIndex || currentTabIndex > endIndex) {
var currentTab = tabDataList[currentTabIndex];
_this.handlePageScroll(currentTab);
}
};
_this.handleAddClick = function () {
var onAdd = _this.props.onAdd;
onAdd === null || onAdd === void 0 ? void 0 : onAdd();
};
return _this;
}
Object.defineProperty(OperationTabs.prototype, "tabsWrapperWidth", {
get: function () {
var _a;
return ((_a = this.tabsWrapperRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0;
},
enumerable: false,
configurable: true
});
Object.defineProperty(OperationTabs.prototype, "isControlled", {
get: function () {
return 'activeId' in this.props;
},
enumerable: false,
configurable: true
});
OperationTabs.prototype.getTabsInfo = function () {
var _a;
var tabDataList = this.props.tabDataList;
var tabs = ((_a = this.tabsMainRef.current) === null || _a === void 0 ? void 0 : _a.children) || [];
var list = [];
var tabsTotalWidth = 0;
for (var i = 0; i < tabs.length; i++) {
var width = tabs[i].offsetWidth;
var id = tabDataList[i].key;
list.push({ id: id, width: width, accumWidth: tabsTotalWidth });
tabsTotalWidth += width;
}
return { list: list, tabsTotalWidth: tabsTotalWidth };
};
OperationTabs.prototype.renderSlideOperations = function () {
var _this = this;
var tabDataList = this.props.tabDataList;
var _a = this.state, startIndex = _a.startIndex, endIndex = _a.endIndex;
var disablePrev = !startIndex;
var disableNext = endIndex >= tabDataList.length - 1;
return (_jsx(SlideOperation, { disablePrev: disablePrev, disableNext: disableNext, onPrevChange: function () { return _this.onSlidePageChange(true, disablePrev); }, onNextChange: function () { return _this.onSlidePageChange(false, disableNext); } }, void 0));
};
OperationTabs.prototype.renderAnchorOperations = function (tabs) {
return !!tabs.length ? (_jsx(AnchorOperation, { tabs: tabs, onChange: this.onAnchorPageChange }, void 0)) : null;
};
OperationTabs.prototype.componentDidMount = function () {
this.onStartChange(0, this.getTabsInfo());
};
OperationTabs.prototype.render = function () {
var _a, _b, _c;
var _d = this.props, overflowMode = _d.overflowMode, tabs = _d.tabs, tabDataList = _d.tabDataList, onAdd = _d.onAdd;
var _e = this.state, translateX = _e.translateX, startIndex = _e.startIndex, endIndex = _e.endIndex;
var contentClassName = classNamePrefix + "-" + overflowMode;
var hiddenTabs = this.getHiddenTabs(tabDataList, startIndex, endIndex);
var isHiddenTab = hiddenTabs.length !== 0;
return (_jsxs(_Fragment, { children: [_jsxs("div", __assign({ className: cn(contentClassName, (_a = {},
_a[contentClassName + "-left"] = !!startIndex,
_a[contentClassName + "-right"] = endIndex !== tabs.length - 1,
_a)), ref: this.tabsWrapperRef, "data-zv": '10.0.17' }, { children: [_jsx("div", __assign({ className: cn(contentClassName + "-main", (_b = {},
_b[contentClassName + "-main--has-add"] = !isHiddenTab && onAdd,
_b)), ref: this.tabsMainRef, onScroll: this.onResize, style: {
transform: "translateX(-" + (isHiddenTab ? translateX : 0) + "px)",
}, "data-zv": '10.0.17' }, { children: tabs }), void 0), !isHiddenTab && onAdd && (_jsx("span", __assign({ className: contentClassName + "__add-btn", onClick: this.handleAddClick, "data-zv": '10.0.17' }, { children: _jsx(Icon, { type: "plus", className: contentClassName + "__add-icon" }, void 0) }), void 0))] }), void 0), isHiddenTab && (_jsxs(_Fragment, { children: [_jsxs("div", __assign({ className: cn(contentClassName + "-option", (_c = {},
_c[contentClassName + "-option--right"] = endIndex !== tabs.length - 1,
_c)), "data-zv": '10.0.17' }, { children: [overflowMode === 'slide' && this.renderSlideOperations(), overflowMode === 'anchor' &&
this.renderAnchorOperations(hiddenTabs), onAdd && (_jsx("span", __assign({ className: contentClassName + "-option__add-btn", onClick: this.handleAddClick, "data-zv": '10.0.17' }, { children: _jsx(Icon, { type: "plus", className: contentClassName + "__add-icon" }, void 0) }), void 0))] }), void 0), _jsx(WindowResizeHandler, { onResize: this.onResize }, void 0)] }, void 0))] }, void 0));
};
OperationTabs.defaultProps = {
overflowMode: 'anchor',
};
return OperationTabs;
}(Component));
export default OperationTabs;