vxe-pc-ui
Version:
A vue based PC component library
992 lines (991 loc) • 33 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _vue = require("vue");
var _comp = require("../../ui/src/comp");
var _ui = require("../../ui");
var _vn = require("../../ui/src/vn");
var _dom = require("../../ui/src/dom");
var _utils = require("../../ui/src/utils");
var _log = require("../../ui/src/log");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _loading = _interopRequireDefault(require("../../loading/src/loading"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const scrollbarOffsetSize = 20;
var _default = exports.default = (0, _comp.defineVxeComponent)({
name: 'VxeTabs',
props: {
modelValue: [String, Number, Boolean],
options: Array,
width: [String, Number],
height: [String, Number],
destroyOnClose: {
type: Boolean,
default: () => (0, _ui.getConfig)().tabs.destroyOnClose
},
titleWidth: [String, Number],
titleAlign: [String, Number],
type: {
type: String,
default: () => (0, _ui.getConfig)().tabs.type
},
position: {
type: String,
default: () => (0, _ui.getConfig)().tabs.position
},
showClose: Boolean,
showBody: {
type: Boolean,
default: true
},
padding: {
type: Boolean,
default: () => (0, _ui.getConfig)().tabs.padding
},
trigger: String,
beforeChangeMethod: Function,
closeConfig: Object,
refreshConfig: Object,
size: {
type: String,
default: () => (0, _ui.getConfig)().tabs.size || (0, _ui.getConfig)().size
},
// 已废弃
beforeCloseMethod: Function
},
emits: ['update:modelValue', 'change', 'tab-change', 'tab-change-fail', 'tab-close', 'tab-close-fail', 'tab-click', 'tab-load'],
setup(props, context) {
const {
slots,
emit
} = context;
const xID = _xeUtils.default.uniqueId();
const $xeParentTabs = (0, _vue.inject)('$xeTabs', null);
const {
computeSize
} = (0, _ui.useSize)(props);
const refElem = (0, _vue.ref)();
const refHeadWrapperElem = (0, _vue.ref)();
const refHeadPrevElem = (0, _vue.ref)();
const refHeadNextElem = (0, _vue.ref)();
const reactData = (0, _vue.reactive)({
staticTabs: [],
activeName: null,
initNames: [],
lintLeft: 0,
lintTop: 0,
lintWidth: 0,
lintHeight: 0,
scrollbarWidth: 0,
scrollbarHeight: 0,
isTabOver: false,
resizeFlag: 1,
cacheTabMaps: {}
});
const internalData = {
slTimeout: undefined
};
const refMaps = {
refElem
};
const computeTabType = (0, _vue.computed)(() => {
const {
type
} = props;
return type || 'default';
});
const computeTabPosition = (0, _vue.computed)(() => {
const {
position
} = props;
return position || 'top';
});
const computeLrPosition = (0, _vue.computed)(() => {
const tabPosition = computeTabPosition.value;
return tabPosition === 'left' || tabPosition === 'right';
});
const computeLineStyle = (0, _vue.computed)(() => {
const {
lintLeft,
lintTop,
lintWidth,
lintHeight
} = reactData;
const lrPosition = computeLrPosition.value;
return lrPosition ? {
top: `${lintTop}px`,
height: `${lintHeight}px`
} : {
left: `${lintLeft}px`,
width: `${lintWidth}px`
};
});
const computeWrapperStyle = (0, _vue.computed)(() => {
const {
width
} = props;
const stys = {};
if (width) {
stys.width = (0, _dom.toCssUnit)(width);
}
return stys;
});
const computeCloseOpts = (0, _vue.computed)(() => {
return Object.assign({}, (0, _ui.getConfig)().tabs.closeConfig, props.closeConfig);
});
const computeRefreshOpts = (0, _vue.computed)(() => {
return Object.assign({}, (0, _ui.getConfig)().tabs.refreshConfig, props.refreshConfig);
});
const computeTabOptions = (0, _vue.computed)(() => {
const {
options
} = props;
return (options || []).filter(item => handleFilterTab(item));
});
const computeTabStaticOptions = (0, _vue.computed)(() => {
const {
staticTabs
} = reactData;
return staticTabs.filter(item => handleFilterTab(item));
});
const computeParentTabsResizeFlag = (0, _vue.computed)(() => {
return $xeParentTabs ? $xeParentTabs.reactData.resizeFlag : null;
});
const computeMaps = {};
const $xeTabs = {
xID,
props,
context,
reactData,
getRefMaps: () => refMaps,
getComputeMaps: () => computeMaps
};
const handleFilterTab = item => {
const {
permissionCode
} = item;
if (permissionCode) {
if (!_ui.permission.checkVisible(permissionCode)) {
return false;
}
}
return true;
};
const callSlot = (slotFunc, params) => {
if (slotFunc) {
if (_xeUtils.default.isString(slotFunc)) {
slotFunc = slots[slotFunc] || null;
}
if (_xeUtils.default.isFunction(slotFunc)) {
return (0, _vn.getSlotVNs)(slotFunc(params));
}
}
return [];
};
const checkScrolling = () => {
const lrPosition = computeLrPosition.value;
const headerWrapperEl = refHeadWrapperElem.value;
const headPrevEl = refHeadPrevElem.value;
const headNextEl = refHeadNextElem.value;
if (headerWrapperEl) {
const {
scrollLeft,
scrollTop,
clientWidth,
clientHeight,
scrollWidth,
scrollHeight
} = headerWrapperEl;
if (headPrevEl) {
if ((lrPosition ? scrollTop : scrollLeft) > 0) {
(0, _dom.addClass)(headPrevEl, 'scrolling--middle');
} else {
(0, _dom.removeClass)(headPrevEl, 'scrolling--middle');
}
}
if (headNextEl) {
if (lrPosition ? clientHeight < scrollHeight - Math.ceil(scrollTop) : clientWidth < scrollWidth - Math.ceil(scrollLeft)) {
(0, _dom.addClass)(headNextEl, 'scrolling--middle');
} else {
(0, _dom.removeClass)(headNextEl, 'scrolling--middle');
}
}
}
};
const updateTabStyle = () => {
const handleStyle = () => {
const {
activeName
} = reactData;
const tabType = computeTabType.value;
const tabOptions = computeTabOptions.value;
const tabStaticOptions = computeTabStaticOptions.value;
const headerWrapperEl = refHeadWrapperElem.value;
const lrPosition = computeLrPosition.value;
let lintWidth = 0;
let lintHeight = 0;
let lintLeft = 0;
let lintTop = 0;
let sBarWidth = 0;
let sBarHeight = 0;
let isOver = false;
if (headerWrapperEl) {
const index = _xeUtils.default.findIndexOf(tabStaticOptions.length ? tabStaticOptions : tabOptions, item => item.name === activeName);
const {
children,
offsetWidth,
scrollWidth,
offsetHeight,
scrollHeight,
clientWidth,
clientHeight
} = headerWrapperEl;
sBarWidth = offsetWidth - clientWidth;
sBarHeight = offsetHeight - clientHeight;
if (lrPosition) {
isOver = scrollHeight !== clientHeight;
if (index > -1) {
const tabEl = children[index];
if (tabEl) {
const tabHeight = tabEl.clientHeight;
const tabWidth = tabEl.clientWidth;
if (tabType === 'card') {
lintWidth = tabWidth;
lintHeight = tabHeight;
lintTop = tabEl.offsetTop;
} else if (tabType === 'border-card') {
lintWidth = tabWidth;
lintHeight = tabHeight;
lintTop = tabEl.offsetTop - 1;
} else {
lintHeight = Math.max(4, Math.floor(tabHeight * 0.6));
lintTop = tabEl.offsetTop + Math.floor((tabHeight - lintHeight) / 2);
}
}
}
} else {
isOver = scrollWidth !== clientWidth;
if (index > -1) {
const tabEl = children[index];
if (tabEl) {
const tabWidth = tabEl.clientWidth;
if (tabType === 'card') {
lintWidth = tabWidth + 1;
lintLeft = tabEl.offsetLeft;
} else if (tabType === 'border-card') {
lintWidth = tabWidth;
lintLeft = tabEl.offsetLeft - 1;
} else {
lintWidth = Math.max(4, Math.floor(tabWidth * 0.6));
lintLeft = tabEl.offsetLeft + Math.floor((tabWidth - lintWidth) / 2);
}
}
}
}
}
reactData.scrollbarWidth = sBarWidth;
reactData.scrollbarHeight = sBarHeight;
reactData.lintLeft = lintLeft;
reactData.lintTop = lintTop;
reactData.lintWidth = lintWidth;
reactData.lintHeight = lintHeight;
reactData.isTabOver = isOver;
checkScrolling();
};
handleStyle();
(0, _vue.nextTick)(handleStyle);
};
const dispatchEvent = (type, params, evnt) => {
emit(type, (0, _ui.createEvent)(evnt, {
$tabs: $xeTabs
}, params));
};
const emitModel = value => {
emit('update:modelValue', value);
};
const addInitName = (name, evnt) => {
const {
initNames
} = reactData;
if (name && !initNames.includes(name)) {
dispatchEvent('tab-load', {
name
}, evnt);
initNames.push(name);
return true;
}
return false;
};
const initDefaultName = list => {
let activeName = null;
const nameMaps = {};
if (list && list.length) {
let validVal = false;
activeName = props.modelValue;
list.forEach(item => {
const {
name,
preload
} = item || {};
if (name) {
nameMaps[`${name}`] = {
loading: false
};
if (activeName === name) {
validVal = true;
}
if (preload) {
addInitName(name, null);
}
}
});
if (!validVal) {
activeName = list[0].name;
addInitName(activeName, null);
emitModel(activeName);
}
}
reactData.activeName = activeName;
reactData.cacheTabMaps = nameMaps;
};
const clickEvent = (evnt, item) => {
const {
trigger
} = props;
const beforeMethod = props.beforeChangeMethod || (0, _ui.getConfig)().tabs.beforeChangeMethod;
const {
activeName
} = reactData;
const {
name
} = item;
const value = name;
dispatchEvent('tab-click', {
name
}, evnt);
if (trigger === 'manual') {
return;
}
if (name !== activeName) {
Promise.resolve(!beforeMethod || beforeMethod({
$tabs: $xeTabs,
name,
oldName: activeName,
newName: name,
option: item
})).then(status => {
if (status) {
reactData.activeName = name;
emitModel(value);
addInitName(name, evnt);
dispatchEvent('change', {
value,
name,
oldName: activeName,
newName: name,
option: item
}, evnt);
dispatchEvent('tab-change', {
value,
name,
oldName: activeName,
newName: name,
option: item
}, evnt);
} else {
dispatchEvent('tab-change-fail', {
value,
name,
oldName: activeName,
newName: name,
option: item
}, evnt);
}
}).catch(() => {
dispatchEvent('tab-change-fail', {
value,
name,
oldName: activeName,
newName: name,
option: item
}, evnt);
});
}
};
const handleRefreshTabEvent = (evnt, item) => {
evnt.stopPropagation();
const {
activeName,
cacheTabMaps
} = reactData;
const {
name
} = item;
const refreshOpts = computeRefreshOpts.value;
const {
queryMethod
} = refreshOpts;
const cacheItem = name ? cacheTabMaps[`${name}`] : null;
if (cacheItem) {
if (queryMethod) {
if (cacheItem.loading) {
return;
}
cacheItem.loading = true;
Promise.resolve(queryMethod({
$tabs: $xeTabs,
value: activeName,
name,
option: item
})).finally(() => {
cacheItem.loading = false;
});
} else {
(0, _log.errLog)('vxe.error.notFunc', ['refresh-config.queryMethod']);
}
}
};
const handleCloseTabEvent = (evnt, item, index, list) => {
evnt.stopPropagation();
const {
activeName
} = reactData;
const closeOpts = computeCloseOpts.value;
const beforeMethod = closeOpts.beforeMethod || props.beforeCloseMethod || (0, _ui.getConfig)().tabs.beforeCloseMethod;
const {
name
} = item;
const value = activeName;
let nextName = value;
if (activeName === name) {
const nextItem = index < list.length - 1 ? list[index + 1] : list[index - 1];
nextName = nextItem ? nextItem.name : null;
}
Promise.resolve(!beforeMethod || beforeMethod({
$tabs: $xeTabs,
value,
name,
nextName,
option: item
})).then(status => {
if (status) {
dispatchEvent('tab-close', {
value,
name,
nextName
}, evnt);
} else {
dispatchEvent('tab-close-fail', {
value,
name,
nextName
}, evnt);
}
}).catch(() => {
dispatchEvent('tab-close-fail', {
value,
name,
nextName
}, evnt);
});
};
const startScrollAnimation = (offsetPos, offsetSize) => {
const {
slTimeout
} = internalData;
const lrPosition = computeLrPosition.value;
let offsetLeft = lrPosition ? 0 : offsetSize;
let offsetTop = lrPosition ? offsetSize : 0;
let scrollCount = 6;
let delayNum = 35;
if (slTimeout) {
clearTimeout(slTimeout);
internalData.slTimeout = undefined;
}
const scrollAnimate = () => {
const headerWrapperEl = refHeadWrapperElem.value;
if (scrollCount > 0) {
scrollCount--;
if (headerWrapperEl) {
const {
clientWidth,
clientHeight,
scrollWidth,
scrollHeight,
scrollLeft,
scrollTop
} = headerWrapperEl;
if (lrPosition) {
offsetTop = Math.floor(offsetTop / 2);
if (offsetPos > 0) {
if (clientHeight + scrollTop < scrollHeight) {
headerWrapperEl.scrollTop += offsetTop;
delayNum -= 4;
internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
}
} else {
if (scrollTop > 0) {
headerWrapperEl.scrollTop -= offsetTop;
delayNum -= 4;
internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
}
}
} else {
offsetLeft = Math.floor(offsetLeft / 2);
if (offsetPos > 0) {
if (clientWidth + scrollLeft < scrollWidth) {
headerWrapperEl.scrollLeft += offsetLeft;
delayNum -= 4;
internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
}
} else {
if (scrollLeft > 0) {
headerWrapperEl.scrollLeft -= offsetLeft;
delayNum -= 4;
internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
}
}
}
updateTabStyle();
}
}
};
scrollAnimate();
};
const handleScrollToLeft = offsetPos => {
const lrPosition = computeLrPosition.value;
const headerWrapperEl = refHeadWrapperElem.value;
if (headerWrapperEl) {
const {
clientWidth,
clientHeight
} = headerWrapperEl;
const offsetSize = Math.floor((lrPosition ? clientHeight : clientWidth) * 0.75);
startScrollAnimation(offsetPos, offsetSize);
}
};
const scrollLeftEvent = () => {
handleScrollToLeft(-1);
};
const scrollRightEvent = () => {
handleScrollToLeft(1);
};
const scrollToTab = name => {
const tabOptions = computeTabOptions.value;
const tabStaticOptions = computeTabStaticOptions.value;
const lrPosition = computeLrPosition.value;
return (0, _vue.nextTick)().then(() => {
const headerWrapperEl = refHeadWrapperElem.value;
if (headerWrapperEl) {
const index = _xeUtils.default.findIndexOf(tabStaticOptions.length ? tabStaticOptions : tabOptions, item => item.name === name);
if (index > -1) {
const {
scrollLeft,
scrollTop,
clientWidth,
clientHeight,
children
} = headerWrapperEl;
const tabEl = children[index];
if (tabEl) {
if (lrPosition) {
const tabOffsetTop = tabEl.offsetTop;
const tabClientHeight = tabEl.clientHeight;
// 如果顶部被挡
const overSize = tabOffsetTop + tabClientHeight - (scrollTop + clientHeight);
if (overSize > 0) {
headerWrapperEl.scrollTop += overSize;
}
// 如果底部被挡,优先
if (tabOffsetTop < scrollTop) {
headerWrapperEl.scrollTop = tabOffsetTop;
}
} else {
const tabOffsetLeft = tabEl.offsetLeft;
const tabClientWidth = tabEl.clientWidth;
// 如果右侧被挡
const overSize = tabOffsetLeft + tabClientWidth - (scrollLeft + clientWidth);
if (overSize > 0) {
headerWrapperEl.scrollLeft += overSize;
}
// 如果左侧被挡,优先
if (tabOffsetLeft < scrollLeft) {
headerWrapperEl.scrollLeft = tabOffsetLeft;
}
}
}
}
updateTabStyle();
}
});
};
const handlePrevNext = isNext => {
const {
activeName
} = reactData;
const tabOptions = computeTabOptions.value;
const tabStaticOptions = computeTabStaticOptions.value;
const list = tabStaticOptions.length ? tabStaticOptions : tabOptions;
const index = _xeUtils.default.findIndexOf(list, item => item.name === activeName);
if (index > -1) {
let item = null;
if (isNext) {
if (index < list.length - 1) {
item = list[index + 1];
}
} else {
if (index > 0) {
item = list[index - 1];
}
}
if (item) {
const name = item.name;
const value = name;
reactData.activeName = name;
emitModel(value);
addInitName(name, null);
}
}
return (0, _vue.nextTick)();
};
const tabsMethods = {
dispatchEvent,
scrollToTab,
prev() {
return handlePrevNext(false);
},
next() {
return handlePrevNext(true);
},
prevTab() {
(0, _log.warnLog)('vxe.error.delFunc', ['[tabs] prevTab', 'prev']);
return tabsMethods.prev();
},
nextTab() {
(0, _log.warnLog)('vxe.error.delFunc', ['[tabs] nextTab', 'next']);
return tabsMethods.next();
}
};
const tabsPrivateMethods = {};
Object.assign($xeTabs, tabsMethods, tabsPrivateMethods);
const renderTabHeader = tabList => {
const {
titleWidth: allTitleWidth,
titleAlign: allTitleAlign,
showClose,
closeConfig,
refreshConfig
} = props;
const {
activeName,
scrollbarWidth,
scrollbarHeight,
isTabOver,
cacheTabMaps
} = reactData;
const tabType = computeTabType.value;
const tabPosition = computeTabPosition.value;
const lrPosition = computeLrPosition.value;
const lineStyle = computeLineStyle.value;
const tabPrefixSlot = slots.tabPrefix || slots['tab-prefix'] || slots.prefix;
const tabSuffixSlot = slots.tabSuffix || slots['tab-suffix'] || slots.suffix || slots.extra;
const closeOpts = computeCloseOpts.value;
const closeVisibleMethod = closeOpts.visibleMethod;
const refreshOpts = computeRefreshOpts.value;
const refreshVisibleMethod = refreshOpts.visibleMethod;
return (0, _vue.h)('div', {
key: 'th',
class: ['vxe-tabs-header', `type--${tabType}`, `pos--${tabPosition}`]
}, [tabPrefixSlot ? (0, _vue.h)('div', {
class: ['vxe-tabs-header--prefix', `type--${tabType}`, `pos--${tabPosition}`]
}, callSlot(tabPrefixSlot, {
name: activeName
})) : (0, _ui.renderEmptyElement)($xeTabs), isTabOver ? (0, _vue.h)('div', {
ref: refHeadPrevElem,
class: ['vxe-tabs-header--bar vxe-tabs-header--prev-bar', `type--${tabType}`, `pos--${tabPosition}`],
onClick: scrollLeftEvent
}, [(0, _vue.h)('span', {
class: lrPosition ? (0, _ui.getIcon)().TABS_TAB_BUTTON_TOP : (0, _ui.getIcon)().TABS_TAB_BUTTON_LEFT
})]) : (0, _ui.renderEmptyElement)($xeTabs), (0, _vue.h)('div', {
class: ['vxe-tabs-header--wrapper', `type--${tabType}`, `pos--${tabPosition}`]
}, [(0, _vue.h)('div', {
ref: refHeadWrapperElem,
class: 'vxe-tabs-header--item-wrapper',
style: lrPosition ? {
marginRight: `-${scrollbarWidth + scrollbarOffsetSize}px`,
paddingRight: `${scrollbarOffsetSize}px`
} : {
marginBottom: `-${scrollbarHeight + scrollbarOffsetSize}px`,
paddingBottom: `${scrollbarOffsetSize}px`
},
onScroll: checkScrolling
}, tabList.map((item, index) => {
const {
title,
titleWidth,
titleAlign,
icon,
name
} = item;
const itemSlots = item.slots || {};
const titleSlot = itemSlots.title || itemSlots.tab;
const titlePrefixSlot = itemSlots.titlePrefix || itemSlots['title-prefix'];
const titleSuffixSlot = itemSlots.titleSuffix || itemSlots['title-suffix'];
const itemWidth = titleWidth || allTitleWidth;
const itemAlign = titleAlign || allTitleAlign;
const params = {
$tabs: $xeTabs,
value: activeName,
name,
option: item
};
const isActive = activeName === name;
const cacheItem = name ? cacheTabMaps[`${name}`] : null;
const isLoading = cacheItem ? cacheItem.loading : false;
return (0, _vue.h)('div', {
key: `${name}`,
class: ['vxe-tabs-header--item', `type--${tabType}`, `pos--${tabPosition}`, itemAlign ? `align--${itemAlign}` : '', {
'is--active': isActive
}],
style: itemWidth ? {
width: (0, _dom.toCssUnit)(itemWidth)
} : undefined,
onClick(evnt) {
clickEvent(evnt, item);
}
}, [(0, _vue.h)('div', {
class: 'vxe-tabs-header--item-inner'
}, [(0, _vue.h)('div', {
class: 'vxe-tabs-header--item-content'
}, [icon ? (0, _vue.h)('span', {
class: 'vxe-tabs-header--item-icon'
}, [(0, _vue.h)('i', {
class: icon
})]) : (0, _ui.renderEmptyElement)($xeTabs), titlePrefixSlot ? (0, _vue.h)('span', {
class: 'vxe-tabs-header--item-prefix'
}, callSlot(titlePrefixSlot, {
name,
title
})) : (0, _ui.renderEmptyElement)($xeTabs), (0, _vue.h)('span', {
class: 'vxe-tabs-header--item-name'
}, titleSlot ? callSlot(titleSlot, {
name,
title
}) : `${title}`), titleSuffixSlot ? (0, _vue.h)('span', {
class: 'vxe-tabs-header--item-suffix'
}, callSlot(titleSuffixSlot, {
name,
title
})) : (0, _ui.renderEmptyElement)($xeTabs)]), ((0, _utils.isEnableConf)(refreshConfig) || refreshOpts.enabled) && (refreshVisibleMethod ? refreshVisibleMethod(params) : true) ? (0, _vue.h)('div', {
class: ['vxe-tabs-header--refresh-btn', {
'is--active': isActive,
'is--loading': isLoading,
'is--disabled': isLoading
}],
onClick(evnt) {
handleRefreshTabEvent(evnt, item);
}
}, [(0, _vue.h)('i', {
class: isLoading ? (0, _ui.getIcon)().TABS_TAB_REFRESH_LOADING : (0, _ui.getIcon)().TABS_TAB_REFRESH
})]) : (0, _ui.renderEmptyElement)($xeTabs), (showClose || (0, _utils.isEnableConf)(closeConfig) || closeOpts.enabled) && (!closeVisibleMethod || closeVisibleMethod(params)) ? (0, _vue.h)('div', {
class: ['vxe-tabs-header--close-btn', {
'is--active': isActive
}],
onClick(evnt) {
handleCloseTabEvent(evnt, item, index, tabList);
}
}, [(0, _vue.h)('i', {
class: (0, _ui.getIcon)().TABS_TAB_CLOSE
})]) : (0, _ui.renderEmptyElement)($xeTabs)])]);
}).concat([(0, _vue.h)('span', {
key: 'line',
class: ['vxe-tabs-header--active-line', `type--${tabType}`, `pos--${tabPosition}`],
style: lineStyle
})]))]), isTabOver ? (0, _vue.h)('div', {
ref: refHeadNextElem,
class: ['vxe-tabs-header--bar vxe-tabs-header--next-bar', `type--${tabType}`, `pos--${tabPosition}`],
onClick: scrollRightEvent
}, [(0, _vue.h)('span', {
class: lrPosition ? (0, _ui.getIcon)().TABS_TAB_BUTTON_BOTTOM : (0, _ui.getIcon)().TABS_TAB_BUTTON_RIGHT
})]) : (0, _ui.renderEmptyElement)($xeTabs), tabSuffixSlot ? (0, _vue.h)('div', {
class: ['vxe-tabs-header--suffix', `type--${tabType}`, `pos--${tabPosition}`]
}, callSlot(tabSuffixSlot, {
name: activeName
})) : (0, _ui.renderEmptyElement)($xeTabs)]);
};
const renderTabPane = item => {
const {
initNames,
activeName
} = reactData;
const {
name,
slots
} = item;
const defaultSlot = slots ? slots.default : null;
return name && initNames.includes(name) ? (0, _vue.h)('div', {
key: `${name}`,
class: ['vxe-tabs-pane--item', {
'is--visible': activeName === name
}]
}, defaultSlot ? callSlot(defaultSlot, {
name
}) : []) : (0, _ui.renderEmptyElement)($xeTabs);
};
const renderTabContent = tabList => {
const {
destroyOnClose
} = props;
const {
activeName
} = reactData;
if (destroyOnClose) {
const activeTab = tabList.find(item => item.name === activeName);
return [activeTab ? renderTabPane(activeTab) : (0, _ui.renderEmptyElement)($xeTabs)];
}
return tabList.map(item => renderTabPane(item));
};
const rendetTabBody = tabList => {
const {
height,
padding,
showBody
} = props;
const {
activeName,
cacheTabMaps
} = reactData;
const vSize = computeSize.value;
const tabType = computeTabType.value;
const tabPosition = computeTabPosition.value;
const refreshOpts = computeRefreshOpts.value;
const {
showLoading
} = refreshOpts;
const headerpSlot = slots.header;
const footerSlot = slots.footer;
if (!showBody) {
return (0, _ui.renderEmptyElement)($xeTabs);
}
const cacheItem = activeName ? cacheTabMaps[`${activeName}`] : null;
const isLoading = cacheItem ? cacheItem.loading : false;
const defParams = {
name: activeName
};
return (0, _vue.h)('div', {
key: 'tb',
class: ['vxe-tabs-pane--wrapper', `type--${tabType}`, `pos--${tabPosition}`, {
'is--content': showBody
}]
}, [headerpSlot ? (0, _vue.h)('div', {
class: 'vxe-tabs-pane--header'
}, callSlot(headerpSlot, defParams)) : (0, _ui.renderEmptyElement)($xeTabs), (0, _vue.h)('div', {
class: ['vxe-tabs-pane--body', `type--${tabType}`, `pos--${tabPosition}`, {
[`size--${vSize}`]: vSize,
'is--padding': padding,
'is--height': height
}]
}, renderTabContent(tabList)), footerSlot ? (0, _vue.h)('div', {
class: 'vxe-tabs-pane--footer'
}, callSlot(footerSlot, defParams)) : (0, _ui.renderEmptyElement)($xeTabs), showLoading && isLoading ? (0, _ui.renderEmptyElement)($xeTabs) : (0, _vue.h)(_loading.default, {
class: 'vxe-tabs--loading',
modelValue: isLoading
})]);
};
const renderVN = () => {
const {
height,
padding,
trigger
} = props;
const {
activeName
} = reactData;
const vSize = computeSize.value;
const tabOptions = computeTabOptions.value;
const tabStaticOptions = computeTabStaticOptions.value;
const tabType = computeTabType.value;
const tabPosition = computeTabPosition.value;
const wrapperStyle = computeWrapperStyle.value;
const defaultSlot = slots.default;
const tabList = defaultSlot ? tabStaticOptions : tabOptions;
const vns = [(0, _vue.h)('div', {
key: 'ts',
class: 'vxe-tabs-slots'
}, defaultSlot ? defaultSlot({
name: activeName
}) : [])];
if (tabPosition === 'right' || tabPosition === 'bottom') {
vns.push(rendetTabBody(tabList), renderTabHeader(tabList));
} else {
vns.push(renderTabHeader(tabList), rendetTabBody(tabList));
}
return (0, _vue.h)('div', {
ref: refElem,
class: ['vxe-tabs', `pos--${tabPosition}`, `vxe-tabs--${tabType}`, `trigger--${trigger === 'manual' ? 'trigger' : 'default'}`, {
[`size--${vSize}`]: vSize,
'is--padding': padding,
'is--height': height
}],
style: wrapperStyle
}, vns);
};
(0, _vue.watch)(() => props.position, () => {
reactData.resizeFlag++;
});
(0, _vue.watch)(() => props.modelValue, val => {
addInitName(val, null);
reactData.activeName = val;
});
(0, _vue.watch)(() => reactData.activeName, val => {
scrollToTab(val);
});
const optsFlag = (0, _vue.ref)(0);
(0, _vue.watch)(() => props.options ? props.options.length : -1, () => {
optsFlag.value++;
});
(0, _vue.watch)(() => props.options, () => {
optsFlag.value++;
});
(0, _vue.watch)(optsFlag, () => {
initDefaultName(props.options);
reactData.resizeFlag++;
});
const stFlag = (0, _vue.ref)(0);
(0, _vue.watch)(() => reactData.staticTabs ? reactData.staticTabs.length : -1, () => {
stFlag.value++;
});
(0, _vue.watch)(() => reactData.staticTabs, () => {
stFlag.value++;
});
(0, _vue.watch)(stFlag, () => {
initDefaultName(reactData.staticTabs);
reactData.resizeFlag++;
});
(0, _vue.watch)(computeParentTabsResizeFlag, () => {
reactData.resizeFlag++;
});
(0, _vue.watch)(() => reactData.resizeFlag, () => {
(0, _vue.nextTick)(() => {
updateTabStyle();
});
});
(0, _vue.onMounted)(() => {
updateTabStyle();
_ui.globalEvents.on($xeTabs, 'resize', updateTabStyle);
});
(0, _vue.onUnmounted)(() => {
_ui.globalEvents.off($xeTabs, 'resize');
});
(0, _vue.provide)('$xeTabs', $xeTabs);
addInitName(props.modelValue, null);
initDefaultName(reactData.staticTabs.length ? reactData.staticTabs : props.options);
$xeTabs.renderVN = renderVN;
return $xeTabs;
},
render() {
return this.renderVN();
}
});