@veltra/desktop 1.1.12 → 1.1.14
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/components/batch-edit/batch-edit.js +1 -1
- package/dist/components/batch-edit/batch-edit.js.map +1 -1
- package/dist/components/batch-edit/style2.css +7 -1
- package/dist/components/cascade/cascade.vue.d.ts +1 -1
- package/dist/components/file-viewer/file-viewer.js +62 -19
- package/dist/components/file-viewer/file-viewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/image-previewer.js +3 -2
- package/dist/components/file-viewer/previewers/image-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/pdf-previewer.js +60 -17
- package/dist/components/file-viewer/previewers/pdf-previewer.js.map +1 -1
- package/dist/components/file-viewer/previewers/pdf-viewport-scroll.js +83 -0
- package/dist/components/file-viewer/previewers/pdf-viewport-scroll.js.map +1 -0
- package/dist/components/file-viewer/previewers/pdf-zoom-bridge.js +32 -0
- package/dist/components/file-viewer/previewers/pdf-zoom-bridge.js.map +1 -0
- package/dist/components/file-viewer/style2.css +14 -1
- package/dist/components/multi-select/multi-select.vue.d.ts +1 -1
- package/dist/components/multi-tree-select/multi-tree-select.vue.d.ts +1 -1
- package/dist/components/scroll/scroll.js +94 -30
- package/dist/components/scroll/scroll.js.map +1 -1
- package/dist/components/scroll/style2.css +22 -0
- package/dist/components/tabs/tabs-horizontal.vue.d.ts +2 -2
- package/dist/components/tabs/tabs-vertical.vue.d.ts +2 -2
- package/dist/components/tabs/tabs.vue.d.ts +2 -2
- package/dist/components/tree/tree.vue.d.ts +1 -1
- package/dist/components/tree-select/tree-select.vue.d.ts +1 -1
- package/dist/types/scroll.d.ts +6 -1
- package/package.json +12 -11
- package/src/components/batch-edit/batch-edit.vue +1 -1
- package/src/components/batch-edit/style.scss +9 -1
- package/src/components/file-viewer/file-viewer.vue +73 -16
- package/src/components/file-viewer/previewers/image-previewer.vue +1 -0
- package/src/components/file-viewer/previewers/pdf-previewer.vue +67 -14
- package/src/components/file-viewer/previewers/pdf-viewport-scroll.vue +112 -0
- package/src/components/file-viewer/previewers/pdf-zoom-bridge.vue +33 -0
- package/src/components/file-viewer/style.scss +16 -1
- package/src/components/scroll/scroll.vue +124 -75
- package/src/components/scroll/style.scss +22 -0
- package/src/types/scroll.ts +7 -1
|
@@ -1,23 +1,35 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="className" :style="style" ref="scrollRef">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
<component
|
|
10
|
-
ref="contentRef"
|
|
11
|
-
:style="contentStyle"
|
|
12
|
-
:class="[cls.e('content'), contentClass]"
|
|
13
|
-
:is="tag"
|
|
3
|
+
<template v-if="!isExternal">
|
|
4
|
+
<div
|
|
5
|
+
ref="containerRef"
|
|
6
|
+
:class="[cls.e('container'), containerClass]"
|
|
7
|
+
@scroll.passive="handleScroll"
|
|
8
|
+
:style="containerStyle"
|
|
14
9
|
>
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
<component
|
|
11
|
+
ref="contentRef"
|
|
12
|
+
:style="contentStyle"
|
|
13
|
+
:class="[cls.e('content'), contentClass]"
|
|
14
|
+
:is="tag"
|
|
15
|
+
>
|
|
16
|
+
<slot />
|
|
17
|
+
</component>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<u-scroll-bar type="y" :class="cls.e('bar-y')" @drag="handleDragY" ref="barY" />
|
|
21
|
+
<u-scroll-bar type="x" :class="cls.e('bar-x')" @drag="handleDragX" ref="barX" />
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<template v-else>
|
|
25
|
+
<slot />
|
|
26
|
+
<Teleport v-if="externalTarget" :to="externalTarget">
|
|
27
|
+
<div ref="overlayRef" :class="cls.e('overlay')">
|
|
28
|
+
<u-scroll-bar type="y" :class="cls.e('bar-y')" @drag="handleDragY" ref="barY" />
|
|
29
|
+
<u-scroll-bar type="x" :class="cls.e('bar-x')" @drag="handleDragX" ref="barX" />
|
|
30
|
+
</div>
|
|
31
|
+
</Teleport>
|
|
32
|
+
</template>
|
|
21
33
|
</div>
|
|
22
34
|
</template>
|
|
23
35
|
|
|
@@ -25,7 +37,15 @@
|
|
|
25
37
|
import { debounce } from '@cat-kit/core'
|
|
26
38
|
import { useResizeObserver } from '@veltra/compositions'
|
|
27
39
|
import { bem, withUnit } from '@veltra/utils'
|
|
28
|
-
import {
|
|
40
|
+
import {
|
|
41
|
+
type CSSProperties,
|
|
42
|
+
computed,
|
|
43
|
+
onBeforeUnmount,
|
|
44
|
+
provide,
|
|
45
|
+
shallowRef,
|
|
46
|
+
toValue,
|
|
47
|
+
watch
|
|
48
|
+
} from 'vue'
|
|
29
49
|
|
|
30
50
|
import type { ScrollPosition, _ScrollExposed, ScrollProps, ScrollEmits } from '../../types'
|
|
31
51
|
import { ScrollDIKey } from './di'
|
|
@@ -49,24 +69,26 @@ defineSlots<{
|
|
|
49
69
|
}>()
|
|
50
70
|
|
|
51
71
|
const cls = bem('scroll')
|
|
72
|
+
|
|
73
|
+
const isExternal = computed(() => props.target !== undefined)
|
|
74
|
+
|
|
75
|
+
const externalTarget = computed(() => (isExternal.value ? toValue(props.target) : null))
|
|
76
|
+
|
|
52
77
|
const className = computed(() => {
|
|
53
|
-
return [cls.b, bem.is('always', props.always)]
|
|
78
|
+
return [cls.b, bem.is('always', props.always), bem.is('external', isExternal.value)]
|
|
54
79
|
})
|
|
55
80
|
|
|
56
|
-
// 样式-------------------------------------------------------------
|
|
57
81
|
const style = computed<CSSProperties>(() => {
|
|
82
|
+
if (isExternal.value) return {}
|
|
58
83
|
return {
|
|
59
84
|
height: withUnit(props.height, 'px')
|
|
60
85
|
}
|
|
61
86
|
})
|
|
62
87
|
|
|
63
|
-
// 模板引用------------------------------------------------
|
|
64
|
-
/** 内容引用 */
|
|
65
88
|
const contentRef = shallowRef<HTMLElement>()
|
|
66
|
-
/** 滚动根元素引用 */
|
|
67
89
|
const scrollRef = shallowRef<HTMLElement>()
|
|
68
|
-
/** 容器引用 */
|
|
69
90
|
const containerRef = shallowRef<HTMLElement>()
|
|
91
|
+
const overlayRef = shallowRef<HTMLElement>()
|
|
70
92
|
const barX = shallowRef<InstanceType<typeof UScrollBar>>()
|
|
71
93
|
const barY = shallowRef<InstanceType<typeof UScrollBar>>()
|
|
72
94
|
const minSize = 20
|
|
@@ -76,40 +98,28 @@ const trackSize = {
|
|
|
76
98
|
height: 0
|
|
77
99
|
}
|
|
78
100
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
trackSize.width = clientWidth
|
|
86
|
-
trackSize.height = clientHeight
|
|
101
|
+
function getScrollContainer(): HTMLElement | undefined {
|
|
102
|
+
if (isExternal.value) {
|
|
103
|
+
return externalTarget.value ?? undefined
|
|
104
|
+
}
|
|
105
|
+
return containerRef.value
|
|
106
|
+
}
|
|
87
107
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
108
|
+
function syncTrackSize() {
|
|
109
|
+
const container = getScrollContainer()
|
|
110
|
+
if (!container) return
|
|
91
111
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
})
|
|
112
|
+
trackSize.width = container.clientWidth
|
|
113
|
+
trackSize.height = container.clientHeight
|
|
114
|
+
barX.value?.setTrackSize(trackSize.width)
|
|
115
|
+
barY.value?.setTrackSize(trackSize.height)
|
|
116
|
+
}
|
|
99
117
|
|
|
100
|
-
// 更新滚动条
|
|
101
118
|
const updateBar = () => {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const {
|
|
105
|
-
scrollHeight,
|
|
106
|
-
clientHeight,
|
|
107
|
-
scrollTop,
|
|
119
|
+
const container = getScrollContainer()
|
|
120
|
+
if (!container) return
|
|
108
121
|
|
|
109
|
-
|
|
110
|
-
clientWidth,
|
|
111
|
-
scrollLeft
|
|
112
|
-
} = containerRef.value
|
|
122
|
+
const { scrollHeight, clientHeight, scrollTop, scrollWidth, clientWidth, scrollLeft } = container
|
|
113
123
|
|
|
114
124
|
emit('scroll', {
|
|
115
125
|
x: scrollLeft,
|
|
@@ -122,9 +132,7 @@ const updateBar = () => {
|
|
|
122
132
|
|
|
123
133
|
if (scrollHeight !== clientHeight) {
|
|
124
134
|
const barYHeight = Math.max((clientHeight / scrollHeight) * trackSize.height, minSize)
|
|
125
|
-
|
|
126
135
|
const barYTop = (scrollTop / (scrollHeight - clientHeight)) * (trackSize.height - barYHeight)
|
|
127
|
-
|
|
128
136
|
barY.value?.update(barYHeight, barYTop)
|
|
129
137
|
} else {
|
|
130
138
|
barY.value?.update(0, 0)
|
|
@@ -132,21 +140,18 @@ const updateBar = () => {
|
|
|
132
140
|
|
|
133
141
|
if (scrollWidth !== clientWidth) {
|
|
134
142
|
const barXWidth = Math.max((clientWidth / scrollWidth) * trackSize.width, minSize)
|
|
135
|
-
|
|
136
143
|
const barXLeft = (scrollLeft / (scrollWidth - clientWidth)) * (trackSize.width - barXWidth)
|
|
137
|
-
|
|
138
144
|
barX.value?.update(barXWidth, barXLeft)
|
|
139
145
|
} else {
|
|
140
146
|
barX.value?.update(0, 0)
|
|
141
147
|
}
|
|
142
148
|
}
|
|
143
149
|
|
|
144
|
-
// 滚动条拖拽
|
|
145
150
|
const handleDragX = debounce(
|
|
146
151
|
(offset: number, size: number) => {
|
|
147
|
-
const container =
|
|
152
|
+
const container = getScrollContainer()
|
|
153
|
+
if (!container) return
|
|
148
154
|
const { clientWidth, scrollWidth } = container
|
|
149
|
-
|
|
150
155
|
container.scrollLeft = (offset / (trackSize.width - size)) * (scrollWidth - clientWidth)
|
|
151
156
|
},
|
|
152
157
|
props.dragDebounce ?? 0,
|
|
@@ -155,7 +160,8 @@ const handleDragX = debounce(
|
|
|
155
160
|
|
|
156
161
|
const handleDragY = debounce(
|
|
157
162
|
(offset: number, size: number) => {
|
|
158
|
-
const container =
|
|
163
|
+
const container = getScrollContainer()
|
|
164
|
+
if (!container) return
|
|
159
165
|
const { clientHeight, scrollHeight } = container
|
|
160
166
|
container.scrollTop = (offset / (trackSize.height - size)) * (scrollHeight - clientHeight)
|
|
161
167
|
},
|
|
@@ -163,28 +169,61 @@ const handleDragY = debounce(
|
|
|
163
169
|
false
|
|
164
170
|
)
|
|
165
171
|
|
|
166
|
-
|
|
167
|
-
const handleScroll = (e) => {
|
|
172
|
+
const handleScroll = () => {
|
|
168
173
|
updateBar()
|
|
169
174
|
}
|
|
170
175
|
|
|
171
|
-
|
|
176
|
+
useResizeObserver({
|
|
177
|
+
targets: [contentRef, scrollRef, () => externalTarget.value ?? null],
|
|
178
|
+
onResize: (entries) => {
|
|
179
|
+
syncTrackSize()
|
|
180
|
+
updateBar()
|
|
181
|
+
if (entries.length) {
|
|
182
|
+
emit(
|
|
183
|
+
'resize',
|
|
184
|
+
entries.map((entry) => entry.target as HTMLElement)
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
let detachExternalScroll: (() => void) | undefined
|
|
191
|
+
|
|
192
|
+
watch(
|
|
193
|
+
externalTarget,
|
|
194
|
+
(el, _, onCleanup) => {
|
|
195
|
+
detachExternalScroll?.()
|
|
196
|
+
detachExternalScroll = undefined
|
|
197
|
+
if (!el || !isExternal.value) return
|
|
198
|
+
|
|
199
|
+
const onScroll = () => updateBar()
|
|
200
|
+
el.addEventListener('scroll', onScroll, { passive: true })
|
|
201
|
+
detachExternalScroll = () => el.removeEventListener('scroll', onScroll)
|
|
202
|
+
syncTrackSize()
|
|
203
|
+
updateBar()
|
|
204
|
+
|
|
205
|
+
onCleanup(() => {
|
|
206
|
+
detachExternalScroll?.()
|
|
207
|
+
detachExternalScroll = undefined
|
|
208
|
+
})
|
|
209
|
+
},
|
|
210
|
+
{ immediate: true }
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
onBeforeUnmount(() => {
|
|
214
|
+
detachExternalScroll?.()
|
|
215
|
+
})
|
|
216
|
+
|
|
172
217
|
const scrollToLeft = (left: number) => {
|
|
173
|
-
const container =
|
|
218
|
+
const container = getScrollContainer()
|
|
174
219
|
if (!container) return
|
|
175
|
-
|
|
176
|
-
container.scrollTo({
|
|
177
|
-
left
|
|
178
|
-
})
|
|
220
|
+
container.scrollTo({ left })
|
|
179
221
|
}
|
|
180
222
|
|
|
181
223
|
const scrollToTop = (top: number) => {
|
|
182
|
-
const container =
|
|
224
|
+
const container = getScrollContainer()
|
|
183
225
|
if (!container) return
|
|
184
|
-
|
|
185
|
-
container.scrollTo({
|
|
186
|
-
top
|
|
187
|
-
})
|
|
226
|
+
container.scrollTo({ top })
|
|
188
227
|
}
|
|
189
228
|
|
|
190
229
|
const scrollTo = (position: ScrollPosition) => {
|
|
@@ -196,10 +235,20 @@ provide(ScrollDIKey, {
|
|
|
196
235
|
cls
|
|
197
236
|
})
|
|
198
237
|
|
|
238
|
+
const activeContainerRef = shallowRef<HTMLElement>()
|
|
239
|
+
|
|
240
|
+
watch(
|
|
241
|
+
[isExternal, externalTarget, containerRef],
|
|
242
|
+
() => {
|
|
243
|
+
activeContainerRef.value = getScrollContainer()
|
|
244
|
+
},
|
|
245
|
+
{ immediate: true }
|
|
246
|
+
)
|
|
247
|
+
|
|
199
248
|
const exposed: _ScrollExposed = {
|
|
200
249
|
el: scrollRef,
|
|
201
250
|
contentRef,
|
|
202
|
-
containerRef,
|
|
251
|
+
containerRef: activeContainerRef,
|
|
203
252
|
scrollTo,
|
|
204
253
|
update: updateBar
|
|
205
254
|
}
|
|
@@ -12,6 +12,28 @@ $root-name: scroll;
|
|
|
12
12
|
overflow: hidden;
|
|
13
13
|
scroll-behavior: auto;
|
|
14
14
|
|
|
15
|
+
@include m.is(external) {
|
|
16
|
+
display: contents;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@include m.e(overlay) {
|
|
20
|
+
position: absolute;
|
|
21
|
+
inset: 0;
|
|
22
|
+
overflow: hidden;
|
|
23
|
+
pointer-events: none;
|
|
24
|
+
z-index: 2;
|
|
25
|
+
|
|
26
|
+
@include m.bem($root-name, (bar-x, bar-y)) {
|
|
27
|
+
pointer-events: auto;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&:hover > {
|
|
31
|
+
@include m.bem($root-name, (bar-x, bar-y)) {
|
|
32
|
+
opacity: 1;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
15
37
|
// 滚动容器
|
|
16
38
|
@include m.e(container) {
|
|
17
39
|
overflow: auto;
|
package/src/types/scroll.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DeconstructValue } from '@veltra/utils'
|
|
2
|
-
import type { CSSProperties, ShallowRef } from 'vue'
|
|
2
|
+
import type { CSSProperties, MaybeRefOrGetter, ShallowRef } from 'vue'
|
|
3
3
|
|
|
4
4
|
export type ScrollPosition = {
|
|
5
5
|
/** 横向位置 */
|
|
@@ -53,6 +53,12 @@ export interface ScrollProps {
|
|
|
53
53
|
|
|
54
54
|
/** 拖拽防抖时间 */
|
|
55
55
|
dragDebounce?: number
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 外部滚动容器(如 EmbedPDF Viewport)。
|
|
59
|
+
* 提供时仅渲染自定义滚动条并同步该元素的滚动,不创建内部滚动容器。
|
|
60
|
+
*/
|
|
61
|
+
target?: MaybeRefOrGetter<HTMLElement | null | undefined>
|
|
56
62
|
}
|
|
57
63
|
|
|
58
64
|
export interface ScrollEmits {
|