vxe-pc-ui 3.19.7 → 3.20.0

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 (97) hide show
  1. package/es/card/src/card.js +48 -11
  2. package/es/card/style.css +42 -44
  3. package/es/card/style.min.css +1 -1
  4. package/es/icon/style.css +1 -1
  5. package/es/list/src/list.js +360 -19
  6. package/es/list/style.css +26 -0
  7. package/es/list/style.min.css +1 -1
  8. package/es/scrollbar/src/scrollbar.js +6 -0
  9. package/es/scrollbar/style.css +6 -5
  10. package/es/scrollbar/style.min.css +1 -1
  11. package/es/style.css +1 -1
  12. package/es/style.min.css +1 -1
  13. package/es/tabs/src/tabs.js +35 -8
  14. package/es/tabs/style.css +4 -2
  15. package/es/tabs/style.min.css +1 -1
  16. package/es/tree/src/tree.js +6 -2
  17. package/es/ui/index.js +1 -1
  18. package/es/ui/src/log.js +1 -1
  19. package/es/ui/src/utils.js +9 -0
  20. package/es/vxe-card/style.css +42 -44
  21. package/es/vxe-card/style.min.css +1 -1
  22. package/es/vxe-list/style.css +26 -0
  23. package/es/vxe-list/style.min.css +1 -1
  24. package/es/vxe-scrollbar/style.css +6 -5
  25. package/es/vxe-scrollbar/style.min.css +1 -1
  26. package/es/vxe-tabs/style.css +4 -2
  27. package/es/vxe-tabs/style.min.css +1 -1
  28. package/lib/card/src/card.js +55 -5
  29. package/lib/card/src/card.min.js +1 -1
  30. package/lib/card/style/style.css +42 -44
  31. package/lib/card/style/style.min.css +1 -1
  32. package/lib/icon/style/style.css +1 -1
  33. package/lib/icon/style/style.min.css +1 -1
  34. package/lib/index.umd.js +5966 -5536
  35. package/lib/index.umd.min.js +1 -1
  36. package/lib/list/src/list.js +344 -20
  37. package/lib/list/src/list.min.js +1 -1
  38. package/lib/list/style/style.css +26 -0
  39. package/lib/list/style/style.min.css +1 -1
  40. package/lib/scrollbar/src/scrollbar.js +6 -0
  41. package/lib/scrollbar/src/scrollbar.min.js +1 -1
  42. package/lib/scrollbar/style/style.css +6 -5
  43. package/lib/scrollbar/style/style.min.css +1 -1
  44. package/lib/style.css +1 -1
  45. package/lib/style.min.css +1 -1
  46. package/lib/tabs/src/tabs.js +45 -8
  47. package/lib/tabs/src/tabs.min.js +1 -1
  48. package/lib/tabs/style/style.css +4 -2
  49. package/lib/tabs/style/style.min.css +1 -1
  50. package/lib/tree/src/tree.js +4 -0
  51. package/lib/tree/src/tree.min.js +1 -1
  52. package/lib/ui/index.js +1 -1
  53. package/lib/ui/index.min.js +1 -1
  54. package/lib/ui/src/log.js +1 -1
  55. package/lib/ui/src/log.min.js +1 -1
  56. package/lib/ui/src/utils.js +10 -0
  57. package/lib/ui/src/utils.min.js +1 -1
  58. package/lib/vxe-card/style/style.css +42 -44
  59. package/lib/vxe-card/style/style.min.css +1 -1
  60. package/lib/vxe-list/style/style.css +26 -0
  61. package/lib/vxe-list/style/style.min.css +1 -1
  62. package/lib/vxe-scrollbar/style/style.css +6 -5
  63. package/lib/vxe-scrollbar/style/style.min.css +1 -1
  64. package/lib/vxe-tabs/style/style.css +4 -2
  65. package/lib/vxe-tabs/style/style.min.css +1 -1
  66. package/package.json +1 -1
  67. package/packages/card/src/card.ts +65 -11
  68. package/packages/list/src/list.ts +388 -21
  69. package/packages/scrollbar/src/scrollbar.ts +6 -0
  70. package/packages/tabs/src/tabs.ts +40 -8
  71. package/packages/tree/src/tree.ts +6 -2
  72. package/packages/ui/src/utils.ts +10 -0
  73. package/styles/components/card.scss +44 -58
  74. package/styles/components/list.scss +51 -0
  75. package/styles/components/scrollbar.scss +18 -11
  76. package/styles/components/tabs.scss +2 -1
  77. package/types/components/card.d.ts +11 -0
  78. package/types/components/grid.d.ts +37 -0
  79. package/types/components/layout-aside.d.ts +7 -1
  80. package/types/components/layout-body.d.ts +7 -1
  81. package/types/components/list.d.ts +24 -2
  82. package/types/components/menu.d.ts +6 -0
  83. package/types/components/table-plugins/extend-cell-area.d.ts +1 -1
  84. package/types/components/table.d.ts +27 -4
  85. package/types/components/tabs.d.ts +11 -0
  86. /package/es/icon/{iconfont.1791794439953.ttf → iconfont.1791880407207.ttf} +0 -0
  87. /package/es/icon/{iconfont.1791794439953.woff → iconfont.1791880407207.woff} +0 -0
  88. /package/es/icon/{iconfont.1791794439953.woff2 → iconfont.1791880407207.woff2} +0 -0
  89. /package/es/{iconfont.1791794439953.ttf → iconfont.1791880407207.ttf} +0 -0
  90. /package/es/{iconfont.1791794439953.woff → iconfont.1791880407207.woff} +0 -0
  91. /package/es/{iconfont.1791794439953.woff2 → iconfont.1791880407207.woff2} +0 -0
  92. /package/lib/icon/style/{iconfont.1791794439953.ttf → iconfont.1791880407207.ttf} +0 -0
  93. /package/lib/icon/style/{iconfont.1791794439953.woff → iconfont.1791880407207.woff} +0 -0
  94. /package/lib/icon/style/{iconfont.1791794439953.woff2 → iconfont.1791880407207.woff2} +0 -0
  95. /package/lib/{iconfont.1791794439953.ttf → iconfont.1791880407207.ttf} +0 -0
  96. /package/lib/{iconfont.1791794439953.woff → iconfont.1791880407207.woff} +0 -0
  97. /package/lib/{iconfont.1791794439953.woff2 → iconfont.1791880407207.woff2} +0 -0
@@ -1,17 +1,18 @@
1
1
  import { PropType, CreateElement, VNode } from 'vue'
2
2
  import { defineVxeComponent } from '../../ui/src/comp'
3
3
  import XEUtils, { XEBrowse } from 'xe-utils'
4
- import { VxeUI, getConfig, getIcon, getI18n, menus, globalEvents, globalResize, createEvent, globalMixins, renderEmptyElement } from '../../ui'
4
+ import { VxeUI, getConfig, getIcon, getI18n, domUtils, menus, globalEvents, globalResize, createEvent, globalMixins, renderEmptyElement } from '../../ui'
5
5
  import { crossListDragRowGlobal, getCrossListDragRowInfo } from './store'
6
- import { addClass, getTpImg, isScale, removeClass, toCssUnit } from '../../ui/src/dom'
6
+ import { addClass, getTpImg, hasClass, isScale, removeClass, toCssUnit } from '../../ui/src/dom'
7
7
  import { isEnableConf, getText, enModelValue, deModelValue } from '../../ui/src/utils'
8
8
  import { getSlotVNs } from '../../ui/src/vn'
9
9
  import { createComponentLog } from '../../ui/src/log'
10
10
  import { moveRowAnimateToTb, clearRowAnimate } from '../../ui/src/anime'
11
+ import { getThumbOffsetSize, getThumbSize, getScrollFromClick, getScrollFromDrag } from '../../scrollbar/src/util'
11
12
  import { getItemCacheObj } from './util'
12
13
  import VxeLoadingComponent from '../../loading'
13
14
 
14
- import type { VxeListPropTypes, VxeListEmits, VxeComponentSizeType, ListReactData, VxeListDefines, ValueOf, ListInternalData, VxeListConstructor, VxeListPrivateMethods, VxeComponentStyleType } from '../../../types'
15
+ import type { VxeListPropTypes, VxeListEmits, VxeComponentSizeType, ListReactData, VxeListDefines, ValueOf, ListInternalData, VxeListConstructor, VxeListPrivateMethods, VxeComponentStyleType, VxeScrollbarPropTypes } from '../../../types'
15
16
 
16
17
  const { warnLog, errLog } = createComponentLog('tree')
17
18
 
@@ -52,6 +53,11 @@ function createReactData (): ListReactData {
52
53
  updateCheckboxFlag: 1,
53
54
  isAllChecked: false,
54
55
  isAllIndeterminate: false,
56
+
57
+ // 滚动条
58
+ yThumbHeight: 0,
59
+ xThumbWidth: 0,
60
+
55
61
  insertRowFlag: 1,
56
62
  removeRowFlag: 1,
57
63
  dragRow: null,
@@ -62,13 +68,20 @@ function createReactData (): ListReactData {
62
68
 
63
69
  function createInternalData (): ListInternalData {
64
70
  return {
65
- resizeObserver: undefined,
66
71
  fullData: [],
67
72
  afterList: [],
68
73
  fullKeyMaps: {},
69
74
  rowMaps: {},
70
- lastScrollLeft: 0,
75
+
76
+ // 滚动条
77
+ // resizeObserver: undefined,
78
+ // isThumbDrag: false,
79
+ thumbDragOffset: 0,
80
+ yThumbTop: 0,
81
+ xThumbLeft: 0,
71
82
  lastScrollTop: 0,
83
+ lastScrollLeft: 0,
84
+
72
85
  scrollYStore: {
73
86
  startIndex: 0,
74
87
  endIndex: 0,
@@ -125,7 +138,12 @@ export default /* define-vxe-component start */ defineVxeComponent({
125
138
  dragConfig: Object as PropType<VxeListPropTypes.DragConfig>,
126
139
  menuConfig: Object as PropType<VxeListPropTypes.MenuConfig>,
127
140
  virtualYConfig: Object as PropType<VxeListPropTypes.VirtualYConfig>,
128
- scrollY: Object as PropType<VxeListPropTypes.ScrollY>
141
+ scrollY: Object as PropType<VxeListPropTypes.ScrollY>,
142
+ useScrollbar: {
143
+ type: Boolean as PropType<VxeListPropTypes.UseScrollbar>,
144
+ default: () => getConfig().list.useScrollbar
145
+ },
146
+ scrollbarConfig: Object as PropType<VxeListPropTypes.ScrollbarConfig>
129
147
  },
130
148
  data () {
131
149
  const xID = XEUtils.uniqueId()
@@ -208,11 +226,19 @@ export default /* define-vxe-component start */ defineVxeComponent({
208
226
  const $xeList = this
209
227
 
210
228
  const rowHeight = $xeList.computeRowHeight
211
- const style: VxeComponentStyleType = {}
229
+ const scrollbarXOpts = $xeList.computeScrollbarXOpts as VxeScrollbarPropTypes.XConfig
230
+ const scrollbarYOpts = $xeList.computeScrollbarYOpts as VxeScrollbarPropTypes.YConfig
231
+ const stys: VxeComponentStyleType = {}
212
232
  if (rowHeight) {
213
- style['--vxe-ui-list-row-height'] = toCssUnit(rowHeight)
233
+ stys['--vxe-ui-list-row-height'] = toCssUnit(rowHeight)
214
234
  }
215
- return style
235
+ if (scrollbarYOpts.width) {
236
+ stys['--vxe-ui-scrollbar-y-width'] = toCssUnit(scrollbarYOpts.width)
237
+ }
238
+ if (scrollbarXOpts.height) {
239
+ stys['--vxe-ui-scrollbar-x-height'] = toCssUnit(scrollbarXOpts.height)
240
+ }
241
+ return stys
216
242
  },
217
243
  computeVirtualStyles () {
218
244
  const $xeList = this
@@ -229,8 +255,62 @@ export default /* define-vxe-component start */ defineVxeComponent({
229
255
  style.maxHeight = toCssUnit(Math.max(20, customMaxHeight - headHeight - footHeight))
230
256
  }
231
257
  return style
232
- }
258
+ },
259
+ computeScrollbarOpts () {
260
+ const $xeList = this
261
+ const props = $xeList
233
262
 
263
+ return Object.assign({}, getConfig().list.scrollbarConfig, props.scrollbarConfig)
264
+ },
265
+ computeScrollbarXOpts () {
266
+ const $xeList = this
267
+
268
+ const scrollbarOpts = $xeList.computeScrollbarOpts as VxeListPropTypes.ScrollbarConfig
269
+ return Object.assign({}, getConfig().scrollbar.xConfig, scrollbarOpts.xConfig)
270
+ },
271
+ computeScrollbarYOpts () {
272
+ const $xeList = this
273
+
274
+ const scrollbarOpts = $xeList.computeScrollbarOpts as VxeListPropTypes.ScrollbarConfig
275
+ return Object.assign({}, getConfig().scrollbar.yConfig, scrollbarOpts.yConfig)
276
+ },
277
+ computeScrollbarWrapperClss () {
278
+ const $xeList = this
279
+ const reactData = $xeList.reactData
280
+
281
+ const scrollbarOpts = $xeList.computeScrollbarOpts as VxeListPropTypes.ScrollbarConfig
282
+ const { padding } = scrollbarOpts
283
+ const { yThumbHeight, xThumbWidth } = reactData
284
+ const scrollbarXOpts = $xeList.computeScrollbarXOpts as VxeScrollbarPropTypes.XConfig
285
+ const scrollbarYOpts = $xeList.computeScrollbarYOpts as VxeScrollbarPropTypes.YConfig
286
+ const scrollbarXToTop = $xeList.computeScrollbarXToTop
287
+ const scrollbarYToLeft = $xeList.computeScrollbarYToLeft
288
+ return domUtils.buildClass([
289
+ 'vxe-scrollbar is--virtual',
290
+ `ov-x--${scrollbarXOpts.visible || 'visible'}`,
291
+ `ov-y--${scrollbarYOpts.visible || 'visible'}`,
292
+ `sx-pos--${scrollbarXToTop ? 'top' : 'bottom'}`,
293
+ `sy-pos--${scrollbarYToLeft ? 'left' : 'right'}`
294
+ ], {
295
+ 'is--padding': padding,
296
+ 'ov-x--auto-hide': scrollbarXOpts.autoHide,
297
+ 'ov-y--auto-hide': scrollbarYOpts.autoHide,
298
+ 'overflow-y': yThumbHeight,
299
+ 'overflow-x': xThumbWidth
300
+ })
301
+ },
302
+ computeScrollbarXToTop () {
303
+ const $xeList = this
304
+
305
+ const scrollbarXOpts = $xeList.computeScrollbarXOpts as VxeScrollbarPropTypes.XConfig
306
+ return scrollbarXOpts.position === 'top'
307
+ },
308
+ computeScrollbarYToLeft () {
309
+ const $xeList = this
310
+
311
+ const scrollbarYOpts = $xeList.computeScrollbarYOpts as VxeScrollbarPropTypes.YConfig
312
+ return scrollbarYOpts.position === 'left'
313
+ }
234
314
  },
235
315
  methods: {
236
316
  //
@@ -573,6 +653,12 @@ export default /* define-vxe-component start */ defineVxeComponent({
573
653
  }
574
654
  })
575
655
  },
656
+ updateScrollbar () {
657
+ const $xeList = this
658
+
659
+ $xeList.updateThumbSize()
660
+ $xeList.updateThumbOffset()
661
+ },
576
662
  /**
577
663
  * 重新计算列表
578
664
  */
@@ -582,13 +668,18 @@ export default /* define-vxe-component start */ defineVxeComponent({
582
668
 
583
669
  const el = $xeList.$refs.refElem as HTMLDivElement
584
670
  if (el) {
585
- const parentEl = el.parentElement
671
+ let parentEl = el.parentElement
586
672
  let parentHeight = 0
673
+ // 如果是虚拟滚动条
674
+ if (parentEl && hasClass(parentEl, 'vxe-scrollbar--view-inner')) {
675
+ parentEl = parentEl.parentElement
676
+ }
587
677
  if (parentEl) {
588
678
  const parentStyle = getComputedStyle(parentEl)
589
679
  parentHeight = parentEl.clientHeight - Math.ceil(XEUtils.toNumber(parentStyle.paddingLeft) + XEUtils.toNumber(parentStyle.paddingRight))
590
680
  }
591
681
  reactData.parentHeight = parentHeight
682
+ $xeList.updateScrollbar()
592
683
  $xeList.updateHeight()
593
684
  if (el.clientWidth && el.clientHeight) {
594
685
  return $xeList.computeScrollLoad()
@@ -625,6 +716,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
625
716
  const scrollLeft = scrollBodyElem.scrollLeft
626
717
  const isX = scrollLeft !== internalData.lastScrollLeft
627
718
  const isY = scrollTop !== internalData.lastScrollTop
719
+ $xeList.updateThumbOffset()
628
720
  internalData.lastScrollTop = scrollTop
629
721
  internalData.lastScrollLeft = scrollLeft
630
722
  if (reactData.scrollYLoad) {
@@ -1947,6 +2039,200 @@ export default /* define-vxe-component start */ defineVxeComponent({
1947
2039
  }
1948
2040
  $xeList.dispatchEvent('row-menu', { row }, evnt)
1949
2041
  },
2042
+ // 滚动条
2043
+ updateThumbSize () {
2044
+ const $xeList = this
2045
+ const reactData = $xeList.reactData
2046
+
2047
+ const viewEl = $xeList.$refs.refVirtualWrapper as HTMLDivElement
2048
+ if (!viewEl) {
2049
+ return
2050
+ }
2051
+ if (!viewEl.clientHeight || !viewEl.clientHeight) {
2052
+ return
2053
+ }
2054
+ const trackXEl = $xeList.$refs.refTrackXElem as HTMLDivElement
2055
+ const xThumbWidth = trackXEl ? getThumbSize(viewEl.clientWidth, viewEl.scrollWidth, trackXEl.clientWidth) : 0
2056
+ const thumbXElem = $xeList.$refs.refThumbXElem as HTMLDivElement
2057
+ if (thumbXElem) {
2058
+ thumbXElem.style.width = xThumbWidth + 'px'
2059
+ }
2060
+ reactData.xThumbWidth = xThumbWidth
2061
+
2062
+ const trackYEl = $xeList.$refs.refTrackYElem as HTMLDivElement
2063
+
2064
+ const yThumbHeight = trackYEl ? getThumbSize(viewEl.clientHeight, viewEl.scrollHeight, trackYEl.clientHeight) : 0
2065
+ const thumbYElem = $xeList.$refs.refThumbYElem as HTMLDivElement
2066
+ if (thumbYElem) {
2067
+ thumbYElem.style.height = yThumbHeight + 'px'
2068
+ }
2069
+ reactData.yThumbHeight = yThumbHeight
2070
+ },
2071
+ updateThumbOffset () {
2072
+ const $xeList = this
2073
+ const reactData = $xeList.reactData
2074
+ const internalData = $xeList.internalData
2075
+
2076
+ const viewEl = $xeList.$refs.refVirtualWrapper as HTMLDivElement
2077
+ if (!viewEl) {
2078
+ return
2079
+ }
2080
+ if (!viewEl.clientHeight || !viewEl.clientHeight) {
2081
+ return
2082
+ }
2083
+ const { xThumbWidth, yThumbHeight } = reactData
2084
+ const trackXEl = $xeList.$refs.refTrackXElem as HTMLDivElement
2085
+ const thumbXElem = $xeList.$refs.refThumbXElem as HTMLDivElement
2086
+ const xThumbLeft = trackXEl && xThumbWidth ? getThumbOffsetSize(viewEl.scrollLeft, viewEl.clientWidth, viewEl.scrollWidth, trackXEl.clientWidth, xThumbWidth) : 0
2087
+ internalData.xThumbLeft = xThumbLeft
2088
+ if (thumbXElem && xThumbWidth) {
2089
+ thumbXElem.style.width = xThumbWidth + 'px'
2090
+ thumbXElem.style.transform = `translateX(${xThumbLeft}px)`
2091
+ }
2092
+
2093
+ const trackYEl = $xeList.$refs.refTrackYElem as HTMLDivElement
2094
+ const thumbYElem = $xeList.$refs.refThumbYElem as HTMLDivElement
2095
+ const yThumbTop = trackYEl && yThumbHeight ? getThumbOffsetSize(viewEl.scrollTop, viewEl.clientHeight, viewEl.scrollHeight, trackYEl.clientHeight, yThumbHeight) : 0
2096
+ internalData.yThumbTop = yThumbTop
2097
+ if (thumbYElem && yThumbHeight) {
2098
+ thumbYElem.style.height = yThumbHeight + 'px'
2099
+ thumbYElem.style.transform = `translateY(${yThumbTop}px)`
2100
+ }
2101
+ },
2102
+ clickTrackXEvent (evnt: MouseEvent) {
2103
+ const $xeList = this
2104
+ const reactData = $xeList.reactData
2105
+
2106
+ const trackEl = evnt.currentTarget as HTMLDivElement
2107
+ if (trackEl !== evnt.target) {
2108
+ return
2109
+ }
2110
+ const viewEl = $xeList.$refs.refVirtualWrapper as HTMLDivElement
2111
+ if (!viewEl) {
2112
+ return
2113
+ }
2114
+ const { xThumbWidth } = reactData
2115
+ const trackRect = trackEl.getBoundingClientRect()
2116
+ viewEl.scrollTo({
2117
+ left: getScrollFromClick(evnt.clientX - trackRect.left, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth),
2118
+ behavior: 'auto'
2119
+ })
2120
+ },
2121
+ clickTrackYEvent (evnt: MouseEvent) {
2122
+ const $xeList = this
2123
+ const reactData = $xeList.reactData
2124
+
2125
+ const trackEl = evnt.currentTarget as HTMLDivElement
2126
+ if (trackEl !== evnt.target) {
2127
+ return
2128
+ }
2129
+ const viewEl = $xeList.$refs.refVirtualWrapper as HTMLDivElement
2130
+ if (!viewEl) {
2131
+ return
2132
+ }
2133
+ const { yThumbHeight } = reactData
2134
+ const trackRect = trackEl.getBoundingClientRect()
2135
+ viewEl.scrollTo({
2136
+ top: getScrollFromClick(evnt.clientY - trackRect.top, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight),
2137
+ behavior: 'auto'
2138
+ })
2139
+ },
2140
+ pointerdownThumbXEvent (evnt: PointerEvent) {
2141
+ const $xeList = this
2142
+ const reactData = $xeList.reactData
2143
+ const internalData = $xeList.internalData
2144
+
2145
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2146
+ internalData.isThumbDrag = true
2147
+ thumbEl.setPointerCapture(evnt.pointerId)
2148
+
2149
+ const viewEl = $xeList.$refs.refVirtualWrapper as HTMLDivElement
2150
+ if (!viewEl) {
2151
+ return
2152
+ }
2153
+ const { xThumbWidth } = reactData
2154
+ const trackEl = thumbEl.parentElement as HTMLDivElement
2155
+ const trackRect = trackEl.getBoundingClientRect()
2156
+ const pointerPosition = evnt.clientX - trackRect.left
2157
+ // 记录 thumb 的偏移
2158
+ const thumbOffset = getThumbOffsetSize(viewEl.scrollLeft, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth)
2159
+ internalData.thumbDragOffset = pointerPosition - thumbOffset
2160
+ },
2161
+ pointermoveThumbXEvent (evnt: PointerEvent) {
2162
+ const $xeList = this
2163
+ const reactData = $xeList.reactData
2164
+ const internalData = $xeList.internalData
2165
+
2166
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2167
+ if (!thumbEl.hasPointerCapture(evnt.pointerId)) {
2168
+ return
2169
+ }
2170
+ const { isThumbDrag, thumbDragOffset } = internalData
2171
+ if (isThumbDrag) {
2172
+ const viewEl = $xeList.$refs.refVirtualWrapper as HTMLDivElement
2173
+ if (!viewEl) {
2174
+ return
2175
+ }
2176
+ const { xThumbWidth } = reactData
2177
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2178
+ const trackEl = thumbEl.parentElement as HTMLDivElement
2179
+ const trackRect = trackEl.getBoundingClientRect()
2180
+ // 更新偏移
2181
+ viewEl.scrollLeft = getScrollFromDrag(evnt.clientX - trackRect.left, thumbDragOffset, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth)
2182
+ }
2183
+ },
2184
+ cleatPointerThumbEvent (evnt: PointerEvent) {
2185
+ const $xeList = this
2186
+ const internalData = $xeList.internalData
2187
+
2188
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2189
+ thumbEl.releasePointerCapture(evnt.pointerId)
2190
+ internalData.isThumbDrag = false
2191
+ },
2192
+ pointerdownThumbYEvent (evnt: PointerEvent) {
2193
+ const $xeList = this
2194
+ const reactData = $xeList.reactData
2195
+ const internalData = $xeList.internalData
2196
+
2197
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2198
+ internalData.isThumbDrag = true
2199
+ thumbEl.setPointerCapture(evnt.pointerId)
2200
+
2201
+ const viewEl = $xeList.$refs.refVirtualWrapper as HTMLDivElement
2202
+ if (!viewEl) {
2203
+ return
2204
+ }
2205
+ const { yThumbHeight } = reactData
2206
+ const trackEl = thumbEl.parentElement as HTMLDivElement
2207
+ const trackRect = trackEl.getBoundingClientRect()
2208
+ const pointerPosition = evnt.clientY - trackRect.top
2209
+ // 记录 thumb 的偏移
2210
+ const thumbOffset = getThumbOffsetSize(viewEl.scrollTop, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight)
2211
+ internalData.thumbDragOffset = pointerPosition - thumbOffset
2212
+ },
2213
+ pointermoveThumbYEvent (evnt: PointerEvent) {
2214
+ const $xeList = this
2215
+ const reactData = $xeList.reactData
2216
+ const internalData = $xeList.internalData
2217
+
2218
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2219
+ if (!thumbEl.hasPointerCapture(evnt.pointerId)) {
2220
+ return
2221
+ }
2222
+ const { isThumbDrag, thumbDragOffset } = internalData
2223
+ if (isThumbDrag) {
2224
+ const viewEl = $xeList.$refs.refVirtualWrapper as HTMLDivElement
2225
+ if (!viewEl) {
2226
+ return
2227
+ }
2228
+ const { yThumbHeight } = reactData
2229
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2230
+ const trackEl = thumbEl.parentElement as HTMLDivElement
2231
+ const trackRect = trackEl.getBoundingClientRect()
2232
+ // 更新偏移
2233
+ viewEl.scrollTop = getScrollFromDrag(evnt.clientY - trackRect.top, thumbDragOffset, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight)
2234
+ }
2235
+ },
1950
2236
 
1951
2237
  //
1952
2238
  // Render
@@ -2211,7 +2497,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
2211
2497
  const reactData = $xeList.reactData
2212
2498
  const slots = $xeList.$scopedSlots
2213
2499
 
2214
- const { showCheckbox, className, loading } = props
2500
+ const { showCheckbox, className, loading, useScrollbar } = props
2215
2501
  const { bodyHeight, topSpaceHeight, rowList, isAllChecked, isAllIndeterminate } = reactData
2216
2502
  const defaultSlot = slots.default
2217
2503
  const headerSlot = slots.header
@@ -2225,6 +2511,10 @@ export default /* define-vxe-component start */ defineVxeComponent({
2225
2511
  const { trigger, isCrossListDrag } = dragOpts
2226
2512
  const rowOpts = $xeList.computeRowOpts
2227
2513
  const { isHover, padding } = rowOpts
2514
+ const isDrag = $xeList.computeIsDrag
2515
+ const scrollbarXOpts = $xeList.computeScrollbarXOpts
2516
+ const scrollbarYOpts = $xeList.computeScrollbarYOpts
2517
+ const scrollbarWrapperClss = $xeList.computeScrollbarWrapperClss
2228
2518
  const showDefChekboxHead = showCheckbox && checkboxOpts.showHeader !== false
2229
2519
 
2230
2520
  const leOns: {
@@ -2237,6 +2527,10 @@ export default /* define-vxe-component start */ defineVxeComponent({
2237
2527
  ref: 'refElem',
2238
2528
  class: ['vxe-list', className ? (XEUtils.isFunction(className) ? className({ $list: $xeList }) : className) : '', {
2239
2529
  [`size--${vSize}`]: vSize,
2530
+ 'is--virtual-scrollbar': useScrollbar,
2531
+ 'ov-x--auto-hide': useScrollbar && scrollbarXOpts.autoHide,
2532
+ 'ov-y--auto-hide': useScrollbar && scrollbarYOpts.autoHide,
2533
+ 'is--drag': isDrag,
2240
2534
  'is--loading': loading
2241
2535
  }],
2242
2536
  on: leOns,
@@ -2299,7 +2593,17 @@ export default /* define-vxe-component start */ defineVxeComponent({
2299
2593
  style: {
2300
2594
  marginTop: topSpaceHeight ? `${topSpaceHeight}px` : ''
2301
2595
  }
2302
- }, defaultSlot ? defaultSlot({ items: rowList, $list: $xeList }) : rowList.map((row, i) => $xeList.renderRow(h, row, i)))
2596
+ }, useScrollbar
2597
+ ? (
2598
+ defaultSlot ? defaultSlot({ items: rowList, $list: $xeList }) : rowList.map((row, i) => $xeList.renderRow(h, row, i))
2599
+ )
2600
+ : [
2601
+ h('div', {
2602
+ key: 'vi',
2603
+ ref: 'refViewInnerElem',
2604
+ class: 'vxe-scrollbar--view-inner'
2605
+ }, defaultSlot ? defaultSlot({ items: rowList, $list: $xeList }) : rowList.map((row, i) => $xeList.renderRow(h, row, i)))
2606
+ ])
2303
2607
  ]),
2304
2608
  footerSlot
2305
2609
  ? h('div', {
@@ -2307,6 +2611,57 @@ export default /* define-vxe-component start */ defineVxeComponent({
2307
2611
  class: 'vxe-list--footer-wrapper'
2308
2612
  }, footerSlot({ items: rowList, $list: $xeList }))
2309
2613
  : renderEmptyElement($xeList),
2614
+ /**
2615
+ * 滚动条
2616
+ */
2617
+ useScrollbar
2618
+ ? h('div', {
2619
+ class: scrollbarWrapperClss
2620
+ }, [
2621
+ scrollbarXOpts.visible === 'hidden'
2622
+ ? renderEmptyElement($xeList)
2623
+ : h('div', {
2624
+ ref: 'refTrackXElem',
2625
+ class: 'vxe-scrollbar--track-x',
2626
+ on: {
2627
+ click: $xeList.clickTrackXEvent
2628
+ }
2629
+ }, [
2630
+ h('div', {
2631
+ ref: 'refThumbXElem',
2632
+ class: 'vxe-scrollbar--thumb-x',
2633
+ on: {
2634
+ pointerdown: $xeList.pointerdownThumbXEvent,
2635
+ pointermove: $xeList.pointermoveThumbXEvent,
2636
+ pointerup: $xeList.cleatPointerThumbEvent,
2637
+ pointercancel: $xeList.cleatPointerThumbEvent,
2638
+ lostpointercapture: $xeList.cleatPointerThumbEvent
2639
+ }
2640
+ })
2641
+ ]),
2642
+ scrollbarYOpts.visible === 'hidden'
2643
+ ? renderEmptyElement($xeList)
2644
+ : h('div', {
2645
+ ref: 'refTrackYElem',
2646
+ class: 'vxe-scrollbar--track-y',
2647
+ on: {
2648
+ click: $xeList.clickTrackYEvent
2649
+ }
2650
+ }, [
2651
+ h('div', {
2652
+ ref: 'refThumbYElem',
2653
+ class: 'vxe-scrollbar--thumb-y',
2654
+ on: {
2655
+ pointerdown: $xeList.pointerdownThumbYEvent,
2656
+ pointermove: $xeList.pointermoveThumbYEvent,
2657
+ pointerup: $xeList.cleatPointerThumbEvent,
2658
+ pointercancel: $xeList.cleatPointerThumbEvent,
2659
+ lostpointercapture: $xeList.cleatPointerThumbEvent
2660
+ }
2661
+ })
2662
+ ])
2663
+ ])
2664
+ : renderEmptyElement($xeList),
2310
2665
  /**
2311
2666
  * 拖拽提示
2312
2667
  */
@@ -2382,7 +2737,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
2382
2737
  const props = $xeList
2383
2738
  const internalData = $xeList.internalData
2384
2739
 
2385
- const { showSeq, showRadio, showCheckbox } = props
2740
+ const { showSeq, showRadio, showCheckbox, autoResize, useScrollbar } = props
2386
2741
  const rowOpts = $xeList.computeRowOpts
2387
2742
  const { useKey, keyField } = rowOpts
2388
2743
  const isDrag = $xeList.computeIsDrag
@@ -2403,22 +2758,34 @@ export default /* define-vxe-component start */ defineVxeComponent({
2403
2758
  if (useKey && !keyField) {
2404
2759
  errLog('vxe.error.reqSupportProp', ['row-config.useKey', 'row-config.keyField'])
2405
2760
  }
2406
- if (props.autoResize) {
2761
+ if (useScrollbar || autoResize) {
2407
2762
  const el = $xeList.$refs.refElem as HTMLDivElement
2408
- const resizeObserver = globalResize.create(() => $xeList.recalculate())
2763
+ const viewInnerEl = $xeList.$refs.refViewInnerElem as HTMLDivElement
2764
+ const resizeObserver = globalResize.create(() => {
2765
+ $xeList.reFlag++
2766
+ })
2409
2767
  resizeObserver.observe(el)
2410
- if (el) {
2411
- resizeObserver.observe(el.parentElement as HTMLDivElement)
2768
+ if (autoResize) {
2769
+ if (el) {
2770
+ resizeObserver.observe(el.parentElement as HTMLDivElement)
2771
+ }
2772
+ }
2773
+ if (viewInnerEl) {
2774
+ resizeObserver.observe(viewInnerEl)
2412
2775
  }
2413
2776
  internalData.resizeObserver = resizeObserver
2414
2777
  }
2415
- $xeList.recalculate()
2416
- globalEvents.on($xeList, 'resize', $xeList.recalculate)
2778
+ $xeList.reFlag++
2779
+ globalEvents.on($xeList, 'resize', () => {
2780
+ $xeList.reFlag++
2781
+ })
2417
2782
  },
2418
2783
  activated () {
2419
2784
  const $xeList = this
2420
2785
 
2421
- $xeList.recalculate().then(() => $xeList.refreshScroll())
2786
+ $xeList.recalculate().then(() => {
2787
+ $xeList.refreshScroll()
2788
+ })
2422
2789
  },
2423
2790
  beforeDestroy () {
2424
2791
  const $xeList = this
@@ -279,6 +279,9 @@ export default /* define-vxe-component start */ defineVxeComponent({
279
279
  if (!viewEl) {
280
280
  return
281
281
  }
282
+ if (!viewEl.clientHeight || !viewEl.clientHeight) {
283
+ return
284
+ }
282
285
  const trackXEl = $xeScrollbar.$refs.refTrackXElem as HTMLDivElement
283
286
  const xThumbWidth = trackXEl ? getThumbSize(viewEl.clientWidth, viewEl.scrollWidth, trackXEl.clientWidth) : 0
284
287
  const thumbXElem = $xeScrollbar.$refs.refThumbXElem as HTMLDivElement
@@ -303,6 +306,9 @@ export default /* define-vxe-component start */ defineVxeComponent({
303
306
  const viewEl = $xeScrollbar.$refs.refViewElem as HTMLDivElement
304
307
  if (!viewEl) {
305
308
  return
309
+ if (!viewEl.clientHeight || !viewEl.clientHeight) {
310
+ return
311
+ }
306
312
  }
307
313
  const { xThumbWidth, yThumbHeight } = reactData
308
314
  const trackXEl = $xeScrollbar.$refs.refTrackXElem as HTMLDivElement
@@ -7,6 +7,7 @@ import { toCssUnit, addClass, removeClass } from '../../ui/src/dom'
7
7
  import { isEnableConf } from '../../ui/src/utils'
8
8
  import { createComponentLog } from '../../ui/src/log'
9
9
  import VxeLoadingComponent from '../../loading'
10
+ import VxeScrollbarComponent from '../../scrollbar'
10
11
 
11
12
  import type { VxeTabsPropTypes, VxeTabPaneProps, VxeTabsEmits, TabsInternalData, TabsReactData, VxeComponentSizeType, VxeTabsConstructor, VxeTabsPrivateMethods, VxeTabPaneDefines, ValueOf, VxeComponentStyleType } from '../../../types'
12
13
 
@@ -55,6 +56,11 @@ export default /* define-vxe-component start */ defineVxeComponent({
55
56
  type: String as PropType<VxeTabsPropTypes.Size>,
56
57
  default: () => getConfig().tabs.size || getConfig().size
57
58
  },
59
+ useScrollbar: {
60
+ type: Boolean as PropType<VxeTabsPropTypes.UseScrollbar>,
61
+ default: () => getConfig().tabs.useScrollbar
62
+ },
63
+ scrollbarConfig: Object as PropType<VxeTabsPropTypes.ScrollbarConfig>,
58
64
  // 已废弃
59
65
  beforeCloseMethod: Function as PropType<VxeTabsPropTypes.BeforeCloseMethod>
60
66
  },
@@ -181,6 +187,12 @@ export default /* define-vxe-component start */ defineVxeComponent({
181
187
 
182
188
  const staticTabs = reactData.staticTabs as VxeTabPaneDefines.TabConfig[]
183
189
  return staticTabs.filter((item) => $xeTabs.handleFilterTab(item))
190
+ },
191
+ computeScrollbarOpts () {
192
+ const $xeTabs = this
193
+ const props = $xeTabs
194
+
195
+ return Object.assign({}, getConfig().tabs.scrollbarConfig, props.scrollbarConfig)
184
196
  }
185
197
  },
186
198
  methods: {
@@ -821,19 +833,39 @@ export default /* define-vxe-component start */ defineVxeComponent({
821
833
  },
822
834
  renderTabPane (h: CreateElement, item: VxeTabPaneProps | VxeTabPaneDefines.TabConfig) {
823
835
  const $xeTabs = this
836
+ const props = $xeTabs
824
837
  const reactData = $xeTabs.reactData
825
838
 
839
+ const { useScrollbar } = props
826
840
  const { initNames, activeName } = reactData
827
841
  const { name, slots } = item
828
842
  const defaultSlot = slots ? slots.default : null
829
- return name && initNames.includes(name)
830
- ? h('div', {
831
- key: `${name}`,
832
- class: ['vxe-tabs-pane--item', {
833
- 'is--visible': activeName === name
834
- }]
835
- }, defaultSlot ? $xeTabs.callSlot(defaultSlot, { name }, h) : [])
836
- : renderEmptyElement($xeTabs)
843
+ const scrollbarOpts = $xeTabs.computeScrollbarOpts
844
+ const { viewClassName, viewInnerClassName } = scrollbarOpts
845
+ if (name && initNames.includes(name)) {
846
+ return useScrollbar
847
+ ? h(VxeScrollbarComponent, {
848
+ key: `${name}`,
849
+ class: ['vxe-tabs-pane--scrollbar-item', {
850
+ 'is--visible': activeName === name
851
+ }],
852
+ props: {
853
+ ...scrollbarOpts,
854
+ viewClassName: 'vxe-tabs-pane--scrollbar-item-view' + (viewClassName ? (' ' + viewClassName) : ''),
855
+ viewInnerClassName: 'vxe-tabs-pane--scrollbar-item-inner' + (viewClassName ? (' ' + viewInnerClassName) : '')
856
+ },
857
+ scopedSlots: {
858
+ default: () => defaultSlot ? $xeTabs.callSlot(defaultSlot, { name }, h) : []
859
+ }
860
+ })
861
+ : h('div', {
862
+ key: `${name}`,
863
+ class: ['vxe-tabs-pane--item', {
864
+ 'is--visible': activeName === name
865
+ }]
866
+ }, defaultSlot ? $xeTabs.callSlot(defaultSlot, { name }, h) : [])
867
+ }
868
+ return renderEmptyElement($xeTabs)
837
869
  },
838
870
  renderTabContent (h: CreateElement, tabList: VxeTabsPropTypes.Options | VxeTabPaneDefines.TabConfig[]) {
839
871
  const $xeTabs = this
@@ -6,7 +6,7 @@ import { calcTreeLine, getItemCacheObj } from './util'
6
6
  import { createComponentLog } from '../../ui/src/log'
7
7
  import { getSlotVNs } from '../../ui/src/vn'
8
8
  import { crossTreeDragNodeGlobal, getCrossTreeDragNodeInfo } from './store'
9
- import { toCssUnit, isScale, getPaddingTopBottomSize, addClass, removeClass, getTpImg, hasControlKey, getEventTargetNode } from '../../ui/src/dom'
9
+ import { toCssUnit, isScale, getPaddingTopBottomSize, addClass, removeClass, getTpImg, hasControlKey, getEventTargetNode, hasClass } from '../../ui/src/dom'
10
10
  import { isEnableConf, enModelValue, deModelValue, getText } from '../../ui/src/utils'
11
11
  import { moveRowAnimateToTb, clearRowAnimate } from '../../ui/src/anime'
12
12
  import VxeLoadingComponent from '../../loading'
@@ -1574,11 +1574,15 @@ export default /* define-vxe-component start */ defineVxeComponent({
1574
1574
  const { rowHeight } = scrollYStore
1575
1575
  const el = $xeTree.$refs.refElem as HTMLDivElement
1576
1576
  if (el && el.clientWidth && el.clientHeight) {
1577
- const parentEl = $xeTree.getParentElem()
1577
+ let parentEl = $xeTree.getParentElem()
1578
1578
  const headerWrapperEl = $xeTree.$refs.refHeaderWrapperElem as HTMLDivElement
1579
1579
  const footerWrapperEl = $xeTree.$refs.refFooterWrapperElem as HTMLDivElement
1580
1580
  const headHeight = headerWrapperEl ? headerWrapperEl.clientHeight : 0
1581
1581
  const footHeight = footerWrapperEl ? footerWrapperEl.clientHeight : 0
1582
+ // 如果是虚拟滚动条
1583
+ if (parentEl && hasClass(parentEl, 'vxe-scrollbar--view-inner')) {
1584
+ parentEl = parentEl.parentElement
1585
+ }
1582
1586
  if (parentEl) {
1583
1587
  const parentPaddingSize = getPaddingTopBottomSize(parentEl)
1584
1588
  reactData.parentHeight = Math.max(headHeight + footHeight + rowHeight, parentEl.clientHeight - parentPaddingSize - headHeight - footHeight)