vxe-pc-ui 4.19.8 → 4.20.1

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 (100) hide show
  1. package/dist/all.esm.js +878 -115
  2. package/dist/style.css +1 -1
  3. package/dist/style.min.css +1 -1
  4. package/es/card/src/card.js +17 -3
  5. package/es/icon/style.css +1 -1
  6. package/es/language/fr-FR.js +29 -29
  7. package/es/layout-aside/src/layout-aside.js +8 -5
  8. package/es/layout-body/src/layout-body.js +19 -11
  9. package/es/list/src/list.js +364 -21
  10. package/es/list/style.css +43 -0
  11. package/es/list/style.min.css +1 -1
  12. package/es/scrollbar/src/scrollbar.js +59 -17
  13. package/es/scrollbar/style.css +1 -0
  14. package/es/style.css +1 -1
  15. package/es/style.min.css +1 -1
  16. package/es/tabs/src/tabs.js +19 -4
  17. package/es/tree/src/tree.js +393 -55
  18. package/es/tree/style.css +43 -0
  19. package/es/tree/style.min.css +1 -1
  20. package/es/ui/index.js +1 -1
  21. package/es/ui/src/log.js +1 -1
  22. package/es/ui/src/utils.js +12 -0
  23. package/es/vxe-list/style.css +43 -0
  24. package/es/vxe-list/style.min.css +1 -1
  25. package/es/vxe-scrollbar/style.css +1 -0
  26. package/es/vxe-tree/style.css +43 -0
  27. package/es/vxe-tree/style.min.css +1 -1
  28. package/lib/card/src/card.js +17 -3
  29. package/lib/card/src/card.min.js +1 -1
  30. package/lib/icon/style/style.css +1 -1
  31. package/lib/icon/style/style.min.css +1 -1
  32. package/lib/index.umd.js +914 -126
  33. package/lib/index.umd.min.js +1 -1
  34. package/lib/language/fr-FR.js +29 -29
  35. package/lib/language/fr-FR.min.js +1 -1
  36. package/lib/language/fr-FR.umd.js +29 -29
  37. package/lib/layout-aside/src/layout-aside.js +7 -7
  38. package/lib/layout-aside/src/layout-aside.min.js +1 -1
  39. package/lib/layout-body/src/layout-body.js +27 -21
  40. package/lib/layout-body/src/layout-body.min.js +1 -1
  41. package/lib/list/src/list.js +368 -21
  42. package/lib/list/src/list.min.js +1 -1
  43. package/lib/list/style/style.css +43 -0
  44. package/lib/list/style/style.min.css +1 -1
  45. package/lib/scrollbar/src/scrollbar.js +67 -15
  46. package/lib/scrollbar/src/scrollbar.min.js +1 -1
  47. package/lib/scrollbar/style/style.css +1 -0
  48. package/lib/style.css +1 -1
  49. package/lib/style.min.css +1 -1
  50. package/lib/tabs/src/tabs.js +22 -10
  51. package/lib/tabs/src/tabs.min.js +1 -1
  52. package/lib/tree/src/tree.js +397 -53
  53. package/lib/tree/src/tree.min.js +1 -1
  54. package/lib/tree/style/style.css +43 -0
  55. package/lib/tree/style/style.min.css +1 -1
  56. package/lib/ui/index.js +1 -1
  57. package/lib/ui/index.min.js +1 -1
  58. package/lib/ui/src/log.js +1 -1
  59. package/lib/ui/src/log.min.js +1 -1
  60. package/lib/ui/src/utils.js +14 -0
  61. package/lib/ui/src/utils.min.js +1 -1
  62. package/lib/vxe-list/style/style.css +43 -0
  63. package/lib/vxe-list/style/style.min.css +1 -1
  64. package/lib/vxe-scrollbar/style/style.css +1 -0
  65. package/lib/vxe-tree/style/style.css +43 -0
  66. package/lib/vxe-tree/style/style.min.css +1 -1
  67. package/package.json +1 -1
  68. package/packages/card/src/card.ts +18 -3
  69. package/packages/language/fr-FR.ts +903 -903
  70. package/packages/layout-aside/src/layout-aside.ts +8 -5
  71. package/packages/layout-body/src/layout-body.ts +23 -14
  72. package/packages/list/src/list.ts +397 -24
  73. package/packages/scrollbar/src/scrollbar.ts +63 -16
  74. package/packages/tabs/src/tabs.ts +19 -5
  75. package/packages/tree/src/tree.ts +432 -64
  76. package/packages/ui/src/utils.ts +14 -0
  77. package/styles/components/list.scss +76 -0
  78. package/styles/components/scrollbar.scss +3 -0
  79. package/styles/components/tree.scss +76 -0
  80. package/types/components/card.d.ts +10 -1
  81. package/types/components/layout-aside.d.ts +10 -1
  82. package/types/components/layout-body.d.ts +10 -1
  83. package/types/components/list.d.ts +33 -2
  84. package/types/components/scrollbar.d.ts +17 -2
  85. package/types/components/table-plugins/extend-cell-area.d.ts +1 -1
  86. package/types/components/table.d.ts +71 -4
  87. package/types/components/tabs.d.ts +10 -1
  88. package/types/components/tree.d.ts +33 -2
  89. /package/es/icon/{iconfont.1791862962954.ttf → iconfont.1791950625324.ttf} +0 -0
  90. /package/es/icon/{iconfont.1791862962954.woff → iconfont.1791950625324.woff} +0 -0
  91. /package/es/icon/{iconfont.1791862962954.woff2 → iconfont.1791950625324.woff2} +0 -0
  92. /package/es/{iconfont.1791862962954.ttf → iconfont.1791950625324.ttf} +0 -0
  93. /package/es/{iconfont.1791862962954.woff → iconfont.1791950625324.woff} +0 -0
  94. /package/es/{iconfont.1791862962954.woff2 → iconfont.1791950625324.woff2} +0 -0
  95. /package/lib/icon/style/{iconfont.1791862962954.ttf → iconfont.1791950625324.ttf} +0 -0
  96. /package/lib/icon/style/{iconfont.1791862962954.woff → iconfont.1791950625324.woff} +0 -0
  97. /package/lib/icon/style/{iconfont.1791862962954.woff2 → iconfont.1791950625324.woff2} +0 -0
  98. /package/lib/{iconfont.1791862962954.ttf → iconfont.1791950625324.ttf} +0 -0
  99. /package/lib/{iconfont.1791862962954.woff → iconfont.1791950625324.woff} +0 -0
  100. /package/lib/{iconfont.1791862962954.woff2 → iconfont.1791950625324.woff2} +0 -0
@@ -97,7 +97,7 @@ export default defineVxeComponent({
97
97
  const vSize = computeSize.value
98
98
  const collapseOpts = computeCollapseOpts.value
99
99
  const scrollbarOpts = computeScrollbarOpts.value
100
- const { native, yConfig, className, viewAttrs, viewClassName, viewInnerClassName } = scrollbarOpts
100
+ const { className, viewClassName, viewInnerClassName } = scrollbarOpts
101
101
  const defaultSlot = slots.default
102
102
 
103
103
  return h('aside', {
@@ -113,13 +113,16 @@ export default defineVxeComponent({
113
113
  }, [
114
114
  useScrollbar
115
115
  ? h(VxeScrollbarComponent, {
116
- native,
116
+ width: scrollbarOpts.width,
117
+ height: scrollbarOpts.height,
118
+ autoHide: scrollbarOpts.autoHide,
119
+ visible: scrollbarOpts.visible,
117
120
  xConfig: {
118
- visible: 'hidden'
121
+ visible: false
119
122
  },
120
- yConfig,
123
+ yConfig: scrollbarOpts.yConfig,
121
124
  className: 'vxe-layout-aside--scrollbar' + (className ? (' ' + className) : ''),
122
- viewAttrs,
125
+ viewAttrs: scrollbarOpts.viewAttrs,
123
126
  viewClassName: 'vxe-layout-aside--scrollbar-view' + (viewClassName ? (' ' + viewClassName) : ''),
124
127
  viewInnerClassName: 'vxe-layout-aside--scrollbar-inner' + (viewInnerClassName ? (' ' + viewInnerClassName) : '')
125
128
  }, {
@@ -64,6 +64,27 @@ export default defineVxeComponent({
64
64
  return Object.assign({}, getConfig().layoutBody.scrollbarConfig, props.scrollbarConfig)
65
65
  })
66
66
 
67
+ const computeScrollbarProps = computed(() => {
68
+ const { showBacktop } = props
69
+ const scrollbarOpts = computeScrollbarOpts.value
70
+ const { className, viewClassName, viewInnerClassName } = scrollbarOpts
71
+ return {
72
+ width: scrollbarOpts.width,
73
+ height: scrollbarOpts.height,
74
+ autoHide: scrollbarOpts.autoHide,
75
+ visible: scrollbarOpts.visible,
76
+ xConfig: scrollbarOpts.xConfig,
77
+ yConfig: scrollbarOpts.yConfig,
78
+ className: 'vxe-layout-body--scrollbar' + (className ? (' ' + className) : ''),
79
+ viewAttrs: {
80
+ ...scrollbarOpts.viewAttrs,
81
+ id: showBacktop ? (backtopId || null) : null
82
+ },
83
+ viewClassName: 'vxe-layout-body--scrollbar-view' + (viewClassName ? (' ' + viewClassName) : ''),
84
+ viewInnerClassName: 'vxe-layout-body--scrollbar-inner' + (viewInnerClassName ? (' ' + viewInnerClassName) : '')
85
+ }
86
+ })
87
+
67
88
  const computeMaps: VxeLayoutBodyPrivateComputed = {
68
89
  computeSize
69
90
  }
@@ -95,8 +116,7 @@ export default defineVxeComponent({
95
116
  const renderVN = () => {
96
117
  const { loading, padding, showBacktop, useScrollbar } = props
97
118
  const backtopOpts = computeBacktopOpts.value
98
- const scrollbarOpts = computeScrollbarOpts.value
99
- const { native, xConfig, yConfig, className, viewAttrs, viewClassName, viewInnerClassName } = scrollbarOpts
119
+ const scrollbarProps = computeScrollbarProps.value
100
120
  const vSize = computeSize.value
101
121
  const defaultSlot = slots.default
102
122
  const backtopSlot = slots.backtop
@@ -125,18 +145,7 @@ export default defineVxeComponent({
125
145
  }]
126
146
  }, [
127
147
  useScrollbar
128
- ? h(VxeScrollbarComponent, {
129
- native,
130
- xConfig,
131
- yConfig,
132
- className: 'vxe-layout-body--scrollbar' + (className ? (' ' + className) : ''),
133
- viewAttrs: {
134
- ...viewAttrs,
135
- id: showBacktop ? (backtopId || null) : null
136
- },
137
- viewClassName: 'vxe-layout-body--scrollbar-view' + (viewClassName ? (' ' + viewClassName) : ''),
138
- viewInnerClassName: 'vxe-layout-body--scrollbar-inner' + (viewInnerClassName ? (' ' + viewInnerClassName) : '')
139
- }, {
148
+ ? h(VxeScrollbarComponent, scrollbarProps, {
140
149
  default: () => defaultSlot ? defaultSlot({}) : []
141
150
  })
142
151
  : h('div', {
@@ -1,12 +1,13 @@
1
1
  import { h, PropType, ref, Ref, computed, onBeforeUnmount, watch, reactive, nextTick, onActivated, onMounted, VNode } from 'vue'
2
2
  import { defineVxeComponent } from '../../ui/src/comp'
3
3
  import XEUtils from 'xe-utils'
4
- import { VxeUI, getConfig, getIcon, getI18n, menus, globalEvents, globalResize, createEvent, useSize, renderEmptyElement } from '../../ui'
4
+ import { VxeUI, getConfig, getIcon, getI18n, domUtils, menus, globalEvents, globalResize, useSize, createEvent, renderEmptyElement } from '../../ui'
5
5
  import { getCrossListDragRowInfo } from './store'
6
6
  import { isScale, removeClass, addClass, getTpImg, toCssUnit, hasClass } from '../../ui/src/dom'
7
- import { isEnableConf, getText, enModelValue, deModelValue } from '../../ui/src/utils'
7
+ import { isEnableConf, getText, enModelValue, deModelValue, getDefaultConfig } from '../../ui/src/utils'
8
8
  import { createComponentLog } from '../../ui/src/log'
9
9
  import { moveRowAnimateToTb, clearRowAnimate } from '../../ui/src/anime'
10
+ import { getThumbOffsetSize, getThumbSize, getScrollFromClick, getScrollFromDrag } from '../../scrollbar/src/util'
10
11
  import { getItemCacheObj } from './util'
11
12
  import VxeLoadingComponent from '../../loading'
12
13
 
@@ -42,6 +43,11 @@ function createReactData (): ListReactData {
42
43
  updateCheckboxFlag: 1,
43
44
  isAllChecked: false,
44
45
  isAllIndeterminate: false,
46
+
47
+ // 滚动条
48
+ yThumbHeight: 0,
49
+ xThumbWidth: 0,
50
+
45
51
  insertRowFlag: 1,
46
52
  removeRowFlag: 1,
47
53
  dragRow: null,
@@ -52,13 +58,20 @@ function createReactData (): ListReactData {
52
58
 
53
59
  function createInternalData (): ListInternalData {
54
60
  return {
55
- resizeObserver: undefined,
56
61
  fullData: [],
57
62
  afterList: [],
58
63
  fullKeyMaps: {},
59
64
  rowMaps: {},
60
- lastScrollLeft: 0,
65
+
66
+ // 滚动条
67
+ // resizeObserver: undefined,
68
+ // isThumbDrag: false,
69
+ thumbDragOffset: 0,
70
+ yThumbTop: 0,
71
+ xThumbLeft: 0,
61
72
  lastScrollTop: 0,
73
+ lastScrollLeft: 0,
74
+
62
75
  scrollYStore: {
63
76
  startIndex: 0,
64
77
  endIndex: 0,
@@ -117,7 +130,12 @@ export default defineVxeComponent({
117
130
  dragConfig: Object as PropType<VxeListPropTypes.DragConfig>,
118
131
  menuConfig: Object as PropType<VxeListPropTypes.MenuConfig>,
119
132
  virtualYConfig: Object as PropType<VxeListPropTypes.VirtualYConfig>,
120
- scrollY: Object as PropType<VxeListPropTypes.ScrollY>
133
+ scrollY: Object as PropType<VxeListPropTypes.ScrollY>,
134
+ useScrollbar: {
135
+ type: Boolean as PropType<VxeListPropTypes.UseScrollbar>,
136
+ default: () => getConfig().list.useScrollbar
137
+ },
138
+ scrollbarConfig: Object as PropType<VxeListPropTypes.ScrollbarConfig>
121
139
  },
122
140
  emits: [
123
141
  'update:checkRowKey',
@@ -158,6 +176,11 @@ export default defineVxeComponent({
158
176
  const refVirtualWrapper = ref() as Ref<HTMLDivElement>
159
177
  const refVirtualBody = ref() as Ref<HTMLDivElement>
160
178
 
179
+ const refTrackXElem = ref<HTMLDivElement>()
180
+ const refTrackYElem = ref<HTMLDivElement>()
181
+ const refThumbXElem = ref<HTMLDivElement>()
182
+ const refThumbYElem = ref<HTMLDivElement>()
183
+
161
184
  const refDragRowLineElem = ref<HTMLDivElement>()
162
185
  const refDragTipElem = ref<HTMLDivElement>()
163
186
 
@@ -218,11 +241,20 @@ export default defineVxeComponent({
218
241
 
219
242
  const computeWrapperStyles = computed(() => {
220
243
  const rowHeight = computeRowHeight.value
221
- const style: VxeComponentStyleType = {}
244
+ const scrollbarOpts = computeScrollbarOpts.value
245
+ const scrollbarXOpts = computeScrollbarXOpts.value
246
+ const scrollbarYOpts = computeScrollbarYOpts.value
247
+ const barWidth = getDefaultConfig(getDefaultConfig(scrollbarYOpts.width, scrollbarOpts.width), getConfig().scrollbar.width)
248
+ const barHeight = getDefaultConfig(getDefaultConfig(scrollbarXOpts.height, scrollbarOpts.height), getConfig().scrollbar.height)
249
+ const stys: VxeComponentStyleType = {}
222
250
  if (rowHeight) {
223
- style['--vxe-ui-list-row-height'] = toCssUnit(rowHeight)
251
+ stys['--vxe-ui-list-row-height'] = toCssUnit(rowHeight)
224
252
  }
225
- return style
253
+ if (barWidth || barHeight) {
254
+ stys['--vxe-ui-scrollbar-y-width'] = toCssUnit(barWidth || barHeight)
255
+ stys['--vxe-ui-scrollbar-x-height'] = toCssUnit(barHeight || barWidth)
256
+ }
257
+ return stys
226
258
  })
227
259
 
228
260
  const computeVirtualStyles = computed(() => {
@@ -238,6 +270,79 @@ export default defineVxeComponent({
238
270
  return style
239
271
  })
240
272
 
273
+ const computeScrollbarOpts = computed(() => {
274
+ return Object.assign({}, getConfig().list.scrollbarConfig, props.scrollbarConfig)
275
+ })
276
+
277
+ const computeScrollbarXOpts = computed(() => {
278
+ const scrollbarOpts = computeScrollbarOpts.value
279
+ return Object.assign({}, getConfig().scrollbar.xConfig, scrollbarOpts.xConfig)
280
+ })
281
+
282
+ const computeScrollbarYOpts = computed(() => {
283
+ const scrollbarOpts = computeScrollbarOpts.value
284
+ return Object.assign({}, getConfig().scrollbar.yConfig, scrollbarOpts.yConfig)
285
+ })
286
+
287
+ const computeScrollXVisible = computed(() => {
288
+ const scrollbarOpts = computeScrollbarOpts.value
289
+ const scrollbarXOpts = computeScrollbarXOpts.value
290
+ return getDefaultConfig(scrollbarXOpts.visible, scrollbarOpts.visible)
291
+ })
292
+
293
+ const computeScrollYVisible = computed(() => {
294
+ const scrollbarOpts = computeScrollbarOpts.value
295
+ const scrollbarYOpts = computeScrollbarYOpts.value
296
+ return getDefaultConfig(scrollbarYOpts.visible, scrollbarOpts.visible)
297
+ })
298
+
299
+ const computeScrollXAutoHide = computed(() => {
300
+ const scrollbarOpts = computeScrollbarOpts.value
301
+ const scrollbarXOpts = computeScrollbarXOpts.value
302
+ return getDefaultConfig(getDefaultConfig(scrollbarXOpts.autoHide, scrollbarOpts.autoHide), getConfig().scrollbar.autoHide)
303
+ })
304
+
305
+ const computeScrollYAutoHide = computed(() => {
306
+ const scrollbarOpts = computeScrollbarOpts.value
307
+ const scrollbarYOpts = computeScrollbarYOpts.value
308
+ return getDefaultConfig(getDefaultConfig(scrollbarYOpts.autoHide, scrollbarOpts.autoHide), getConfig().scrollbar.autoHide)
309
+ })
310
+
311
+ const computeScrollbarWrapperClss = computed(() => {
312
+ const scrollbarOpts = computeScrollbarOpts.value
313
+ const { padding } = scrollbarOpts
314
+ const { yThumbHeight, xThumbWidth } = reactData
315
+ const scrollbarXToTop = computeScrollbarXToTop.value
316
+ const scrollbarYToLeft = computeScrollbarYToLeft.value
317
+ const scrollXVisible = computeScrollXVisible.value
318
+ const scrollYVisible = computeScrollYVisible.value
319
+ const scrollXAutoHide = computeScrollXAutoHide.value
320
+ const scrollYAutoHide = computeScrollYAutoHide.value
321
+ return domUtils.buildClass([
322
+ 'vxe-scrollbar is--virtual',
323
+ `ov-x--${scrollXVisible === false ? 'hidden' : 'visible'}`,
324
+ `ov-y--${scrollYVisible === false ? 'hidden' : 'visible'}`,
325
+ `sx-pos--${scrollbarXToTop ? 'top' : 'bottom'}`,
326
+ `sy-pos--${scrollbarYToLeft ? 'left' : 'right'}`
327
+ ], {
328
+ 'is--padding': padding,
329
+ 'ov-x--auto-hide': scrollXAutoHide,
330
+ 'ov-y--auto-hide': scrollYAutoHide,
331
+ 'overflow-y': yThumbHeight,
332
+ 'overflow-x': xThumbWidth
333
+ })
334
+ })
335
+
336
+ const computeScrollbarXToTop = computed(() => {
337
+ const scrollbarXOpts = computeScrollbarXOpts.value
338
+ return scrollbarXOpts.position === 'top'
339
+ })
340
+
341
+ const computeScrollbarYToLeft = computed(() => {
342
+ const scrollbarYOpts = computeScrollbarYOpts.value
343
+ return scrollbarYOpts.position === 'left'
344
+ })
345
+
241
346
  const dispatchEvent = (type: ValueOf<VxeListEmits>, params: Record<string, any>, evnt: Event | null) => {
242
347
  emit(type, createEvent(evnt, { $list: $xeList }, params))
243
348
  }
@@ -404,6 +509,7 @@ export default defineVxeComponent({
404
509
  */
405
510
  const refreshScroll = () => {
406
511
  const { lastScrollLeft, lastScrollTop } = internalData
512
+ updateScrollbar()
407
513
  return clearScroll().then(() => {
408
514
  if (lastScrollLeft || lastScrollTop) {
409
515
  internalData.lastScrollLeft = 0
@@ -413,6 +519,11 @@ export default defineVxeComponent({
413
519
  })
414
520
  }
415
521
 
522
+ const updateScrollbar = () => {
523
+ updateThumbSize()
524
+ updateThumbOffset()
525
+ }
526
+
416
527
  /**
417
528
  * 重新计算列表
418
529
  */
@@ -430,6 +541,7 @@ export default defineVxeComponent({
430
541
  parentHeight = parentEl.clientHeight - Math.ceil(XEUtils.toNumber(parentStyle.paddingLeft) + XEUtils.toNumber(parentStyle.paddingRight))
431
542
  }
432
543
  reactData.parentHeight = parentHeight
544
+ updateScrollbar()
433
545
  updateHeight()
434
546
  if (el.clientWidth && el.clientHeight) {
435
547
  return computeScrollLoad()
@@ -461,6 +573,7 @@ export default defineVxeComponent({
461
573
  const scrollLeft = scrollBodyElem.scrollLeft
462
574
  const isX = scrollLeft !== internalData.lastScrollLeft
463
575
  const isY = scrollTop !== internalData.lastScrollTop
576
+ updateThumbOffset()
464
577
  internalData.lastScrollTop = scrollTop
465
578
  internalData.lastScrollLeft = scrollLeft
466
579
  if (reactData.scrollYLoad) {
@@ -1815,6 +1928,176 @@ export default defineVxeComponent({
1815
1928
  }
1816
1929
  }
1817
1930
 
1931
+ const updateThumbSize = () => {
1932
+ const viewEl = refVirtualWrapper.value
1933
+ if (!viewEl) {
1934
+ return
1935
+ }
1936
+ if (!viewEl.clientHeight || !viewEl.clientHeight) {
1937
+ return
1938
+ }
1939
+ const trackXEl = refTrackXElem.value
1940
+ const xThumbWidth = trackXEl ? getThumbSize(viewEl.clientWidth, viewEl.scrollWidth, trackXEl.clientWidth) : 0
1941
+ const thumbXElem = refThumbXElem.value
1942
+ if (thumbXElem) {
1943
+ thumbXElem.style.width = xThumbWidth + 'px'
1944
+ }
1945
+ reactData.xThumbWidth = xThumbWidth
1946
+
1947
+ const trackYEl = refTrackYElem.value
1948
+
1949
+ const yThumbHeight = trackYEl ? getThumbSize(viewEl.clientHeight, viewEl.scrollHeight, trackYEl.clientHeight) : 0
1950
+ const thumbYElem = refThumbYElem.value
1951
+ if (thumbYElem) {
1952
+ thumbYElem.style.height = yThumbHeight + 'px'
1953
+ }
1954
+ reactData.yThumbHeight = yThumbHeight
1955
+ }
1956
+
1957
+ const updateThumbOffset = () => {
1958
+ const viewEl = refVirtualWrapper.value
1959
+ if (!viewEl) {
1960
+ return
1961
+ }
1962
+ if (!viewEl.clientHeight || !viewEl.clientHeight) {
1963
+ return
1964
+ }
1965
+ const { xThumbWidth, yThumbHeight } = reactData
1966
+ const trackXEl = refTrackXElem.value
1967
+ const thumbXElem = refThumbXElem.value
1968
+ const xThumbLeft = trackXEl && xThumbWidth ? getThumbOffsetSize(viewEl.scrollLeft, viewEl.clientWidth, viewEl.scrollWidth, trackXEl.clientWidth, xThumbWidth) : 0
1969
+ internalData.xThumbLeft = xThumbLeft
1970
+ if (thumbXElem && xThumbWidth) {
1971
+ thumbXElem.style.width = xThumbWidth + 'px'
1972
+ thumbXElem.style.transform = `translateX(${xThumbLeft}px)`
1973
+ }
1974
+
1975
+ const trackYEl = refTrackYElem.value
1976
+ const thumbYElem = refThumbYElem.value
1977
+ const yThumbTop = trackYEl && yThumbHeight ? getThumbOffsetSize(viewEl.scrollTop, viewEl.clientHeight, viewEl.scrollHeight, trackYEl.clientHeight, yThumbHeight) : 0
1978
+ internalData.yThumbTop = yThumbTop
1979
+ if (thumbYElem && yThumbHeight) {
1980
+ thumbYElem.style.height = yThumbHeight + 'px'
1981
+ thumbYElem.style.transform = `translateY(${yThumbTop}px)`
1982
+ }
1983
+ }
1984
+
1985
+ const clickTrackXEvent = (evnt: MouseEvent) => {
1986
+ const trackEl = evnt.currentTarget as HTMLDivElement
1987
+ if (trackEl !== evnt.target) {
1988
+ return
1989
+ }
1990
+ const viewEl = refVirtualWrapper.value
1991
+ if (!viewEl) {
1992
+ return
1993
+ }
1994
+ const { xThumbWidth } = reactData
1995
+ const trackRect = trackEl.getBoundingClientRect()
1996
+ viewEl.scrollTo({
1997
+ left: getScrollFromClick(evnt.clientX - trackRect.left, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth),
1998
+ behavior: 'auto'
1999
+ })
2000
+ }
2001
+
2002
+ const clickTrackYEvent = (evnt: MouseEvent) => {
2003
+ const trackEl = evnt.currentTarget as HTMLDivElement
2004
+ if (trackEl !== evnt.target) {
2005
+ return
2006
+ }
2007
+ const viewEl = refVirtualWrapper.value
2008
+ if (!viewEl) {
2009
+ return
2010
+ }
2011
+ const { yThumbHeight } = reactData
2012
+ const trackRect = trackEl.getBoundingClientRect()
2013
+ viewEl.scrollTo({
2014
+ top: getScrollFromClick(evnt.clientY - trackRect.top, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight),
2015
+ behavior: 'auto'
2016
+ })
2017
+ }
2018
+
2019
+ const pointerdownThumbXEvent = (evnt: PointerEvent) => {
2020
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2021
+ internalData.isThumbDrag = true
2022
+ thumbEl.setPointerCapture(evnt.pointerId)
2023
+
2024
+ const viewEl = refVirtualWrapper.value
2025
+ if (!viewEl) {
2026
+ return
2027
+ }
2028
+ const { xThumbWidth } = reactData
2029
+ const trackEl = thumbEl.parentElement as HTMLDivElement
2030
+ const trackRect = trackEl.getBoundingClientRect()
2031
+ const pointerPosition = evnt.clientX - trackRect.left
2032
+ // 记录 thumb 的偏移
2033
+ const thumbOffset = getThumbOffsetSize(viewEl.scrollLeft, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth)
2034
+ internalData.thumbDragOffset = pointerPosition - thumbOffset
2035
+ }
2036
+
2037
+ const pointermoveThumbXEvent = (evnt: PointerEvent) => {
2038
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2039
+ if (!thumbEl.hasPointerCapture(evnt.pointerId)) {
2040
+ return
2041
+ }
2042
+ const { isThumbDrag, thumbDragOffset } = internalData
2043
+ if (isThumbDrag) {
2044
+ const viewEl = refVirtualWrapper.value
2045
+ if (!viewEl) {
2046
+ return
2047
+ }
2048
+ const { xThumbWidth } = reactData
2049
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2050
+ const trackEl = thumbEl.parentElement as HTMLDivElement
2051
+ const trackRect = trackEl.getBoundingClientRect()
2052
+ // 更新偏移
2053
+ viewEl.scrollLeft = getScrollFromDrag(evnt.clientX - trackRect.left, thumbDragOffset, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth)
2054
+ }
2055
+ }
2056
+
2057
+ const cleatPointerThumbEvent = (evnt: PointerEvent) => {
2058
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2059
+ thumbEl.releasePointerCapture(evnt.pointerId)
2060
+ internalData.isThumbDrag = false
2061
+ }
2062
+
2063
+ const pointerdownThumbYEvent = (evnt: PointerEvent) => {
2064
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2065
+ internalData.isThumbDrag = true
2066
+ thumbEl.setPointerCapture(evnt.pointerId)
2067
+
2068
+ const viewEl = refVirtualWrapper.value
2069
+ if (!viewEl) {
2070
+ return
2071
+ }
2072
+ const { yThumbHeight } = reactData
2073
+ const trackEl = thumbEl.parentElement as HTMLDivElement
2074
+ const trackRect = trackEl.getBoundingClientRect()
2075
+ const pointerPosition = evnt.clientY - trackRect.top
2076
+ // 记录 thumb 的偏移
2077
+ const thumbOffset = getThumbOffsetSize(viewEl.scrollTop, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight)
2078
+ internalData.thumbDragOffset = pointerPosition - thumbOffset
2079
+ }
2080
+
2081
+ const pointermoveThumbYEvent = (evnt: PointerEvent) => {
2082
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2083
+ if (!thumbEl.hasPointerCapture(evnt.pointerId)) {
2084
+ return
2085
+ }
2086
+ const { isThumbDrag, thumbDragOffset } = internalData
2087
+ if (isThumbDrag) {
2088
+ const viewEl = refVirtualWrapper.value
2089
+ if (!viewEl) {
2090
+ return
2091
+ }
2092
+ const { yThumbHeight } = reactData
2093
+ const thumbEl = evnt.currentTarget as HTMLDivElement
2094
+ const trackEl = thumbEl.parentElement as HTMLDivElement
2095
+ const trackRect = trackEl.getBoundingClientRect()
2096
+ // 更新偏移
2097
+ viewEl.scrollTop = getScrollFromDrag(evnt.clientY - trackRect.top, thumbDragOffset, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight)
2098
+ }
2099
+ }
2100
+
1818
2101
  Object.assign($xeList, listMethods, listPrivateMethods)
1819
2102
 
1820
2103
  const renderDragTip = () => {
@@ -2053,8 +2336,8 @@ export default defineVxeComponent({
2053
2336
  }
2054
2337
 
2055
2338
  const renderVN = () => {
2056
- const { showCheckbox, className, loading } = props
2057
- const { bodyHeight, topSpaceHeight, rowList, isAllChecked, isAllIndeterminate } = reactData
2339
+ const { showCheckbox, className, loading, useScrollbar } = props
2340
+ const { bodyHeight, topSpaceHeight, rowList, isAllChecked, isAllIndeterminate, xThumbWidth, yThumbHeight } = reactData
2058
2341
  const defaultSlot = slots.default
2059
2342
  const headerSlot = slots.header
2060
2343
  const footerSlot = slots.footer
@@ -2069,6 +2352,14 @@ export default defineVxeComponent({
2069
2352
  const rowOpts = computeRowOpts.value
2070
2353
  const { isHover, padding } = rowOpts
2071
2354
  const isDrag = computeIsDrag.value
2355
+ const scrollbarOpts = computeScrollbarOpts.value
2356
+ const scrollXVisible = computeScrollXVisible.value
2357
+ const scrollYVisible = computeScrollYVisible.value
2358
+ const scrollbarXToTop = computeScrollbarXToTop.value
2359
+ const scrollbarYToLeft = computeScrollbarYToLeft.value
2360
+ const scrollXAutoHide = computeScrollXAutoHide.value
2361
+ const scrollYAutoHide = computeScrollYAutoHide.value
2362
+ const scrollbarWrapperClss = computeScrollbarWrapperClss.value
2072
2363
  const showDefChekboxHead = showCheckbox && showHeader !== false
2073
2364
 
2074
2365
  const leOns: {
@@ -2079,11 +2370,25 @@ export default defineVxeComponent({
2079
2370
  }
2080
2371
  return h('div', {
2081
2372
  ref: refElem,
2082
- class: ['vxe-list', className ? (XEUtils.isFunction(className) ? className({ $list: $xeList }) : className) : '', {
2083
- [`size--${vSize}`]: vSize,
2084
- 'is--drag': isDrag,
2085
- 'is--loading': loading
2086
- }],
2373
+ class: [
2374
+ 'vxe-list',
2375
+ useScrollbar ? `ov-x--${scrollXVisible === false ? 'hidden' : 'visible'}` : '',
2376
+ useScrollbar ? `ov-y--${scrollYVisible === false ? 'hidden' : 'visible'}` : '',
2377
+ useScrollbar ? `sx-pos--${scrollbarXToTop ? 'top' : 'bottom'}` : '',
2378
+ useScrollbar ? `sy-pos--${scrollbarYToLeft ? 'left' : 'right'}` : '',
2379
+ className ? (XEUtils.isFunction(className) ? className({ $list: $xeList }) : className) : '',
2380
+ {
2381
+ [`size--${vSize}`]: vSize,
2382
+ 'is--virtual-scrollbar': useScrollbar,
2383
+ 'ov-padding': useScrollbar && scrollbarOpts.padding,
2384
+ 'ov-x--auto-hide': useScrollbar && scrollXAutoHide,
2385
+ 'ov-y--auto-hide': useScrollbar && scrollYAutoHide,
2386
+ 'overflow-y': yThumbHeight,
2387
+ 'overflow-x': xThumbWidth,
2388
+ 'is--drag': isDrag,
2389
+ 'is--loading': loading
2390
+ }
2391
+ ],
2087
2392
  style: wrapperStyles,
2088
2393
  ...leOns
2089
2394
  }, [
@@ -2151,6 +2456,49 @@ export default defineVxeComponent({
2151
2456
  class: 'vxe-list--footer-wrapper'
2152
2457
  }, footerSlot({ items: rowList, $list: $xeList }))
2153
2458
  : renderEmptyElement($xeList),
2459
+ /**
2460
+ * 滚动条
2461
+ */
2462
+ useScrollbar
2463
+ ? h('div', {
2464
+ class: scrollbarWrapperClss
2465
+ }, [
2466
+ scrollXVisible === false
2467
+ ? renderEmptyElement($xeList)
2468
+ : h('div', {
2469
+ ref: refTrackXElem,
2470
+ class: 'vxe-scrollbar--track-x',
2471
+ onClick: clickTrackXEvent
2472
+ }, [
2473
+ h('div', {
2474
+ ref: refThumbXElem,
2475
+ class: 'vxe-scrollbar--thumb-x',
2476
+ onPointerdown: pointerdownThumbXEvent,
2477
+ onPointermove: pointermoveThumbXEvent,
2478
+ onPointerup: cleatPointerThumbEvent,
2479
+ onPointercancel: cleatPointerThumbEvent,
2480
+ onLostpointercapture: cleatPointerThumbEvent
2481
+ })
2482
+ ]),
2483
+ scrollYVisible === false
2484
+ ? renderEmptyElement($xeList)
2485
+ : h('div', {
2486
+ ref: refTrackYElem,
2487
+ class: 'vxe-scrollbar--track-y',
2488
+ onClick: clickTrackYEvent
2489
+ }, [
2490
+ h('div', {
2491
+ ref: refThumbYElem,
2492
+ class: 'vxe-scrollbar--thumb-y',
2493
+ onPointerdown: pointerdownThumbYEvent,
2494
+ onPointermove: pointermoveThumbYEvent,
2495
+ onPointerup: cleatPointerThumbEvent,
2496
+ onPointercancel: cleatPointerThumbEvent,
2497
+ onLostpointercapture: cleatPointerThumbEvent
2498
+ })
2499
+ ])
2500
+ ])
2501
+ : renderEmptyElement($xeList),
2154
2502
  /**
2155
2503
  * 拖拽提示
2156
2504
  */
@@ -2186,11 +2534,24 @@ export default defineVxeComponent({
2186
2534
  watch(() => props.syncResize, () => {
2187
2535
  reFlag.value++
2188
2536
  })
2537
+ watch(() => props.useScrollbar, () => {
2538
+ reFlag.value++
2539
+ })
2189
2540
  watch(computeRowHeight, () => {
2190
2541
  reFlag.value++
2191
2542
  })
2192
- watch(reFlag, () => {
2543
+ watch(computeScrollXVisible, () => {
2544
+ nextTick(() => {
2545
+ reFlag.value++
2546
+ })
2547
+ })
2548
+ watch(computeScrollYVisible, () => {
2193
2549
  nextTick(() => {
2550
+ reFlag.value++
2551
+ })
2552
+ })
2553
+ watch(reFlag, () => {
2554
+ recalculate().then(() => {
2194
2555
  recalculate()
2195
2556
  })
2196
2557
  })
@@ -2211,7 +2572,9 @@ export default defineVxeComponent({
2211
2572
  })
2212
2573
 
2213
2574
  onActivated(() => {
2214
- recalculate().then(() => refreshScroll())
2575
+ recalculate().then(() => {
2576
+ refreshScroll()
2577
+ })
2215
2578
  })
2216
2579
 
2217
2580
  nextTick(() => {
@@ -2219,7 +2582,7 @@ export default defineVxeComponent({
2219
2582
  })
2220
2583
 
2221
2584
  onMounted(() => {
2222
- const { showSeq, showRadio, showCheckbox } = props
2585
+ const { showSeq, showRadio, showCheckbox, autoResize, useScrollbar } = props
2223
2586
  const rowOpts = computeRowOpts.value
2224
2587
  const { useKey } = rowOpts
2225
2588
 
@@ -2242,17 +2605,27 @@ export default defineVxeComponent({
2242
2605
  if (useKey && !keyField) {
2243
2606
  errLog('vxe.error.reqSupportProp', ['row-config.useKey', 'row-config.keyField'])
2244
2607
  }
2245
- if (props.autoResize) {
2608
+ if (useScrollbar || autoResize) {
2246
2609
  const el = refElem.value
2247
- const resizeObserver = globalResize.create(() => recalculate())
2248
- resizeObserver.observe(el)
2610
+ const viewInnerEl = refVirtualBody.value
2611
+ const resizeObserver = globalResize.create(() => {
2612
+ reFlag.value++
2613
+ })
2249
2614
  if (el) {
2250
- resizeObserver.observe(el.parentElement as HTMLDivElement)
2615
+ resizeObserver.observe(el)
2616
+ if (autoResize) {
2617
+ resizeObserver.observe(el.parentElement as HTMLDivElement)
2618
+ }
2619
+ }
2620
+ if (viewInnerEl) {
2621
+ resizeObserver.observe(viewInnerEl)
2251
2622
  }
2252
2623
  internalData.resizeObserver = resizeObserver
2253
2624
  }
2254
- recalculate()
2255
- globalEvents.on($xeList, 'resize', recalculate)
2625
+ reFlag.value++
2626
+ globalEvents.on($xeList, 'resize', () => {
2627
+ reFlag.value++
2628
+ })
2256
2629
  })
2257
2630
 
2258
2631
  onBeforeUnmount(() => {