fix(components): [scrollbar] multiple rendering (#15822)

* fix:The namespace of the showOverflowTooltip is invalid.

* fix(components): [scrollbar] multiple rendering

* fix(components): [scrollbar] multiple rendering

* fix(components): [scrollbar] multiple rendering

* Update packages/components/scrollbar/src/bar.vue

Co-authored-by: kooriookami <38392315+kooriookami@users.noreply.github.com>

* test(components): [scrollbar] adjusting style attributes

---------

Co-authored-by: kooriookami <38392315+kooriookami@users.noreply.github.com>
This commit is contained in:
xingyixiang 2024-02-08 17:59:02 +08:00 committed by GitHub
parent f33979d228
commit 5e3fa20774
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 52 additions and 58 deletions

View File

@ -30,11 +30,11 @@ describe('ScrollBar', () => {
await makeScroll(scrollDom, 'scrollTop', 100)
expect(wrapper.find('.is-vertical div').attributes('style')).toContain(
'height: 80px; transform: translateY(50%);'
'transform: translateY(50%); height: 80px;'
)
await makeScroll(scrollDom, 'scrollTop', 300)
expect(wrapper.find('.is-vertical div').attributes('style')).toContain(
'height: 80px; transform: translateY(150%);'
'transform: translateY(150%); height: 80px;'
)
offsetHeightRestore()
scrollHeightRestore()
@ -64,11 +64,11 @@ describe('ScrollBar', () => {
await makeScroll(scrollDom, 'scrollLeft', 100)
expect(wrapper.find('.is-horizontal div').attributes('style')).toContain(
'width: 80px; transform: translateX(50%);'
'transform: translateX(50%); width: 80px;'
)
await makeScroll(scrollDom, 'scrollLeft', 300)
expect(wrapper.find('.is-horizontal div').attributes('style')).toContain(
'width: 80px; transform: translateX(150%);'
'transform: translateX(150%); width: 80px;'
)
offsetWidthRestore()
scrollWidthRestore()
@ -111,18 +111,18 @@ describe('ScrollBar', () => {
await makeScroll(scrollDom, 'scrollTop', 100)
await makeScroll(scrollDom, 'scrollLeft', 100)
expect(wrapper.find('.is-vertical div').attributes('style')).toContain(
'height: 80px; transform: translateY(50%);'
'transform: translateY(50%); height: 80px;'
)
expect(wrapper.find('.is-horizontal div').attributes('style')).toContain(
'width: 80px; transform: translateX(50%);'
'transform: translateX(50%); width: 80px;'
)
await makeScroll(scrollDom, 'scrollTop', 300)
await makeScroll(scrollDom, 'scrollLeft', 300)
expect(wrapper.find('.is-vertical div').attributes('style')).toContain(
'height: 80px; transform: translateY(150%);'
'transform: translateY(150%); height: 80px;'
)
expect(wrapper.find('.is-horizontal div').attributes('style')).toContain(
'width: 80px; transform: translateX(150%);'
'transform: translateX(150%); width: 80px;'
)
offsetHeightRestore()
@ -221,10 +221,10 @@ describe('ScrollBar', () => {
scrollbar.setScrollLeft(100)
await nextTick()
expect(wrapper.find('.is-vertical div').attributes('style')).toContain(
'height: 80px; transform: translateY(0%);'
'transform: translateY(0%); height: 80px;'
)
expect(wrapper.find('.is-horizontal div').attributes('style')).toContain(
'width: 80px; transform: translateX(0%);'
'transform: translateX(0%); width: 80px;'
)
offsetHeightRestore()
@ -257,7 +257,7 @@ describe('ScrollBar', () => {
await makeScroll(scrollDom, 'scrollTop', 0)
expect(wrapper.find('.is-vertical div').attributes('style')).toContain(
'height: 20px; transform: translateY(0%);'
'transform: translateY(0%); height: 20px;'
)
offsetHeightRestore()
scrollHeightRestore()

View File

@ -7,15 +7,9 @@ export const barProps = buildProps({
type: Boolean,
default: true,
},
width: String,
height: String,
ratioX: {
minSize: {
type: Number,
default: 1,
},
ratioY: {
type: Number,
default: 1,
required: true,
},
} as const)
export type BarProps = ExtractPropTypes<typeof barProps>

View File

@ -1,35 +1,67 @@
<template>
<thumb :move="moveX" :ratio="ratioX" :size="width" :always="always" />
<thumb :move="moveX" :ratio="ratioX" :size="sizeWidth" :always="always" />
<thumb
:move="moveY"
:ratio="ratioY"
:size="height"
:size="sizeHeight"
vertical
:always="always"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { inject, ref } from 'vue'
import { GAP } from './util'
import Thumb from './thumb.vue'
import { barProps } from './bar'
import { scrollbarContextKey } from './constants'
const props = defineProps(barProps)
const scrollbar = inject(scrollbarContextKey)
const moveX = ref(0)
const moveY = ref(0)
const sizeWidth = ref('')
const sizeHeight = ref('')
const ratioY = ref(1)
const ratioX = ref(1)
const handleScroll = (wrap: HTMLDivElement) => {
if (wrap) {
const offsetHeight = wrap.offsetHeight - GAP
const offsetWidth = wrap.offsetWidth - GAP
moveY.value = ((wrap.scrollTop * 100) / offsetHeight) * props.ratioY
moveX.value = ((wrap.scrollLeft * 100) / offsetWidth) * props.ratioX
moveY.value = ((wrap.scrollTop * 100) / offsetHeight) * ratioY.value
moveX.value = ((wrap.scrollLeft * 100) / offsetWidth) * ratioX.value
}
}
const update = () => {
const wrap = scrollbar?.wrapElement
if (!wrap) return
const offsetHeight = wrap.offsetHeight - GAP
const offsetWidth = wrap.offsetWidth - GAP
const originalHeight = offsetHeight ** 2 / wrap.scrollHeight
const originalWidth = offsetWidth ** 2 / wrap.scrollWidth
const height = Math.max(originalHeight, props.minSize)
const width = Math.max(originalWidth, props.minSize)
ratioY.value =
originalHeight /
(offsetHeight - originalHeight) /
(height / (offsetHeight - height))
ratioX.value =
originalWidth /
(offsetWidth - originalWidth) /
(width / (offsetWidth - width))
sizeHeight.value = height + GAP < offsetHeight ? `${height}px` : ''
sizeWidth.value = width + GAP < offsetWidth ? `${width}px` : ''
}
defineExpose({
handleScroll,
update,
})
</script>

View File

@ -20,14 +20,7 @@
</component>
</div>
<template v-if="!native">
<bar
ref="barRef"
:height="sizeHeight"
:width="sizeWidth"
:always="always"
:ratio-x="ratioX"
:ratio-y="ratioY"
/>
<bar ref="barRef" :always="always" :min-size="minSize" />
</template>
</div>
</template>
@ -45,7 +38,6 @@ import {
import { useEventListener, useResizeObserver } from '@vueuse/core'
import { addUnit, debugWarn, isNumber, isObject } from '@element-plus/utils'
import { useNamespace } from '@element-plus/hooks'
import { GAP } from './util'
import Bar from './bar.vue'
import { scrollbarContextKey } from './constants'
import { scrollbarEmits, scrollbarProps } from './scrollbar'
@ -69,12 +61,7 @@ let stopResizeListener: (() => void) | undefined = undefined
const scrollbarRef = ref<HTMLDivElement>()
const wrapRef = ref<HTMLDivElement>()
const resizeRef = ref<HTMLElement>()
const sizeWidth = ref('0')
const sizeHeight = ref('0')
const barRef = ref<BarInstance>()
const ratioY = ref(1)
const ratioX = ref(1)
const wrapStyle = computed<StyleValue>(() => {
const style: CSSProperties = {}
@ -135,26 +122,7 @@ const setScrollLeft = (value: number) => {
}
const update = () => {
if (!wrapRef.value) return
const offsetHeight = wrapRef.value.offsetHeight - GAP
const offsetWidth = wrapRef.value.offsetWidth - GAP
const originalHeight = offsetHeight ** 2 / wrapRef.value.scrollHeight
const originalWidth = offsetWidth ** 2 / wrapRef.value.scrollWidth
const height = Math.max(originalHeight, props.minSize)
const width = Math.max(originalWidth, props.minSize)
ratioY.value =
originalHeight /
(offsetHeight - originalHeight) /
(height / (offsetHeight - height))
ratioX.value =
originalWidth /
(offsetWidth - originalWidth) /
(width / (offsetWidth - width))
sizeHeight.value = height + GAP < offsetHeight ? `${height}px` : ''
sizeWidth.value = width + GAP < offsetWidth ? `${width}px` : ''
barRef.value?.update()
}
watch(