vxe-pc-ui 4.20.0 → 4.20.2

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 (128) hide show
  1. package/dist/all.esm.js +780 -173
  2. package/dist/style.css +1 -1
  3. package/dist/style.min.css +1 -1
  4. package/es/card/src/card.js +19 -4
  5. package/es/drawer/src/drawer.js +59 -15
  6. package/es/drawer/style.css +13 -6
  7. package/es/drawer/style.min.css +1 -1
  8. package/es/icon/style.css +1 -1
  9. package/es/language/fr-FR.js +29 -29
  10. package/es/layout-aside/src/layout-aside.js +10 -6
  11. package/es/layout-body/src/layout-body.js +21 -12
  12. package/es/list/src/list.js +118 -49
  13. package/es/list/style.css +25 -8
  14. package/es/list/style.min.css +1 -1
  15. package/es/menu/src/menu.js +2 -2
  16. package/es/modal/src/modal.js +56 -12
  17. package/es/modal/style.css +15 -4
  18. package/es/modal/style.min.css +1 -1
  19. package/es/scrollbar/src/scrollbar.js +73 -19
  20. package/es/style.css +1 -1
  21. package/es/style.min.css +1 -1
  22. package/es/tabs/src/tabs.js +21 -6
  23. package/es/tree/src/tree.js +410 -53
  24. package/es/tree/style.css +43 -0
  25. package/es/tree/style.min.css +1 -1
  26. package/es/ui/index.js +1 -1
  27. package/es/ui/src/log.js +1 -1
  28. package/es/ui/src/utils.js +3 -0
  29. package/es/vxe-drawer/style.css +13 -6
  30. package/es/vxe-drawer/style.min.css +1 -1
  31. package/es/vxe-list/style.css +25 -8
  32. package/es/vxe-list/style.min.css +1 -1
  33. package/es/vxe-modal/style.css +15 -4
  34. package/es/vxe-modal/style.min.css +1 -1
  35. package/es/vxe-tree/style.css +43 -0
  36. package/es/vxe-tree/style.min.css +1 -1
  37. package/lib/card/src/card.js +19 -4
  38. package/lib/card/src/card.min.js +1 -1
  39. package/lib/drawer/src/drawer.js +64 -11
  40. package/lib/drawer/src/drawer.min.js +1 -1
  41. package/lib/drawer/style/style.css +13 -6
  42. package/lib/drawer/style/style.min.css +1 -1
  43. package/lib/icon/style/style.css +1 -1
  44. package/lib/icon/style/style.min.css +1 -1
  45. package/lib/index.umd.js +887 -183
  46. package/lib/index.umd.min.js +1 -1
  47. package/lib/language/fr-FR.js +29 -29
  48. package/lib/language/fr-FR.min.js +1 -1
  49. package/lib/language/fr-FR.umd.js +29 -29
  50. package/lib/layout-aside/src/layout-aside.js +9 -8
  51. package/lib/layout-aside/src/layout-aside.min.js +1 -1
  52. package/lib/layout-body/src/layout-body.js +29 -22
  53. package/lib/layout-body/src/layout-body.min.js +1 -1
  54. package/lib/list/src/list.js +110 -47
  55. package/lib/list/src/list.min.js +1 -1
  56. package/lib/list/style/style.css +25 -8
  57. package/lib/list/style/style.min.css +1 -1
  58. package/lib/menu/src/menu.js +1 -1
  59. package/lib/menu/src/menu.min.js +1 -1
  60. package/lib/modal/src/modal.js +61 -10
  61. package/lib/modal/src/modal.min.js +1 -1
  62. package/lib/modal/style/style.css +15 -4
  63. package/lib/modal/style/style.min.css +1 -1
  64. package/lib/scrollbar/src/scrollbar.js +81 -17
  65. package/lib/scrollbar/src/scrollbar.min.js +1 -1
  66. package/lib/style.css +1 -1
  67. package/lib/style.min.css +1 -1
  68. package/lib/tabs/src/tabs.js +23 -11
  69. package/lib/tabs/src/tabs.min.js +1 -1
  70. package/lib/tree/src/tree.js +412 -50
  71. package/lib/tree/src/tree.min.js +1 -1
  72. package/lib/tree/style/style.css +43 -0
  73. package/lib/tree/style/style.min.css +1 -1
  74. package/lib/ui/index.js +1 -1
  75. package/lib/ui/index.min.js +1 -1
  76. package/lib/ui/src/log.js +1 -1
  77. package/lib/ui/src/log.min.js +1 -1
  78. package/lib/ui/src/utils.js +4 -0
  79. package/lib/ui/src/utils.min.js +1 -1
  80. package/lib/vxe-drawer/style/style.css +13 -6
  81. package/lib/vxe-drawer/style/style.min.css +1 -1
  82. package/lib/vxe-list/style/style.css +25 -8
  83. package/lib/vxe-list/style/style.min.css +1 -1
  84. package/lib/vxe-modal/style/style.css +15 -4
  85. package/lib/vxe-modal/style/style.min.css +1 -1
  86. package/lib/vxe-tree/style/style.css +43 -0
  87. package/lib/vxe-tree/style/style.min.css +1 -1
  88. package/package.json +2 -2
  89. package/packages/card/src/card.ts +20 -4
  90. package/packages/drawer/src/drawer.ts +73 -16
  91. package/packages/language/fr-FR.ts +903 -903
  92. package/packages/layout-aside/src/layout-aside.ts +10 -6
  93. package/packages/layout-body/src/layout-body.ts +25 -15
  94. package/packages/list/src/list.ts +130 -55
  95. package/packages/menu/src/menu.ts +2 -2
  96. package/packages/modal/src/modal.ts +71 -14
  97. package/packages/scrollbar/src/scrollbar.ts +79 -18
  98. package/packages/tabs/src/tabs.ts +21 -7
  99. package/packages/tree/src/tree.ts +452 -62
  100. package/packages/ui/src/utils.ts +4 -0
  101. package/styles/components/drawer.scss +13 -6
  102. package/styles/components/list.scss +35 -10
  103. package/styles/components/modal.scss +12 -4
  104. package/styles/components/tree.scss +76 -0
  105. package/types/components/card.d.ts +10 -1
  106. package/types/components/drawer.d.ts +20 -0
  107. package/types/components/gantt-module/gantt-view.d.ts +24 -1
  108. package/types/components/gantt.d.ts +2 -0
  109. package/types/components/layout-aside.d.ts +10 -1
  110. package/types/components/layout-body.d.ts +10 -1
  111. package/types/components/list.d.ts +13 -2
  112. package/types/components/modal.d.ts +20 -0
  113. package/types/components/scrollbar.d.ts +17 -2
  114. package/types/components/table.d.ts +80 -6
  115. package/types/components/tabs.d.ts +10 -1
  116. package/types/components/tree.d.ts +35 -2
  117. /package/es/icon/{iconfont.1791880413927.ttf → iconfont.1792034967421.ttf} +0 -0
  118. /package/es/icon/{iconfont.1791880413927.woff → iconfont.1792034967421.woff} +0 -0
  119. /package/es/icon/{iconfont.1791880413927.woff2 → iconfont.1792034967421.woff2} +0 -0
  120. /package/es/{iconfont.1791880413927.ttf → iconfont.1792034967421.ttf} +0 -0
  121. /package/es/{iconfont.1791880413927.woff → iconfont.1792034967421.woff} +0 -0
  122. /package/es/{iconfont.1791880413927.woff2 → iconfont.1792034967421.woff2} +0 -0
  123. /package/lib/icon/style/{iconfont.1791880413927.ttf → iconfont.1792034967421.ttf} +0 -0
  124. /package/lib/icon/style/{iconfont.1791880413927.woff → iconfont.1792034967421.woff} +0 -0
  125. /package/lib/icon/style/{iconfont.1791880413927.woff2 → iconfont.1792034967421.woff2} +0 -0
  126. /package/lib/{iconfont.1791880413927.ttf → iconfont.1792034967421.ttf} +0 -0
  127. /package/lib/{iconfont.1791880413927.woff → iconfont.1792034967421.woff} +0 -0
  128. /package/lib/{iconfont.1791880413927.woff2 → iconfont.1792034967421.woff2} +0 -0
@@ -1,14 +1,15 @@
1
1
  import { ref, h, reactive, PropType, computed, VNode, watch, onBeforeUnmount, nextTick, onMounted, provide } from 'vue'
2
2
  import { defineVxeComponent } from '../../ui/src/comp'
3
- import { VxeUI, createEvent, useSize, globalEvents, globalResize, renderEmptyElement } from '../../ui'
3
+ import { VxeUI, domUtils, createEvent, useSize, globalEvents, globalResize, renderEmptyElement } from '../../ui'
4
4
  import { calcTreeLine, getItemCacheObj } from './util'
5
5
  import { createComponentLog } from '../../ui/src/log'
6
6
  import { getCrossTreeDragNodeInfo } from './store'
7
7
  import XEUtils from 'xe-utils'
8
8
  import { getSlotVNs } from '../../ui/src/vn'
9
9
  import { toCssUnit, isScale, getPaddingTopBottomSize, addClass, removeClass, getTpImg, hasControlKey, getEventTargetNode, hasClass } from '../../ui/src/dom'
10
- import { isEnableConf, enModelValue, deModelValue, getText } from '../../ui/src/utils'
10
+ import { isEnableConf, enModelValue, deModelValue, getText, getDefaultConfig } from '../../ui/src/utils'
11
11
  import { moveRowAnimateToTb, clearRowAnimate } from '../../ui/src/anime'
12
+ import { getThumbOffsetSize, getThumbSize, getScrollFromClick, getScrollFromDrag } from '../../scrollbar/src/util'
12
13
  import VxeLoadingComponent from '../../loading'
13
14
  import VxeTooltipComponent from '../../tooltip'
14
15
 
@@ -25,6 +26,37 @@ function getNodeUniqueId () {
25
26
  return XEUtils.uniqueId('node_')
26
27
  }
27
28
 
29
+ function createReactData ():TreeReactData {
30
+ return {
31
+ parentHeight: 0,
32
+ customHeight: 0,
33
+ customMinHeight: 0,
34
+ customMaxHeight: 0,
35
+ currentNode: null,
36
+ scrollYLoad: false,
37
+ bodyHeight: 0,
38
+ topSpaceHeight: 0,
39
+ selectRadioKey: null,
40
+ treeList: [],
41
+ updateExpandedFlag: 1,
42
+ updateCheckboxFlag: 1,
43
+
44
+ // 滚动条
45
+ yThumbHeight: 0,
46
+ xThumbWidth: 0,
47
+
48
+ insertNodeFlag: 1,
49
+ removeNodeFlag: 1,
50
+ dragNode: null,
51
+ dragTipText: '',
52
+ isCrossDragNode: false,
53
+ tooltipStore: {
54
+ visible: false,
55
+ node: null
56
+ }
57
+ }
58
+ }
59
+
28
60
  function createInternalData (): TreeInternalData {
29
61
  return {
30
62
  // initialized: false,
@@ -38,8 +70,17 @@ function createInternalData (): TreeInternalData {
38
70
  treeExpandedMaps: {},
39
71
  treeExpandLazyLoadedMaps: {},
40
72
 
41
- lastScrollLeft: 0,
73
+ // resizeObserver: undefined,
74
+
75
+ // 滚动条
76
+ // scrollObserver: undefined,
77
+ // isThumbDrag: false,
78
+ thumbDragOffset: 0,
79
+ yThumbTop: 0,
80
+ xThumbLeft: 0,
42
81
  lastScrollTop: 0,
82
+ lastScrollLeft: 0,
83
+
43
84
  scrollYStore: {
44
85
  startIndex: 0,
45
86
  endIndex: 0,
@@ -60,32 +101,6 @@ function createInternalData (): TreeInternalData {
60
101
  }
61
102
  }
62
103
 
63
- function createReactData ():TreeReactData {
64
- return {
65
- parentHeight: 0,
66
- customHeight: 0,
67
- customMinHeight: 0,
68
- customMaxHeight: 0,
69
- currentNode: null,
70
- scrollYLoad: false,
71
- bodyHeight: 0,
72
- topSpaceHeight: 0,
73
- selectRadioKey: null,
74
- treeList: [],
75
- updateExpandedFlag: 1,
76
- updateCheckboxFlag: 1,
77
- insertNodeFlag: 1,
78
- removeNodeFlag: 1,
79
- dragNode: null,
80
- dragTipText: '',
81
- isCrossDragNode: false,
82
- tooltipStore: {
83
- visible: false,
84
- node: null
85
- }
86
- }
87
- }
88
-
89
104
  let crossTreeDragNodeObj: {
90
105
  $oldTree: VxeTreeConstructor & VxeTreePrivateMethods
91
106
  $newTree: (VxeTreeConstructor & VxeTreePrivateMethods) | null
@@ -220,7 +235,12 @@ export default defineVxeComponent({
220
235
  type: String as PropType<VxeTreePropTypes.Size>,
221
236
  default: () => getConfig().tree.size || getConfig().size
222
237
  },
223
- virtualYConfig: Object as PropType<VxeTreePropTypes.VirtualYConfig>
238
+ virtualYConfig: Object as PropType<VxeTreePropTypes.VirtualYConfig>,
239
+ useScrollbar: {
240
+ type: Boolean as PropType<VxeTreePropTypes.UseScrollbar>,
241
+ default: () => getDefaultConfig(getConfig().tree.useScrollbar, getConfig().useScrollbar)
242
+ },
243
+ scrollbarConfig: Object as PropType<VxeTreePropTypes.ScrollbarConfig>
224
244
  },
225
245
  emits: [
226
246
  'update:modelValue',
@@ -256,6 +276,11 @@ export default defineVxeComponent({
256
276
  const refVirtualWrapper = ref<HTMLDivElement>()
257
277
  const refVirtualBody = ref<HTMLDivElement>()
258
278
 
279
+ const refTrackXElem = ref<HTMLDivElement>()
280
+ const refTrackYElem = ref<HTMLDivElement>()
281
+ const refThumbXElem = ref<HTMLDivElement>()
282
+ const refThumbYElem = ref<HTMLDivElement>()
283
+
259
284
  const refDragNodeLineElem = ref<HTMLDivElement>()
260
285
  const refDragTipElem = ref<HTMLDivElement>()
261
286
 
@@ -349,6 +374,17 @@ export default defineVxeComponent({
349
374
  return Object.assign({}, getConfig().tree.menuConfig, props.menuConfig)
350
375
  })
351
376
 
377
+ const computeWrapperStyles = computed(() => {
378
+ const barWidth = computeScrollYWidth.value
379
+ const barHeight = computeScrollXHeight.value
380
+ const stys: VxeComponentStyleType = {}
381
+ if (barWidth || barHeight) {
382
+ stys['--vxe-ui-scrollbar-y-width'] = toCssUnit(barWidth || barHeight)
383
+ stys['--vxe-ui-scrollbar-x-height'] = toCssUnit(barHeight || barWidth)
384
+ }
385
+ return stys
386
+ })
387
+
352
388
  const computeTreeStyle = computed(() => {
353
389
  const { indent } = props
354
390
  const { customHeight, customMinHeight, customMaxHeight } = reactData
@@ -383,6 +419,86 @@ export default defineVxeComponent({
383
419
  return Object.assign({}, getConfig().tree.filterConfig, props.filterConfig)
384
420
  })
385
421
 
422
+ const computeScrollbarOpts = computed(() => {
423
+ return Object.assign({}, getConfig().tree.scrollbarConfig, props.scrollbarConfig)
424
+ })
425
+
426
+ const computeScrollbarXOpts = computed(() => {
427
+ const scrollbarOpts = computeScrollbarOpts.value
428
+ return Object.assign({}, getConfig().scrollbar.xConfig, scrollbarOpts.xConfig, {
429
+ visible: false
430
+ })
431
+ })
432
+
433
+ const computeScrollbarYOpts = computed(() => {
434
+ const scrollbarOpts = computeScrollbarOpts.value
435
+ return Object.assign({}, getConfig().scrollbar.yConfig, scrollbarOpts.yConfig)
436
+ })
437
+
438
+ const computeScrollXHeight = computed(() => {
439
+ const scrollbarOpts = computeScrollbarOpts.value
440
+ const scrollbarXOpts = computeScrollbarXOpts.value
441
+ return getDefaultConfig(getDefaultConfig(scrollbarXOpts.height, scrollbarOpts.height), getConfig().scrollbar.height)
442
+ })
443
+
444
+ const computeScrollYWidth = computed(() => {
445
+ const scrollbarOpts = computeScrollbarOpts.value
446
+ const scrollbarYOpts = computeScrollbarYOpts.value
447
+ return getDefaultConfig(getDefaultConfig(scrollbarYOpts.width, scrollbarOpts.width), getConfig().scrollbar.width)
448
+ })
449
+
450
+ const computeScrollXVisible = computed(() => {
451
+ const scrollbarOpts = computeScrollbarOpts.value
452
+ const scrollbarXOpts = computeScrollbarXOpts.value
453
+ return getDefaultConfig(scrollbarXOpts.visible, scrollbarOpts.visible)
454
+ })
455
+
456
+ const computeScrollYVisible = computed(() => {
457
+ const scrollbarOpts = computeScrollbarOpts.value
458
+ const scrollbarYOpts = computeScrollbarYOpts.value
459
+ return getDefaultConfig(scrollbarYOpts.visible, scrollbarOpts.visible)
460
+ })
461
+
462
+ const computeScrollXAutoHide = computed(() => {
463
+ const scrollbarOpts = computeScrollbarOpts.value
464
+ const scrollbarXOpts = computeScrollbarXOpts.value
465
+ return getDefaultConfig(getDefaultConfig(scrollbarXOpts.autoHide, scrollbarOpts.autoHide), getConfig().scrollbar.autoHide)
466
+ })
467
+
468
+ const computeScrollYAutoHide = computed(() => {
469
+ const scrollbarOpts = computeScrollbarOpts.value
470
+ const scrollbarYOpts = computeScrollbarYOpts.value
471
+ return getDefaultConfig(getDefaultConfig(scrollbarYOpts.autoHide, scrollbarOpts.autoHide), getConfig().scrollbar.autoHide)
472
+ })
473
+
474
+ const computeScrollbarWrapperClss = computed(() => {
475
+ const { yThumbHeight, xThumbWidth } = reactData
476
+ const scrollbarXToTop = computeScrollbarXToTop.value
477
+ const scrollbarYToLeft = computeScrollbarYToLeft.value
478
+ const scrollXVisible = computeScrollXVisible.value
479
+ const scrollYVisible = computeScrollYVisible.value
480
+ return domUtils.buildClass([
481
+ 'vxe-scrollbar is--virtual',
482
+ `ov-x--${scrollXVisible === false ? 'hidden' : 'visible'}`,
483
+ `ov-y--${scrollYVisible === false ? 'hidden' : 'visible'}`,
484
+ `sx-pos--${scrollbarXToTop ? 'top' : 'bottom'}`,
485
+ `sy-pos--${scrollbarYToLeft ? 'left' : 'right'}`
486
+ ], {
487
+ 'overflow-y': yThumbHeight,
488
+ 'overflow-x': xThumbWidth
489
+ })
490
+ })
491
+
492
+ const computeScrollbarXToTop = computed(() => {
493
+ const scrollbarXOpts = computeScrollbarXOpts.value
494
+ return scrollbarXOpts.position === 'top'
495
+ })
496
+
497
+ const computeScrollbarYToLeft = computed(() => {
498
+ const scrollbarYOpts = computeScrollbarYOpts.value
499
+ return scrollbarYOpts.position === 'left'
500
+ })
501
+
386
502
  const computeMaps: VxeTreePrivateComputed = {
387
503
  computeKeyField,
388
504
  computeParentField,
@@ -928,6 +1044,11 @@ export default defineVxeComponent({
928
1044
  })
929
1045
  }
930
1046
 
1047
+ const updateScrollbar = () => {
1048
+ updateThumbSize()
1049
+ updateThumbOffset()
1050
+ }
1051
+
931
1052
  /**
932
1053
  * 重新计算列表
933
1054
  */
@@ -949,6 +1070,7 @@ export default defineVxeComponent({
949
1070
  const parentPaddingSize = getPaddingTopBottomSize(parentEl)
950
1071
  reactData.parentHeight = Math.max(headHeight + footHeight + rowHeight, parentEl.clientHeight - parentPaddingSize - headHeight - footHeight)
951
1072
  }
1073
+ updateScrollbar()
952
1074
  updateHeight()
953
1075
  return computeScrollLoad().then(() => {
954
1076
  updateHeight()
@@ -984,6 +1106,7 @@ export default defineVxeComponent({
984
1106
  const scrollLeft = scrollBodyElem.scrollLeft
985
1107
  const isX = scrollLeft !== internalData.lastScrollLeft
986
1108
  const isY = scrollTop !== internalData.lastScrollTop
1109
+ updateThumbOffset()
987
1110
  internalData.lastScrollTop = scrollTop
988
1111
  internalData.lastScrollLeft = scrollLeft
989
1112
  if (reactData.scrollYLoad) {
@@ -1531,14 +1654,6 @@ export default defineVxeComponent({
1531
1654
  dispatchEvent('radio-change', { node, value, checked: isChecked }, evnt)
1532
1655
  }
1533
1656
 
1534
- const handleGlobalResizeEvent = () => {
1535
- const el = refElem.value
1536
- if (!el || !el.clientWidth) {
1537
- return
1538
- }
1539
- recalculate()
1540
- }
1541
-
1542
1657
  const insertTreeNode = (newRecords: any[], isAppend: boolean) => {
1543
1658
  const { treeFullData, nodeMaps } = internalData
1544
1659
  const keyField = computeKeyField.value
@@ -2997,6 +3112,176 @@ export default defineVxeComponent({
2997
3112
  }
2998
3113
  }
2999
3114
 
3115
+ const updateThumbSize = () => {
3116
+ const viewEl = refVirtualWrapper.value
3117
+ if (!viewEl) {
3118
+ return
3119
+ }
3120
+ if (!viewEl.clientHeight || !viewEl.clientHeight) {
3121
+ return
3122
+ }
3123
+ const trackXEl = refTrackXElem.value
3124
+ const xThumbWidth = trackXEl ? getThumbSize(viewEl.clientWidth, viewEl.scrollWidth, trackXEl.clientWidth) : 0
3125
+ const thumbXElem = refThumbXElem.value
3126
+ if (thumbXElem) {
3127
+ thumbXElem.style.width = xThumbWidth + 'px'
3128
+ }
3129
+ reactData.xThumbWidth = xThumbWidth
3130
+
3131
+ const trackYEl = refTrackYElem.value
3132
+
3133
+ const yThumbHeight = trackYEl ? getThumbSize(viewEl.clientHeight, viewEl.scrollHeight, trackYEl.clientHeight) : 0
3134
+ const thumbYElem = refThumbYElem.value
3135
+ if (thumbYElem) {
3136
+ thumbYElem.style.height = yThumbHeight + 'px'
3137
+ }
3138
+ reactData.yThumbHeight = yThumbHeight
3139
+ }
3140
+
3141
+ const updateThumbOffset = () => {
3142
+ const viewEl = refVirtualWrapper.value
3143
+ if (!viewEl) {
3144
+ return
3145
+ }
3146
+ if (!viewEl.clientHeight || !viewEl.clientHeight) {
3147
+ return
3148
+ }
3149
+ const { xThumbWidth, yThumbHeight } = reactData
3150
+ const trackXEl = refTrackXElem.value
3151
+ const thumbXElem = refThumbXElem.value
3152
+ const xThumbLeft = trackXEl && xThumbWidth ? getThumbOffsetSize(viewEl.scrollLeft, viewEl.clientWidth, viewEl.scrollWidth, trackXEl.clientWidth, xThumbWidth) : 0
3153
+ internalData.xThumbLeft = xThumbLeft
3154
+ if (thumbXElem && xThumbWidth) {
3155
+ thumbXElem.style.width = xThumbWidth + 'px'
3156
+ thumbXElem.style.transform = `translateX(${xThumbLeft}px)`
3157
+ }
3158
+
3159
+ const trackYEl = refTrackYElem.value
3160
+ const thumbYElem = refThumbYElem.value
3161
+ const yThumbTop = trackYEl && yThumbHeight ? getThumbOffsetSize(viewEl.scrollTop, viewEl.clientHeight, viewEl.scrollHeight, trackYEl.clientHeight, yThumbHeight) : 0
3162
+ internalData.yThumbTop = yThumbTop
3163
+ if (thumbYElem && yThumbHeight) {
3164
+ thumbYElem.style.height = yThumbHeight + 'px'
3165
+ thumbYElem.style.transform = `translateY(${yThumbTop}px)`
3166
+ }
3167
+ }
3168
+
3169
+ const clickTrackXEvent = (evnt: MouseEvent) => {
3170
+ const trackEl = evnt.currentTarget as HTMLDivElement
3171
+ if (trackEl !== evnt.target) {
3172
+ return
3173
+ }
3174
+ const viewEl = refVirtualWrapper.value
3175
+ if (!viewEl) {
3176
+ return
3177
+ }
3178
+ const { xThumbWidth } = reactData
3179
+ const trackRect = trackEl.getBoundingClientRect()
3180
+ viewEl.scrollTo({
3181
+ left: getScrollFromClick(evnt.clientX - trackRect.left, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth),
3182
+ behavior: 'auto'
3183
+ })
3184
+ }
3185
+
3186
+ const clickTrackYEvent = (evnt: MouseEvent) => {
3187
+ const trackEl = evnt.currentTarget as HTMLDivElement
3188
+ if (trackEl !== evnt.target) {
3189
+ return
3190
+ }
3191
+ const viewEl = refVirtualWrapper.value
3192
+ if (!viewEl) {
3193
+ return
3194
+ }
3195
+ const { yThumbHeight } = reactData
3196
+ const trackRect = trackEl.getBoundingClientRect()
3197
+ viewEl.scrollTo({
3198
+ top: getScrollFromClick(evnt.clientY - trackRect.top, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight),
3199
+ behavior: 'auto'
3200
+ })
3201
+ }
3202
+
3203
+ const pointerdownThumbXEvent = (evnt: PointerEvent) => {
3204
+ const thumbEl = evnt.currentTarget as HTMLDivElement
3205
+ internalData.isThumbDrag = true
3206
+ thumbEl.setPointerCapture(evnt.pointerId)
3207
+
3208
+ const viewEl = refVirtualWrapper.value
3209
+ if (!viewEl) {
3210
+ return
3211
+ }
3212
+ const { xThumbWidth } = reactData
3213
+ const trackEl = thumbEl.parentElement as HTMLDivElement
3214
+ const trackRect = trackEl.getBoundingClientRect()
3215
+ const pointerPosition = evnt.clientX - trackRect.left
3216
+ // 记录 thumb 的偏移
3217
+ const thumbOffset = getThumbOffsetSize(viewEl.scrollLeft, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth)
3218
+ internalData.thumbDragOffset = pointerPosition - thumbOffset
3219
+ }
3220
+
3221
+ const pointermoveThumbXEvent = (evnt: PointerEvent) => {
3222
+ const thumbEl = evnt.currentTarget as HTMLDivElement
3223
+ if (!thumbEl.hasPointerCapture(evnt.pointerId)) {
3224
+ return
3225
+ }
3226
+ const { isThumbDrag, thumbDragOffset } = internalData
3227
+ if (isThumbDrag) {
3228
+ const viewEl = refVirtualWrapper.value
3229
+ if (!viewEl) {
3230
+ return
3231
+ }
3232
+ const { xThumbWidth } = reactData
3233
+ const thumbEl = evnt.currentTarget as HTMLDivElement
3234
+ const trackEl = thumbEl.parentElement as HTMLDivElement
3235
+ const trackRect = trackEl.getBoundingClientRect()
3236
+ // 更新偏移
3237
+ viewEl.scrollLeft = getScrollFromDrag(evnt.clientX - trackRect.left, thumbDragOffset, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth)
3238
+ }
3239
+ }
3240
+
3241
+ const cleatPointerThumbEvent = (evnt: PointerEvent) => {
3242
+ const thumbEl = evnt.currentTarget as HTMLDivElement
3243
+ thumbEl.releasePointerCapture(evnt.pointerId)
3244
+ internalData.isThumbDrag = false
3245
+ }
3246
+
3247
+ const pointerdownThumbYEvent = (evnt: PointerEvent) => {
3248
+ const thumbEl = evnt.currentTarget as HTMLDivElement
3249
+ internalData.isThumbDrag = true
3250
+ thumbEl.setPointerCapture(evnt.pointerId)
3251
+
3252
+ const viewEl = refVirtualWrapper.value
3253
+ if (!viewEl) {
3254
+ return
3255
+ }
3256
+ const { yThumbHeight } = reactData
3257
+ const trackEl = thumbEl.parentElement as HTMLDivElement
3258
+ const trackRect = trackEl.getBoundingClientRect()
3259
+ const pointerPosition = evnt.clientY - trackRect.top
3260
+ // 记录 thumb 的偏移
3261
+ const thumbOffset = getThumbOffsetSize(viewEl.scrollTop, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight)
3262
+ internalData.thumbDragOffset = pointerPosition - thumbOffset
3263
+ }
3264
+
3265
+ const pointermoveThumbYEvent = (evnt: PointerEvent) => {
3266
+ const thumbEl = evnt.currentTarget as HTMLDivElement
3267
+ if (!thumbEl.hasPointerCapture(evnt.pointerId)) {
3268
+ return
3269
+ }
3270
+ const { isThumbDrag, thumbDragOffset } = internalData
3271
+ if (isThumbDrag) {
3272
+ const viewEl = refVirtualWrapper.value
3273
+ if (!viewEl) {
3274
+ return
3275
+ }
3276
+ const { yThumbHeight } = reactData
3277
+ const thumbEl = evnt.currentTarget as HTMLDivElement
3278
+ const trackEl = thumbEl.parentElement as HTMLDivElement
3279
+ const trackRect = trackEl.getBoundingClientRect()
3280
+ // 更新偏移
3281
+ viewEl.scrollTop = getScrollFromDrag(evnt.clientY - trackRect.top, thumbDragOffset, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight)
3282
+ }
3283
+ }
3284
+
3000
3285
  Object.assign($xeTree, treeMethods, treePrivateMethods)
3001
3286
 
3002
3287
  const renderDragIcon = (node: any, nodeid: string) => {
@@ -3341,13 +3626,14 @@ export default defineVxeComponent({
3341
3626
  }
3342
3627
 
3343
3628
  const renderVN = () => {
3344
- const { loading, trigger, showLine } = props
3345
- const { bodyHeight, topSpaceHeight, treeList, tooltipStore } = reactData
3629
+ const { loading, trigger, showLine, useScrollbar } = props
3630
+ const { bodyHeight, topSpaceHeight, treeList, tooltipStore, xThumbWidth, yThumbHeight } = reactData
3346
3631
  const vSize = computeSize.value
3347
3632
  const radioOpts = computeRadioOpts.value
3348
3633
  const checkboxOpts = computeCheckboxOpts.value
3349
3634
  const loadingOpts = computeLoadingOpts.value
3350
3635
  const isNodeHover = computeIsNodeHover.value
3636
+ const wrapperStyles = computeWrapperStyles.value
3351
3637
  const treeStyle = computeTreeStyle.value
3352
3638
  const dragOpts = computeDragOpts.value
3353
3639
  const tooltipOpts = computeTooltipOpts.value
@@ -3355,6 +3641,14 @@ export default defineVxeComponent({
3355
3641
  const headerSlot = slots.header
3356
3642
  const footerSlot = slots.footer
3357
3643
  const tooltipSlot = slots.tooltip
3644
+ const scrollbarOpts = computeScrollbarOpts.value
3645
+ const scrollXVisible = computeScrollXVisible.value
3646
+ const scrollYVisible = computeScrollYVisible.value
3647
+ const scrollbarXToTop = computeScrollbarXToTop.value
3648
+ const scrollbarYToLeft = computeScrollbarYToLeft.value
3649
+ const scrollXAutoHide = computeScrollXAutoHide.value
3650
+ const scrollYAutoHide = computeScrollYAutoHide.value
3651
+ const scrollbarWrapperClss = computeScrollbarWrapperClss.value
3358
3652
 
3359
3653
  const teOns: {
3360
3654
  onDragover?: (...args: any[]) => void
@@ -3364,15 +3658,29 @@ export default defineVxeComponent({
3364
3658
  }
3365
3659
  return h('div', {
3366
3660
  ref: refElem,
3367
- class: ['vxe-tree', {
3368
- [`size--${vSize}`]: vSize,
3369
- 'show--line': showLine,
3370
- 'checkbox--highlight': checkboxOpts.highlight,
3371
- 'radio--highlight': radioOpts.highlight,
3372
- 'node--hover': isNodeHover,
3373
- 'node--trigger': trigger === 'node',
3374
- 'is--loading': loading
3375
- }],
3661
+ class: [
3662
+ 'vxe-tree',
3663
+ useScrollbar ? `ov-x--${scrollXVisible === false ? 'hidden' : 'visible'}` : '',
3664
+ useScrollbar ? `ov-y--${scrollYVisible === false ? 'hidden' : 'visible'}` : '',
3665
+ useScrollbar ? `sx-pos--${scrollbarXToTop ? 'top' : 'bottom'}` : '',
3666
+ useScrollbar ? `sy-pos--${scrollbarYToLeft ? 'left' : 'right'}` : '',
3667
+ {
3668
+ [`size--${vSize}`]: vSize,
3669
+ 'show--line': showLine,
3670
+ 'is--virtual-scrollbar': useScrollbar,
3671
+ 'ov-padding': useScrollbar && scrollbarOpts.padding,
3672
+ 'ov-x--auto-hide': useScrollbar && scrollXAutoHide,
3673
+ 'ov-y--auto-hide': useScrollbar && scrollYAutoHide,
3674
+ 'overflow-y': yThumbHeight,
3675
+ 'overflow-x': xThumbWidth,
3676
+ 'checkbox--highlight': checkboxOpts.highlight,
3677
+ 'radio--highlight': radioOpts.highlight,
3678
+ 'node--hover': isNodeHover,
3679
+ 'node--trigger': trigger === 'node',
3680
+ 'is--loading': loading
3681
+ }
3682
+ ],
3683
+ style: wrapperStyles,
3376
3684
  ...teOns
3377
3685
  }, [
3378
3686
  headerSlot
@@ -3407,6 +3715,49 @@ export default defineVxeComponent({
3407
3715
  class: 'vxe-tree--footer-wrapper'
3408
3716
  }, footerSlot({ $tree: $xeTree }))
3409
3717
  : renderEmptyElement($xeTree),
3718
+ /**
3719
+ * 滚动条
3720
+ */
3721
+ useScrollbar
3722
+ ? h('div', {
3723
+ class: scrollbarWrapperClss
3724
+ }, [
3725
+ scrollXVisible === false
3726
+ ? renderEmptyElement($xeTree)
3727
+ : h('div', {
3728
+ ref: refTrackXElem,
3729
+ class: 'vxe-scrollbar--track-x',
3730
+ onClick: clickTrackXEvent
3731
+ }, [
3732
+ h('div', {
3733
+ ref: refThumbXElem,
3734
+ class: 'vxe-scrollbar--thumb-x',
3735
+ onPointerdown: pointerdownThumbXEvent,
3736
+ onPointermove: pointermoveThumbXEvent,
3737
+ onPointerup: cleatPointerThumbEvent,
3738
+ onPointercancel: cleatPointerThumbEvent,
3739
+ onLostpointercapture: cleatPointerThumbEvent
3740
+ })
3741
+ ]),
3742
+ scrollYVisible === false
3743
+ ? renderEmptyElement($xeTree)
3744
+ : h('div', {
3745
+ ref: refTrackYElem,
3746
+ class: 'vxe-scrollbar--track-y',
3747
+ onClick: clickTrackYEvent
3748
+ }, [
3749
+ h('div', {
3750
+ ref: refThumbYElem,
3751
+ class: 'vxe-scrollbar--thumb-y',
3752
+ onPointerdown: pointerdownThumbYEvent,
3753
+ onPointermove: pointermoveThumbYEvent,
3754
+ onPointerup: cleatPointerThumbEvent,
3755
+ onPointercancel: cleatPointerThumbEvent,
3756
+ onLostpointercapture: cleatPointerThumbEvent
3757
+ })
3758
+ ])
3759
+ ])
3760
+ : renderEmptyElement($xeTree),
3410
3761
  /**
3411
3762
  * 拖拽提示
3412
3763
  */
@@ -3495,22 +3846,43 @@ export default defineVxeComponent({
3495
3846
  triggerSearchEvent(new Event('filter'))
3496
3847
  })
3497
3848
 
3498
- const hFlag = ref(0)
3849
+ const reFlag = ref(0)
3499
3850
  watch(() => props.height, () => {
3500
- hFlag.value++
3851
+ reFlag.value++
3501
3852
  })
3502
3853
  watch(() => props.minHeight, () => {
3503
- hFlag.value++
3854
+ reFlag.value++
3504
3855
  })
3505
3856
  watch(() => props.maxHeight, () => {
3506
- hFlag.value++
3857
+ reFlag.value++
3507
3858
  })
3508
- watch(hFlag, () => {
3509
- recalculate()
3859
+ watch(() => props.useScrollbar, () => {
3860
+ reFlag.value++
3861
+ })
3862
+ watch(computeScrollYWidth, () => {
3863
+ reFlag.value++
3864
+ })
3865
+ watch(computeScrollXHeight, () => {
3866
+ reFlag.value++
3867
+ })
3868
+ watch(computeScrollXVisible, () => {
3869
+ nextTick(() => {
3870
+ reFlag.value++
3871
+ })
3872
+ })
3873
+ watch(computeScrollYVisible, () => {
3874
+ nextTick(() => {
3875
+ reFlag.value++
3876
+ })
3877
+ })
3878
+ watch(reFlag, () => {
3879
+ recalculate().then(() => {
3880
+ recalculate()
3881
+ })
3510
3882
  })
3511
3883
 
3512
3884
  onMounted(() => {
3513
- const { transform, drag, menuConfig, showOverflow, lazy, loadMethod } = props
3885
+ const { transform, drag, menuConfig, showOverflow, lazy, loadMethod, autoResize, useScrollbar } = props
3514
3886
  const dragOpts = computeDragOpts.value
3515
3887
  if (!showOverflow) {
3516
3888
  errLog('vxe.error.errProp', ['show-overflow=false', 'show-overflow=true'])
@@ -3531,12 +3903,25 @@ export default defineVxeComponent({
3531
3903
  if (menuConfig && !VxeUIContextMenu) {
3532
3904
  errLog('vxe.error.reqComp', ['vxe-context-menu'])
3533
3905
  }
3534
- if (props.autoResize) {
3535
- const el = refElem.value
3906
+ const el = refElem.value
3907
+ if (useScrollbar || autoResize) {
3908
+ const viewInnerEl = refVirtualBody.value
3909
+ const scrollObserver = globalResize.create(() => {
3910
+ updateScrollbar()
3911
+ })
3912
+ if (el) {
3913
+ scrollObserver.observe(el)
3914
+ }
3915
+ if (viewInnerEl) {
3916
+ scrollObserver.observe(viewInnerEl)
3917
+ }
3918
+ internalData.scrollObserver = scrollObserver
3919
+ }
3920
+ if (autoResize) {
3536
3921
  const parentEl = getParentElem()
3537
3922
  const resizeObserver = globalResize.create(() => {
3538
3923
  if (props.autoResize) {
3539
- recalculate()
3924
+ reFlag.value++
3540
3925
  }
3541
3926
  })
3542
3927
  if (el) {
@@ -3548,15 +3933,20 @@ export default defineVxeComponent({
3548
3933
  internalData.resizeObserver = resizeObserver
3549
3934
  }
3550
3935
 
3551
- recalculate()
3552
- globalEvents.on($xeTree, 'resize', handleGlobalResizeEvent)
3936
+ reFlag.value++
3937
+ globalEvents.on($xeTree, 'resize', () => {
3938
+ reFlag.value++
3939
+ })
3553
3940
  })
3554
3941
 
3555
3942
  onBeforeUnmount(() => {
3556
- const { resizeObserver } = internalData
3943
+ const { scrollObserver, resizeObserver } = internalData
3557
3944
  if (resizeObserver) {
3558
3945
  resizeObserver.disconnect()
3559
3946
  }
3947
+ if (scrollObserver) {
3948
+ scrollObserver.disconnect()
3949
+ }
3560
3950
  globalEvents.off($xeTree, 'resize')
3561
3951
  XEUtils.assign(reactData, createReactData())
3562
3952
  XEUtils.assign(internalData, createInternalData())
@@ -72,3 +72,7 @@ export function enModelValue (nodeid: string | number | null | undefined) {
72
72
  export function deModelValue (nodeid: string | number | null) {
73
73
  return nodeid ? decodeURIComponent(`${nodeid}`) : nodeid
74
74
  }
75
+
76
+ export function getDefaultConfig <T = any, D = any> (val1: T, def1: D): (T | D) {
77
+ return XEUtils.eqNull(val1) ? def1 : val1
78
+ }