更新歌曲播放栏布局

This commit is contained in:
lyswhut
2022-11-03 06:34:57 +08:00
parent 2003c5a0c9
commit 716120ea61
25 changed files with 731 additions and 233 deletions
+150
View File
@@ -0,0 +1,150 @@
<template>
<teleport to="#root">
<div :class="[$style.popup, {[$style.top]: isShowTop}, {[$style.active]: props.visible}]" :style="popupStyle" :aria-hidden="!props.visible" @click.stop>
<div ref="dom_content" class="scroll" :class="$style.list">
<slot />
</div>
</div>
</teleport>
</template>
<script setup lang="ts">
import { ref, watch, onMounted, onBeforeUnmount, reactive, defineEmits } from '@common/utils/vueTools'
const props = defineProps<{
visible: boolean
el: HTMLElement | null
}>()
interface Emitter {
(event: 'update:visible', visible: boolean): void
}
const emit = defineEmits<Emitter>()
const dom_content = ref<HTMLElement | null>(null)
const isShowTop = ref(false)
const popupStyle = reactive({
maxHeight: 'none',
top: '0px',
left: '0px',
'--arrow-left': '0px',
})
const arrowHeight = 9
const arrowWidth = 8
watch(() => props.visible, (visible) => {
if (!visible || !dom_content.value || !props.el) return
const rect = props.el.getBoundingClientRect()
const maxHeight = document.body.clientHeight
const elTop = rect.top - window.lx.rootOffset
const bottomTopVal = elTop + rect.height
const contentHeight = dom_content.value.scrollHeight + arrowHeight + 10
if (bottomTopVal + contentHeight < maxHeight || (contentHeight > elTop && elTop <= maxHeight - bottomTopVal)) {
isShowTop.value = false
popupStyle.top = bottomTopVal + arrowHeight + 'px'
popupStyle.maxHeight = maxHeight - bottomTopVal - arrowHeight - 10 + 'px'
} else {
isShowTop.value = true
let maxContentHeight = elTop - arrowHeight - 10
popupStyle.top = (elTop - (elTop < contentHeight ? elTop : contentHeight) + 10) + 'px'
popupStyle.maxHeight = maxContentHeight + 'px'
}
const maxWidth = document.body.clientWidth - 20
let center = dom_content.value.clientWidth / 2
let left = rect.left + rect.width / 2 - window.lx.rootOffset - center
if (left < 10) {
center -= 10 - left
left = 10
} else if (left + dom_content.value.clientWidth > maxWidth) {
let newLeft = maxWidth - dom_content.value.clientWidth
center = center + left - newLeft
left = newLeft
}
popupStyle.left = left + 'px'
popupStyle['--arrow-left'] = center - arrowWidth + 'px'
})
const handleHide = (evt?: MouseEvent) => {
// if (evt && (evt.target as HTMLElement)?.parentNode != dom_content.value && props.visible) return emit('update:visible', false)
// console.log(this.$refs)
// if (evt && (evt.target == dom_btn.value || dom_btn.value?.contains(evt.target as HTMLElement))) return
// setTimeout(() => {
// popupVisible.value = false
emit('update:visible', false)
// }, 50)
}
onMounted(() => {
document.addEventListener('click', handleHide)
})
onBeforeUnmount(() => {
document.removeEventListener('click', handleHide)
})
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.popup {
position: absolute;
// top: -100%;
// width: 645px;
// left: 8px;
// margin-top: 12px;
max-width: 98%;
border-radius: 4px;
background-color: var(--color-content-background);
opacity: 0;
transform: scale(.8, .8);
transform-origin: 0 0 0;
transition: .16s ease;
transition-property: transform, opacity;
max-height: 250px;
z-index: 10;
pointer-events: none;
filter: drop-shadow(0px 0px 4px rgba(0, 0, 0, .15));
display: flex;
&:before {
content: " ";
position: absolute;
top: -8px;
left: var(--arrow-left);
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-bottom: 8px solid var(--color-content-background);
}
&.active {
opacity: 1;
transform: scale(1);
pointer-events: initial;
}
&.top {
filter: drop-shadow(0px 1px 4px rgba(0, 0, 0, .15));
transform-origin: 50% 100% 0;
&:before {
top: 100%;
border-bottom: none;
border-top: 8px solid var(--color-content-background);
}
}
}
.list {
padding: 10px;
box-sizing: border-box;
// box-shadow: 0 0 4px rgba(0, 0, 0, .2);
}
</style>