vxe-pc-ui 4.6.35 → 4.6.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/es/icon/style.css +1 -1
  2. package/es/notice-bar/src/notice-bar.js +9 -2
  3. package/es/style.css +1 -1
  4. package/es/style.min.css +1 -1
  5. package/es/tabs/src/tabs.js +323 -106
  6. package/es/tabs/style.css +434 -156
  7. package/es/tabs/style.min.css +1 -1
  8. package/es/ui/index.js +3 -1
  9. package/es/ui/src/log.js +1 -1
  10. package/es/vxe-tabs/style.css +434 -156
  11. package/es/vxe-tabs/style.min.css +1 -1
  12. package/lib/icon/style/style.css +1 -1
  13. package/lib/icon/style/style.min.css +1 -1
  14. package/lib/index.umd.js +354 -102
  15. package/lib/index.umd.min.js +1 -1
  16. package/lib/notice-bar/src/notice-bar.js +8 -1
  17. package/lib/notice-bar/src/notice-bar.min.js +1 -1
  18. package/lib/style.css +1 -1
  19. package/lib/style.min.css +1 -1
  20. package/lib/tabs/src/tabs.js +342 -99
  21. package/lib/tabs/src/tabs.min.js +1 -1
  22. package/lib/tabs/style/style.css +434 -156
  23. package/lib/tabs/style/style.min.css +1 -1
  24. package/lib/ui/index.js +3 -1
  25. package/lib/ui/index.min.js +1 -1
  26. package/lib/ui/src/log.js +1 -1
  27. package/lib/ui/src/log.min.js +1 -1
  28. package/lib/vxe-tabs/style/style.css +434 -156
  29. package/lib/vxe-tabs/style/style.min.css +1 -1
  30. package/package.json +1 -1
  31. package/packages/notice-bar/src/notice-bar.ts +13 -3
  32. package/packages/tabs/src/tabs.ts +334 -107
  33. package/packages/ui/index.ts +2 -0
  34. package/styles/components/tabs.scss +539 -183
  35. package/types/components/tabs.d.ts +27 -7
  36. package/types/ui/global-icon.d.ts +2 -0
  37. /package/es/icon/{iconfont.1750910542831.ttf → iconfont.1751116737472.ttf} +0 -0
  38. /package/es/icon/{iconfont.1750910542831.woff → iconfont.1751116737472.woff} +0 -0
  39. /package/es/icon/{iconfont.1750910542831.woff2 → iconfont.1751116737472.woff2} +0 -0
  40. /package/es/{iconfont.1750910542831.ttf → iconfont.1751116737472.ttf} +0 -0
  41. /package/es/{iconfont.1750910542831.woff → iconfont.1751116737472.woff} +0 -0
  42. /package/es/{iconfont.1750910542831.woff2 → iconfont.1751116737472.woff2} +0 -0
  43. /package/lib/icon/style/{iconfont.1750910542831.ttf → iconfont.1751116737472.ttf} +0 -0
  44. /package/lib/icon/style/{iconfont.1750910542831.woff → iconfont.1751116737472.woff} +0 -0
  45. /package/lib/icon/style/{iconfont.1750910542831.woff2 → iconfont.1751116737472.woff2} +0 -0
  46. /package/lib/{iconfont.1750910542831.ttf → iconfont.1751116737472.ttf} +0 -0
  47. /package/lib/{iconfont.1750910542831.woff → iconfont.1751116737472.woff} +0 -0
  48. /package/lib/{iconfont.1750910542831.woff2 → iconfont.1751116737472.woff2} +0 -0
@@ -2,21 +2,34 @@ import { ref, h, reactive, inject, provide, computed, onUnmounted, watch, nextTi
2
2
  import { defineVxeComponent } from '../../ui/src/comp';
3
3
  import { createEvent, getConfig, getIcon, globalEvents, permission, renderEmptyElement } from '../../ui';
4
4
  import { getSlotVNs } from '../../ui/src/vn';
5
- import { toCssUnit } from '../../ui/src/dom';
5
+ import { toCssUnit, addClass, removeClass } from '../../ui/src/dom';
6
6
  import { isEnableConf } from '../../ui/src/utils';
7
7
  import { warnLog, errLog } from '../../ui/src/log';
8
8
  import XEUtils from 'xe-utils';
9
+ const scrollbarOffsetSize = 20;
9
10
  export default defineVxeComponent({
10
11
  name: 'VxeTabs',
11
12
  props: {
12
13
  modelValue: [String, Number, Boolean],
13
14
  options: Array,
15
+ width: [String, Number],
14
16
  height: [String, Number],
15
17
  destroyOnClose: Boolean,
16
18
  titleWidth: [String, Number],
17
19
  titleAlign: [String, Number],
18
- type: String,
20
+ type: {
21
+ type: String,
22
+ default: () => getConfig().tabs.type
23
+ },
24
+ position: {
25
+ type: String,
26
+ default: () => getConfig().tabs.position
27
+ },
19
28
  showClose: Boolean,
29
+ showBody: {
30
+ type: Boolean,
31
+ default: true
32
+ },
20
33
  padding: {
21
34
  type: Boolean,
22
35
  default: () => getConfig().tabs.padding
@@ -44,12 +57,18 @@ export default defineVxeComponent({
44
57
  const $xeParentTabs = inject('$xeTabs', null);
45
58
  const refElem = ref();
46
59
  const refHeadWrapperElem = ref();
60
+ const refHeadPrevElem = ref();
61
+ const refHeadNextElem = ref();
47
62
  const reactData = reactive({
48
63
  staticTabs: [],
49
64
  activeName: null,
50
65
  initNames: [],
51
66
  lintLeft: 0,
67
+ lintTop: 0,
52
68
  lintWidth: 0,
69
+ lintHeight: 0,
70
+ scrollbarWidth: 0,
71
+ scrollbarHeight: 0,
53
72
  isTabOver: false,
54
73
  resizeFlag: 1,
55
74
  cacheTabMaps: {}
@@ -60,6 +79,42 @@ export default defineVxeComponent({
60
79
  const refMaps = {
61
80
  refElem
62
81
  };
82
+ const computeTabType = computed(() => {
83
+ const { type } = props;
84
+ return type || 'default';
85
+ });
86
+ const computeTabPosition = computed(() => {
87
+ const { position } = props;
88
+ return position || 'top';
89
+ });
90
+ const computeLrPosition = computed(() => {
91
+ const tabPosition = computeTabPosition.value;
92
+ return tabPosition === 'left' || tabPosition === 'right';
93
+ });
94
+ const computeLineStyle = computed(() => {
95
+ const { lintLeft, lintTop, lintWidth, lintHeight } = reactData;
96
+ const lrPosition = computeLrPosition.value;
97
+ return lrPosition
98
+ ? {
99
+ top: `${lintTop}px`,
100
+ height: `${lintHeight}px`
101
+ }
102
+ : {
103
+ left: `${lintLeft}px`,
104
+ width: `${lintWidth}px`
105
+ };
106
+ });
107
+ const computeWrapperStyle = computed(() => {
108
+ const { width, height } = props;
109
+ const stys = {};
110
+ if (width) {
111
+ stys.width = toCssUnit(width);
112
+ }
113
+ if (width) {
114
+ stys.height = toCssUnit(height);
115
+ }
116
+ return stys;
117
+ });
63
118
  const computeCloseOpts = computed(() => {
64
119
  return Object.assign({}, getConfig().tabs.closeConfig, props.closeConfig);
65
120
  });
@@ -74,6 +129,9 @@ export default defineVxeComponent({
74
129
  const { staticTabs } = reactData;
75
130
  return staticTabs.filter((item) => handleFilterTab(item));
76
131
  });
132
+ const computeParentTabsResizeFlag = computed(() => {
133
+ return $xeParentTabs ? $xeParentTabs.reactData.resizeFlag : null;
134
+ });
77
135
  const computeMaps = {};
78
136
  const $xeTabs = {
79
137
  xID,
@@ -103,43 +161,108 @@ export default defineVxeComponent({
103
161
  }
104
162
  return [];
105
163
  };
164
+ const checkScrolling = () => {
165
+ const lrPosition = computeLrPosition.value;
166
+ const headerWrapperEl = refHeadWrapperElem.value;
167
+ const headPrevEl = refHeadPrevElem.value;
168
+ const headNextEl = refHeadNextElem.value;
169
+ if (headerWrapperEl) {
170
+ const { scrollLeft, scrollTop, clientWidth, clientHeight, scrollWidth, scrollHeight } = headerWrapperEl;
171
+ if (headPrevEl) {
172
+ if ((lrPosition ? scrollTop : scrollLeft) > 0) {
173
+ addClass(headPrevEl, 'scrolling--middle');
174
+ }
175
+ else {
176
+ removeClass(headPrevEl, 'scrolling--middle');
177
+ }
178
+ }
179
+ if (headNextEl) {
180
+ if (lrPosition ? (clientHeight < scrollHeight - Math.ceil(scrollTop)) : (clientWidth < scrollWidth - Math.ceil(scrollLeft))) {
181
+ addClass(headNextEl, 'scrolling--middle');
182
+ }
183
+ else {
184
+ removeClass(headNextEl, 'scrolling--middle');
185
+ }
186
+ }
187
+ }
188
+ };
106
189
  const updateTabStyle = () => {
107
- nextTick(() => {
108
- const { type } = props;
190
+ const handleStyle = () => {
109
191
  const { activeName } = reactData;
192
+ const tabType = computeTabType.value;
110
193
  const tabOptions = computeTabOptions.value;
111
194
  const tabStaticOptions = computeTabStaticOptions.value;
112
195
  const headerWrapperEl = refHeadWrapperElem.value;
196
+ const lrPosition = computeLrPosition.value;
113
197
  let lintWidth = 0;
198
+ let lintHeight = 0;
114
199
  let lintLeft = 0;
200
+ let lintTop = 0;
201
+ let sBarWidth = 0;
202
+ let sBarHeight = 0;
115
203
  let isOver = false;
116
204
  if (headerWrapperEl) {
117
205
  const index = XEUtils.findIndexOf(tabStaticOptions.length ? tabStaticOptions : tabOptions, item => item.name === activeName);
118
- const { children, scrollWidth, clientWidth } = headerWrapperEl;
119
- isOver = scrollWidth !== clientWidth;
120
- if (index > -1) {
121
- const tabEl = children[index];
122
- const tabWidth = tabEl.clientWidth;
123
- if (type) {
124
- if (type === 'card') {
125
- lintWidth = tabWidth + 2;
126
- lintLeft = tabEl.offsetLeft;
127
- }
128
- else if (type === 'border-card') {
129
- lintWidth = tabWidth + 2;
130
- lintLeft = tabEl.offsetLeft - 1;
206
+ const { children, offsetWidth, scrollWidth, offsetHeight, scrollHeight, clientWidth, clientHeight } = headerWrapperEl;
207
+ sBarWidth = offsetWidth - clientWidth;
208
+ sBarHeight = offsetHeight - clientHeight;
209
+ if (lrPosition) {
210
+ isOver = scrollHeight !== clientHeight;
211
+ if (index > -1) {
212
+ const tabEl = children[index];
213
+ if (tabEl) {
214
+ const tabHeight = tabEl.clientHeight;
215
+ const tabWidth = tabEl.clientWidth;
216
+ if (tabType === 'card') {
217
+ lintWidth = tabWidth;
218
+ lintHeight = tabHeight;
219
+ lintTop = tabEl.offsetTop;
220
+ }
221
+ else if (tabType === 'border-card') {
222
+ lintWidth = tabWidth;
223
+ lintHeight = tabHeight;
224
+ lintTop = tabEl.offsetTop - 1;
225
+ }
226
+ else {
227
+ lintHeight = Math.max(4, Math.floor(tabHeight * 0.6));
228
+ lintTop = tabEl.offsetTop + Math.floor((tabHeight - lintHeight) / 2);
229
+ }
131
230
  }
132
231
  }
133
- else {
134
- lintWidth = Math.max(4, Math.floor(tabWidth * 0.6));
135
- lintLeft = tabEl.offsetLeft + Math.floor((tabWidth - lintWidth) / 2);
232
+ }
233
+ else {
234
+ isOver = scrollWidth !== clientWidth;
235
+ if (index > -1) {
236
+ const tabEl = children[index];
237
+ if (tabEl) {
238
+ const tabWidth = tabEl.clientWidth;
239
+ if (tabType === 'card') {
240
+ lintWidth = tabWidth + 1;
241
+ lintLeft = tabEl.offsetLeft;
242
+ }
243
+ else if (tabType === 'border-card') {
244
+ lintWidth = tabWidth;
245
+ lintLeft = tabEl.offsetLeft - 1;
246
+ }
247
+ else {
248
+ lintWidth = Math.max(4, Math.floor(tabWidth * 0.6));
249
+ lintLeft = tabEl.offsetLeft + Math.floor((tabWidth - lintWidth) / 2);
250
+ }
251
+ }
136
252
  }
137
253
  }
138
254
  }
255
+ reactData.scrollbarWidth = sBarWidth;
256
+ reactData.scrollbarHeight = sBarHeight;
139
257
  reactData.lintLeft = lintLeft;
258
+ reactData.lintTop = lintTop;
140
259
  reactData.lintWidth = lintWidth;
260
+ reactData.lintHeight = lintHeight;
141
261
  reactData.isTabOver = isOver;
142
- });
262
+ checkScrolling();
263
+ };
264
+ handleStyle();
265
+ nextTick(handleStyle);
143
266
  };
144
267
  const dispatchEvent = (type, params, evnt) => {
145
268
  emit(type, createEvent(evnt, { $tabs: $xeTabs }, params));
@@ -253,7 +376,9 @@ export default defineVxeComponent({
253
376
  };
254
377
  const startScrollAnimation = (offsetPos, offsetSize) => {
255
378
  const { slTimeout } = internalData;
256
- let offsetLeft = offsetSize;
379
+ const lrPosition = computeLrPosition.value;
380
+ let offsetLeft = lrPosition ? 0 : offsetSize;
381
+ let offsetTop = lrPosition ? offsetSize : 0;
257
382
  let scrollCount = 6;
258
383
  let delayNum = 35;
259
384
  if (slTimeout) {
@@ -265,20 +390,39 @@ export default defineVxeComponent({
265
390
  if (scrollCount > 0) {
266
391
  scrollCount--;
267
392
  if (headerWrapperEl) {
268
- const { clientWidth, scrollWidth, scrollLeft } = headerWrapperEl;
269
- offsetLeft = Math.floor(offsetLeft / 2);
270
- if (offsetPos > 0) {
271
- if (clientWidth + scrollLeft < scrollWidth) {
272
- headerWrapperEl.scrollLeft += offsetLeft;
273
- delayNum -= 4;
274
- internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
393
+ const { clientWidth, clientHeight, scrollWidth, scrollHeight, scrollLeft, scrollTop } = headerWrapperEl;
394
+ if (lrPosition) {
395
+ offsetTop = Math.floor(offsetTop / 2);
396
+ if (offsetPos > 0) {
397
+ if (clientHeight + scrollTop < scrollHeight) {
398
+ headerWrapperEl.scrollTop += offsetTop;
399
+ delayNum -= 4;
400
+ internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
401
+ }
402
+ }
403
+ else {
404
+ if (scrollTop > 0) {
405
+ headerWrapperEl.scrollTop -= offsetTop;
406
+ delayNum -= 4;
407
+ internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
408
+ }
275
409
  }
276
410
  }
277
411
  else {
278
- if (scrollLeft > 0) {
279
- headerWrapperEl.scrollLeft -= offsetLeft;
280
- delayNum -= 4;
281
- internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
412
+ offsetLeft = Math.floor(offsetLeft / 2);
413
+ if (offsetPos > 0) {
414
+ if (clientWidth + scrollLeft < scrollWidth) {
415
+ headerWrapperEl.scrollLeft += offsetLeft;
416
+ delayNum -= 4;
417
+ internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
418
+ }
419
+ }
420
+ else {
421
+ if (scrollLeft > 0) {
422
+ headerWrapperEl.scrollLeft -= offsetLeft;
423
+ delayNum -= 4;
424
+ internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
425
+ }
282
426
  }
283
427
  }
284
428
  updateTabStyle();
@@ -288,9 +432,11 @@ export default defineVxeComponent({
288
432
  scrollAnimate();
289
433
  };
290
434
  const handleScrollToLeft = (offsetPos) => {
435
+ const lrPosition = computeLrPosition.value;
291
436
  const headerWrapperEl = refHeadWrapperElem.value;
292
437
  if (headerWrapperEl) {
293
- const offsetSize = Math.floor(headerWrapperEl.clientWidth * 0.75);
438
+ const { clientWidth, clientHeight } = headerWrapperEl;
439
+ const offsetSize = Math.floor((lrPosition ? clientHeight : clientWidth) * 0.75);
294
440
  startScrollAnimation(offsetPos, offsetSize);
295
441
  }
296
442
  };
@@ -303,24 +449,40 @@ export default defineVxeComponent({
303
449
  const scrollToTab = (name) => {
304
450
  const tabOptions = computeTabOptions.value;
305
451
  const tabStaticOptions = computeTabStaticOptions.value;
452
+ const lrPosition = computeLrPosition.value;
306
453
  return nextTick().then(() => {
307
454
  const headerWrapperEl = refHeadWrapperElem.value;
308
455
  if (headerWrapperEl) {
309
456
  const index = XEUtils.findIndexOf(tabStaticOptions.length ? tabStaticOptions : tabOptions, item => item.name === name);
310
457
  if (index > -1) {
311
- const { scrollLeft, clientWidth, children } = headerWrapperEl;
458
+ const { scrollLeft, scrollTop, clientWidth, clientHeight, children } = headerWrapperEl;
312
459
  const tabEl = children[index];
313
460
  if (tabEl) {
314
- const tabOffsetLeft = tabEl.offsetLeft;
315
- const tabClientWidth = tabEl.clientWidth;
316
- // 如果右侧被挡
317
- const overSize = (tabOffsetLeft + tabClientWidth) - (scrollLeft + clientWidth);
318
- if (overSize > 0) {
319
- headerWrapperEl.scrollLeft += overSize;
461
+ if (lrPosition) {
462
+ const tabOffsetTop = tabEl.offsetTop;
463
+ const tabClientHeight = tabEl.clientHeight;
464
+ // 如果顶部被挡
465
+ const overSize = (tabOffsetTop + tabClientHeight) - (scrollTop + clientHeight);
466
+ if (overSize > 0) {
467
+ headerWrapperEl.scrollTop += overSize;
468
+ }
469
+ // 如果底部被挡,优先
470
+ if (tabOffsetTop < scrollTop) {
471
+ headerWrapperEl.scrollTop = tabOffsetTop;
472
+ }
320
473
  }
321
- // 如果左侧被挡,优先
322
- if (tabOffsetLeft < scrollLeft) {
323
- headerWrapperEl.scrollLeft = tabOffsetLeft;
474
+ else {
475
+ const tabOffsetLeft = tabEl.offsetLeft;
476
+ const tabClientWidth = tabEl.clientWidth;
477
+ // 如果右侧被挡
478
+ const overSize = (tabOffsetLeft + tabClientWidth) - (scrollLeft + clientWidth);
479
+ if (overSize > 0) {
480
+ headerWrapperEl.scrollLeft += overSize;
481
+ }
482
+ // 如果左侧被挡,优先
483
+ if (tabOffsetLeft < scrollLeft) {
484
+ headerWrapperEl.scrollLeft = tabOffsetLeft;
485
+ }
324
486
  }
325
487
  }
326
488
  }
@@ -377,32 +539,54 @@ export default defineVxeComponent({
377
539
  const tabsPrivateMethods = {};
378
540
  Object.assign($xeTabs, tabsMethods, tabsPrivateMethods);
379
541
  const renderTabHeader = (tabList) => {
380
- const { type, titleWidth: allTitleWidth, titleAlign: allTitleAlign, showClose, closeConfig, refreshConfig } = props;
381
- const { activeName, lintLeft, lintWidth, isTabOver, cacheTabMaps } = reactData;
382
- const extraSlot = slots.extra;
542
+ const { titleWidth: allTitleWidth, titleAlign: allTitleAlign, showClose, closeConfig, refreshConfig } = props;
543
+ const { activeName, scrollbarWidth, scrollbarHeight, isTabOver, cacheTabMaps } = reactData;
544
+ const tabType = computeTabType.value;
545
+ const tabPosition = computeTabPosition.value;
546
+ const lrPosition = computeLrPosition.value;
547
+ const lineStyle = computeLineStyle.value;
548
+ const prefixSlot = slots.prefix;
549
+ const suffixSlot = slots.suffix || slots.extra;
383
550
  const closeOpts = computeCloseOpts.value;
384
551
  const closeVisibleMethod = closeOpts.visibleMethod;
385
552
  const refreshOpts = computeRefreshOpts.value;
386
553
  const refreshVisibleMethod = refreshOpts.visibleMethod;
387
554
  return h('div', {
388
- class: 'vxe-tabs-header'
555
+ key: 'th',
556
+ class: ['vxe-tabs-header', `type--${tabType}`, `pos--${tabPosition}`]
389
557
  }, [
558
+ prefixSlot
559
+ ? h('div', {
560
+ class: ['vxe-tabs-header--prefix', `type--${tabType}`, `pos--${tabPosition}`]
561
+ }, getSlotVNs(prefixSlot({ name: activeName })))
562
+ : renderEmptyElement($xeTabs),
390
563
  isTabOver
391
564
  ? h('div', {
392
- class: 'vxe-tabs-header--bar vxe-tabs-header--left-bar',
565
+ ref: refHeadPrevElem,
566
+ class: ['vxe-tabs-header--bar vxe-tabs-header--prev-bar', `type--${tabType}`, `pos--${tabPosition}`],
393
567
  onClick: scrollLeftEvent
394
568
  }, [
395
569
  h('span', {
396
- class: getIcon().TABS_TAB_BUTTON_LEFT
570
+ class: lrPosition ? getIcon().TABS_TAB_BUTTON_TOP : getIcon().TABS_TAB_BUTTON_LEFT
397
571
  })
398
572
  ])
399
573
  : renderEmptyElement($xeTabs),
400
574
  h('div', {
401
- class: 'vxe-tabs-header--wrapper'
575
+ class: ['vxe-tabs-header--wrapper', `type--${tabType}`, `pos--${tabPosition}`]
402
576
  }, [
403
577
  h('div', {
404
578
  ref: refHeadWrapperElem,
405
- class: 'vxe-tabs-header--item-wrapper'
579
+ class: 'vxe-tabs-header--item-wrapper',
580
+ style: lrPosition
581
+ ? {
582
+ marginRight: `-${scrollbarWidth + scrollbarOffsetSize}px`,
583
+ paddingRight: `${scrollbarOffsetSize}px`
584
+ }
585
+ : {
586
+ marginBottom: `-${scrollbarHeight + scrollbarOffsetSize}px`,
587
+ paddingBottom: `${scrollbarOffsetSize}px`
588
+ },
589
+ onScroll: checkScrolling
406
590
  }, tabList.map((item, index) => {
407
591
  const { title, titleWidth, titleAlign, icon, name, slots } = item;
408
592
  const titleSlot = slots ? (slots.title || slots.tab) : null;
@@ -414,14 +598,14 @@ export default defineVxeComponent({
414
598
  const isLoading = cacheItem ? cacheItem.loading : false;
415
599
  return h('div', {
416
600
  key: `${name}`,
417
- class: ['vxe-tabs-header--item', itemAlign ? `align--${itemAlign}` : '', {
601
+ class: ['vxe-tabs-header--item', `type--${tabType}`, `pos--${tabPosition}`, itemAlign ? `align--${itemAlign}` : '', {
418
602
  'is--active': isActive
419
603
  }],
420
604
  style: itemWidth
421
605
  ? {
422
606
  width: toCssUnit(itemWidth)
423
607
  }
424
- : null,
608
+ : undefined,
425
609
  onClick(evnt) {
426
610
  clickEvent(evnt, item);
427
611
  }
@@ -445,9 +629,11 @@ export default defineVxeComponent({
445
629
  class: 'vxe-tabs-header--item-name'
446
630
  }, titleSlot ? callSlot(titleSlot, { name, title }) : `${title}`)
447
631
  ]),
448
- (isEnableConf(refreshConfig) || refreshOpts.enabled) && (refreshVisibleMethod ? refreshVisibleMethod(params) : isActive)
632
+ (isEnableConf(refreshConfig) || refreshOpts.enabled) && (refreshVisibleMethod ? refreshVisibleMethod(params) : true)
449
633
  ? h('div', {
450
- class: 'vxe-tabs-header--refresh-btn',
634
+ class: ['vxe-tabs-header--refresh-btn', {
635
+ 'is--active': isActive
636
+ }],
451
637
  onClick(evnt) {
452
638
  handleRefreshTabEvent(evnt, item);
453
639
  }
@@ -459,7 +645,9 @@ export default defineVxeComponent({
459
645
  : renderEmptyElement($xeTabs),
460
646
  (showClose || (isEnableConf(closeConfig) || closeOpts.enabled)) && (!closeVisibleMethod || closeVisibleMethod(params))
461
647
  ? h('div', {
462
- class: 'vxe-tabs-header--close-btn',
648
+ class: ['vxe-tabs-header--close-btn', {
649
+ 'is--active': isActive
650
+ }],
463
651
  onClick(evnt) {
464
652
  handleCloseTabEvent(evnt, item, index, tabList);
465
653
  }
@@ -474,28 +662,26 @@ export default defineVxeComponent({
474
662
  }).concat([
475
663
  h('span', {
476
664
  key: 'line',
477
- class: `vxe-tabs-header--active-line type--${type || 'default'}`,
478
- style: {
479
- left: `${lintLeft}px`,
480
- width: `${lintWidth}px`
481
- }
665
+ class: ['vxe-tabs-header--active-line', `type--${tabType}`, `pos--${tabPosition}`],
666
+ style: lineStyle
482
667
  })
483
668
  ]))
484
669
  ]),
485
670
  isTabOver
486
671
  ? h('div', {
487
- class: 'vxe-tabs-header--bar vxe-tabs-header--right-bar',
672
+ ref: refHeadNextElem,
673
+ class: ['vxe-tabs-header--bar vxe-tabs-header--next-bar', `type--${tabType}`, `pos--${tabPosition}`],
488
674
  onClick: scrollRightEvent
489
675
  }, [
490
676
  h('span', {
491
- class: getIcon().TABS_TAB_BUTTON_RIGHT
677
+ class: lrPosition ? getIcon().TABS_TAB_BUTTON_BOTTOM : getIcon().TABS_TAB_BUTTON_RIGHT
492
678
  })
493
679
  ])
494
680
  : renderEmptyElement($xeTabs),
495
- extraSlot
681
+ suffixSlot
496
682
  ? h('div', {
497
- class: 'vxe-tabs-header--extra'
498
- }, getSlotVNs(extraSlot({})))
683
+ class: ['vxe-tabs-header--suffix', `type--${tabType}`, `pos--${tabPosition}`]
684
+ }, getSlotVNs(suffixSlot({ name: activeName })))
499
685
  : renderEmptyElement($xeTabs)
500
686
  ]);
501
687
  };
@@ -507,63 +693,96 @@ export default defineVxeComponent({
507
693
  ? h('div', {
508
694
  key: `${name}`,
509
695
  class: ['vxe-tabs-pane--item', {
510
- 'is--visible': activeName === name,
511
- 'has--content': !!defaultSlot
696
+ 'is--visible': activeName === name
512
697
  }]
513
698
  }, defaultSlot ? callSlot(defaultSlot, { name }) : [])
514
699
  : renderEmptyElement($xeTabs);
515
700
  };
516
- const renderTabContent = (tabList) => {
701
+ const renderTabContent = (tabList, activeTab) => {
517
702
  const { destroyOnClose } = props;
518
- const { activeName } = reactData;
519
- const activeDefaultTab = tabList.find(item => item.name === activeName);
520
703
  if (destroyOnClose) {
521
- return [activeDefaultTab ? renderTabPane(activeDefaultTab) : renderEmptyElement($xeTabs)];
704
+ return [activeTab ? renderTabPane(activeTab) : renderEmptyElement($xeTabs)];
522
705
  }
523
706
  return tabList.map((item) => renderTabPane(item));
524
707
  };
708
+ const rendetTabBody = (tabList) => {
709
+ const { height, padding, showBody } = props;
710
+ const { activeName } = reactData;
711
+ const tabType = computeTabType.value;
712
+ const tabPosition = computeTabPosition.value;
713
+ const headerpSlot = slots.header;
714
+ const footerSlot = slots.footer;
715
+ const defParams = { name: activeName };
716
+ const activeDefaultTab = tabList.find(item => item.name === activeName);
717
+ let hasContent = false;
718
+ if (activeDefaultTab) {
719
+ const { slots } = activeDefaultTab;
720
+ hasContent = !!(slots && slots.default);
721
+ }
722
+ return h('div', {
723
+ key: 'tb',
724
+ class: ['vxe-tabs-pane--wrapper', `type--${tabType}`, `pos--${tabPosition}`, {
725
+ 'is--content': showBody === false ? showBody : hasContent
726
+ }]
727
+ }, [
728
+ headerpSlot
729
+ ? h('div', {
730
+ class: 'vxe-tabs-pane--header'
731
+ }, callSlot(headerpSlot, defParams))
732
+ : renderEmptyElement($xeTabs),
733
+ h('div', {
734
+ class: ['vxe-tabs-pane--body', `type--${tabType}`, `pos--${tabPosition}`, {
735
+ 'is--padding': padding,
736
+ 'is--height': height
737
+ }]
738
+ }, renderTabContent(tabList, activeDefaultTab)),
739
+ footerSlot
740
+ ? h('div', {
741
+ class: 'vxe-tabs-pane--footer'
742
+ }, callSlot(footerSlot, defParams))
743
+ : renderEmptyElement($xeTabs)
744
+ ]);
745
+ };
525
746
  const renderVN = () => {
526
- const { type, height, padding, trigger } = props;
747
+ const { height, padding, trigger } = props;
748
+ const { activeName } = reactData;
527
749
  const tabOptions = computeTabOptions.value;
528
750
  const tabStaticOptions = computeTabStaticOptions.value;
751
+ const tabType = computeTabType.value;
752
+ const tabPosition = computeTabPosition.value;
753
+ const wrapperStyle = computeWrapperStyle.value;
529
754
  const defaultSlot = slots.default;
530
- const footerSlot = slots.footer;
531
755
  const tabList = defaultSlot ? tabStaticOptions : tabOptions;
756
+ const vns = [
757
+ h('div', {
758
+ key: 'ts',
759
+ class: 'vxe-tabs-slots'
760
+ }, defaultSlot ? defaultSlot({ name: activeName }) : [])
761
+ ];
762
+ if (tabPosition === 'right' || tabPosition === 'bottom') {
763
+ vns.push(rendetTabBody(tabList), renderTabHeader(tabList));
764
+ }
765
+ else {
766
+ vns.push(renderTabHeader(tabList), rendetTabBody(tabList));
767
+ }
532
768
  return h('div', {
533
769
  ref: refElem,
534
- class: ['vxe-tabs', `vxe-tabs--${type || 'default'}`, `trigger--${trigger === 'manual' ? 'trigger' : 'default'}`, {
770
+ class: ['vxe-tabs', `pos--${tabPosition}`, `vxe-tabs--${tabType}`, `trigger--${trigger === 'manual' ? 'trigger' : 'default'}`, {
535
771
  'is--padding': padding,
536
772
  'is--height': height
537
773
  }],
538
- style: height
539
- ? {
540
- height: toCssUnit(height)
541
- }
542
- : null
543
- }, [
544
- h('div', {
545
- class: 'vxe-tabs-slots'
546
- }, defaultSlot ? defaultSlot({}) : []),
547
- renderTabHeader(tabList),
548
- h('div', {
549
- class: 'vxe-tabs-pane'
550
- }, renderTabContent(tabList)),
551
- footerSlot
552
- ? h('div', {
553
- class: 'vxe-tabs-footer'
554
- }, callSlot(footerSlot, {}))
555
- : renderEmptyElement($xeTabs)
556
- ]);
774
+ style: wrapperStyle
775
+ }, vns);
557
776
  };
777
+ watch(() => props.position, () => {
778
+ reactData.resizeFlag++;
779
+ });
558
780
  watch(() => props.modelValue, (val) => {
559
781
  addInitName(val, null);
560
782
  reactData.activeName = val;
561
783
  });
562
784
  watch(() => reactData.activeName, (val) => {
563
785
  scrollToTab(val);
564
- nextTick(() => {
565
- reactData.resizeFlag++;
566
- });
567
786
  });
568
787
  const optsFlag = ref(0);
569
788
  watch(() => props.options ? props.options.length : -1, () => {
@@ -574,7 +793,7 @@ export default defineVxeComponent({
574
793
  });
575
794
  watch(optsFlag, () => {
576
795
  initDefaultName(props.options);
577
- updateTabStyle();
796
+ reactData.resizeFlag++;
578
797
  });
579
798
  const stFlag = ref(0);
580
799
  watch(() => reactData.staticTabs ? reactData.staticTabs.length : -1, () => {
@@ -585,21 +804,19 @@ export default defineVxeComponent({
585
804
  });
586
805
  watch(stFlag, () => {
587
806
  initDefaultName(reactData.staticTabs);
588
- updateTabStyle();
807
+ reactData.resizeFlag++;
808
+ });
809
+ watch(computeParentTabsResizeFlag, () => {
810
+ reactData.resizeFlag++;
589
811
  });
590
- if ($xeParentTabs) {
591
- watch(() => $xeParentTabs ? $xeParentTabs.reactData.resizeFlag : null, () => {
592
- reactData.resizeFlag++;
593
- });
594
- }
595
812
  watch(() => reactData.resizeFlag, () => {
596
813
  nextTick(() => {
597
814
  updateTabStyle();
598
815
  });
599
816
  });
600
817
  onMounted(() => {
601
- globalEvents.on($xeTabs, 'resize', updateTabStyle);
602
818
  updateTabStyle();
819
+ globalEvents.on($xeTabs, 'resize', updateTabStyle);
603
820
  });
604
821
  onUnmounted(() => {
605
822
  globalEvents.off($xeTabs, 'resize');