vxe-pc-ui 4.18.21 → 4.18.23
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.
- package/dist/all.esm.js +1638 -1048
- package/dist/style.css +1 -1
- package/dist/style.min.css +1 -1
- package/es/components.js +3 -0
- package/es/icon/style.css +1 -1
- package/es/result/src/result.js +1 -1
- package/es/scrollbar/index.js +12 -0
- package/es/scrollbar/src/scrollbar.js +520 -0
- package/es/scrollbar/src/util.js +54 -0
- package/es/scrollbar/style.css +101 -0
- package/es/scrollbar/style.min.css +1 -0
- package/es/style.css +1 -1
- package/es/style.min.css +1 -1
- package/es/ui/index.js +10 -1
- package/es/ui/src/log.js +1 -1
- package/es/upload/style.css +5 -3
- package/es/upload/style.min.css +1 -1
- package/es/vxe-scrollbar/index.js +3 -0
- package/es/vxe-scrollbar/style.css +101 -0
- package/es/vxe-scrollbar/style.min.css +1 -0
- package/es/vxe-upload/style.css +5 -3
- package/es/vxe-upload/style.min.css +1 -1
- package/lib/components.js +13 -1
- package/lib/components.min.js +1 -1
- package/lib/icon/style/style.css +1 -1
- package/lib/icon/style/style.min.css +1 -1
- package/lib/index.umd.js +697 -6
- package/lib/index.umd.min.js +1 -1
- package/lib/result/src/result.js +1 -1
- package/lib/result/src/result.min.js +1 -1
- package/lib/scrollbar/index.js +19 -0
- package/lib/scrollbar/index.min.js +1 -0
- package/lib/scrollbar/src/scrollbar.js +560 -0
- package/lib/scrollbar/src/scrollbar.min.js +1 -0
- package/lib/scrollbar/src/util.js +63 -0
- package/lib/scrollbar/src/util.min.js +1 -0
- package/lib/scrollbar/style/index.js +1 -0
- package/lib/scrollbar/style/style.css +101 -0
- package/lib/scrollbar/style/style.min.css +1 -0
- package/lib/style.css +1 -1
- package/lib/style.min.css +1 -1
- package/lib/ui/index.js +10 -1
- package/lib/ui/index.min.js +1 -1
- package/lib/ui/src/log.js +1 -1
- package/lib/ui/src/log.min.js +1 -1
- package/lib/upload/style/style.css +5 -3
- package/lib/upload/style/style.min.css +1 -1
- package/lib/vxe-scrollbar/index.js +21 -0
- package/lib/vxe-scrollbar/index.min.js +1 -0
- package/lib/vxe-scrollbar/style/index.js +1 -0
- package/lib/vxe-scrollbar/style/style.css +101 -0
- package/lib/vxe-scrollbar/style/style.min.css +1 -0
- package/lib/vxe-upload/style/style.css +5 -3
- package/lib/vxe-upload/style/style.min.css +1 -1
- package/package.json +2 -2
- package/packages/components.ts +3 -0
- package/packages/result/src/result.ts +1 -1
- package/packages/scrollbar/index.ts +16 -0
- package/packages/scrollbar/src/scrollbar.ts +564 -0
- package/packages/scrollbar/src/util.ts +57 -0
- package/packages/ui/index.ts +9 -0
- package/styles/all.scss +1 -0
- package/styles/components/scrollbar.scss +114 -0
- package/styles/components/upload.scss +5 -3
- package/styles/theme/base.scss +5 -0
- package/styles/theme/dark.scss +5 -0
- package/styles/theme/light.scss +5 -0
- package/styles/variable.scss +5 -0
- package/types/all.d.ts +3 -0
- package/types/components/gantt.d.ts +3 -3
- package/types/components/scrollbar.d.ts +216 -0
- package/types/ui/global-config.d.ts +2 -0
- /package/es/icon/{iconfont.1790757619500.ttf → iconfont.1791517860186.ttf} +0 -0
- /package/es/icon/{iconfont.1790757619500.woff → iconfont.1791517860186.woff} +0 -0
- /package/es/icon/{iconfont.1790757619500.woff2 → iconfont.1791517860186.woff2} +0 -0
- /package/es/{iconfont.1790757619500.ttf → iconfont.1791517860186.ttf} +0 -0
- /package/es/{iconfont.1790757619500.woff → iconfont.1791517860186.woff} +0 -0
- /package/es/{iconfont.1790757619500.woff2 → iconfont.1791517860186.woff2} +0 -0
- /package/lib/icon/style/{iconfont.1790757619500.ttf → iconfont.1791517860186.ttf} +0 -0
- /package/lib/icon/style/{iconfont.1790757619500.woff → iconfont.1791517860186.woff} +0 -0
- /package/lib/icon/style/{iconfont.1790757619500.woff2 → iconfont.1791517860186.woff2} +0 -0
- /package/lib/{iconfont.1790757619500.ttf → iconfont.1791517860186.ttf} +0 -0
- /package/lib/{iconfont.1790757619500.woff → iconfont.1791517860186.woff} +0 -0
- /package/lib/{iconfont.1790757619500.woff2 → iconfont.1791517860186.woff2} +0 -0
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
import { ref, h, reactive, computed, PropType, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
|
|
2
|
+
import { defineVxeComponent } from '../../ui/src/comp'
|
|
3
|
+
import XEUtils from 'xe-utils'
|
|
4
|
+
import { VxeUI } from '../../ui'
|
|
5
|
+
import { toCssUnit } from '../../ui/src/dom'
|
|
6
|
+
import { getThumbOffsetSize, getThumbSize, getScrollFromClick, getScrollFromDrag } from './util'
|
|
7
|
+
import VxeLoadingComponent from '../../loading'
|
|
8
|
+
|
|
9
|
+
import type { ScrollbarReactData, ScrollbarInternalData, VxeScrollbarEmits, ScrollbarMethods, ScrollbarPrivateMethods, VxeScrollbarPropTypes, ValueOf, ScrollbarPrivateRef, VxeScrollbarPrivateComputed, VxeScrollbarConstructor, VxeScrollbarPrivateMethods, VxeComponentStyleType } from '../../../types'
|
|
10
|
+
|
|
11
|
+
const { getConfig, createEvent, domUtils, globalResize, renderEmptyElement } = VxeUI
|
|
12
|
+
|
|
13
|
+
function createReactData (): ScrollbarReactData {
|
|
14
|
+
return {
|
|
15
|
+
yThumbHeight: 0,
|
|
16
|
+
xThumbWidth: 0
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function createInternalData (): ScrollbarInternalData {
|
|
21
|
+
return {
|
|
22
|
+
// resizeObserver: undefined,
|
|
23
|
+
// isThumbDrag: false,
|
|
24
|
+
thumbDragOffset: 0,
|
|
25
|
+
yThumbTop: 0,
|
|
26
|
+
xThumbLeft: 0,
|
|
27
|
+
lastScrollTop: 0,
|
|
28
|
+
lastScrollLeft: 0
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default defineVxeComponent({
|
|
33
|
+
name: 'VxeScrollbar',
|
|
34
|
+
props: {
|
|
35
|
+
width: [String, Number] as PropType<VxeScrollbarPropTypes.Width>,
|
|
36
|
+
height: [String, Number] as PropType<VxeScrollbarPropTypes.Height>,
|
|
37
|
+
minWidth: [String, Number] as PropType<VxeScrollbarPropTypes.MinWidth>,
|
|
38
|
+
minHeight: [String, Number] as PropType<VxeScrollbarPropTypes.MinHeight>,
|
|
39
|
+
maxWidth: [String, Number] as PropType<VxeScrollbarPropTypes.MaxWidth>,
|
|
40
|
+
maxHeight: [String, Number] as PropType<VxeScrollbarPropTypes.MaxHeight>,
|
|
41
|
+
loading: Boolean as PropType<VxeScrollbarPropTypes.Loading>,
|
|
42
|
+
native: {
|
|
43
|
+
type: Boolean as PropType<VxeScrollbarPropTypes.Native>,
|
|
44
|
+
default: () => getConfig().scrollbar.native
|
|
45
|
+
},
|
|
46
|
+
xConfig: Object as PropType<VxeScrollbarPropTypes.XConfig>,
|
|
47
|
+
yConfig: Object as PropType<VxeScrollbarPropTypes.YConfig>,
|
|
48
|
+
className: String as PropType<VxeScrollbarPropTypes.ClassName>,
|
|
49
|
+
viewClassName: String as PropType<VxeScrollbarPropTypes.ViewClassName>,
|
|
50
|
+
autoResize: {
|
|
51
|
+
type: Boolean as PropType<VxeScrollbarPropTypes.AutoResize>,
|
|
52
|
+
default: () => getConfig().scrollbar.autoResize
|
|
53
|
+
},
|
|
54
|
+
syncResize: [Boolean, String, Number] as PropType<VxeScrollbarPropTypes.SyncResize>
|
|
55
|
+
},
|
|
56
|
+
emits: [
|
|
57
|
+
'scroll',
|
|
58
|
+
'scroll-boundary'
|
|
59
|
+
] as VxeScrollbarEmits,
|
|
60
|
+
setup (props, context) {
|
|
61
|
+
const { emit, slots } = context
|
|
62
|
+
|
|
63
|
+
const xID = XEUtils.uniqueId()
|
|
64
|
+
|
|
65
|
+
const refElem = ref<HTMLDivElement>()
|
|
66
|
+
const refViewElem = ref<HTMLDivElement>()
|
|
67
|
+
const refViewInnerElem = ref<HTMLDivElement>()
|
|
68
|
+
const refTrackXElem = ref<HTMLDivElement>()
|
|
69
|
+
const refTrackYElem = ref<HTMLDivElement>()
|
|
70
|
+
const refThumbXElem = ref<HTMLDivElement>()
|
|
71
|
+
const refThumbYElem = ref<HTMLDivElement>()
|
|
72
|
+
|
|
73
|
+
const reactData = reactive(createReactData())
|
|
74
|
+
|
|
75
|
+
const internalData = createInternalData()
|
|
76
|
+
|
|
77
|
+
const computeWrapperStyle = computed(() => {
|
|
78
|
+
const { width, height, minWidth, minHeight, maxWidth, maxHeight } = props
|
|
79
|
+
const xOpts = computeXOpts.value
|
|
80
|
+
const yOpts = computeYOpts.value
|
|
81
|
+
const stys: VxeComponentStyleType = {}
|
|
82
|
+
if (width) {
|
|
83
|
+
stys.width = toCssUnit(width)
|
|
84
|
+
}
|
|
85
|
+
if (height) {
|
|
86
|
+
stys.height = toCssUnit(height)
|
|
87
|
+
}
|
|
88
|
+
if (minWidth) {
|
|
89
|
+
stys.minWidth = toCssUnit(minWidth)
|
|
90
|
+
}
|
|
91
|
+
if (minHeight) {
|
|
92
|
+
stys.minHeight = toCssUnit(minHeight)
|
|
93
|
+
}
|
|
94
|
+
if (maxWidth) {
|
|
95
|
+
stys.maxWidth = toCssUnit(maxWidth)
|
|
96
|
+
}
|
|
97
|
+
if (maxHeight) {
|
|
98
|
+
stys.maxHeight = toCssUnit(maxHeight)
|
|
99
|
+
}
|
|
100
|
+
if (yOpts.width) {
|
|
101
|
+
stys['--vxe-ui-scrollbar-y-width'] = toCssUnit(yOpts.width)
|
|
102
|
+
}
|
|
103
|
+
if (xOpts.height) {
|
|
104
|
+
stys['--vxe-ui-scrollbar-x-height'] = toCssUnit(xOpts.height)
|
|
105
|
+
}
|
|
106
|
+
return stys
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
const computeWrapperClss = computed(() => {
|
|
110
|
+
const { native, className } = props
|
|
111
|
+
const xOpts = computeXOpts.value
|
|
112
|
+
const yOpts = computeYOpts.value
|
|
113
|
+
return domUtils.buildClass([
|
|
114
|
+
'vxe-scrollbar',
|
|
115
|
+
`ov-x--${xOpts.visible || 'visible'}`,
|
|
116
|
+
`ov-y--${yOpts.visible || 'visible'}`,
|
|
117
|
+
native ? 'is--native' : 'is--virtual',
|
|
118
|
+
className
|
|
119
|
+
], {
|
|
120
|
+
'ov-x--auto-hide': xOpts.autoHide,
|
|
121
|
+
'ov-y--auto-hide': yOpts.autoHide
|
|
122
|
+
})
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
const computeViewClss = computed(() => {
|
|
126
|
+
const { viewClassName } = props
|
|
127
|
+
return domUtils.buildClass([
|
|
128
|
+
'vxe-scrollbar--view',
|
|
129
|
+
viewClassName
|
|
130
|
+
])
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
const computeXOpts = computed(() => {
|
|
134
|
+
return Object.assign({}, getConfig().scrollbar.xConfig, props.xConfig)
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
const computeYOpts = computed(() => {
|
|
138
|
+
return Object.assign({}, getConfig().scrollbar.yConfig, props.yConfig)
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
const refMaps: ScrollbarPrivateRef = {
|
|
142
|
+
refElem
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const computeMaps: VxeScrollbarPrivateComputed = {
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const $xeScrollbar = {
|
|
149
|
+
xID,
|
|
150
|
+
props,
|
|
151
|
+
context,
|
|
152
|
+
reactData,
|
|
153
|
+
internalData,
|
|
154
|
+
|
|
155
|
+
getRefMaps: () => refMaps,
|
|
156
|
+
getComputeMaps: () => computeMaps
|
|
157
|
+
} as unknown as VxeScrollbarConstructor & VxeScrollbarPrivateMethods
|
|
158
|
+
|
|
159
|
+
const dispatchEvent = (type: ValueOf<VxeScrollbarEmits>, params: Record<string, any>, evnt: Event | null) => {
|
|
160
|
+
emit(type, createEvent(evnt, { $scrollbar: $xeScrollbar }, params))
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const scrollbarMethods: ScrollbarMethods = {
|
|
164
|
+
dispatchEvent,
|
|
165
|
+
scrollTo (left: ScrollToOptions | number, top?: number) {
|
|
166
|
+
const viewEl = refViewElem.value
|
|
167
|
+
if (viewEl) {
|
|
168
|
+
if (XEUtils.isNumber(left)) {
|
|
169
|
+
viewEl.scrollTo(left, top || 0)
|
|
170
|
+
} else {
|
|
171
|
+
viewEl.scrollTo(left)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
scrollIntoView () {
|
|
176
|
+
const viewEl = refViewElem.value
|
|
177
|
+
if (viewEl) {
|
|
178
|
+
viewEl.scrollIntoView()
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
recalculate () {
|
|
182
|
+
updateThumbSize()
|
|
183
|
+
updateThumbOffset()
|
|
184
|
+
return nextTick()
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const updateThumbSize = () => {
|
|
189
|
+
const viewEl = refViewElem.value
|
|
190
|
+
if (!viewEl) {
|
|
191
|
+
return
|
|
192
|
+
}
|
|
193
|
+
const trackXEl = refTrackXElem.value
|
|
194
|
+
const xThumbWidth = trackXEl ? getThumbSize(viewEl.clientWidth, viewEl.scrollWidth, trackXEl.clientWidth) : 0
|
|
195
|
+
const thumbXElem = refThumbXElem.value
|
|
196
|
+
if (thumbXElem) {
|
|
197
|
+
thumbXElem.style.width = xThumbWidth + 'px'
|
|
198
|
+
}
|
|
199
|
+
reactData.xThumbWidth = xThumbWidth
|
|
200
|
+
|
|
201
|
+
const trackYEl = refTrackYElem.value
|
|
202
|
+
const yThumbHeight = trackYEl ? getThumbSize(viewEl.clientHeight, viewEl.scrollHeight, trackYEl.clientHeight) : 0
|
|
203
|
+
const thumbYElem = refThumbYElem.value
|
|
204
|
+
if (thumbYElem) {
|
|
205
|
+
thumbYElem.style.height = yThumbHeight + 'px'
|
|
206
|
+
}
|
|
207
|
+
reactData.yThumbHeight = yThumbHeight
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const updateThumbOffset = () => {
|
|
211
|
+
const viewEl = refViewElem.value
|
|
212
|
+
if (!viewEl) {
|
|
213
|
+
return
|
|
214
|
+
}
|
|
215
|
+
const { xThumbWidth, yThumbHeight } = reactData
|
|
216
|
+
const trackXEl = refTrackXElem.value
|
|
217
|
+
const thumbXElem = refThumbXElem.value
|
|
218
|
+
const xThumbLeft = trackXEl && xThumbWidth ? getThumbOffsetSize(viewEl.scrollLeft, viewEl.clientWidth, viewEl.scrollWidth, trackXEl.clientWidth, xThumbWidth) : 0
|
|
219
|
+
internalData.xThumbLeft = xThumbLeft
|
|
220
|
+
if (thumbXElem && xThumbWidth) {
|
|
221
|
+
thumbXElem.style.width = xThumbWidth + 'px'
|
|
222
|
+
thumbXElem.style.transform = `translateX(${xThumbLeft}px)`
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const trackYEl = refTrackYElem.value
|
|
226
|
+
const thumbYElem = refThumbYElem.value
|
|
227
|
+
const yThumbTop = trackYEl && yThumbHeight ? getThumbOffsetSize(viewEl.scrollTop, viewEl.clientHeight, viewEl.scrollHeight, trackYEl.clientHeight, yThumbHeight) : 0
|
|
228
|
+
internalData.yThumbTop = yThumbTop
|
|
229
|
+
if (thumbYElem && yThumbHeight) {
|
|
230
|
+
thumbYElem.style.height = yThumbHeight + 'px'
|
|
231
|
+
thumbYElem.style.transform = `translateY(${yThumbTop}px)`
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const scrollEvent = (evnt: Event) => {
|
|
236
|
+
const { xThumbWidth, yThumbHeight } = reactData
|
|
237
|
+
const { lastScrollTop, lastScrollLeft } = internalData
|
|
238
|
+
const xOpts = computeXOpts.value
|
|
239
|
+
const yOpts = computeYOpts.value
|
|
240
|
+
const viewEl = evnt.currentTarget as HTMLDivElement
|
|
241
|
+
const { scrollTop, scrollLeft, clientWidth, clientHeight, scrollHeight, scrollWidth } = viewEl
|
|
242
|
+
let direction = ''
|
|
243
|
+
let isTopBoundary = false
|
|
244
|
+
let isBottomBoundary = false
|
|
245
|
+
let isLeftBoundary = false
|
|
246
|
+
let isRightBoundary = false
|
|
247
|
+
if (lastScrollTop !== scrollTop) {
|
|
248
|
+
const yThreshold = XEUtils.toNumber(yOpts.threshold) || 1
|
|
249
|
+
if (lastScrollTop < scrollTop) {
|
|
250
|
+
direction = 'bottom'
|
|
251
|
+
if (yThumbHeight > 0 && scrollTop + clientHeight >= scrollHeight - yThreshold) {
|
|
252
|
+
isBottomBoundary = true
|
|
253
|
+
}
|
|
254
|
+
} else {
|
|
255
|
+
direction = 'top'
|
|
256
|
+
if (yThumbHeight > 0 && scrollTop <= yThreshold) {
|
|
257
|
+
isTopBoundary = true
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (lastScrollLeft !== scrollLeft) {
|
|
262
|
+
const xThreshold = XEUtils.toNumber(xOpts.threshold) || 1
|
|
263
|
+
if (lastScrollLeft < scrollLeft) {
|
|
264
|
+
direction = 'right'
|
|
265
|
+
if (xThumbWidth > 0 && scrollLeft + clientWidth >= scrollWidth - xThreshold) {
|
|
266
|
+
isRightBoundary = true
|
|
267
|
+
}
|
|
268
|
+
} else {
|
|
269
|
+
direction = 'left'
|
|
270
|
+
if (xThumbWidth > 0 && scrollLeft <= xThreshold) {
|
|
271
|
+
isLeftBoundary = true
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
updateThumbOffset()
|
|
276
|
+
internalData.lastScrollTop = scrollTop
|
|
277
|
+
internalData.lastScrollLeft = scrollLeft
|
|
278
|
+
if (isBottomBoundary || isTopBoundary || isRightBoundary || isLeftBoundary) {
|
|
279
|
+
dispatchEvent('scroll-boundary', {
|
|
280
|
+
direction: direction,
|
|
281
|
+
isTop: isTopBoundary,
|
|
282
|
+
isBottom: isBottomBoundary,
|
|
283
|
+
isLeft: isLeftBoundary,
|
|
284
|
+
isRight: isRightBoundary,
|
|
285
|
+
scrollTop: scrollTop,
|
|
286
|
+
scrollLeft: scrollLeft,
|
|
287
|
+
clientWidth: clientWidth,
|
|
288
|
+
clientHeight: clientHeight,
|
|
289
|
+
scrollHeight: scrollHeight,
|
|
290
|
+
scrollWidth: scrollWidth
|
|
291
|
+
}, evnt)
|
|
292
|
+
}
|
|
293
|
+
dispatchEvent('scroll', {
|
|
294
|
+
direction: direction,
|
|
295
|
+
isTop: yThumbHeight > 0 && scrollTop <= 0,
|
|
296
|
+
isBottom: yThumbHeight > 0 && scrollTop + clientHeight >= scrollHeight,
|
|
297
|
+
isLeft: xThumbWidth > 0 && scrollLeft <= 0,
|
|
298
|
+
isRight: xThumbWidth > 0 && scrollLeft + clientWidth >= scrollWidth,
|
|
299
|
+
scrollTop: scrollTop,
|
|
300
|
+
scrollLeft: scrollLeft,
|
|
301
|
+
clientWidth: clientWidth,
|
|
302
|
+
clientHeight: clientHeight,
|
|
303
|
+
scrollHeight: scrollHeight,
|
|
304
|
+
scrollWidth: scrollWidth
|
|
305
|
+
}, evnt)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const clickTrackXEvent = (evnt: MouseEvent) => {
|
|
309
|
+
const trackEl = evnt.currentTarget as HTMLDivElement
|
|
310
|
+
if (trackEl !== evnt.target) {
|
|
311
|
+
return
|
|
312
|
+
}
|
|
313
|
+
const viewEl = refViewElem.value
|
|
314
|
+
if (!viewEl) {
|
|
315
|
+
return
|
|
316
|
+
}
|
|
317
|
+
const { xThumbWidth } = reactData
|
|
318
|
+
const trackRect = trackEl.getBoundingClientRect()
|
|
319
|
+
viewEl.scrollTo({
|
|
320
|
+
left: getScrollFromClick(evnt.clientX - trackRect.left, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth),
|
|
321
|
+
behavior: 'auto'
|
|
322
|
+
})
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const clickTrackYEvent = (evnt: MouseEvent) => {
|
|
326
|
+
const trackEl = evnt.currentTarget as HTMLDivElement
|
|
327
|
+
if (trackEl !== evnt.target) {
|
|
328
|
+
return
|
|
329
|
+
}
|
|
330
|
+
const viewEl = refViewElem.value
|
|
331
|
+
if (!viewEl) {
|
|
332
|
+
return
|
|
333
|
+
}
|
|
334
|
+
const { yThumbHeight } = reactData
|
|
335
|
+
const trackRect = trackEl.getBoundingClientRect()
|
|
336
|
+
viewEl.scrollTo({
|
|
337
|
+
top: getScrollFromClick(evnt.clientY - trackRect.top, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight),
|
|
338
|
+
behavior: 'auto'
|
|
339
|
+
})
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const pointerdownThumbXEvent = (evnt: PointerEvent) => {
|
|
343
|
+
const thumbEl = evnt.currentTarget as HTMLDivElement
|
|
344
|
+
internalData.isThumbDrag = true
|
|
345
|
+
thumbEl.setPointerCapture(evnt.pointerId)
|
|
346
|
+
|
|
347
|
+
const viewEl = refViewElem.value
|
|
348
|
+
if (!viewEl) {
|
|
349
|
+
return
|
|
350
|
+
}
|
|
351
|
+
const { xThumbWidth } = reactData
|
|
352
|
+
const trackEl = thumbEl.parentElement as HTMLDivElement
|
|
353
|
+
const trackRect = trackEl.getBoundingClientRect()
|
|
354
|
+
const pointerPosition = evnt.clientX - trackRect.left
|
|
355
|
+
// 记录 thumb 的偏移
|
|
356
|
+
const thumbOffset = getThumbOffsetSize(viewEl.scrollLeft, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth)
|
|
357
|
+
internalData.thumbDragOffset = pointerPosition - thumbOffset
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const pointermoveThumbXEvent = (evnt: PointerEvent) => {
|
|
361
|
+
const thumbEl = evnt.currentTarget as HTMLDivElement
|
|
362
|
+
if (!thumbEl.hasPointerCapture(evnt.pointerId)) {
|
|
363
|
+
return
|
|
364
|
+
}
|
|
365
|
+
const { isThumbDrag, thumbDragOffset } = internalData
|
|
366
|
+
if (isThumbDrag) {
|
|
367
|
+
const viewEl = refViewElem.value
|
|
368
|
+
if (!viewEl) {
|
|
369
|
+
return
|
|
370
|
+
}
|
|
371
|
+
const { xThumbWidth } = reactData
|
|
372
|
+
const thumbEl = evnt.currentTarget as HTMLDivElement
|
|
373
|
+
const trackEl = thumbEl.parentElement as HTMLDivElement
|
|
374
|
+
const trackRect = trackEl.getBoundingClientRect()
|
|
375
|
+
// 更新偏移
|
|
376
|
+
viewEl.scrollLeft = getScrollFromDrag(evnt.clientX - trackRect.left, thumbDragOffset, viewEl.clientWidth, viewEl.scrollWidth, trackEl.clientWidth, xThumbWidth)
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const cleatPointerThumbEvent = (evnt: PointerEvent) => {
|
|
381
|
+
const thumbEl = evnt.currentTarget as HTMLDivElement
|
|
382
|
+
thumbEl.releasePointerCapture(evnt.pointerId)
|
|
383
|
+
internalData.isThumbDrag = false
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const pointerdownThumbYEvent = (evnt: PointerEvent) => {
|
|
387
|
+
const thumbEl = evnt.currentTarget as HTMLDivElement
|
|
388
|
+
internalData.isThumbDrag = true
|
|
389
|
+
thumbEl.setPointerCapture(evnt.pointerId)
|
|
390
|
+
|
|
391
|
+
const viewEl = refViewElem.value
|
|
392
|
+
if (!viewEl) {
|
|
393
|
+
return
|
|
394
|
+
}
|
|
395
|
+
const { yThumbHeight } = reactData
|
|
396
|
+
const trackEl = thumbEl.parentElement as HTMLDivElement
|
|
397
|
+
const trackRect = trackEl.getBoundingClientRect()
|
|
398
|
+
const pointerPosition = evnt.clientY - trackRect.top
|
|
399
|
+
// 记录 thumb 的偏移
|
|
400
|
+
const thumbOffset = getThumbOffsetSize(viewEl.scrollTop, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight)
|
|
401
|
+
internalData.thumbDragOffset = pointerPosition - thumbOffset
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const pointermoveThumbYEvent = (evnt: PointerEvent) => {
|
|
405
|
+
const thumbEl = evnt.currentTarget as HTMLDivElement
|
|
406
|
+
if (!thumbEl.hasPointerCapture(evnt.pointerId)) {
|
|
407
|
+
return
|
|
408
|
+
}
|
|
409
|
+
const { isThumbDrag, thumbDragOffset } = internalData
|
|
410
|
+
if (isThumbDrag) {
|
|
411
|
+
const viewEl = refViewElem.value
|
|
412
|
+
if (!viewEl) {
|
|
413
|
+
return
|
|
414
|
+
}
|
|
415
|
+
const { yThumbHeight } = reactData
|
|
416
|
+
const thumbEl = evnt.currentTarget as HTMLDivElement
|
|
417
|
+
const trackEl = thumbEl.parentElement as HTMLDivElement
|
|
418
|
+
const trackRect = trackEl.getBoundingClientRect()
|
|
419
|
+
// 更新偏移
|
|
420
|
+
viewEl.scrollTop = getScrollFromDrag(evnt.clientY - trackRect.top, thumbDragOffset, viewEl.clientHeight, viewEl.scrollHeight, trackEl.clientHeight, yThumbHeight)
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const scrollbarPrivateMethods: ScrollbarPrivateMethods = {
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
Object.assign($xeScrollbar, scrollbarMethods, scrollbarPrivateMethods)
|
|
428
|
+
|
|
429
|
+
const renderVN = () => {
|
|
430
|
+
const { native, loading, autoResize } = props
|
|
431
|
+
const wrapperStyle = computeWrapperStyle.value
|
|
432
|
+
const wrapperClss = computeWrapperClss.value
|
|
433
|
+
const viewClss = computeViewClss.value
|
|
434
|
+
const xOpts = computeXOpts.value
|
|
435
|
+
const yOpts = computeYOpts.value
|
|
436
|
+
const defaultSlot = slots.default
|
|
437
|
+
return h('div', {
|
|
438
|
+
ref: refElem,
|
|
439
|
+
class: wrapperClss,
|
|
440
|
+
style: wrapperStyle
|
|
441
|
+
}, [
|
|
442
|
+
h('div', {
|
|
443
|
+
ref: refViewElem,
|
|
444
|
+
class: viewClss,
|
|
445
|
+
onScroll: scrollEvent
|
|
446
|
+
}, autoResize
|
|
447
|
+
? [
|
|
448
|
+
h('div', {
|
|
449
|
+
key: 'vi',
|
|
450
|
+
ref: refViewInnerElem,
|
|
451
|
+
class: 'vxe-scrollbar--view-inner'
|
|
452
|
+
}, defaultSlot ? defaultSlot({}) : [])
|
|
453
|
+
]
|
|
454
|
+
: defaultSlot ? defaultSlot({}) : []),
|
|
455
|
+
native || xOpts.visible === 'hidden'
|
|
456
|
+
? renderEmptyElement($xeScrollbar)
|
|
457
|
+
: h('div', {
|
|
458
|
+
ref: refTrackXElem,
|
|
459
|
+
class: 'vxe-scrollbar--track-x',
|
|
460
|
+
onClick: clickTrackXEvent
|
|
461
|
+
}, [
|
|
462
|
+
h('div', {
|
|
463
|
+
ref: refThumbXElem,
|
|
464
|
+
class: 'vxe-scrollbar--thumb-x',
|
|
465
|
+
onPointerdown: pointerdownThumbXEvent,
|
|
466
|
+
onPointermove: pointermoveThumbXEvent,
|
|
467
|
+
onPointerup: cleatPointerThumbEvent,
|
|
468
|
+
onPointercancel: cleatPointerThumbEvent,
|
|
469
|
+
onLostpointercapture: cleatPointerThumbEvent
|
|
470
|
+
})
|
|
471
|
+
]),
|
|
472
|
+
native || yOpts.visible === 'hidden'
|
|
473
|
+
? renderEmptyElement($xeScrollbar)
|
|
474
|
+
: h('div', {
|
|
475
|
+
ref: refTrackYElem,
|
|
476
|
+
class: 'vxe-scrollbar--track-y',
|
|
477
|
+
onClick: clickTrackYEvent
|
|
478
|
+
}, [
|
|
479
|
+
h('div', {
|
|
480
|
+
ref: refThumbYElem,
|
|
481
|
+
class: 'vxe-scrollbar--thumb-y',
|
|
482
|
+
onPointerdown: pointerdownThumbYEvent,
|
|
483
|
+
onPointermove: pointermoveThumbYEvent,
|
|
484
|
+
onPointerup: cleatPointerThumbEvent,
|
|
485
|
+
onPointercancel: cleatPointerThumbEvent,
|
|
486
|
+
onLostpointercapture: cleatPointerThumbEvent
|
|
487
|
+
})
|
|
488
|
+
]),
|
|
489
|
+
h(VxeLoadingComponent, {
|
|
490
|
+
class: 'vxe-scrollbar--loading',
|
|
491
|
+
modelValue: loading
|
|
492
|
+
})
|
|
493
|
+
])
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
const reFlag = ref(0)
|
|
497
|
+
|
|
498
|
+
watch(() => props.height, () => {
|
|
499
|
+
reFlag.value++
|
|
500
|
+
})
|
|
501
|
+
watch(() => props.width, () => {
|
|
502
|
+
reFlag.value++
|
|
503
|
+
})
|
|
504
|
+
watch(() => props.minHeight, () => {
|
|
505
|
+
reFlag.value++
|
|
506
|
+
})
|
|
507
|
+
watch(() => props.minWidth, () => {
|
|
508
|
+
reFlag.value++
|
|
509
|
+
})
|
|
510
|
+
watch(() => props.maxHeight, () => {
|
|
511
|
+
reFlag.value++
|
|
512
|
+
})
|
|
513
|
+
watch(() => props.maxWidth, () => {
|
|
514
|
+
reFlag.value++
|
|
515
|
+
})
|
|
516
|
+
watch(() => props.native, () => {
|
|
517
|
+
reFlag.value++
|
|
518
|
+
})
|
|
519
|
+
watch(() => props.syncResize, () => {
|
|
520
|
+
reFlag.value++
|
|
521
|
+
})
|
|
522
|
+
watch(reFlag, () => {
|
|
523
|
+
$xeScrollbar.recalculate().then(() => {
|
|
524
|
+
$xeScrollbar.recalculate()
|
|
525
|
+
})
|
|
526
|
+
})
|
|
527
|
+
|
|
528
|
+
onMounted(() => {
|
|
529
|
+
const { autoResize } = props
|
|
530
|
+
const viewEl = refViewElem.value
|
|
531
|
+
const viewInnerEl = refViewInnerElem.value
|
|
532
|
+
if (autoResize) {
|
|
533
|
+
const resizeObserver = globalResize.create(() => {
|
|
534
|
+
if (props.autoResize) {
|
|
535
|
+
reFlag.value++
|
|
536
|
+
}
|
|
537
|
+
})
|
|
538
|
+
if (viewEl) {
|
|
539
|
+
resizeObserver.observe(viewEl)
|
|
540
|
+
}
|
|
541
|
+
if (viewInnerEl) {
|
|
542
|
+
resizeObserver.observe(viewInnerEl)
|
|
543
|
+
}
|
|
544
|
+
internalData.resizeObserver = resizeObserver
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
reFlag.value++
|
|
548
|
+
})
|
|
549
|
+
|
|
550
|
+
onBeforeUnmount(() => {
|
|
551
|
+
const { resizeObserver } = internalData
|
|
552
|
+
if (resizeObserver) {
|
|
553
|
+
resizeObserver.disconnect()
|
|
554
|
+
}
|
|
555
|
+
})
|
|
556
|
+
|
|
557
|
+
$xeScrollbar.renderVN = renderVN
|
|
558
|
+
|
|
559
|
+
return $xeScrollbar
|
|
560
|
+
},
|
|
561
|
+
render () {
|
|
562
|
+
return this.renderVN()
|
|
563
|
+
}
|
|
564
|
+
})
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 计算滚动条滑块的长度
|
|
3
|
+
*/
|
|
4
|
+
export function getThumbSize (viewportSize: number, contentSize: number, trackSize: number) {
|
|
5
|
+
if (contentSize <= viewportSize) {
|
|
6
|
+
return 0
|
|
7
|
+
}
|
|
8
|
+
const ratio = viewportSize / contentSize
|
|
9
|
+
const ideal = trackSize * ratio
|
|
10
|
+
return Math.max(20, Math.min(ideal, trackSize))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 计算滚动条滑块的偏移位置
|
|
15
|
+
*/
|
|
16
|
+
export function getThumbOffsetSize (offsetSize: number, viewportSize: number, contentSize: number, trackSize: number, thumbSize: number) {
|
|
17
|
+
const maxScroll = contentSize - viewportSize
|
|
18
|
+
if (maxScroll <= 0) {
|
|
19
|
+
return 0
|
|
20
|
+
}
|
|
21
|
+
const maxThumbOffset = trackSize - thumbSize
|
|
22
|
+
if (maxThumbOffset <= 0) {
|
|
23
|
+
return 0
|
|
24
|
+
}
|
|
25
|
+
const clamped = Math.min(Math.max(offsetSize, 0), maxScroll)
|
|
26
|
+
const ratio = clamped / maxScroll
|
|
27
|
+
return ratio * maxThumbOffset
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 根据点击轨道的位置,计算滑块的偏移位置
|
|
32
|
+
*/
|
|
33
|
+
export function getScrollFromClick (clickPosition: number, viewportSize: number, contentSize: number, trackSize: number, thumbSize: number) {
|
|
34
|
+
const maxThumbOffset = trackSize - thumbSize
|
|
35
|
+
const maxScroll = contentSize - viewportSize
|
|
36
|
+
if (maxScroll <= 0 || maxThumbOffset <= 0) {
|
|
37
|
+
return 0
|
|
38
|
+
}
|
|
39
|
+
let thumbOffset = clickPosition - thumbSize / 2
|
|
40
|
+
thumbOffset = Math.min(Math.max(thumbOffset, 0), maxThumbOffset)
|
|
41
|
+
const scrollOffset = (thumbOffset / maxThumbOffset) * maxScroll
|
|
42
|
+
return scrollOffset
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 拖拽 thumb 时,根据鼠标位置计算滑块的偏移位置
|
|
47
|
+
*/
|
|
48
|
+
export function getScrollFromDrag (pointerPosition: number, dragOffset: number, viewportSize: number, contentSize: number, trackSize: number, thumbSize: number) {
|
|
49
|
+
const maxScroll = contentSize - viewportSize
|
|
50
|
+
const maxThumbOffset = trackSize - thumbSize
|
|
51
|
+
if (maxScroll <= 0 || maxThumbOffset <= 0) {
|
|
52
|
+
return 0
|
|
53
|
+
}
|
|
54
|
+
let thumbOffset = pointerPosition - dragOffset
|
|
55
|
+
thumbOffset = Math.min(Math.max(thumbOffset, 0), maxThumbOffset)
|
|
56
|
+
return (thumbOffset / maxThumbOffset) * maxScroll
|
|
57
|
+
}
|
package/packages/ui/index.ts
CHANGED
|
@@ -353,6 +353,15 @@ setConfig({
|
|
|
353
353
|
rate: {},
|
|
354
354
|
result: {},
|
|
355
355
|
row: {},
|
|
356
|
+
scrollbar: {
|
|
357
|
+
autoResize: true,
|
|
358
|
+
xConfig: {
|
|
359
|
+
// visible: 'visible'
|
|
360
|
+
},
|
|
361
|
+
yConfig: {
|
|
362
|
+
// visible: 'visible'
|
|
363
|
+
}
|
|
364
|
+
},
|
|
356
365
|
segmented: {},
|
|
357
366
|
select: {
|
|
358
367
|
emptyValue: null,
|
package/styles/all.scss
CHANGED