tabs.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var vue = require('vue');
  4. var index$2 = require('../../icon/index.js');
  5. var iconsVue = require('@element-plus/icons-vue');
  6. var constants = require('./constants.js');
  7. var tabNav = require('./tab-nav.js');
  8. var runtime = require('../../../utils/vue/props/runtime.js');
  9. var event = require('../../../constants/event.js');
  10. var index = require('../../../hooks/use-namespace/index.js');
  11. var index$1 = require('../../../hooks/use-ordered-children/index.js');
  12. var aria = require('../../../constants/aria.js');
  13. var shared = require('@vue/shared');
  14. var types = require('../../../utils/types.js');
  15. const tabsProps = runtime.buildProps({
  16. type: {
  17. type: String,
  18. values: ["card", "border-card", ""],
  19. default: ""
  20. },
  21. closable: Boolean,
  22. addable: Boolean,
  23. modelValue: {
  24. type: [String, Number]
  25. },
  26. editable: Boolean,
  27. tabPosition: {
  28. type: String,
  29. values: ["top", "right", "bottom", "left"],
  30. default: "top"
  31. },
  32. beforeLeave: {
  33. type: runtime.definePropType(Function),
  34. default: () => true
  35. },
  36. stretch: Boolean
  37. });
  38. const isPaneName = (value) => shared.isString(value) || types.isNumber(value);
  39. const tabsEmits = {
  40. [event.UPDATE_MODEL_EVENT]: (name) => isPaneName(name),
  41. tabClick: (pane, ev) => ev instanceof Event,
  42. tabChange: (name) => isPaneName(name),
  43. edit: (paneName, action) => ["remove", "add"].includes(action),
  44. tabRemove: (name) => isPaneName(name),
  45. tabAdd: () => true
  46. };
  47. const Tabs = vue.defineComponent({
  48. name: "ElTabs",
  49. props: tabsProps,
  50. emits: tabsEmits,
  51. setup(props, {
  52. emit,
  53. slots,
  54. expose
  55. }) {
  56. var _a;
  57. const ns = index.useNamespace("tabs");
  58. const isVertical = vue.computed(() => ["left", "right"].includes(props.tabPosition));
  59. const {
  60. children: panes,
  61. addChild: sortPane,
  62. removeChild: unregisterPane
  63. } = index$1.useOrderedChildren(vue.getCurrentInstance(), "ElTabPane");
  64. const nav$ = vue.ref();
  65. const currentName = vue.ref((_a = props.modelValue) != null ? _a : "0");
  66. const setCurrentName = async (value, trigger = false) => {
  67. var _a2, _b;
  68. if (currentName.value === value || types.isUndefined(value))
  69. return;
  70. try {
  71. let canLeave;
  72. if (props.beforeLeave) {
  73. const result = props.beforeLeave(value, currentName.value);
  74. canLeave = result instanceof Promise ? await result : result;
  75. } else {
  76. canLeave = true;
  77. }
  78. if (canLeave !== false) {
  79. currentName.value = value;
  80. if (trigger) {
  81. emit(event.UPDATE_MODEL_EVENT, value);
  82. emit("tabChange", value);
  83. }
  84. (_b = (_a2 = nav$.value) == null ? void 0 : _a2.removeFocus) == null ? void 0 : _b.call(_a2);
  85. }
  86. } catch (e) {
  87. }
  88. };
  89. const handleTabClick = (tab, tabName, event) => {
  90. if (tab.props.disabled)
  91. return;
  92. emit("tabClick", tab, event);
  93. setCurrentName(tabName, true);
  94. };
  95. const handleTabRemove = (pane, ev) => {
  96. if (pane.props.disabled || types.isUndefined(pane.props.name))
  97. return;
  98. ev.stopPropagation();
  99. emit("edit", pane.props.name, "remove");
  100. emit("tabRemove", pane.props.name);
  101. };
  102. const handleTabAdd = () => {
  103. emit("edit", void 0, "add");
  104. emit("tabAdd");
  105. };
  106. vue.watch(() => props.modelValue, (modelValue) => setCurrentName(modelValue));
  107. vue.watch(currentName, async () => {
  108. var _a2;
  109. await vue.nextTick();
  110. (_a2 = nav$.value) == null ? void 0 : _a2.scrollToActiveTab();
  111. });
  112. vue.provide(constants.tabsRootContextKey, {
  113. props,
  114. currentName,
  115. registerPane: (pane) => {
  116. panes.value.push(pane);
  117. },
  118. sortPane,
  119. unregisterPane
  120. });
  121. expose({
  122. currentName
  123. });
  124. const TabNavRenderer = ({
  125. render
  126. }) => {
  127. return render();
  128. };
  129. return () => {
  130. const addSlot = slots["add-icon"];
  131. const newButton = props.editable || props.addable ? vue.createVNode("div", {
  132. "class": [ns.e("new-tab"), isVertical.value && ns.e("new-tab-vertical")],
  133. "tabindex": "0",
  134. "onClick": handleTabAdd,
  135. "onKeydown": (ev) => {
  136. if ([aria.EVENT_CODE.enter, aria.EVENT_CODE.numpadEnter].includes(ev.code))
  137. handleTabAdd();
  138. }
  139. }, [addSlot ? vue.renderSlot(slots, "add-icon") : vue.createVNode(index$2.ElIcon, {
  140. "class": ns.is("icon-plus")
  141. }, {
  142. default: () => [vue.createVNode(iconsVue.Plus, null, null)]
  143. })]) : null;
  144. const header = vue.createVNode("div", {
  145. "class": [ns.e("header"), isVertical.value && ns.e("header-vertical"), ns.is(props.tabPosition)]
  146. }, [vue.createVNode(TabNavRenderer, {
  147. "render": () => {
  148. const hasLabelSlot = panes.value.some((pane) => pane.slots.label);
  149. return vue.createVNode(tabNav["default"], {
  150. ref: nav$,
  151. currentName: currentName.value,
  152. editable: props.editable,
  153. type: props.type,
  154. panes: panes.value,
  155. stretch: props.stretch,
  156. onTabClick: handleTabClick,
  157. onTabRemove: handleTabRemove
  158. }, {
  159. $stable: !hasLabelSlot
  160. });
  161. }
  162. }, null), newButton]);
  163. const panels = vue.createVNode("div", {
  164. "class": ns.e("content")
  165. }, [vue.renderSlot(slots, "default")]);
  166. return vue.createVNode("div", {
  167. "class": [ns.b(), ns.m(props.tabPosition), {
  168. [ns.m("card")]: props.type === "card",
  169. [ns.m("border-card")]: props.type === "border-card"
  170. }]
  171. }, [panels, header]);
  172. };
  173. }
  174. });
  175. var Tabs$1 = Tabs;
  176. exports["default"] = Tabs$1;
  177. exports.tabsEmits = tabsEmits;
  178. exports.tabsProps = tabsProps;
  179. //# sourceMappingURL=tabs.js.map