vxe-pc-ui 4.6.34 → 4.6.36

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 (45) hide show
  1. package/es/icon/style.css +1 -1
  2. package/es/style.css +1 -1
  3. package/es/style.min.css +1 -1
  4. package/es/tabs/src/tabs.js +290 -89
  5. package/es/tabs/style.css +431 -156
  6. package/es/tabs/style.min.css +1 -1
  7. package/es/ui/index.js +3 -1
  8. package/es/ui/src/log.js +1 -1
  9. package/es/vxe-tabs/style.css +431 -156
  10. package/es/vxe-tabs/style.min.css +1 -1
  11. package/lib/icon/style/style.css +1 -1
  12. package/lib/icon/style/style.min.css +1 -1
  13. package/lib/index.umd.js +310 -84
  14. package/lib/index.umd.min.js +1 -1
  15. package/lib/style.css +1 -1
  16. package/lib/style.min.css +1 -1
  17. package/lib/tabs/src/tabs.js +306 -82
  18. package/lib/tabs/src/tabs.min.js +1 -1
  19. package/lib/tabs/style/style.css +431 -156
  20. package/lib/tabs/style/style.min.css +1 -1
  21. package/lib/ui/index.js +3 -1
  22. package/lib/ui/index.min.js +1 -1
  23. package/lib/ui/src/log.js +1 -1
  24. package/lib/ui/src/log.min.js +1 -1
  25. package/lib/vxe-tabs/style/style.css +431 -156
  26. package/lib/vxe-tabs/style/style.min.css +1 -1
  27. package/package.json +1 -1
  28. package/packages/tabs/src/tabs.ts +299 -90
  29. package/packages/ui/index.ts +2 -0
  30. package/styles/components/tabs.scss +534 -183
  31. package/types/components/table-plugins/extend-cell-area.d.ts +1 -1
  32. package/types/components/tabs.d.ts +22 -6
  33. package/types/ui/global-icon.d.ts +2 -0
  34. /package/es/icon/{iconfont.1750769664150.ttf → iconfont.1751108492990.ttf} +0 -0
  35. /package/es/icon/{iconfont.1750769664150.woff → iconfont.1751108492990.woff} +0 -0
  36. /package/es/icon/{iconfont.1750769664150.woff2 → iconfont.1751108492990.woff2} +0 -0
  37. /package/es/{iconfont.1750769664150.ttf → iconfont.1751108492990.ttf} +0 -0
  38. /package/es/{iconfont.1750769664150.woff → iconfont.1751108492990.woff} +0 -0
  39. /package/es/{iconfont.1750769664150.woff2 → iconfont.1751108492990.woff2} +0 -0
  40. /package/lib/icon/style/{iconfont.1750769664150.ttf → iconfont.1751108492990.ttf} +0 -0
  41. /package/lib/icon/style/{iconfont.1750769664150.woff → iconfont.1751108492990.woff} +0 -0
  42. /package/lib/icon/style/{iconfont.1750769664150.woff2 → iconfont.1751108492990.woff2} +0 -0
  43. /package/lib/{iconfont.1750769664150.ttf → iconfont.1751108492990.ttf} +0 -0
  44. /package/lib/{iconfont.1750769664150.woff → iconfont.1751108492990.woff} +0 -0
  45. /package/lib/{iconfont.1750769664150.woff2 → iconfont.1751108492990.woff2} +0 -0
@@ -2,7 +2,7 @@ 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';
@@ -11,11 +11,19 @@ export default defineVxeComponent({
11
11
  props: {
12
12
  modelValue: [String, Number, Boolean],
13
13
  options: Array,
14
+ width: [String, Number],
14
15
  height: [String, Number],
15
16
  destroyOnClose: Boolean,
16
17
  titleWidth: [String, Number],
17
18
  titleAlign: [String, Number],
18
- type: String,
19
+ type: {
20
+ type: String,
21
+ default: () => getConfig().tabs.type
22
+ },
23
+ position: {
24
+ type: String,
25
+ default: () => getConfig().tabs.position
26
+ },
19
27
  showClose: Boolean,
20
28
  padding: {
21
29
  type: Boolean,
@@ -44,12 +52,17 @@ export default defineVxeComponent({
44
52
  const $xeParentTabs = inject('$xeTabs', null);
45
53
  const refElem = ref();
46
54
  const refHeadWrapperElem = ref();
55
+ const refHeadPrevElem = ref();
56
+ const refHeadNextElem = ref();
47
57
  const reactData = reactive({
48
58
  staticTabs: [],
49
59
  activeName: null,
50
60
  initNames: [],
51
61
  lintLeft: 0,
62
+ lintTop: 0,
52
63
  lintWidth: 0,
64
+ lintHeight: 0,
65
+ scrollbarWidth: 0,
53
66
  isTabOver: false,
54
67
  resizeFlag: 1,
55
68
  cacheTabMaps: {}
@@ -60,6 +73,42 @@ export default defineVxeComponent({
60
73
  const refMaps = {
61
74
  refElem
62
75
  };
76
+ const computeTabType = computed(() => {
77
+ const { type } = props;
78
+ return type || 'default';
79
+ });
80
+ const computeTabPosition = computed(() => {
81
+ const { position } = props;
82
+ return position || 'top';
83
+ });
84
+ const computeLrPosition = computed(() => {
85
+ const tabPosition = computeTabPosition.value;
86
+ return tabPosition === 'left' || tabPosition === 'right';
87
+ });
88
+ const computeLineStyle = computed(() => {
89
+ const { lintLeft, lintTop, lintWidth, lintHeight } = reactData;
90
+ const lrPosition = computeLrPosition.value;
91
+ return lrPosition
92
+ ? {
93
+ top: `${lintTop}px`,
94
+ height: `${lintHeight}px`
95
+ }
96
+ : {
97
+ left: `${lintLeft}px`,
98
+ width: `${lintWidth}px`
99
+ };
100
+ });
101
+ const computeWrapperStyle = computed(() => {
102
+ const { width, height } = props;
103
+ const stys = {};
104
+ if (width) {
105
+ stys.width = toCssUnit(width);
106
+ }
107
+ if (width) {
108
+ stys.height = toCssUnit(height);
109
+ }
110
+ return stys;
111
+ });
63
112
  const computeCloseOpts = computed(() => {
64
113
  return Object.assign({}, getConfig().tabs.closeConfig, props.closeConfig);
65
114
  });
@@ -103,43 +152,105 @@ export default defineVxeComponent({
103
152
  }
104
153
  return [];
105
154
  };
155
+ const checkScrolling = () => {
156
+ const lrPosition = computeLrPosition.value;
157
+ const headerWrapperEl = refHeadWrapperElem.value;
158
+ const headPrevEl = refHeadPrevElem.value;
159
+ const headNextEl = refHeadNextElem.value;
160
+ if (headerWrapperEl) {
161
+ const { scrollLeft, scrollTop, clientWidth, clientHeight, scrollWidth, scrollHeight } = headerWrapperEl;
162
+ if (headPrevEl) {
163
+ if ((lrPosition ? scrollTop : scrollLeft) > 0) {
164
+ addClass(headPrevEl, 'scrolling--middle');
165
+ }
166
+ else {
167
+ removeClass(headPrevEl, 'scrolling--middle');
168
+ }
169
+ }
170
+ if (headNextEl) {
171
+ if (lrPosition ? (clientHeight < scrollHeight - Math.ceil(scrollTop)) : (clientWidth < scrollWidth - Math.ceil(scrollLeft))) {
172
+ addClass(headNextEl, 'scrolling--middle');
173
+ }
174
+ else {
175
+ removeClass(headNextEl, 'scrolling--middle');
176
+ }
177
+ }
178
+ }
179
+ };
106
180
  const updateTabStyle = () => {
107
- nextTick(() => {
108
- const { type } = props;
181
+ const handleStyle = () => {
109
182
  const { activeName } = reactData;
183
+ const tabType = computeTabType.value;
110
184
  const tabOptions = computeTabOptions.value;
111
185
  const tabStaticOptions = computeTabStaticOptions.value;
112
186
  const headerWrapperEl = refHeadWrapperElem.value;
187
+ const lrPosition = computeLrPosition.value;
113
188
  let lintWidth = 0;
189
+ let lintHeight = 0;
114
190
  let lintLeft = 0;
191
+ let lintTop = 0;
192
+ let scrollbarWidth = 0;
115
193
  let isOver = false;
116
194
  if (headerWrapperEl) {
117
195
  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;
196
+ const { children, offsetWidth, scrollWidth, scrollHeight, clientWidth, clientHeight } = headerWrapperEl;
197
+ scrollbarWidth = offsetWidth - clientWidth;
198
+ if (lrPosition) {
199
+ isOver = scrollHeight !== clientHeight;
200
+ if (index > -1) {
201
+ const tabEl = children[index];
202
+ if (tabEl) {
203
+ const tabHeight = tabEl.clientHeight;
204
+ const tabWidth = tabEl.clientWidth;
205
+ if (tabType === 'card') {
206
+ lintWidth = tabWidth;
207
+ lintHeight = tabHeight;
208
+ lintTop = tabEl.offsetTop;
209
+ }
210
+ else if (tabType === 'border-card') {
211
+ lintWidth = tabWidth;
212
+ lintHeight = tabHeight;
213
+ lintTop = tabEl.offsetTop - 1;
214
+ }
215
+ else {
216
+ lintHeight = Math.max(4, Math.floor(tabHeight * 0.6));
217
+ lintTop = tabEl.offsetTop + Math.floor((tabHeight - lintHeight) / 2);
218
+ }
131
219
  }
132
220
  }
133
- else {
134
- lintWidth = Math.max(4, Math.floor(tabWidth * 0.6));
135
- lintLeft = tabEl.offsetLeft + Math.floor((tabWidth - lintWidth) / 2);
221
+ }
222
+ else {
223
+ isOver = scrollWidth !== clientWidth;
224
+ if (index > -1) {
225
+ const tabEl = children[index];
226
+ if (tabEl) {
227
+ const tabWidth = tabEl.clientWidth;
228
+ if (tabType === 'card') {
229
+ lintWidth = tabWidth;
230
+ lintLeft = tabEl.offsetLeft;
231
+ }
232
+ else if (tabType === 'border-card') {
233
+ lintWidth = tabWidth;
234
+ lintLeft = tabEl.offsetLeft - 1;
235
+ }
236
+ else {
237
+ lintWidth = Math.max(4, Math.floor(tabWidth * 0.6));
238
+ lintLeft = tabEl.offsetLeft + Math.floor((tabWidth - lintWidth) / 2);
239
+ }
240
+ }
136
241
  }
137
242
  }
138
243
  }
244
+ reactData.scrollbarWidth = scrollbarWidth;
139
245
  reactData.lintLeft = lintLeft;
246
+ reactData.lintTop = lintTop;
140
247
  reactData.lintWidth = lintWidth;
248
+ reactData.lintHeight = lintHeight;
141
249
  reactData.isTabOver = isOver;
142
- });
250
+ checkScrolling();
251
+ };
252
+ handleStyle();
253
+ nextTick(handleStyle);
143
254
  };
144
255
  const dispatchEvent = (type, params, evnt) => {
145
256
  emit(type, createEvent(evnt, { $tabs: $xeTabs }, params));
@@ -253,7 +364,9 @@ export default defineVxeComponent({
253
364
  };
254
365
  const startScrollAnimation = (offsetPos, offsetSize) => {
255
366
  const { slTimeout } = internalData;
256
- let offsetLeft = offsetSize;
367
+ const lrPosition = computeLrPosition.value;
368
+ let offsetLeft = lrPosition ? 0 : offsetSize;
369
+ let offsetTop = lrPosition ? offsetSize : 0;
257
370
  let scrollCount = 6;
258
371
  let delayNum = 35;
259
372
  if (slTimeout) {
@@ -265,20 +378,39 @@ export default defineVxeComponent({
265
378
  if (scrollCount > 0) {
266
379
  scrollCount--;
267
380
  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);
381
+ const { clientWidth, clientHeight, scrollWidth, scrollHeight, scrollLeft, scrollTop } = headerWrapperEl;
382
+ if (lrPosition) {
383
+ offsetTop = Math.floor(offsetTop / 2);
384
+ if (offsetPos > 0) {
385
+ if (clientHeight + scrollTop < scrollHeight) {
386
+ headerWrapperEl.scrollTop += offsetTop;
387
+ delayNum -= 4;
388
+ internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
389
+ }
390
+ }
391
+ else {
392
+ if (scrollTop > 0) {
393
+ headerWrapperEl.scrollTop -= offsetTop;
394
+ delayNum -= 4;
395
+ internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
396
+ }
275
397
  }
276
398
  }
277
399
  else {
278
- if (scrollLeft > 0) {
279
- headerWrapperEl.scrollLeft -= offsetLeft;
280
- delayNum -= 4;
281
- internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
400
+ offsetLeft = Math.floor(offsetLeft / 2);
401
+ if (offsetPos > 0) {
402
+ if (clientWidth + scrollLeft < scrollWidth) {
403
+ headerWrapperEl.scrollLeft += offsetLeft;
404
+ delayNum -= 4;
405
+ internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
406
+ }
407
+ }
408
+ else {
409
+ if (scrollLeft > 0) {
410
+ headerWrapperEl.scrollLeft -= offsetLeft;
411
+ delayNum -= 4;
412
+ internalData.slTimeout = setTimeout(scrollAnimate, delayNum);
413
+ }
282
414
  }
283
415
  }
284
416
  updateTabStyle();
@@ -288,9 +420,11 @@ export default defineVxeComponent({
288
420
  scrollAnimate();
289
421
  };
290
422
  const handleScrollToLeft = (offsetPos) => {
423
+ const lrPosition = computeLrPosition.value;
291
424
  const headerWrapperEl = refHeadWrapperElem.value;
292
425
  if (headerWrapperEl) {
293
- const offsetSize = Math.floor(headerWrapperEl.clientWidth * 0.75);
426
+ const { clientWidth, clientHeight } = headerWrapperEl;
427
+ const offsetSize = Math.floor((lrPosition ? clientHeight : clientWidth) * 0.75);
294
428
  startScrollAnimation(offsetPos, offsetSize);
295
429
  }
296
430
  };
@@ -303,24 +437,40 @@ export default defineVxeComponent({
303
437
  const scrollToTab = (name) => {
304
438
  const tabOptions = computeTabOptions.value;
305
439
  const tabStaticOptions = computeTabStaticOptions.value;
440
+ const lrPosition = computeLrPosition.value;
306
441
  return nextTick().then(() => {
307
442
  const headerWrapperEl = refHeadWrapperElem.value;
308
443
  if (headerWrapperEl) {
309
444
  const index = XEUtils.findIndexOf(tabStaticOptions.length ? tabStaticOptions : tabOptions, item => item.name === name);
310
445
  if (index > -1) {
311
- const { scrollLeft, clientWidth, children } = headerWrapperEl;
446
+ const { scrollLeft, scrollTop, clientWidth, clientHeight, children } = headerWrapperEl;
312
447
  const tabEl = children[index];
313
448
  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;
449
+ if (lrPosition) {
450
+ const tabOffsetTop = tabEl.offsetTop;
451
+ const tabClientHeight = tabEl.clientHeight;
452
+ // 如果顶部被挡
453
+ const overSize = (tabOffsetTop + tabClientHeight) - (scrollTop + clientHeight);
454
+ if (overSize > 0) {
455
+ headerWrapperEl.scrollTop += overSize;
456
+ }
457
+ // 如果底部被挡,优先
458
+ if (tabOffsetTop < scrollTop) {
459
+ headerWrapperEl.scrollTop = tabOffsetTop;
460
+ }
320
461
  }
321
- // 如果左侧被挡,优先
322
- if (tabOffsetLeft < scrollLeft) {
323
- headerWrapperEl.scrollLeft = tabOffsetLeft;
462
+ else {
463
+ const tabOffsetLeft = tabEl.offsetLeft;
464
+ const tabClientWidth = tabEl.clientWidth;
465
+ // 如果右侧被挡
466
+ const overSize = (tabOffsetLeft + tabClientWidth) - (scrollLeft + clientWidth);
467
+ if (overSize > 0) {
468
+ headerWrapperEl.scrollLeft += overSize;
469
+ }
470
+ // 如果左侧被挡,优先
471
+ if (tabOffsetLeft < scrollLeft) {
472
+ headerWrapperEl.scrollLeft = tabOffsetLeft;
473
+ }
324
474
  }
325
475
  }
326
476
  }
@@ -377,32 +527,50 @@ export default defineVxeComponent({
377
527
  const tabsPrivateMethods = {};
378
528
  Object.assign($xeTabs, tabsMethods, tabsPrivateMethods);
379
529
  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;
530
+ const { titleWidth: allTitleWidth, titleAlign: allTitleAlign, showClose, closeConfig, refreshConfig } = props;
531
+ const { activeName, scrollbarWidth, isTabOver, cacheTabMaps } = reactData;
532
+ const tabType = computeTabType.value;
533
+ const tabPosition = computeTabPosition.value;
534
+ const lrPosition = computeLrPosition.value;
535
+ const lineStyle = computeLineStyle.value;
536
+ const prefixSlot = slots.prefix;
537
+ const suffixSlot = slots.suffix || slots.extra;
383
538
  const closeOpts = computeCloseOpts.value;
384
539
  const closeVisibleMethod = closeOpts.visibleMethod;
385
540
  const refreshOpts = computeRefreshOpts.value;
386
541
  const refreshVisibleMethod = refreshOpts.visibleMethod;
387
542
  return h('div', {
388
- class: 'vxe-tabs-header'
543
+ key: 'th',
544
+ class: ['vxe-tabs-header', `type--${tabType}`, `pos--${tabPosition}`]
389
545
  }, [
546
+ prefixSlot
547
+ ? h('div', {
548
+ class: ['vxe-tabs-header--prefix', `type--${tabType}`, `pos--${tabPosition}`]
549
+ }, getSlotVNs(prefixSlot({ name: activeName })))
550
+ : renderEmptyElement($xeTabs),
390
551
  isTabOver
391
552
  ? h('div', {
392
- class: 'vxe-tabs-header--bar vxe-tabs-header--left-bar',
553
+ ref: refHeadPrevElem,
554
+ class: ['vxe-tabs-header--bar vxe-tabs-header--prev-bar', `type--${tabType}`, `pos--${tabPosition}`],
393
555
  onClick: scrollLeftEvent
394
556
  }, [
395
557
  h('span', {
396
- class: getIcon().TABS_TAB_BUTTON_LEFT
558
+ class: lrPosition ? getIcon().TABS_TAB_BUTTON_TOP : getIcon().TABS_TAB_BUTTON_LEFT
397
559
  })
398
560
  ])
399
561
  : renderEmptyElement($xeTabs),
400
562
  h('div', {
401
- class: 'vxe-tabs-header--wrapper'
563
+ class: ['vxe-tabs-header--wrapper', `type--${tabType}`, `pos--${tabPosition}`]
402
564
  }, [
403
565
  h('div', {
404
566
  ref: refHeadWrapperElem,
405
- class: 'vxe-tabs-header--item-wrapper'
567
+ class: 'vxe-tabs-header--item-wrapper',
568
+ style: lrPosition && scrollbarWidth
569
+ ? {
570
+ marginRight: `-${scrollbarWidth}px`
571
+ }
572
+ : undefined,
573
+ onScroll: checkScrolling
406
574
  }, tabList.map((item, index) => {
407
575
  const { title, titleWidth, titleAlign, icon, name, slots } = item;
408
576
  const titleSlot = slots ? (slots.title || slots.tab) : null;
@@ -414,14 +582,14 @@ export default defineVxeComponent({
414
582
  const isLoading = cacheItem ? cacheItem.loading : false;
415
583
  return h('div', {
416
584
  key: `${name}`,
417
- class: ['vxe-tabs-header--item', itemAlign ? `align--${itemAlign}` : '', {
585
+ class: ['vxe-tabs-header--item', `type--${tabType}`, `pos--${tabPosition}`, itemAlign ? `align--${itemAlign}` : '', {
418
586
  'is--active': isActive
419
587
  }],
420
588
  style: itemWidth
421
589
  ? {
422
590
  width: toCssUnit(itemWidth)
423
591
  }
424
- : null,
592
+ : undefined,
425
593
  onClick(evnt) {
426
594
  clickEvent(evnt, item);
427
595
  }
@@ -445,9 +613,11 @@ export default defineVxeComponent({
445
613
  class: 'vxe-tabs-header--item-name'
446
614
  }, titleSlot ? callSlot(titleSlot, { name, title }) : `${title}`)
447
615
  ]),
448
- (isEnableConf(refreshConfig) || refreshOpts.enabled) && (refreshVisibleMethod ? refreshVisibleMethod(params) : isActive)
616
+ (isEnableConf(refreshConfig) || refreshOpts.enabled) && (refreshVisibleMethod ? refreshVisibleMethod(params) : true)
449
617
  ? h('div', {
450
- class: 'vxe-tabs-header--refresh-btn',
618
+ class: ['vxe-tabs-header--refresh-btn', {
619
+ 'is--active': isActive
620
+ }],
451
621
  onClick(evnt) {
452
622
  handleRefreshTabEvent(evnt, item);
453
623
  }
@@ -459,7 +629,9 @@ export default defineVxeComponent({
459
629
  : renderEmptyElement($xeTabs),
460
630
  (showClose || (isEnableConf(closeConfig) || closeOpts.enabled)) && (!closeVisibleMethod || closeVisibleMethod(params))
461
631
  ? h('div', {
462
- class: 'vxe-tabs-header--close-btn',
632
+ class: ['vxe-tabs-header--close-btn', {
633
+ 'is--active': isActive
634
+ }],
463
635
  onClick(evnt) {
464
636
  handleCloseTabEvent(evnt, item, index, tabList);
465
637
  }
@@ -474,28 +646,26 @@ export default defineVxeComponent({
474
646
  }).concat([
475
647
  h('span', {
476
648
  key: 'line',
477
- class: `vxe-tabs-header--active-line type--${type || 'default'}`,
478
- style: {
479
- left: `${lintLeft}px`,
480
- width: `${lintWidth}px`
481
- }
649
+ class: ['vxe-tabs-header--active-line', `type--${tabType}`, `pos--${tabPosition}`],
650
+ style: lineStyle
482
651
  })
483
652
  ]))
484
653
  ]),
485
654
  isTabOver
486
655
  ? h('div', {
487
- class: 'vxe-tabs-header--bar vxe-tabs-header--right-bar',
656
+ ref: refHeadNextElem,
657
+ class: ['vxe-tabs-header--bar vxe-tabs-header--next-bar', `type--${tabType}`, `pos--${tabPosition}`],
488
658
  onClick: scrollRightEvent
489
659
  }, [
490
660
  h('span', {
491
- class: getIcon().TABS_TAB_BUTTON_RIGHT
661
+ class: lrPosition ? getIcon().TABS_TAB_BUTTON_BOTTOM : getIcon().TABS_TAB_BUTTON_RIGHT
492
662
  })
493
663
  ])
494
664
  : renderEmptyElement($xeTabs),
495
- extraSlot
665
+ suffixSlot
496
666
  ? h('div', {
497
- class: 'vxe-tabs-header--extra'
498
- }, getSlotVNs(extraSlot({})))
667
+ class: ['vxe-tabs-header--suffix', `type--${tabType}`, `pos--${tabPosition}`]
668
+ }, getSlotVNs(suffixSlot({ name: activeName })))
499
669
  : renderEmptyElement($xeTabs)
500
670
  ]);
501
671
  };
@@ -522,39 +692,70 @@ export default defineVxeComponent({
522
692
  }
523
693
  return tabList.map((item) => renderTabPane(item));
524
694
  };
695
+ const rendetTabBody = (tabList) => {
696
+ const { height, padding } = props;
697
+ const { activeName } = reactData;
698
+ const tabType = computeTabType.value;
699
+ const tabPosition = computeTabPosition.value;
700
+ const topSlot = slots.top;
701
+ const footerSlot = slots.footer;
702
+ const defParams = { name: activeName };
703
+ return h('div', {
704
+ key: 'tb',
705
+ class: ['vxe-tabs-pane--wrapper', `type--${tabType}`, `pos--${tabPosition}`]
706
+ }, [
707
+ topSlot
708
+ ? h('div', {
709
+ class: 'vxe-tabs-pane--top'
710
+ }, callSlot(topSlot, defParams))
711
+ : renderEmptyElement($xeTabs),
712
+ h('div', {
713
+ class: ['vxe-tabs-pane--body', `type--${tabType}`, `pos--${tabPosition}`, {
714
+ 'is--padding': padding,
715
+ 'is--height': height
716
+ }]
717
+ }, renderTabContent(tabList)),
718
+ footerSlot
719
+ ? h('div', {
720
+ class: 'vxe-tabs-pane--footer'
721
+ }, callSlot(footerSlot, defParams))
722
+ : renderEmptyElement($xeTabs)
723
+ ]);
724
+ };
525
725
  const renderVN = () => {
526
- const { type, height, padding, trigger } = props;
726
+ const { height, padding, trigger } = props;
727
+ const { activeName } = reactData;
527
728
  const tabOptions = computeTabOptions.value;
528
729
  const tabStaticOptions = computeTabStaticOptions.value;
730
+ const tabType = computeTabType.value;
731
+ const tabPosition = computeTabPosition.value;
732
+ const wrapperStyle = computeWrapperStyle.value;
529
733
  const defaultSlot = slots.default;
530
- const footerSlot = slots.footer;
531
734
  const tabList = defaultSlot ? tabStaticOptions : tabOptions;
735
+ const vns = [
736
+ h('div', {
737
+ key: 'ts',
738
+ class: 'vxe-tabs-slots'
739
+ }, defaultSlot ? defaultSlot({ name: activeName }) : [])
740
+ ];
741
+ if (tabPosition === 'right' || tabPosition === 'bottom') {
742
+ vns.push(rendetTabBody(tabList), renderTabHeader(tabList));
743
+ }
744
+ else {
745
+ vns.push(renderTabHeader(tabList), rendetTabBody(tabList));
746
+ }
532
747
  return h('div', {
533
748
  ref: refElem,
534
- class: ['vxe-tabs', `vxe-tabs--${type || 'default'}`, `trigger--${trigger === 'manual' ? 'trigger' : 'default'}`, {
749
+ class: ['vxe-tabs', `pos--${tabPosition}`, `vxe-tabs--${tabType}`, `trigger--${trigger === 'manual' ? 'trigger' : 'default'}`, {
535
750
  'is--padding': padding,
536
751
  'is--height': height
537
752
  }],
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
- ]);
753
+ style: wrapperStyle
754
+ }, vns);
557
755
  };
756
+ watch(() => props.position, () => {
757
+ updateTabStyle();
758
+ });
558
759
  watch(() => props.modelValue, (val) => {
559
760
  addInitName(val, null);
560
761
  reactData.activeName = val;