2601 lines
76 KiB
JavaScript
2601 lines
76 KiB
JavaScript
import _objectSpread$1 from '@babel/runtime/helpers/esm/objectSpread2';
|
|
import _extends from '@babel/runtime/helpers/esm/extends';
|
|
import { createVNode, defineComponent, ref, watch, computed, watchEffect, provide, shallowRef, inject, Fragment, toRefs } from 'vue';
|
|
import { w as wrapperRaf } from './raf-ruCY1ktO.mjs';
|
|
import { ba as Icon, J as initDefaultProps, H as flattenChildren, E as omit, P as PropTypes, a9 as isValidElement, bp as camelize, aB as devWarning, C as useConfigInject, D as genComponentStyleHook, bq as useState$1, aq as CloseOutlined, F as classNames, G as arrayType, V as functionType, K as objectType, W as stringType, X as booleanType, aA as someType, Z as merge, br as toPx, ac as cloneElement, N as resetComponent, O as textEllipsis, bs as genFocusStyle, Q as KeyCode, bt as skipFlattenKey } from './server.mjs';
|
|
import { u as useProvideOverride, E as EllipsisOutlined, M as Menu, _ as __nuxt_component_1 } from './index-BlNIpVst.mjs';
|
|
import { T as Trigger } from './index-Dxyzjwb5.mjs';
|
|
import { R as ResizeObserver } from './BaseInput-_gwhwanN.mjs';
|
|
import { u as useRefs } from './useRefs-BHKrVg4I.mjs';
|
|
import pick from 'lodash-es/pick.js';
|
|
import { u as useMergedState } from './useMergedState-BZEfJ8Fl.mjs';
|
|
import { i as initSlideMotion } from './slide-Bfj4jnqX.mjs';
|
|
|
|
// This icon file is generated automatically.
|
|
var PlusOutlined$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "64 64 896 896", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z" } }, { "tag": "path", "attrs": { "d": "M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8z" } }] }, "name": "plus", "theme": "outlined" };
|
|
|
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
|
|
|
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
|
|
var PlusOutlined = function PlusOutlined(props, context) {
|
|
var p = _objectSpread({}, props, context.attrs);
|
|
|
|
return createVNode(Icon, _objectSpread({}, p, {
|
|
"icon": PlusOutlined$1
|
|
}), null);
|
|
};
|
|
|
|
PlusOutlined.displayName = 'PlusOutlined';
|
|
PlusOutlined.inheritAttrs = false;
|
|
|
|
const autoAdjustOverflow = {
|
|
adjustX: 1,
|
|
adjustY: 1
|
|
};
|
|
const targetOffset = [0, 0];
|
|
const placements = {
|
|
topLeft: {
|
|
points: ["bl", "tl"],
|
|
overflow: autoAdjustOverflow,
|
|
offset: [0, -4],
|
|
targetOffset
|
|
},
|
|
topCenter: {
|
|
points: ["bc", "tc"],
|
|
overflow: autoAdjustOverflow,
|
|
offset: [0, -4],
|
|
targetOffset
|
|
},
|
|
topRight: {
|
|
points: ["br", "tr"],
|
|
overflow: autoAdjustOverflow,
|
|
offset: [0, -4],
|
|
targetOffset
|
|
},
|
|
bottomLeft: {
|
|
points: ["tl", "bl"],
|
|
overflow: autoAdjustOverflow,
|
|
offset: [0, 4],
|
|
targetOffset
|
|
},
|
|
bottomCenter: {
|
|
points: ["tc", "bc"],
|
|
overflow: autoAdjustOverflow,
|
|
offset: [0, 4],
|
|
targetOffset
|
|
},
|
|
bottomRight: {
|
|
points: ["tr", "br"],
|
|
overflow: autoAdjustOverflow,
|
|
offset: [0, 4],
|
|
targetOffset
|
|
}
|
|
};
|
|
var __rest = function(s, e) {
|
|
var t = {};
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
|
|
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
|
|
}
|
|
return t;
|
|
};
|
|
const Dropdown = defineComponent({
|
|
compatConfig: {
|
|
MODE: 3
|
|
},
|
|
props: {
|
|
minOverlayWidthMatchTrigger: {
|
|
type: Boolean,
|
|
default: void 0
|
|
},
|
|
arrow: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
prefixCls: PropTypes.string.def("rc-dropdown"),
|
|
transitionName: String,
|
|
overlayClassName: PropTypes.string.def(""),
|
|
openClassName: String,
|
|
animation: PropTypes.any,
|
|
align: PropTypes.object,
|
|
overlayStyle: {
|
|
type: Object,
|
|
default: void 0
|
|
},
|
|
placement: PropTypes.string.def("bottomLeft"),
|
|
overlay: PropTypes.any,
|
|
trigger: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]).def("hover"),
|
|
alignPoint: {
|
|
type: Boolean,
|
|
default: void 0
|
|
},
|
|
showAction: PropTypes.array,
|
|
hideAction: PropTypes.array,
|
|
getPopupContainer: Function,
|
|
visible: {
|
|
type: Boolean,
|
|
default: void 0
|
|
},
|
|
defaultVisible: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
mouseEnterDelay: PropTypes.number.def(0.15),
|
|
mouseLeaveDelay: PropTypes.number.def(0.1)
|
|
},
|
|
emits: ["visibleChange", "overlayClick"],
|
|
setup(props, _ref) {
|
|
let {
|
|
slots,
|
|
emit,
|
|
expose
|
|
} = _ref;
|
|
const triggerVisible = ref(!!props.visible);
|
|
watch(() => props.visible, (val) => {
|
|
if (val !== void 0) {
|
|
triggerVisible.value = val;
|
|
}
|
|
});
|
|
const triggerRef = ref();
|
|
expose({
|
|
triggerRef
|
|
});
|
|
const onClick = (e) => {
|
|
if (props.visible === void 0) {
|
|
triggerVisible.value = false;
|
|
}
|
|
emit("overlayClick", e);
|
|
};
|
|
const onVisibleChange = (visible) => {
|
|
if (props.visible === void 0) {
|
|
triggerVisible.value = visible;
|
|
}
|
|
emit("visibleChange", visible);
|
|
};
|
|
const getMenuElement = () => {
|
|
var _a;
|
|
const overlayElement = (_a = slots.overlay) === null || _a === void 0 ? void 0 : _a.call(slots);
|
|
const extraOverlayProps = {
|
|
prefixCls: `${props.prefixCls}-menu`,
|
|
onClick
|
|
};
|
|
return createVNode(Fragment, {
|
|
"key": skipFlattenKey
|
|
}, [props.arrow && createVNode("div", {
|
|
"class": `${props.prefixCls}-arrow`
|
|
}, null), cloneElement(overlayElement, extraOverlayProps, false)]);
|
|
};
|
|
const minOverlayWidthMatchTrigger = computed(() => {
|
|
const {
|
|
minOverlayWidthMatchTrigger: matchTrigger = !props.alignPoint
|
|
} = props;
|
|
return matchTrigger;
|
|
});
|
|
const renderChildren = () => {
|
|
var _a;
|
|
const children = (_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots);
|
|
return triggerVisible.value && children ? cloneElement(children[0], {
|
|
class: props.openClassName || `${props.prefixCls}-open`
|
|
}, false) : children;
|
|
};
|
|
const triggerHideAction = computed(() => {
|
|
if (!props.hideAction && props.trigger.indexOf("contextmenu") !== -1) {
|
|
return ["click"];
|
|
}
|
|
return props.hideAction;
|
|
});
|
|
return () => {
|
|
const {
|
|
prefixCls,
|
|
arrow,
|
|
showAction,
|
|
overlayStyle,
|
|
trigger,
|
|
placement,
|
|
align,
|
|
getPopupContainer,
|
|
transitionName,
|
|
animation,
|
|
overlayClassName
|
|
} = props, otherProps = __rest(props, ["prefixCls", "arrow", "showAction", "overlayStyle", "trigger", "placement", "align", "getPopupContainer", "transitionName", "animation", "overlayClassName"]);
|
|
return createVNode(Trigger, _objectSpread$1(_objectSpread$1({}, otherProps), {}, {
|
|
"prefixCls": prefixCls,
|
|
"ref": triggerRef,
|
|
"popupClassName": classNames(overlayClassName, {
|
|
[`${prefixCls}-show-arrow`]: arrow
|
|
}),
|
|
"popupStyle": overlayStyle,
|
|
"builtinPlacements": placements,
|
|
"action": trigger,
|
|
"showAction": showAction,
|
|
"hideAction": triggerHideAction.value || [],
|
|
"popupPlacement": placement,
|
|
"popupAlign": align,
|
|
"popupTransitionName": transitionName,
|
|
"popupAnimation": animation,
|
|
"popupVisible": triggerVisible.value,
|
|
"stretch": minOverlayWidthMatchTrigger.value ? "minWidth" : "",
|
|
"onPopupVisibleChange": onVisibleChange,
|
|
"getPopupContainer": getPopupContainer
|
|
}), {
|
|
popup: getMenuElement,
|
|
default: renderChildren
|
|
});
|
|
};
|
|
}
|
|
});
|
|
function useRaf(callback) {
|
|
const rafRef = shallowRef();
|
|
const removedRef = shallowRef(false);
|
|
function trigger() {
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
if (!removedRef.value) {
|
|
wrapperRaf.cancel(rafRef.value);
|
|
rafRef.value = wrapperRaf(() => {
|
|
callback(...args);
|
|
});
|
|
}
|
|
}
|
|
return trigger;
|
|
}
|
|
function useRafState(defaultState) {
|
|
const batchRef = shallowRef([]);
|
|
const state = shallowRef(typeof defaultState === "function" ? defaultState() : defaultState);
|
|
const flushUpdate = useRaf(() => {
|
|
let value = state.value;
|
|
batchRef.value.forEach((callback) => {
|
|
value = callback(value);
|
|
});
|
|
batchRef.value = [];
|
|
state.value = value;
|
|
});
|
|
function updater(callback) {
|
|
batchRef.value.push(callback);
|
|
flushUpdate();
|
|
}
|
|
return [state, updater];
|
|
}
|
|
const TabNode = defineComponent({
|
|
compatConfig: {
|
|
MODE: 3
|
|
},
|
|
name: "TabNode",
|
|
props: {
|
|
id: {
|
|
type: String
|
|
},
|
|
prefixCls: {
|
|
type: String
|
|
},
|
|
tab: {
|
|
type: Object
|
|
},
|
|
active: {
|
|
type: Boolean
|
|
},
|
|
closable: {
|
|
type: Boolean
|
|
},
|
|
editable: {
|
|
type: Object
|
|
},
|
|
onClick: {
|
|
type: Function
|
|
},
|
|
onResize: {
|
|
type: Function
|
|
},
|
|
renderWrapper: {
|
|
type: Function
|
|
},
|
|
removeAriaLabel: {
|
|
type: String
|
|
},
|
|
// onRemove: { type: Function as PropType<() => void> },
|
|
onFocus: {
|
|
type: Function
|
|
}
|
|
},
|
|
emits: ["click", "resize", "remove", "focus"],
|
|
setup(props, _ref) {
|
|
let {
|
|
expose,
|
|
attrs
|
|
} = _ref;
|
|
const domRef = ref();
|
|
function onInternalClick(e) {
|
|
var _a;
|
|
if ((_a = props.tab) === null || _a === void 0 ? void 0 : _a.disabled) {
|
|
return;
|
|
}
|
|
props.onClick(e);
|
|
}
|
|
expose({
|
|
domRef
|
|
});
|
|
function onRemoveTab(event) {
|
|
var _a;
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
props.editable.onEdit("remove", {
|
|
key: (_a = props.tab) === null || _a === void 0 ? void 0 : _a.key,
|
|
event
|
|
});
|
|
}
|
|
const removable = computed(() => {
|
|
var _a;
|
|
return props.editable && props.closable !== false && !((_a = props.tab) === null || _a === void 0 ? void 0 : _a.disabled);
|
|
});
|
|
return () => {
|
|
var _a;
|
|
const {
|
|
prefixCls,
|
|
id,
|
|
active,
|
|
tab: {
|
|
key,
|
|
tab,
|
|
disabled,
|
|
closeIcon
|
|
},
|
|
renderWrapper,
|
|
removeAriaLabel,
|
|
editable,
|
|
onFocus
|
|
} = props;
|
|
const tabPrefix = `${prefixCls}-tab`;
|
|
const node = createVNode("div", {
|
|
"key": key,
|
|
"ref": domRef,
|
|
"class": classNames(tabPrefix, {
|
|
[`${tabPrefix}-with-remove`]: removable.value,
|
|
[`${tabPrefix}-active`]: active,
|
|
[`${tabPrefix}-disabled`]: disabled
|
|
}),
|
|
"style": attrs.style,
|
|
"onClick": onInternalClick
|
|
}, [createVNode("div", {
|
|
"role": "tab",
|
|
"aria-selected": active,
|
|
"id": id && `${id}-tab-${key}`,
|
|
"class": `${tabPrefix}-btn`,
|
|
"aria-controls": id && `${id}-panel-${key}`,
|
|
"aria-disabled": disabled,
|
|
"tabindex": disabled ? null : 0,
|
|
"onClick": (e) => {
|
|
e.stopPropagation();
|
|
onInternalClick(e);
|
|
},
|
|
"onKeydown": (e) => {
|
|
if ([KeyCode.SPACE, KeyCode.ENTER].includes(e.which)) {
|
|
e.preventDefault();
|
|
onInternalClick(e);
|
|
}
|
|
},
|
|
"onFocus": onFocus
|
|
}, [typeof tab === "function" ? tab() : tab]), removable.value && createVNode("button", {
|
|
"type": "button",
|
|
"aria-label": removeAriaLabel || "remove",
|
|
"tabindex": 0,
|
|
"class": `${tabPrefix}-remove`,
|
|
"onClick": (e) => {
|
|
e.stopPropagation();
|
|
onRemoveTab(e);
|
|
}
|
|
}, [(closeIcon === null || closeIcon === void 0 ? void 0 : closeIcon()) || ((_a = editable.removeIcon) === null || _a === void 0 ? void 0 : _a.call(editable)) || "\xD7"])]);
|
|
return renderWrapper ? renderWrapper(node) : node;
|
|
};
|
|
}
|
|
});
|
|
const DEFAULT_SIZE$1 = {
|
|
width: 0,
|
|
height: 0,
|
|
left: 0,
|
|
top: 0
|
|
};
|
|
function useOffsets(tabs, tabSizes) {
|
|
const offsetMap = ref(/* @__PURE__ */ new Map());
|
|
watchEffect(() => {
|
|
var _a, _b;
|
|
const map = /* @__PURE__ */ new Map();
|
|
const tabsValue = tabs.value;
|
|
const lastOffset = tabSizes.value.get((_a = tabsValue[0]) === null || _a === void 0 ? void 0 : _a.key) || DEFAULT_SIZE$1;
|
|
const rightOffset = lastOffset.left + lastOffset.width;
|
|
for (let i = 0; i < tabsValue.length; i += 1) {
|
|
const {
|
|
key
|
|
} = tabsValue[i];
|
|
let data = tabSizes.value.get(key);
|
|
if (!data) {
|
|
data = tabSizes.value.get((_b = tabsValue[i - 1]) === null || _b === void 0 ? void 0 : _b.key) || DEFAULT_SIZE$1;
|
|
}
|
|
const entity = map.get(key) || _extends({}, data);
|
|
entity.right = rightOffset - entity.left - entity.width;
|
|
map.set(key, entity);
|
|
}
|
|
offsetMap.value = new Map(map);
|
|
});
|
|
return offsetMap;
|
|
}
|
|
const AddButton = defineComponent({
|
|
compatConfig: {
|
|
MODE: 3
|
|
},
|
|
name: "AddButton",
|
|
inheritAttrs: false,
|
|
props: {
|
|
prefixCls: String,
|
|
editable: {
|
|
type: Object
|
|
},
|
|
locale: {
|
|
type: Object,
|
|
default: void 0
|
|
}
|
|
},
|
|
setup(props, _ref) {
|
|
let {
|
|
expose,
|
|
attrs
|
|
} = _ref;
|
|
const domRef = ref();
|
|
expose({
|
|
domRef
|
|
});
|
|
return () => {
|
|
const {
|
|
prefixCls,
|
|
editable,
|
|
locale
|
|
} = props;
|
|
if (!editable || editable.showAdd === false) {
|
|
return null;
|
|
}
|
|
return createVNode("button", {
|
|
"ref": domRef,
|
|
"type": "button",
|
|
"class": `${prefixCls}-nav-add`,
|
|
"style": attrs.style,
|
|
"aria-label": (locale === null || locale === void 0 ? void 0 : locale.addAriaLabel) || "Add tab",
|
|
"onClick": (event) => {
|
|
editable.onEdit("add", {
|
|
event
|
|
});
|
|
}
|
|
}, [editable.addIcon ? editable.addIcon() : "+"]);
|
|
};
|
|
}
|
|
});
|
|
const operationNodeProps = {
|
|
prefixCls: {
|
|
type: String
|
|
},
|
|
id: {
|
|
type: String
|
|
},
|
|
tabs: {
|
|
type: Object
|
|
},
|
|
rtl: {
|
|
type: Boolean
|
|
},
|
|
tabBarGutter: {
|
|
type: Number
|
|
},
|
|
activeKey: {
|
|
type: [String, Number]
|
|
},
|
|
mobile: {
|
|
type: Boolean
|
|
},
|
|
moreIcon: PropTypes.any,
|
|
moreTransitionName: {
|
|
type: String
|
|
},
|
|
editable: {
|
|
type: Object
|
|
},
|
|
locale: {
|
|
type: Object,
|
|
default: void 0
|
|
},
|
|
removeAriaLabel: String,
|
|
onTabClick: {
|
|
type: Function
|
|
},
|
|
popupClassName: String,
|
|
getPopupContainer: functionType()
|
|
};
|
|
const OperationNode = defineComponent({
|
|
compatConfig: {
|
|
MODE: 3
|
|
},
|
|
name: "OperationNode",
|
|
inheritAttrs: false,
|
|
props: operationNodeProps,
|
|
emits: ["tabClick"],
|
|
slots: Object,
|
|
setup(props, _ref) {
|
|
let {
|
|
attrs,
|
|
slots
|
|
} = _ref;
|
|
const [open, setOpen] = useState$1(false);
|
|
const [selectedKey, setSelectedKey] = useState$1(null);
|
|
const selectOffset = (offset) => {
|
|
const enabledTabs = props.tabs.filter((tab) => !tab.disabled);
|
|
let selectedIndex = enabledTabs.findIndex((tab) => tab.key === selectedKey.value) || 0;
|
|
const len = enabledTabs.length;
|
|
for (let i = 0; i < len; i += 1) {
|
|
selectedIndex = (selectedIndex + offset + len) % len;
|
|
const tab = enabledTabs[selectedIndex];
|
|
if (!tab.disabled) {
|
|
setSelectedKey(tab.key);
|
|
return;
|
|
}
|
|
}
|
|
};
|
|
const onKeyDown = (e) => {
|
|
const {
|
|
which
|
|
} = e;
|
|
if (!open.value) {
|
|
if ([KeyCode.DOWN, KeyCode.SPACE, KeyCode.ENTER].includes(which)) {
|
|
setOpen(true);
|
|
e.preventDefault();
|
|
}
|
|
return;
|
|
}
|
|
switch (which) {
|
|
case KeyCode.UP:
|
|
selectOffset(-1);
|
|
e.preventDefault();
|
|
break;
|
|
case KeyCode.DOWN:
|
|
selectOffset(1);
|
|
e.preventDefault();
|
|
break;
|
|
case KeyCode.ESC:
|
|
setOpen(false);
|
|
break;
|
|
case KeyCode.SPACE:
|
|
case KeyCode.ENTER:
|
|
if (selectedKey.value !== null) props.onTabClick(selectedKey.value, e);
|
|
break;
|
|
}
|
|
};
|
|
const popupId = computed(() => `${props.id}-more-popup`);
|
|
const selectedItemId = computed(() => selectedKey.value !== null ? `${popupId.value}-${selectedKey.value}` : null);
|
|
const onRemoveTab = (event, key) => {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
props.editable.onEdit("remove", {
|
|
key,
|
|
event
|
|
});
|
|
};
|
|
watch(open, () => {
|
|
if (!open.value) {
|
|
setSelectedKey(null);
|
|
}
|
|
});
|
|
useProvideOverride({});
|
|
return () => {
|
|
var _a;
|
|
const {
|
|
prefixCls,
|
|
id,
|
|
tabs,
|
|
locale,
|
|
mobile,
|
|
moreIcon = ((_a = slots.moreIcon) === null || _a === void 0 ? void 0 : _a.call(slots)) || createVNode(EllipsisOutlined, null, null),
|
|
moreTransitionName,
|
|
editable,
|
|
tabBarGutter,
|
|
rtl,
|
|
onTabClick,
|
|
popupClassName
|
|
} = props;
|
|
if (!tabs.length) return null;
|
|
const dropdownPrefix = `${prefixCls}-dropdown`;
|
|
const dropdownAriaLabel = locale === null || locale === void 0 ? void 0 : locale.dropdownAriaLabel;
|
|
const moreStyle = {
|
|
[rtl ? "marginRight" : "marginLeft"]: tabBarGutter
|
|
};
|
|
if (!tabs.length) {
|
|
moreStyle.visibility = "hidden";
|
|
moreStyle.order = 1;
|
|
}
|
|
const overlayClassName = classNames({
|
|
[`${dropdownPrefix}-rtl`]: rtl,
|
|
[`${popupClassName}`]: true
|
|
});
|
|
const moreNode = mobile ? null : createVNode(Dropdown, {
|
|
"prefixCls": dropdownPrefix,
|
|
"trigger": ["hover"],
|
|
"visible": open.value,
|
|
"transitionName": moreTransitionName,
|
|
"onVisibleChange": setOpen,
|
|
"overlayClassName": overlayClassName,
|
|
"mouseEnterDelay": 0.1,
|
|
"mouseLeaveDelay": 0.1,
|
|
"getPopupContainer": props.getPopupContainer
|
|
}, {
|
|
overlay: () => createVNode(Menu, {
|
|
"onClick": (_ref2) => {
|
|
let {
|
|
key,
|
|
domEvent
|
|
} = _ref2;
|
|
onTabClick(key, domEvent);
|
|
setOpen(false);
|
|
},
|
|
"id": popupId.value,
|
|
"tabindex": -1,
|
|
"role": "listbox",
|
|
"aria-activedescendant": selectedItemId.value,
|
|
"selectedKeys": [selectedKey.value],
|
|
"aria-label": dropdownAriaLabel !== void 0 ? dropdownAriaLabel : "expanded dropdown"
|
|
}, {
|
|
default: () => [tabs.map((tab) => {
|
|
var _a2, _b;
|
|
const removable = editable && tab.closable !== false && !tab.disabled;
|
|
return createVNode(__nuxt_component_1, {
|
|
"key": tab.key,
|
|
"id": `${popupId.value}-${tab.key}`,
|
|
"role": "option",
|
|
"aria-controls": id && `${id}-panel-${tab.key}`,
|
|
"disabled": tab.disabled
|
|
}, {
|
|
default: () => [createVNode("span", null, [typeof tab.tab === "function" ? tab.tab() : tab.tab]), removable && createVNode("button", {
|
|
"type": "button",
|
|
"aria-label": props.removeAriaLabel || "remove",
|
|
"tabindex": 0,
|
|
"class": `${dropdownPrefix}-menu-item-remove`,
|
|
"onClick": (e) => {
|
|
e.stopPropagation();
|
|
onRemoveTab(e, tab.key);
|
|
}
|
|
}, [((_a2 = tab.closeIcon) === null || _a2 === void 0 ? void 0 : _a2.call(tab)) || ((_b = editable.removeIcon) === null || _b === void 0 ? void 0 : _b.call(editable)) || "\xD7"])]
|
|
});
|
|
})]
|
|
}),
|
|
default: () => createVNode("button", {
|
|
"type": "button",
|
|
"class": `${prefixCls}-nav-more`,
|
|
"style": moreStyle,
|
|
"tabindex": -1,
|
|
"aria-hidden": "true",
|
|
"aria-haspopup": "listbox",
|
|
"aria-controls": popupId.value,
|
|
"id": `${id}-more`,
|
|
"aria-expanded": open.value,
|
|
"onKeydown": onKeyDown
|
|
}, [moreIcon])
|
|
});
|
|
return createVNode("div", {
|
|
"class": classNames(`${prefixCls}-nav-operations`, attrs.class),
|
|
"style": attrs.style
|
|
}, [moreNode, createVNode(AddButton, {
|
|
"prefixCls": prefixCls,
|
|
"locale": locale,
|
|
"editable": editable
|
|
}, null)]);
|
|
};
|
|
}
|
|
});
|
|
const TabsContextKey = Symbol("tabsContextKey");
|
|
const useProvideTabs = (props) => {
|
|
provide(TabsContextKey, props);
|
|
};
|
|
const useInjectTabs = () => {
|
|
return inject(TabsContextKey, {
|
|
tabs: ref([]),
|
|
prefixCls: ref()
|
|
});
|
|
};
|
|
defineComponent({
|
|
compatConfig: {
|
|
MODE: 3
|
|
},
|
|
name: "TabsContextProvider",
|
|
inheritAttrs: false,
|
|
props: {
|
|
tabs: {
|
|
type: Object,
|
|
default: void 0
|
|
},
|
|
prefixCls: {
|
|
type: String,
|
|
default: void 0
|
|
}
|
|
},
|
|
setup(props, _ref) {
|
|
let {
|
|
slots
|
|
} = _ref;
|
|
useProvideTabs(toRefs(props));
|
|
return () => {
|
|
var _a;
|
|
return (_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots);
|
|
};
|
|
}
|
|
});
|
|
const MIN_SWIPE_DISTANCE = 0.1;
|
|
const STOP_SWIPE_DISTANCE = 0.01;
|
|
const REFRESH_INTERVAL = 20;
|
|
const SPEED_OFF_MULTIPLE = Math.pow(0.995, REFRESH_INTERVAL);
|
|
function useTouchMove(domRef, onOffset) {
|
|
const [touchPosition, setTouchPosition] = useState$1();
|
|
const [lastTimestamp, setLastTimestamp] = useState$1(0);
|
|
const [lastTimeDiff, setLastTimeDiff] = useState$1(0);
|
|
const [lastOffset, setLastOffset] = useState$1();
|
|
const motionInterval = ref();
|
|
function onTouchStart(e) {
|
|
const {
|
|
screenX,
|
|
screenY
|
|
} = e.touches[0];
|
|
setTouchPosition({
|
|
x: screenX,
|
|
y: screenY
|
|
});
|
|
clearInterval(motionInterval.value);
|
|
}
|
|
function onTouchMove(e) {
|
|
if (!touchPosition.value) return;
|
|
e.preventDefault();
|
|
const {
|
|
screenX,
|
|
screenY
|
|
} = e.touches[0];
|
|
const offsetX = screenX - touchPosition.value.x;
|
|
const offsetY = screenY - touchPosition.value.y;
|
|
onOffset(offsetX, offsetY);
|
|
setTouchPosition({
|
|
x: screenX,
|
|
y: screenY
|
|
});
|
|
const now = Date.now();
|
|
setLastTimeDiff(now - lastTimestamp.value);
|
|
setLastTimestamp(now);
|
|
setLastOffset({
|
|
x: offsetX,
|
|
y: offsetY
|
|
});
|
|
}
|
|
function onTouchEnd() {
|
|
if (!touchPosition.value) return;
|
|
const lastOffsetValue = lastOffset.value;
|
|
setTouchPosition(null);
|
|
setLastOffset(null);
|
|
if (lastOffsetValue) {
|
|
const distanceX = lastOffsetValue.x / lastTimeDiff.value;
|
|
const distanceY = lastOffsetValue.y / lastTimeDiff.value;
|
|
const absX = Math.abs(distanceX);
|
|
const absY = Math.abs(distanceY);
|
|
if (Math.max(absX, absY) < MIN_SWIPE_DISTANCE) return;
|
|
let currentX = distanceX;
|
|
let currentY = distanceY;
|
|
motionInterval.value = setInterval(() => {
|
|
if (Math.abs(currentX) < STOP_SWIPE_DISTANCE && Math.abs(currentY) < STOP_SWIPE_DISTANCE) {
|
|
clearInterval(motionInterval.value);
|
|
return;
|
|
}
|
|
currentX *= SPEED_OFF_MULTIPLE;
|
|
currentY *= SPEED_OFF_MULTIPLE;
|
|
onOffset(currentX * REFRESH_INTERVAL, currentY * REFRESH_INTERVAL);
|
|
}, REFRESH_INTERVAL);
|
|
}
|
|
}
|
|
const lastWheelDirectionRef = ref();
|
|
function onWheel(e) {
|
|
const {
|
|
deltaX,
|
|
deltaY
|
|
} = e;
|
|
let mixed = 0;
|
|
const absX = Math.abs(deltaX);
|
|
const absY = Math.abs(deltaY);
|
|
if (absX === absY) {
|
|
mixed = lastWheelDirectionRef.value === "x" ? deltaX : deltaY;
|
|
} else if (absX > absY) {
|
|
mixed = deltaX;
|
|
lastWheelDirectionRef.value = "x";
|
|
} else {
|
|
mixed = deltaY;
|
|
lastWheelDirectionRef.value = "y";
|
|
}
|
|
if (onOffset(-mixed, -mixed)) {
|
|
e.preventDefault();
|
|
}
|
|
}
|
|
ref({
|
|
onTouchStart,
|
|
onTouchMove,
|
|
onTouchEnd,
|
|
onWheel
|
|
});
|
|
}
|
|
function useSyncState(defaultState, onChange) {
|
|
const stateRef = ref(defaultState);
|
|
function setState(updater) {
|
|
const newValue = typeof updater === "function" ? updater(stateRef.value) : updater;
|
|
if (newValue !== stateRef.value) {
|
|
onChange(newValue, stateRef.value);
|
|
}
|
|
stateRef.value = newValue;
|
|
}
|
|
return [stateRef, setState];
|
|
}
|
|
const DEFAULT_SIZE = {
|
|
width: 0,
|
|
height: 0,
|
|
left: 0,
|
|
top: 0,
|
|
right: 0
|
|
};
|
|
const tabNavListProps = () => {
|
|
return {
|
|
id: {
|
|
type: String
|
|
},
|
|
tabPosition: {
|
|
type: String
|
|
},
|
|
activeKey: {
|
|
type: [String, Number]
|
|
},
|
|
rtl: {
|
|
type: Boolean
|
|
},
|
|
animated: objectType(),
|
|
editable: objectType(),
|
|
moreIcon: PropTypes.any,
|
|
moreTransitionName: {
|
|
type: String
|
|
},
|
|
mobile: {
|
|
type: Boolean
|
|
},
|
|
tabBarGutter: {
|
|
type: Number
|
|
},
|
|
renderTabBar: {
|
|
type: Function
|
|
},
|
|
locale: objectType(),
|
|
popupClassName: String,
|
|
getPopupContainer: functionType(),
|
|
onTabClick: {
|
|
type: Function
|
|
},
|
|
onTabScroll: {
|
|
type: Function
|
|
}
|
|
};
|
|
};
|
|
const getTabSize = (tab, containerRect) => {
|
|
const {
|
|
offsetWidth,
|
|
offsetHeight,
|
|
offsetTop,
|
|
offsetLeft
|
|
} = tab;
|
|
const {
|
|
width,
|
|
height,
|
|
x,
|
|
y
|
|
} = tab.getBoundingClientRect();
|
|
if (Math.abs(width - offsetWidth) < 1) {
|
|
return [width, height, x - containerRect.x, y - containerRect.y];
|
|
}
|
|
return [offsetWidth, offsetHeight, offsetLeft, offsetTop];
|
|
};
|
|
const TabNavList = defineComponent({
|
|
compatConfig: {
|
|
MODE: 3
|
|
},
|
|
name: "TabNavList",
|
|
inheritAttrs: false,
|
|
props: tabNavListProps(),
|
|
slots: Object,
|
|
emits: ["tabClick", "tabScroll"],
|
|
setup(props, _ref) {
|
|
let {
|
|
attrs,
|
|
slots
|
|
} = _ref;
|
|
const {
|
|
tabs,
|
|
prefixCls
|
|
} = useInjectTabs();
|
|
const tabsWrapperRef = shallowRef();
|
|
const tabListRef = shallowRef();
|
|
const operationsRef = shallowRef();
|
|
const innerAddButtonRef = shallowRef();
|
|
const [setRef, btnRefs] = useRefs();
|
|
const tabPositionTopOrBottom = computed(() => props.tabPosition === "top" || props.tabPosition === "bottom");
|
|
const [transformLeft, setTransformLeft] = useSyncState(0, (next, prev) => {
|
|
if (tabPositionTopOrBottom.value && props.onTabScroll) {
|
|
props.onTabScroll({
|
|
direction: next > prev ? "left" : "right"
|
|
});
|
|
}
|
|
});
|
|
const [transformTop, setTransformTop] = useSyncState(0, (next, prev) => {
|
|
if (!tabPositionTopOrBottom.value && props.onTabScroll) {
|
|
props.onTabScroll({
|
|
direction: next > prev ? "top" : "bottom"
|
|
});
|
|
}
|
|
});
|
|
const [wrapperScrollWidth, setWrapperScrollWidth] = useState$1(0);
|
|
const [wrapperScrollHeight, setWrapperScrollHeight] = useState$1(0);
|
|
const [wrapperWidth, setWrapperWidth] = useState$1(null);
|
|
const [wrapperHeight, setWrapperHeight] = useState$1(null);
|
|
const [addWidth, setAddWidth] = useState$1(0);
|
|
const [addHeight, setAddHeight] = useState$1(0);
|
|
const [tabSizes, setTabSizes] = useRafState(/* @__PURE__ */ new Map());
|
|
const tabOffsets = useOffsets(tabs, tabSizes);
|
|
const operationsHiddenClassName = computed(() => `${prefixCls.value}-nav-operations-hidden`);
|
|
const transformMin = shallowRef(0);
|
|
const transformMax = shallowRef(0);
|
|
watchEffect(() => {
|
|
if (!tabPositionTopOrBottom.value) {
|
|
transformMin.value = Math.min(0, wrapperHeight.value - wrapperScrollHeight.value);
|
|
transformMax.value = 0;
|
|
} else if (props.rtl) {
|
|
transformMin.value = 0;
|
|
transformMax.value = Math.max(0, wrapperScrollWidth.value - wrapperWidth.value);
|
|
} else {
|
|
transformMin.value = Math.min(0, wrapperWidth.value - wrapperScrollWidth.value);
|
|
transformMax.value = 0;
|
|
}
|
|
});
|
|
const alignInRange = (value) => {
|
|
if (value < transformMin.value) {
|
|
return transformMin.value;
|
|
}
|
|
if (value > transformMax.value) {
|
|
return transformMax.value;
|
|
}
|
|
return value;
|
|
};
|
|
const touchMovingRef = shallowRef();
|
|
const [lockAnimation, setLockAnimation] = useState$1();
|
|
const doLockAnimation = () => {
|
|
setLockAnimation(Date.now());
|
|
};
|
|
const clearTouchMoving = () => {
|
|
clearTimeout(touchMovingRef.value);
|
|
};
|
|
const doMove = (setState, offset) => {
|
|
setState((value) => {
|
|
const newValue = alignInRange(value + offset);
|
|
return newValue;
|
|
});
|
|
};
|
|
useTouchMove(tabsWrapperRef, (offsetX, offsetY) => {
|
|
if (tabPositionTopOrBottom.value) {
|
|
if (wrapperWidth.value >= wrapperScrollWidth.value) {
|
|
return false;
|
|
}
|
|
doMove(setTransformLeft, offsetX);
|
|
} else {
|
|
if (wrapperHeight.value >= wrapperScrollHeight.value) {
|
|
return false;
|
|
}
|
|
doMove(setTransformTop, offsetY);
|
|
}
|
|
clearTouchMoving();
|
|
doLockAnimation();
|
|
return true;
|
|
});
|
|
watch(lockAnimation, () => {
|
|
clearTouchMoving();
|
|
if (lockAnimation.value) {
|
|
touchMovingRef.value = setTimeout(() => {
|
|
setLockAnimation(0);
|
|
}, 100);
|
|
}
|
|
});
|
|
const scrollToTab = function() {
|
|
let key = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : props.activeKey;
|
|
const tabOffset = tabOffsets.value.get(key) || {
|
|
width: 0,
|
|
height: 0,
|
|
left: 0,
|
|
right: 0,
|
|
top: 0
|
|
};
|
|
if (tabPositionTopOrBottom.value) {
|
|
let newTransform = transformLeft.value;
|
|
if (props.rtl) {
|
|
if (tabOffset.right < transformLeft.value) {
|
|
newTransform = tabOffset.right;
|
|
} else if (tabOffset.right + tabOffset.width > transformLeft.value + wrapperWidth.value) {
|
|
newTransform = tabOffset.right + tabOffset.width - wrapperWidth.value;
|
|
}
|
|
} else if (tabOffset.left < -transformLeft.value) {
|
|
newTransform = -tabOffset.left;
|
|
} else if (tabOffset.left + tabOffset.width > -transformLeft.value + wrapperWidth.value) {
|
|
newTransform = -(tabOffset.left + tabOffset.width - wrapperWidth.value);
|
|
}
|
|
setTransformTop(0);
|
|
setTransformLeft(alignInRange(newTransform));
|
|
} else {
|
|
let newTransform = transformTop.value;
|
|
if (tabOffset.top < -transformTop.value) {
|
|
newTransform = -tabOffset.top;
|
|
} else if (tabOffset.top + tabOffset.height > -transformTop.value + wrapperHeight.value) {
|
|
newTransform = -(tabOffset.top + tabOffset.height - wrapperHeight.value);
|
|
}
|
|
setTransformLeft(0);
|
|
setTransformTop(alignInRange(newTransform));
|
|
}
|
|
};
|
|
const visibleStart = shallowRef(0);
|
|
const visibleEnd = shallowRef(0);
|
|
watchEffect(() => {
|
|
let unit;
|
|
let position;
|
|
let transformSize;
|
|
let basicSize;
|
|
let tabContentSize;
|
|
let addSize;
|
|
const tabOffsetsValue = tabOffsets.value;
|
|
if (["top", "bottom"].includes(props.tabPosition)) {
|
|
unit = "width";
|
|
basicSize = wrapperWidth.value;
|
|
tabContentSize = wrapperScrollWidth.value;
|
|
addSize = addWidth.value;
|
|
position = props.rtl ? "right" : "left";
|
|
transformSize = Math.abs(transformLeft.value);
|
|
} else {
|
|
unit = "height";
|
|
basicSize = wrapperHeight.value;
|
|
tabContentSize = wrapperScrollWidth.value;
|
|
addSize = addHeight.value;
|
|
position = "top";
|
|
transformSize = -transformTop.value;
|
|
}
|
|
let mergedBasicSize = basicSize;
|
|
if (tabContentSize + addSize > basicSize && tabContentSize < basicSize) {
|
|
mergedBasicSize = basicSize - addSize;
|
|
}
|
|
const tabsVal = tabs.value;
|
|
if (!tabsVal.length) {
|
|
return [visibleStart.value, visibleEnd.value] = [0, 0];
|
|
}
|
|
const len = tabsVal.length;
|
|
let endIndex = len;
|
|
for (let i = 0; i < len; i += 1) {
|
|
const offset = tabOffsetsValue.get(tabsVal[i].key) || DEFAULT_SIZE;
|
|
if (offset[position] + offset[unit] > transformSize + mergedBasicSize) {
|
|
endIndex = i - 1;
|
|
break;
|
|
}
|
|
}
|
|
let startIndex = 0;
|
|
for (let i = len - 1; i >= 0; i -= 1) {
|
|
const offset = tabOffsetsValue.get(tabsVal[i].key) || DEFAULT_SIZE;
|
|
if (offset[position] < transformSize) {
|
|
startIndex = i + 1;
|
|
break;
|
|
}
|
|
}
|
|
return [visibleStart.value, visibleEnd.value] = [startIndex, endIndex];
|
|
});
|
|
const updateTabSizes = () => {
|
|
setTabSizes(() => {
|
|
var _a;
|
|
const newSizes = /* @__PURE__ */ new Map();
|
|
const listRect = (_a = tabListRef.value) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
tabs.value.forEach((_ref2) => {
|
|
let {
|
|
key
|
|
} = _ref2;
|
|
const btnRef = btnRefs.value.get(key);
|
|
const btnNode = (btnRef === null || btnRef === void 0 ? void 0 : btnRef.$el) || btnRef;
|
|
if (btnNode) {
|
|
const [width, height, left, top] = getTabSize(btnNode, listRect);
|
|
newSizes.set(key, {
|
|
width,
|
|
height,
|
|
left,
|
|
top
|
|
});
|
|
}
|
|
});
|
|
return newSizes;
|
|
});
|
|
};
|
|
watch(() => tabs.value.map((tab) => tab.key).join("%%"), () => {
|
|
updateTabSizes();
|
|
}, {
|
|
flush: "post"
|
|
});
|
|
const onListHolderResize = () => {
|
|
var _a, _b, _c, _d, _e;
|
|
const offsetWidth = ((_a = tabsWrapperRef.value) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0;
|
|
const offsetHeight = ((_b = tabsWrapperRef.value) === null || _b === void 0 ? void 0 : _b.offsetHeight) || 0;
|
|
const addDom = ((_c = innerAddButtonRef.value) === null || _c === void 0 ? void 0 : _c.$el) || {};
|
|
const newAddWidth = addDom.offsetWidth || 0;
|
|
const newAddHeight = addDom.offsetHeight || 0;
|
|
setWrapperWidth(offsetWidth);
|
|
setWrapperHeight(offsetHeight);
|
|
setAddWidth(newAddWidth);
|
|
setAddHeight(newAddHeight);
|
|
const newWrapperScrollWidth = (((_d = tabListRef.value) === null || _d === void 0 ? void 0 : _d.offsetWidth) || 0) - newAddWidth;
|
|
const newWrapperScrollHeight = (((_e = tabListRef.value) === null || _e === void 0 ? void 0 : _e.offsetHeight) || 0) - newAddHeight;
|
|
setWrapperScrollWidth(newWrapperScrollWidth);
|
|
setWrapperScrollHeight(newWrapperScrollHeight);
|
|
updateTabSizes();
|
|
};
|
|
const hiddenTabs = computed(() => [...tabs.value.slice(0, visibleStart.value), ...tabs.value.slice(visibleEnd.value + 1)]);
|
|
const [inkStyle, setInkStyle] = useState$1();
|
|
const activeTabOffset = computed(() => tabOffsets.value.get(props.activeKey));
|
|
const inkBarRafRef = shallowRef();
|
|
const cleanInkBarRaf = () => {
|
|
wrapperRaf.cancel(inkBarRafRef.value);
|
|
};
|
|
watch([activeTabOffset, tabPositionTopOrBottom, () => props.rtl], () => {
|
|
const newInkStyle = {};
|
|
if (activeTabOffset.value) {
|
|
if (tabPositionTopOrBottom.value) {
|
|
if (props.rtl) {
|
|
newInkStyle.right = toPx(activeTabOffset.value.right);
|
|
} else {
|
|
newInkStyle.left = toPx(activeTabOffset.value.left);
|
|
}
|
|
newInkStyle.width = toPx(activeTabOffset.value.width);
|
|
} else {
|
|
newInkStyle.top = toPx(activeTabOffset.value.top);
|
|
newInkStyle.height = toPx(activeTabOffset.value.height);
|
|
}
|
|
}
|
|
cleanInkBarRaf();
|
|
inkBarRafRef.value = wrapperRaf(() => {
|
|
setInkStyle(newInkStyle);
|
|
});
|
|
});
|
|
watch([() => props.activeKey, activeTabOffset, tabOffsets, tabPositionTopOrBottom], () => {
|
|
scrollToTab();
|
|
}, {
|
|
flush: "post"
|
|
});
|
|
watch([() => props.rtl, () => props.tabBarGutter, () => props.activeKey, () => tabs.value], () => {
|
|
onListHolderResize();
|
|
}, {
|
|
flush: "post"
|
|
});
|
|
const ExtraContent = (_ref3) => {
|
|
let {
|
|
position,
|
|
prefixCls: prefixCls2,
|
|
extra
|
|
} = _ref3;
|
|
if (!extra) return null;
|
|
const content = extra === null || extra === void 0 ? void 0 : extra({
|
|
position
|
|
});
|
|
return content ? createVNode("div", {
|
|
"class": `${prefixCls2}-extra-content`
|
|
}, [content]) : null;
|
|
};
|
|
return () => {
|
|
const {
|
|
id,
|
|
animated,
|
|
activeKey,
|
|
rtl,
|
|
editable,
|
|
locale,
|
|
tabPosition,
|
|
tabBarGutter,
|
|
onTabClick
|
|
} = props;
|
|
const {
|
|
class: className,
|
|
style
|
|
} = attrs;
|
|
const pre = prefixCls.value;
|
|
const hasDropdown = !!hiddenTabs.value.length;
|
|
const wrapPrefix = `${pre}-nav-wrap`;
|
|
let pingLeft;
|
|
let pingRight;
|
|
let pingTop;
|
|
let pingBottom;
|
|
if (tabPositionTopOrBottom.value) {
|
|
if (rtl) {
|
|
pingRight = transformLeft.value > 0;
|
|
pingLeft = transformLeft.value + wrapperWidth.value < wrapperScrollWidth.value;
|
|
} else {
|
|
pingLeft = transformLeft.value < 0;
|
|
pingRight = -transformLeft.value + wrapperWidth.value < wrapperScrollWidth.value;
|
|
}
|
|
} else {
|
|
pingTop = transformTop.value < 0;
|
|
pingBottom = -transformTop.value + wrapperHeight.value < wrapperScrollHeight.value;
|
|
}
|
|
const tabNodeStyle = {};
|
|
if (tabPosition === "top" || tabPosition === "bottom") {
|
|
tabNodeStyle[rtl ? "marginRight" : "marginLeft"] = typeof tabBarGutter === "number" ? `${tabBarGutter}px` : tabBarGutter;
|
|
} else {
|
|
tabNodeStyle.marginTop = typeof tabBarGutter === "number" ? `${tabBarGutter}px` : tabBarGutter;
|
|
}
|
|
const tabNodes = tabs.value.map((tab, i) => {
|
|
const {
|
|
key
|
|
} = tab;
|
|
return createVNode(TabNode, {
|
|
"id": id,
|
|
"prefixCls": pre,
|
|
"key": key,
|
|
"tab": tab,
|
|
"style": i === 0 ? void 0 : tabNodeStyle,
|
|
"closable": tab.closable,
|
|
"editable": editable,
|
|
"active": key === activeKey,
|
|
"removeAriaLabel": locale === null || locale === void 0 ? void 0 : locale.removeAriaLabel,
|
|
"ref": setRef(key),
|
|
"onClick": (e) => {
|
|
onTabClick(key, e);
|
|
},
|
|
"onFocus": () => {
|
|
scrollToTab(key);
|
|
doLockAnimation();
|
|
if (!tabsWrapperRef.value) {
|
|
return;
|
|
}
|
|
if (!rtl) {
|
|
tabsWrapperRef.value.scrollLeft = 0;
|
|
}
|
|
tabsWrapperRef.value.scrollTop = 0;
|
|
}
|
|
}, slots);
|
|
});
|
|
return createVNode("div", {
|
|
"role": "tablist",
|
|
"class": classNames(`${pre}-nav`, className),
|
|
"style": style,
|
|
"onKeydown": () => {
|
|
doLockAnimation();
|
|
}
|
|
}, [createVNode(ExtraContent, {
|
|
"position": "left",
|
|
"prefixCls": pre,
|
|
"extra": slots.leftExtra
|
|
}, null), createVNode(ResizeObserver, {
|
|
"onResize": onListHolderResize
|
|
}, {
|
|
default: () => [createVNode("div", {
|
|
"class": classNames(wrapPrefix, {
|
|
[`${wrapPrefix}-ping-left`]: pingLeft,
|
|
[`${wrapPrefix}-ping-right`]: pingRight,
|
|
[`${wrapPrefix}-ping-top`]: pingTop,
|
|
[`${wrapPrefix}-ping-bottom`]: pingBottom
|
|
}),
|
|
"ref": tabsWrapperRef
|
|
}, [createVNode(ResizeObserver, {
|
|
"onResize": onListHolderResize
|
|
}, {
|
|
default: () => [createVNode("div", {
|
|
"ref": tabListRef,
|
|
"class": `${pre}-nav-list`,
|
|
"style": {
|
|
transform: `translate(${transformLeft.value}px, ${transformTop.value}px)`,
|
|
transition: lockAnimation.value ? "none" : void 0
|
|
}
|
|
}, [tabNodes, createVNode(AddButton, {
|
|
"ref": innerAddButtonRef,
|
|
"prefixCls": pre,
|
|
"locale": locale,
|
|
"editable": editable,
|
|
"style": _extends(_extends({}, tabNodes.length === 0 ? void 0 : tabNodeStyle), {
|
|
visibility: hasDropdown ? "hidden" : null
|
|
})
|
|
}, null), createVNode("div", {
|
|
"class": classNames(`${pre}-ink-bar`, {
|
|
[`${pre}-ink-bar-animated`]: animated.inkBar
|
|
}),
|
|
"style": inkStyle.value
|
|
}, null)])]
|
|
})])]
|
|
}), createVNode(OperationNode, _objectSpread$1(_objectSpread$1({}, props), {}, {
|
|
"removeAriaLabel": locale === null || locale === void 0 ? void 0 : locale.removeAriaLabel,
|
|
"ref": operationsRef,
|
|
"prefixCls": pre,
|
|
"tabs": hiddenTabs.value,
|
|
"class": !hasDropdown && operationsHiddenClassName.value
|
|
}), pick(slots, ["moreIcon"])), createVNode(ExtraContent, {
|
|
"position": "right",
|
|
"prefixCls": pre,
|
|
"extra": slots.rightExtra
|
|
}, null), createVNode(ExtraContent, {
|
|
"position": "right",
|
|
"prefixCls": pre,
|
|
"extra": slots.tabBarExtraContent
|
|
}, null)]);
|
|
};
|
|
}
|
|
});
|
|
const TabPanelList = defineComponent({
|
|
compatConfig: {
|
|
MODE: 3
|
|
},
|
|
name: "TabPanelList",
|
|
inheritAttrs: false,
|
|
props: {
|
|
activeKey: {
|
|
type: [String, Number]
|
|
},
|
|
id: {
|
|
type: String
|
|
},
|
|
rtl: {
|
|
type: Boolean
|
|
},
|
|
animated: {
|
|
type: Object,
|
|
default: void 0
|
|
},
|
|
tabPosition: {
|
|
type: String
|
|
},
|
|
destroyInactiveTabPane: {
|
|
type: Boolean
|
|
}
|
|
},
|
|
setup(props) {
|
|
const {
|
|
tabs,
|
|
prefixCls
|
|
} = useInjectTabs();
|
|
return () => {
|
|
const {
|
|
id,
|
|
activeKey,
|
|
animated,
|
|
tabPosition,
|
|
rtl,
|
|
destroyInactiveTabPane
|
|
} = props;
|
|
const tabPaneAnimated = animated.tabPane;
|
|
const pre = prefixCls.value;
|
|
const activeIndex = tabs.value.findIndex((tab) => tab.key === activeKey);
|
|
return createVNode("div", {
|
|
"class": `${pre}-content-holder`
|
|
}, [createVNode("div", {
|
|
"class": [`${pre}-content`, `${pre}-content-${tabPosition}`, {
|
|
[`${pre}-content-animated`]: tabPaneAnimated
|
|
}],
|
|
"style": activeIndex && tabPaneAnimated ? {
|
|
[rtl ? "marginRight" : "marginLeft"]: `-${activeIndex}00%`
|
|
} : null
|
|
}, [tabs.value.map((tab) => {
|
|
return cloneElement(tab.node, {
|
|
key: tab.key,
|
|
prefixCls: pre,
|
|
tabKey: tab.key,
|
|
id,
|
|
animated: tabPaneAnimated,
|
|
active: tab.key === activeKey,
|
|
destroyInactiveTabPane
|
|
});
|
|
})])]);
|
|
};
|
|
}
|
|
});
|
|
const genMotionStyle = (token) => {
|
|
const {
|
|
componentCls,
|
|
motionDurationSlow
|
|
} = token;
|
|
return [
|
|
{
|
|
[componentCls]: {
|
|
[`${componentCls}-switch`]: {
|
|
"&-appear, &-enter": {
|
|
transition: "none",
|
|
"&-start": {
|
|
opacity: 0
|
|
},
|
|
"&-active": {
|
|
opacity: 1,
|
|
transition: `opacity ${motionDurationSlow}`
|
|
}
|
|
},
|
|
"&-leave": {
|
|
position: "absolute",
|
|
transition: "none",
|
|
inset: 0,
|
|
"&-start": {
|
|
opacity: 1
|
|
},
|
|
"&-active": {
|
|
opacity: 0,
|
|
transition: `opacity ${motionDurationSlow}`
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
// Follow code may reuse in other components
|
|
[initSlideMotion(token, "slide-up"), initSlideMotion(token, "slide-down")]
|
|
];
|
|
};
|
|
const genCardStyle = (token) => {
|
|
const {
|
|
componentCls,
|
|
tabsCardHorizontalPadding,
|
|
tabsCardHeadBackground,
|
|
tabsCardGutter,
|
|
colorSplit
|
|
} = token;
|
|
return {
|
|
[`${componentCls}-card`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab`]: {
|
|
margin: 0,
|
|
padding: tabsCardHorizontalPadding,
|
|
background: tabsCardHeadBackground,
|
|
border: `${token.lineWidth}px ${token.lineType} ${colorSplit}`,
|
|
transition: `all ${token.motionDurationSlow} ${token.motionEaseInOut}`
|
|
},
|
|
[`${componentCls}-tab-active`]: {
|
|
color: token.colorPrimary,
|
|
background: token.colorBgContainer
|
|
},
|
|
[`${componentCls}-ink-bar`]: {
|
|
visibility: "hidden"
|
|
}
|
|
},
|
|
// ========================== Top & Bottom ==========================
|
|
[`&${componentCls}-top, &${componentCls}-bottom`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab + ${componentCls}-tab`]: {
|
|
marginLeft: {
|
|
_skip_check_: true,
|
|
value: `${tabsCardGutter}px`
|
|
}
|
|
}
|
|
}
|
|
},
|
|
[`&${componentCls}-top`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab`]: {
|
|
borderRadius: `${token.borderRadiusLG}px ${token.borderRadiusLG}px 0 0`
|
|
},
|
|
[`${componentCls}-tab-active`]: {
|
|
borderBottomColor: token.colorBgContainer
|
|
}
|
|
}
|
|
},
|
|
[`&${componentCls}-bottom`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab`]: {
|
|
borderRadius: `0 0 ${token.borderRadiusLG}px ${token.borderRadiusLG}px`
|
|
},
|
|
[`${componentCls}-tab-active`]: {
|
|
borderTopColor: token.colorBgContainer
|
|
}
|
|
}
|
|
},
|
|
// ========================== Left & Right ==========================
|
|
[`&${componentCls}-left, &${componentCls}-right`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab + ${componentCls}-tab`]: {
|
|
marginTop: `${tabsCardGutter}px`
|
|
}
|
|
}
|
|
},
|
|
[`&${componentCls}-left`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab`]: {
|
|
borderRadius: {
|
|
_skip_check_: true,
|
|
value: `${token.borderRadiusLG}px 0 0 ${token.borderRadiusLG}px`
|
|
}
|
|
},
|
|
[`${componentCls}-tab-active`]: {
|
|
borderRightColor: {
|
|
_skip_check_: true,
|
|
value: token.colorBgContainer
|
|
}
|
|
}
|
|
}
|
|
},
|
|
[`&${componentCls}-right`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab`]: {
|
|
borderRadius: {
|
|
_skip_check_: true,
|
|
value: `0 ${token.borderRadiusLG}px ${token.borderRadiusLG}px 0`
|
|
}
|
|
},
|
|
[`${componentCls}-tab-active`]: {
|
|
borderLeftColor: {
|
|
_skip_check_: true,
|
|
value: token.colorBgContainer
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
const genDropdownStyle = (token) => {
|
|
const {
|
|
componentCls,
|
|
tabsHoverColor,
|
|
dropdownEdgeChildVerticalPadding
|
|
} = token;
|
|
return {
|
|
[`${componentCls}-dropdown`]: _extends(_extends({}, resetComponent(token)), {
|
|
position: "absolute",
|
|
top: -9999,
|
|
left: {
|
|
_skip_check_: true,
|
|
value: -9999
|
|
},
|
|
zIndex: token.zIndexPopup,
|
|
display: "block",
|
|
"&-hidden": {
|
|
display: "none"
|
|
},
|
|
[`${componentCls}-dropdown-menu`]: {
|
|
maxHeight: token.tabsDropdownHeight,
|
|
margin: 0,
|
|
padding: `${dropdownEdgeChildVerticalPadding}px 0`,
|
|
overflowX: "hidden",
|
|
overflowY: "auto",
|
|
textAlign: {
|
|
_skip_check_: true,
|
|
value: "left"
|
|
},
|
|
listStyleType: "none",
|
|
backgroundColor: token.colorBgContainer,
|
|
backgroundClip: "padding-box",
|
|
borderRadius: token.borderRadiusLG,
|
|
outline: "none",
|
|
boxShadow: token.boxShadowSecondary,
|
|
"&-item": _extends(_extends({}, textEllipsis), {
|
|
display: "flex",
|
|
alignItems: "center",
|
|
minWidth: token.tabsDropdownWidth,
|
|
margin: 0,
|
|
padding: `${token.paddingXXS}px ${token.paddingSM}px`,
|
|
color: token.colorText,
|
|
fontWeight: "normal",
|
|
fontSize: token.fontSize,
|
|
lineHeight: token.lineHeight,
|
|
cursor: "pointer",
|
|
transition: `all ${token.motionDurationSlow}`,
|
|
"> span": {
|
|
flex: 1,
|
|
whiteSpace: "nowrap"
|
|
},
|
|
"&-remove": {
|
|
flex: "none",
|
|
marginLeft: {
|
|
_skip_check_: true,
|
|
value: token.marginSM
|
|
},
|
|
color: token.colorTextDescription,
|
|
fontSize: token.fontSizeSM,
|
|
background: "transparent",
|
|
border: 0,
|
|
cursor: "pointer",
|
|
"&:hover": {
|
|
color: tabsHoverColor
|
|
}
|
|
},
|
|
"&:hover": {
|
|
background: token.controlItemBgHover
|
|
},
|
|
"&-disabled": {
|
|
"&, &:hover": {
|
|
color: token.colorTextDisabled,
|
|
background: "transparent",
|
|
cursor: "not-allowed"
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
};
|
|
};
|
|
const genPositionStyle = (token) => {
|
|
const {
|
|
componentCls,
|
|
margin,
|
|
colorSplit
|
|
} = token;
|
|
return {
|
|
// ========================== Top & Bottom ==========================
|
|
[`${componentCls}-top, ${componentCls}-bottom`]: {
|
|
flexDirection: "column",
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
margin: `0 0 ${margin}px 0`,
|
|
"&::before": {
|
|
position: "absolute",
|
|
right: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
},
|
|
left: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
},
|
|
borderBottom: `${token.lineWidth}px ${token.lineType} ${colorSplit}`,
|
|
content: "''"
|
|
},
|
|
[`${componentCls}-ink-bar`]: {
|
|
height: token.lineWidthBold,
|
|
"&-animated": {
|
|
transition: `width ${token.motionDurationSlow}, left ${token.motionDurationSlow},
|
|
right ${token.motionDurationSlow}`
|
|
}
|
|
},
|
|
[`${componentCls}-nav-wrap`]: {
|
|
"&::before, &::after": {
|
|
top: 0,
|
|
bottom: 0,
|
|
width: token.controlHeight
|
|
},
|
|
"&::before": {
|
|
left: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
},
|
|
boxShadow: token.boxShadowTabsOverflowLeft
|
|
},
|
|
"&::after": {
|
|
right: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
},
|
|
boxShadow: token.boxShadowTabsOverflowRight
|
|
},
|
|
[`&${componentCls}-nav-wrap-ping-left::before`]: {
|
|
opacity: 1
|
|
},
|
|
[`&${componentCls}-nav-wrap-ping-right::after`]: {
|
|
opacity: 1
|
|
}
|
|
}
|
|
}
|
|
},
|
|
[`${componentCls}-top`]: {
|
|
[`> ${componentCls}-nav,
|
|
> div > ${componentCls}-nav`]: {
|
|
"&::before": {
|
|
bottom: 0
|
|
},
|
|
[`${componentCls}-ink-bar`]: {
|
|
bottom: 0
|
|
}
|
|
}
|
|
},
|
|
[`${componentCls}-bottom`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
order: 1,
|
|
marginTop: `${margin}px`,
|
|
marginBottom: 0,
|
|
"&::before": {
|
|
top: 0
|
|
},
|
|
[`${componentCls}-ink-bar`]: {
|
|
top: 0
|
|
}
|
|
},
|
|
[`> ${componentCls}-content-holder, > div > ${componentCls}-content-holder`]: {
|
|
order: 0
|
|
}
|
|
},
|
|
// ========================== Left & Right ==========================
|
|
[`${componentCls}-left, ${componentCls}-right`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
flexDirection: "column",
|
|
minWidth: token.controlHeight * 1.25,
|
|
// >>>>>>>>>>> Tab
|
|
[`${componentCls}-tab`]: {
|
|
padding: `${token.paddingXS}px ${token.paddingLG}px`,
|
|
textAlign: "center"
|
|
},
|
|
[`${componentCls}-tab + ${componentCls}-tab`]: {
|
|
margin: `${token.margin}px 0 0 0`
|
|
},
|
|
// >>>>>>>>>>> Nav
|
|
[`${componentCls}-nav-wrap`]: {
|
|
flexDirection: "column",
|
|
"&::before, &::after": {
|
|
right: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
},
|
|
left: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
},
|
|
height: token.controlHeight
|
|
},
|
|
"&::before": {
|
|
top: 0,
|
|
boxShadow: token.boxShadowTabsOverflowTop
|
|
},
|
|
"&::after": {
|
|
bottom: 0,
|
|
boxShadow: token.boxShadowTabsOverflowBottom
|
|
},
|
|
[`&${componentCls}-nav-wrap-ping-top::before`]: {
|
|
opacity: 1
|
|
},
|
|
[`&${componentCls}-nav-wrap-ping-bottom::after`]: {
|
|
opacity: 1
|
|
}
|
|
},
|
|
// >>>>>>>>>>> Ink Bar
|
|
[`${componentCls}-ink-bar`]: {
|
|
width: token.lineWidthBold,
|
|
"&-animated": {
|
|
transition: `height ${token.motionDurationSlow}, top ${token.motionDurationSlow}`
|
|
}
|
|
},
|
|
[`${componentCls}-nav-list, ${componentCls}-nav-operations`]: {
|
|
flex: "1 0 auto",
|
|
flexDirection: "column"
|
|
}
|
|
}
|
|
},
|
|
[`${componentCls}-left`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
[`${componentCls}-ink-bar`]: {
|
|
right: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
}
|
|
}
|
|
},
|
|
[`> ${componentCls}-content-holder, > div > ${componentCls}-content-holder`]: {
|
|
marginLeft: {
|
|
_skip_check_: true,
|
|
value: `-${token.lineWidth}px`
|
|
},
|
|
borderLeft: {
|
|
_skip_check_: true,
|
|
value: `${token.lineWidth}px ${token.lineType} ${token.colorBorder}`
|
|
},
|
|
[`> ${componentCls}-content > ${componentCls}-tabpane`]: {
|
|
paddingLeft: {
|
|
_skip_check_: true,
|
|
value: token.paddingLG
|
|
}
|
|
}
|
|
}
|
|
},
|
|
[`${componentCls}-right`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
order: 1,
|
|
[`${componentCls}-ink-bar`]: {
|
|
left: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
}
|
|
}
|
|
},
|
|
[`> ${componentCls}-content-holder, > div > ${componentCls}-content-holder`]: {
|
|
order: 0,
|
|
marginRight: {
|
|
_skip_check_: true,
|
|
value: -token.lineWidth
|
|
},
|
|
borderRight: {
|
|
_skip_check_: true,
|
|
value: `${token.lineWidth}px ${token.lineType} ${token.colorBorder}`
|
|
},
|
|
[`> ${componentCls}-content > ${componentCls}-tabpane`]: {
|
|
paddingRight: {
|
|
_skip_check_: true,
|
|
value: token.paddingLG
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
const genSizeStyle = (token) => {
|
|
const {
|
|
componentCls,
|
|
padding
|
|
} = token;
|
|
return {
|
|
[componentCls]: {
|
|
"&-small": {
|
|
[`> ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab`]: {
|
|
padding: `${token.paddingXS}px 0`,
|
|
fontSize: token.fontSize
|
|
}
|
|
}
|
|
},
|
|
"&-large": {
|
|
[`> ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab`]: {
|
|
padding: `${padding}px 0`,
|
|
fontSize: token.fontSizeLG
|
|
}
|
|
}
|
|
}
|
|
},
|
|
[`${componentCls}-card`]: {
|
|
[`&${componentCls}-small`]: {
|
|
[`> ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab`]: {
|
|
padding: `${token.paddingXXS * 1.5}px ${padding}px`
|
|
}
|
|
},
|
|
[`&${componentCls}-bottom`]: {
|
|
[`> ${componentCls}-nav ${componentCls}-tab`]: {
|
|
borderRadius: `0 0 ${token.borderRadius}px ${token.borderRadius}px`
|
|
}
|
|
},
|
|
[`&${componentCls}-top`]: {
|
|
[`> ${componentCls}-nav ${componentCls}-tab`]: {
|
|
borderRadius: `${token.borderRadius}px ${token.borderRadius}px 0 0`
|
|
}
|
|
},
|
|
[`&${componentCls}-right`]: {
|
|
[`> ${componentCls}-nav ${componentCls}-tab`]: {
|
|
borderRadius: {
|
|
_skip_check_: true,
|
|
value: `0 ${token.borderRadius}px ${token.borderRadius}px 0`
|
|
}
|
|
}
|
|
},
|
|
[`&${componentCls}-left`]: {
|
|
[`> ${componentCls}-nav ${componentCls}-tab`]: {
|
|
borderRadius: {
|
|
_skip_check_: true,
|
|
value: `${token.borderRadius}px 0 0 ${token.borderRadius}px`
|
|
}
|
|
}
|
|
}
|
|
},
|
|
[`&${componentCls}-large`]: {
|
|
[`> ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab`]: {
|
|
padding: `${token.paddingXS}px ${padding}px ${token.paddingXXS * 1.5}px`
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
const genTabStyle = (token) => {
|
|
const {
|
|
componentCls,
|
|
tabsActiveColor,
|
|
tabsHoverColor,
|
|
iconCls,
|
|
tabsHorizontalGutter
|
|
} = token;
|
|
const tabCls = `${componentCls}-tab`;
|
|
return {
|
|
[tabCls]: {
|
|
position: "relative",
|
|
display: "inline-flex",
|
|
alignItems: "center",
|
|
padding: `${token.paddingSM}px 0`,
|
|
fontSize: `${token.fontSize}px`,
|
|
background: "transparent",
|
|
border: 0,
|
|
outline: "none",
|
|
cursor: "pointer",
|
|
"&-btn, &-remove": _extends({
|
|
"&:focus:not(:focus-visible), &:active": {
|
|
color: tabsActiveColor
|
|
}
|
|
}, genFocusStyle(token)),
|
|
"&-btn": {
|
|
outline: "none",
|
|
transition: "all 0.3s"
|
|
},
|
|
"&-remove": {
|
|
flex: "none",
|
|
marginRight: {
|
|
_skip_check_: true,
|
|
value: -token.marginXXS
|
|
},
|
|
marginLeft: {
|
|
_skip_check_: true,
|
|
value: token.marginXS
|
|
},
|
|
color: token.colorTextDescription,
|
|
fontSize: token.fontSizeSM,
|
|
background: "transparent",
|
|
border: "none",
|
|
outline: "none",
|
|
cursor: "pointer",
|
|
transition: `all ${token.motionDurationSlow}`,
|
|
"&:hover": {
|
|
color: token.colorTextHeading
|
|
}
|
|
},
|
|
"&:hover": {
|
|
color: tabsHoverColor
|
|
},
|
|
[`&${tabCls}-active ${tabCls}-btn`]: {
|
|
color: token.colorPrimary,
|
|
textShadow: token.tabsActiveTextShadow
|
|
},
|
|
[`&${tabCls}-disabled`]: {
|
|
color: token.colorTextDisabled,
|
|
cursor: "not-allowed"
|
|
},
|
|
[`&${tabCls}-disabled ${tabCls}-btn, &${tabCls}-disabled ${componentCls}-remove`]: {
|
|
"&:focus, &:active": {
|
|
color: token.colorTextDisabled
|
|
}
|
|
},
|
|
[`& ${tabCls}-remove ${iconCls}`]: {
|
|
margin: 0
|
|
},
|
|
[iconCls]: {
|
|
marginRight: {
|
|
_skip_check_: true,
|
|
value: token.marginSM
|
|
}
|
|
}
|
|
},
|
|
[`${tabCls} + ${tabCls}`]: {
|
|
margin: {
|
|
_skip_check_: true,
|
|
value: `0 0 0 ${tabsHorizontalGutter}px`
|
|
}
|
|
}
|
|
};
|
|
};
|
|
const genRtlStyle = (token) => {
|
|
const {
|
|
componentCls,
|
|
tabsHorizontalGutter,
|
|
iconCls,
|
|
tabsCardGutter
|
|
} = token;
|
|
const rtlCls = `${componentCls}-rtl`;
|
|
return {
|
|
[rtlCls]: {
|
|
direction: "rtl",
|
|
[`${componentCls}-nav`]: {
|
|
[`${componentCls}-tab`]: {
|
|
margin: {
|
|
_skip_check_: true,
|
|
value: `0 0 0 ${tabsHorizontalGutter}px`
|
|
},
|
|
[`${componentCls}-tab:last-of-type`]: {
|
|
marginLeft: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
}
|
|
},
|
|
[iconCls]: {
|
|
marginRight: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
},
|
|
marginLeft: {
|
|
_skip_check_: true,
|
|
value: `${token.marginSM}px`
|
|
}
|
|
},
|
|
[`${componentCls}-tab-remove`]: {
|
|
marginRight: {
|
|
_skip_check_: true,
|
|
value: `${token.marginXS}px`
|
|
},
|
|
marginLeft: {
|
|
_skip_check_: true,
|
|
value: `-${token.marginXXS}px`
|
|
},
|
|
[iconCls]: {
|
|
margin: 0
|
|
}
|
|
}
|
|
}
|
|
},
|
|
[`&${componentCls}-left`]: {
|
|
[`> ${componentCls}-nav`]: {
|
|
order: 1
|
|
},
|
|
[`> ${componentCls}-content-holder`]: {
|
|
order: 0
|
|
}
|
|
},
|
|
[`&${componentCls}-right`]: {
|
|
[`> ${componentCls}-nav`]: {
|
|
order: 0
|
|
},
|
|
[`> ${componentCls}-content-holder`]: {
|
|
order: 1
|
|
}
|
|
},
|
|
// ====================== Card ======================
|
|
[`&${componentCls}-card${componentCls}-top, &${componentCls}-card${componentCls}-bottom`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
[`${componentCls}-tab + ${componentCls}-tab`]: {
|
|
marginRight: {
|
|
_skip_check_: true,
|
|
value: `${tabsCardGutter}px`
|
|
},
|
|
marginLeft: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
[`${componentCls}-dropdown-rtl`]: {
|
|
direction: "rtl"
|
|
},
|
|
[`${componentCls}-menu-item`]: {
|
|
[`${componentCls}-dropdown-rtl`]: {
|
|
textAlign: {
|
|
_skip_check_: true,
|
|
value: "right"
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
const genTabsStyle = (token) => {
|
|
const {
|
|
componentCls,
|
|
tabsCardHorizontalPadding,
|
|
tabsCardHeight,
|
|
tabsCardGutter,
|
|
tabsHoverColor,
|
|
tabsActiveColor,
|
|
colorSplit
|
|
} = token;
|
|
return {
|
|
[componentCls]: _extends(_extends(_extends(_extends({}, resetComponent(token)), {
|
|
display: "flex",
|
|
// ========================== Navigation ==========================
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
position: "relative",
|
|
display: "flex",
|
|
flex: "none",
|
|
alignItems: "center",
|
|
[`${componentCls}-nav-wrap`]: {
|
|
position: "relative",
|
|
display: "flex",
|
|
flex: "auto",
|
|
alignSelf: "stretch",
|
|
overflow: "hidden",
|
|
whiteSpace: "nowrap",
|
|
transform: "translate(0)",
|
|
// >>>>> Ping shadow
|
|
"&::before, &::after": {
|
|
position: "absolute",
|
|
zIndex: 1,
|
|
opacity: 0,
|
|
transition: `opacity ${token.motionDurationSlow}`,
|
|
content: "''",
|
|
pointerEvents: "none"
|
|
}
|
|
},
|
|
[`${componentCls}-nav-list`]: {
|
|
position: "relative",
|
|
display: "flex",
|
|
transition: `opacity ${token.motionDurationSlow}`
|
|
},
|
|
// >>>>>>>> Operations
|
|
[`${componentCls}-nav-operations`]: {
|
|
display: "flex",
|
|
alignSelf: "stretch"
|
|
},
|
|
[`${componentCls}-nav-operations-hidden`]: {
|
|
position: "absolute",
|
|
visibility: "hidden",
|
|
pointerEvents: "none"
|
|
},
|
|
[`${componentCls}-nav-more`]: {
|
|
position: "relative",
|
|
padding: tabsCardHorizontalPadding,
|
|
background: "transparent",
|
|
border: 0,
|
|
"&::after": {
|
|
position: "absolute",
|
|
right: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
},
|
|
bottom: 0,
|
|
left: {
|
|
_skip_check_: true,
|
|
value: 0
|
|
},
|
|
height: token.controlHeightLG / 8,
|
|
transform: "translateY(100%)",
|
|
content: "''"
|
|
}
|
|
},
|
|
[`${componentCls}-nav-add`]: _extends({
|
|
minWidth: `${tabsCardHeight}px`,
|
|
marginLeft: {
|
|
_skip_check_: true,
|
|
value: `${tabsCardGutter}px`
|
|
},
|
|
padding: `0 ${token.paddingXS}px`,
|
|
background: "transparent",
|
|
border: `${token.lineWidth}px ${token.lineType} ${colorSplit}`,
|
|
borderRadius: `${token.borderRadiusLG}px ${token.borderRadiusLG}px 0 0`,
|
|
outline: "none",
|
|
cursor: "pointer",
|
|
color: token.colorText,
|
|
transition: `all ${token.motionDurationSlow} ${token.motionEaseInOut}`,
|
|
"&:hover": {
|
|
color: tabsHoverColor
|
|
},
|
|
"&:active, &:focus:not(:focus-visible)": {
|
|
color: tabsActiveColor
|
|
}
|
|
}, genFocusStyle(token))
|
|
},
|
|
[`${componentCls}-extra-content`]: {
|
|
flex: "none"
|
|
},
|
|
// ============================ InkBar ============================
|
|
[`${componentCls}-ink-bar`]: {
|
|
position: "absolute",
|
|
background: token.colorPrimary,
|
|
pointerEvents: "none"
|
|
}
|
|
}), genTabStyle(token)), {
|
|
// =========================== TabPanes ===========================
|
|
[`${componentCls}-content`]: {
|
|
position: "relative",
|
|
display: "flex",
|
|
width: "100%",
|
|
["&-animated"]: {
|
|
transition: "margin 0.3s"
|
|
}
|
|
},
|
|
[`${componentCls}-content-holder`]: {
|
|
flex: "auto",
|
|
minWidth: 0,
|
|
minHeight: 0
|
|
},
|
|
[`${componentCls}-tabpane`]: {
|
|
outline: "none",
|
|
flex: "none",
|
|
width: "100%"
|
|
}
|
|
}),
|
|
[`${componentCls}-centered`]: {
|
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
|
[`${componentCls}-nav-wrap`]: {
|
|
[`&:not([class*='${componentCls}-nav-wrap-ping'])`]: {
|
|
justifyContent: "center"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
const useStyle = genComponentStyleHook("Tabs", (token) => {
|
|
const tabsCardHeight = token.controlHeightLG;
|
|
const tabsToken = merge(token, {
|
|
tabsHoverColor: token.colorPrimaryHover,
|
|
tabsActiveColor: token.colorPrimaryActive,
|
|
tabsCardHorizontalPadding: `${(tabsCardHeight - Math.round(token.fontSize * token.lineHeight)) / 2 - token.lineWidth}px ${token.padding}px`,
|
|
tabsCardHeight,
|
|
tabsCardGutter: token.marginXXS / 2,
|
|
tabsHorizontalGutter: 32,
|
|
tabsCardHeadBackground: token.colorFillAlter,
|
|
dropdownEdgeChildVerticalPadding: token.paddingXXS,
|
|
tabsActiveTextShadow: "0 0 0.25px currentcolor",
|
|
tabsDropdownHeight: 200,
|
|
tabsDropdownWidth: 120
|
|
});
|
|
return [genSizeStyle(tabsToken), genRtlStyle(tabsToken), genPositionStyle(tabsToken), genDropdownStyle(tabsToken), genCardStyle(tabsToken), genTabsStyle(tabsToken), genMotionStyle(tabsToken)];
|
|
}, (token) => ({
|
|
zIndexPopup: token.zIndexPopupBase + 50
|
|
}));
|
|
const tabsProps = () => {
|
|
return {
|
|
prefixCls: {
|
|
type: String
|
|
},
|
|
id: {
|
|
type: String
|
|
},
|
|
popupClassName: String,
|
|
getPopupContainer: functionType(),
|
|
activeKey: {
|
|
type: [String, Number]
|
|
},
|
|
defaultActiveKey: {
|
|
type: [String, Number]
|
|
},
|
|
direction: stringType(),
|
|
animated: someType([Boolean, Object]),
|
|
renderTabBar: functionType(),
|
|
tabBarGutter: {
|
|
type: Number
|
|
},
|
|
tabBarStyle: objectType(),
|
|
tabPosition: stringType(),
|
|
destroyInactiveTabPane: booleanType(),
|
|
hideAdd: Boolean,
|
|
type: stringType(),
|
|
size: stringType(),
|
|
centered: Boolean,
|
|
onEdit: functionType(),
|
|
onChange: functionType(),
|
|
onTabClick: functionType(),
|
|
onTabScroll: functionType(),
|
|
"onUpdate:activeKey": functionType(),
|
|
// Accessibility
|
|
locale: objectType(),
|
|
onPrevClick: functionType(),
|
|
onNextClick: functionType(),
|
|
tabBarExtraContent: PropTypes.any
|
|
};
|
|
};
|
|
function parseTabList(children) {
|
|
return children.map((node) => {
|
|
if (isValidElement(node)) {
|
|
const props = _extends({}, node.props || {});
|
|
for (const [k, v] of Object.entries(props)) {
|
|
delete props[k];
|
|
props[camelize(k)] = v;
|
|
}
|
|
const slots = node.children || {};
|
|
const key = node.key !== void 0 ? node.key : void 0;
|
|
const {
|
|
tab = slots.tab,
|
|
disabled,
|
|
forceRender,
|
|
closable,
|
|
animated,
|
|
active,
|
|
destroyInactiveTabPane
|
|
} = props;
|
|
return _extends(_extends({
|
|
key
|
|
}, props), {
|
|
node,
|
|
closeIcon: slots.closeIcon,
|
|
tab,
|
|
disabled: disabled === "" || disabled,
|
|
forceRender: forceRender === "" || forceRender,
|
|
closable: closable === "" || closable,
|
|
animated: animated === "" || animated,
|
|
active: active === "" || active,
|
|
destroyInactiveTabPane: destroyInactiveTabPane === "" || destroyInactiveTabPane
|
|
});
|
|
}
|
|
return null;
|
|
}).filter((tab) => tab);
|
|
}
|
|
const InternalTabs = defineComponent({
|
|
compatConfig: {
|
|
MODE: 3
|
|
},
|
|
name: "InternalTabs",
|
|
inheritAttrs: false,
|
|
props: _extends(_extends({}, initDefaultProps(tabsProps(), {
|
|
tabPosition: "top",
|
|
animated: {
|
|
inkBar: true,
|
|
tabPane: false
|
|
}
|
|
})), {
|
|
tabs: arrayType()
|
|
}),
|
|
slots: Object,
|
|
// emits: ['tabClick', 'tabScroll', 'change', 'update:activeKey'],
|
|
setup(props, _ref) {
|
|
let {
|
|
attrs,
|
|
slots
|
|
} = _ref;
|
|
devWarning(!(props.onPrevClick !== void 0) && !(props.onNextClick !== void 0), "Tabs", "`onPrevClick / @prevClick` and `onNextClick / @nextClick` has been removed. Please use `onTabScroll / @tabScroll` instead.");
|
|
devWarning(!(props.tabBarExtraContent !== void 0), "Tabs", "`tabBarExtraContent` prop has been removed. Please use `rightExtra` slot instead.");
|
|
devWarning(!(slots.tabBarExtraContent !== void 0), "Tabs", "`tabBarExtraContent` slot is deprecated. Please use `rightExtra` slot instead.");
|
|
const {
|
|
prefixCls,
|
|
direction,
|
|
size,
|
|
rootPrefixCls,
|
|
getPopupContainer
|
|
} = useConfigInject("tabs", props);
|
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
|
const rtl = computed(() => direction.value === "rtl");
|
|
const mergedAnimated = computed(() => {
|
|
const {
|
|
animated,
|
|
tabPosition
|
|
} = props;
|
|
if (animated === false || ["left", "right"].includes(tabPosition)) {
|
|
return {
|
|
inkBar: false,
|
|
tabPane: false
|
|
};
|
|
} else if (animated === true) {
|
|
return {
|
|
inkBar: true,
|
|
tabPane: true
|
|
};
|
|
} else {
|
|
return _extends({
|
|
inkBar: true,
|
|
tabPane: false
|
|
}, typeof animated === "object" ? animated : {});
|
|
}
|
|
});
|
|
const [mobile, setMobile] = useState$1(false);
|
|
const [mergedActiveKey, setMergedActiveKey] = useMergedState(() => {
|
|
var _a;
|
|
return (_a = props.tabs[0]) === null || _a === void 0 ? void 0 : _a.key;
|
|
}, {
|
|
value: computed(() => props.activeKey),
|
|
defaultValue: props.defaultActiveKey
|
|
});
|
|
const [activeIndex, setActiveIndex] = useState$1(() => props.tabs.findIndex((tab) => tab.key === mergedActiveKey.value));
|
|
watchEffect(() => {
|
|
var _a;
|
|
let newActiveIndex = props.tabs.findIndex((tab) => tab.key === mergedActiveKey.value);
|
|
if (newActiveIndex === -1) {
|
|
newActiveIndex = Math.max(0, Math.min(activeIndex.value, props.tabs.length - 1));
|
|
setMergedActiveKey((_a = props.tabs[newActiveIndex]) === null || _a === void 0 ? void 0 : _a.key);
|
|
}
|
|
setActiveIndex(newActiveIndex);
|
|
});
|
|
const [mergedId, setMergedId] = useMergedState(null, {
|
|
value: computed(() => props.id)
|
|
});
|
|
const mergedTabPosition = computed(() => {
|
|
if (mobile.value && !["left", "right"].includes(props.tabPosition)) {
|
|
return "top";
|
|
} else {
|
|
return props.tabPosition;
|
|
}
|
|
});
|
|
const onInternalTabClick = (key, e) => {
|
|
var _a, _b;
|
|
(_a = props.onTabClick) === null || _a === void 0 ? void 0 : _a.call(props, key, e);
|
|
const isActiveChanged = key !== mergedActiveKey.value;
|
|
setMergedActiveKey(key);
|
|
if (isActiveChanged) {
|
|
(_b = props.onChange) === null || _b === void 0 ? void 0 : _b.call(props, key);
|
|
}
|
|
};
|
|
useProvideTabs({
|
|
tabs: computed(() => props.tabs),
|
|
prefixCls
|
|
});
|
|
return () => {
|
|
const {
|
|
id,
|
|
type,
|
|
tabBarGutter,
|
|
tabBarStyle,
|
|
locale,
|
|
destroyInactiveTabPane,
|
|
renderTabBar = slots.renderTabBar,
|
|
onTabScroll,
|
|
hideAdd,
|
|
centered
|
|
} = props;
|
|
const sharedProps = {
|
|
id: mergedId.value,
|
|
activeKey: mergedActiveKey.value,
|
|
animated: mergedAnimated.value,
|
|
tabPosition: mergedTabPosition.value,
|
|
rtl: rtl.value,
|
|
mobile: mobile.value
|
|
};
|
|
let editable;
|
|
if (type === "editable-card") {
|
|
editable = {
|
|
onEdit: (editType, _ref2) => {
|
|
let {
|
|
key,
|
|
event
|
|
} = _ref2;
|
|
var _a;
|
|
(_a = props.onEdit) === null || _a === void 0 ? void 0 : _a.call(props, editType === "add" ? event : key, editType);
|
|
},
|
|
removeIcon: () => createVNode(CloseOutlined, null, null),
|
|
addIcon: slots.addIcon ? slots.addIcon : () => createVNode(PlusOutlined, null, null),
|
|
showAdd: hideAdd !== true
|
|
};
|
|
}
|
|
let tabNavBar;
|
|
const tabNavBarProps = _extends(_extends({}, sharedProps), {
|
|
moreTransitionName: `${rootPrefixCls.value}-slide-up`,
|
|
editable,
|
|
locale,
|
|
tabBarGutter,
|
|
onTabClick: onInternalTabClick,
|
|
onTabScroll,
|
|
style: tabBarStyle,
|
|
getPopupContainer: getPopupContainer.value,
|
|
popupClassName: classNames(props.popupClassName, hashId.value)
|
|
});
|
|
if (renderTabBar) {
|
|
tabNavBar = renderTabBar(_extends(_extends({}, tabNavBarProps), {
|
|
DefaultTabBar: TabNavList
|
|
}));
|
|
} else {
|
|
tabNavBar = createVNode(TabNavList, tabNavBarProps, pick(slots, ["moreIcon", "leftExtra", "rightExtra", "tabBarExtraContent"]));
|
|
}
|
|
const pre = prefixCls.value;
|
|
return wrapSSR(createVNode("div", _objectSpread$1(_objectSpread$1({}, attrs), {}, {
|
|
"id": id,
|
|
"class": classNames(pre, `${pre}-${mergedTabPosition.value}`, {
|
|
[hashId.value]: true,
|
|
[`${pre}-${size.value}`]: size.value,
|
|
[`${pre}-card`]: ["card", "editable-card"].includes(type),
|
|
[`${pre}-editable-card`]: type === "editable-card",
|
|
[`${pre}-centered`]: centered,
|
|
[`${pre}-mobile`]: mobile.value,
|
|
[`${pre}-editable`]: type === "editable-card",
|
|
[`${pre}-rtl`]: rtl.value
|
|
}, attrs.class)
|
|
}), [tabNavBar, createVNode(TabPanelList, _objectSpread$1(_objectSpread$1({
|
|
"destroyInactiveTabPane": destroyInactiveTabPane
|
|
}, sharedProps), {}, {
|
|
"animated": mergedAnimated.value
|
|
}), null)]));
|
|
};
|
|
}
|
|
});
|
|
const Tabs = defineComponent({
|
|
compatConfig: {
|
|
MODE: 3
|
|
},
|
|
name: "ATabs",
|
|
inheritAttrs: false,
|
|
props: initDefaultProps(tabsProps(), {
|
|
tabPosition: "top",
|
|
animated: {
|
|
inkBar: true,
|
|
tabPane: false
|
|
}
|
|
}),
|
|
slots: Object,
|
|
// emits: ['tabClick', 'tabScroll', 'change', 'update:activeKey'],
|
|
setup(props, _ref3) {
|
|
let {
|
|
attrs,
|
|
slots,
|
|
emit
|
|
} = _ref3;
|
|
const handleChange = (key) => {
|
|
emit("update:activeKey", key);
|
|
emit("change", key);
|
|
};
|
|
return () => {
|
|
var _a;
|
|
const tabs = parseTabList(flattenChildren((_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots)));
|
|
return createVNode(InternalTabs, _objectSpread$1(_objectSpread$1(_objectSpread$1({}, omit(props, ["onUpdate:activeKey"])), attrs), {}, {
|
|
"onChange": handleChange,
|
|
"tabs": tabs
|
|
}), slots);
|
|
};
|
|
}
|
|
});
|
|
const tabPaneProps = () => ({
|
|
tab: PropTypes.any,
|
|
disabled: {
|
|
type: Boolean
|
|
},
|
|
forceRender: {
|
|
type: Boolean
|
|
},
|
|
closable: {
|
|
type: Boolean
|
|
},
|
|
animated: {
|
|
type: Boolean
|
|
},
|
|
active: {
|
|
type: Boolean
|
|
},
|
|
destroyInactiveTabPane: {
|
|
type: Boolean
|
|
},
|
|
// Pass by TabPaneList
|
|
prefixCls: {
|
|
type: String
|
|
},
|
|
tabKey: {
|
|
type: [String, Number]
|
|
},
|
|
id: {
|
|
type: String
|
|
}
|
|
// closeIcon: PropTypes.any,
|
|
});
|
|
const __nuxt_component_2 = defineComponent({
|
|
compatConfig: {
|
|
MODE: 3
|
|
},
|
|
name: "ATabPane",
|
|
inheritAttrs: false,
|
|
__ANT_TAB_PANE: true,
|
|
props: tabPaneProps(),
|
|
slots: Object,
|
|
setup(props, _ref) {
|
|
let {
|
|
attrs,
|
|
slots
|
|
} = _ref;
|
|
const visited = ref(props.forceRender);
|
|
watch([() => props.active, () => props.destroyInactiveTabPane], () => {
|
|
if (props.active) {
|
|
visited.value = true;
|
|
} else if (props.destroyInactiveTabPane) {
|
|
visited.value = false;
|
|
}
|
|
}, {
|
|
immediate: true
|
|
});
|
|
const mergedStyle = computed(() => {
|
|
if (!props.active) {
|
|
if (props.animated) {
|
|
return {
|
|
visibility: "hidden",
|
|
height: 0,
|
|
overflowY: "hidden"
|
|
};
|
|
} else {
|
|
return {
|
|
display: "none"
|
|
};
|
|
}
|
|
}
|
|
return {};
|
|
});
|
|
return () => {
|
|
var _a;
|
|
const {
|
|
prefixCls,
|
|
forceRender,
|
|
id,
|
|
active,
|
|
tabKey
|
|
} = props;
|
|
return createVNode("div", {
|
|
"id": id && `${id}-panel-${tabKey}`,
|
|
"role": "tabpanel",
|
|
"tabindex": active ? 0 : -1,
|
|
"aria-labelledby": id && `${id}-tab-${tabKey}`,
|
|
"aria-hidden": !active,
|
|
"style": [mergedStyle.value, attrs.style],
|
|
"class": [`${prefixCls}-tabpane`, active && `${prefixCls}-tabpane-active`, attrs.class]
|
|
}, [(active || visited.value || forceRender) && ((_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots))]);
|
|
};
|
|
}
|
|
});
|
|
Tabs.TabPane = __nuxt_component_2;
|
|
Tabs.install = function(app) {
|
|
app.component(Tabs.name, Tabs);
|
|
app.component(__nuxt_component_2.name, __nuxt_component_2);
|
|
return app;
|
|
};
|
|
|
|
export { Tabs as T, __nuxt_component_2 as _ };
|
|
//# sourceMappingURL=index-yLSGTtLi.mjs.map
|