131 lines
4.2 KiB
JavaScript
131 lines
4.2 KiB
JavaScript
import { h, defineComponent, inject, computed, mergeProps, Fragment } from 'vue';
|
|
import { AddIcon } from "../../_internal/icons/index.mjs";
|
|
import { NBaseClose, NBaseIcon } from "../../_internal/index.mjs";
|
|
import { render, omit } from "../../_utils/index.mjs";
|
|
import { tabsInjectionKey } from "./interface.mjs";
|
|
import { tabPaneProps } from "./TabPane.mjs";
|
|
export const tabProps = Object.assign({
|
|
internalLeftPadded: Boolean,
|
|
internalAddable: Boolean,
|
|
internalCreatedByPane: Boolean
|
|
}, omit(tabPaneProps, ['displayDirective']));
|
|
export default defineComponent({
|
|
__TAB__: true,
|
|
inheritAttrs: false,
|
|
name: 'Tab',
|
|
props: tabProps,
|
|
setup(props) {
|
|
const {
|
|
mergedClsPrefixRef,
|
|
valueRef,
|
|
typeRef,
|
|
closableRef,
|
|
tabStyleRef,
|
|
addTabStyleRef,
|
|
tabClassRef,
|
|
addTabClassRef,
|
|
tabChangeIdRef,
|
|
onBeforeLeaveRef,
|
|
triggerRef,
|
|
handleAdd,
|
|
activateTab,
|
|
handleClose
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
} = inject(tabsInjectionKey);
|
|
return {
|
|
trigger: triggerRef,
|
|
mergedClosable: computed(() => {
|
|
if (props.internalAddable) return false;
|
|
const {
|
|
closable
|
|
} = props;
|
|
if (closable === undefined) return closableRef.value;
|
|
return closable;
|
|
}),
|
|
style: tabStyleRef,
|
|
addStyle: addTabStyleRef,
|
|
tabClass: tabClassRef,
|
|
addTabClass: addTabClassRef,
|
|
clsPrefix: mergedClsPrefixRef,
|
|
value: valueRef,
|
|
type: typeRef,
|
|
handleClose(e) {
|
|
e.stopPropagation();
|
|
if (props.disabled) return;
|
|
handleClose(props.name);
|
|
},
|
|
activateTab() {
|
|
if (props.disabled) return;
|
|
if (props.internalAddable) {
|
|
handleAdd();
|
|
return;
|
|
}
|
|
const {
|
|
name: nameProp
|
|
} = props;
|
|
const id = ++tabChangeIdRef.id;
|
|
if (nameProp !== valueRef.value) {
|
|
const {
|
|
value: onBeforeLeave
|
|
} = onBeforeLeaveRef;
|
|
if (!onBeforeLeave) {
|
|
activateTab(nameProp);
|
|
} else {
|
|
void Promise.resolve(onBeforeLeave(props.name, valueRef.value)).then(allowLeave => {
|
|
if (allowLeave && tabChangeIdRef.id === id) {
|
|
activateTab(nameProp);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
};
|
|
},
|
|
render() {
|
|
const {
|
|
internalAddable,
|
|
clsPrefix,
|
|
name,
|
|
disabled,
|
|
label,
|
|
tab,
|
|
value,
|
|
mergedClosable,
|
|
trigger,
|
|
$slots: {
|
|
default: defaultSlot
|
|
}
|
|
} = this;
|
|
const mergedTab = label !== null && label !== void 0 ? label : tab;
|
|
return h("div", {
|
|
class: `${clsPrefix}-tabs-tab-wrapper`
|
|
}, this.internalLeftPadded ? h("div", {
|
|
class: `${clsPrefix}-tabs-tab-pad`
|
|
}) : null, h("div", Object.assign({
|
|
key: name,
|
|
"data-name": name,
|
|
"data-disabled": disabled ? true : undefined
|
|
}, mergeProps({
|
|
class: [`${clsPrefix}-tabs-tab`, value === name && `${clsPrefix}-tabs-tab--active`, disabled && `${clsPrefix}-tabs-tab--disabled`, mergedClosable && `${clsPrefix}-tabs-tab--closable`, internalAddable && `${clsPrefix}-tabs-tab--addable`, internalAddable ? this.addTabClass : this.tabClass],
|
|
onClick: trigger === 'click' ? this.activateTab : undefined,
|
|
onMouseenter: trigger === 'hover' ? this.activateTab : undefined,
|
|
style: internalAddable ? this.addStyle : this.style
|
|
},
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
this.internalCreatedByPane ? this.tabProps || {} : this.$attrs)), h("span", {
|
|
class: `${clsPrefix}-tabs-tab__label`
|
|
}, internalAddable ? h(Fragment, null, h("div", {
|
|
class: `${clsPrefix}-tabs-tab__height-placeholder`
|
|
}, "\u00A0"), h(NBaseIcon, {
|
|
clsPrefix: clsPrefix
|
|
}, {
|
|
default: () => h(AddIcon, null)
|
|
})) : defaultSlot ? defaultSlot() : typeof mergedTab === 'object' ? mergedTab // VNode
|
|
: render(mergedTab !== null && mergedTab !== void 0 ? mergedTab : name)), mergedClosable && this.type === 'card' ? h(NBaseClose, {
|
|
clsPrefix: clsPrefix,
|
|
class: `${clsPrefix}-tabs-tab__close`,
|
|
onClick: this.handleClose,
|
|
disabled: disabled
|
|
}) : null));
|
|
}
|
|
}); |