mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
feat: better safe triangle for submenus
This commit is contained in:
parent
563e9af0d3
commit
c29abe4657
2 changed files with 35 additions and 28 deletions
|
@ -47,11 +47,19 @@ const preventOffScreen = async (element: HTMLElement, isSubmenu = false) => {
|
|||
}
|
||||
}
|
||||
|
||||
const safeAreaHeight = ref('0px')
|
||||
const safeAreaWidth = ref('0px')
|
||||
const safeAreaClipPath = ref('0 0, 0 0, 0 0, 0 0')
|
||||
|
||||
type MenuItem = HTMLElement & {
|
||||
eventsRegistered?: boolean
|
||||
}
|
||||
|
||||
const initSubmenus = () => {
|
||||
el.value?.querySelectorAll('.has-sub').forEach(item => {
|
||||
el.value?.querySelectorAll<HTMLElement>('.has-sub').forEach((item: MenuItem) => {
|
||||
const submenu = item.querySelector<HTMLElement>('.submenu')
|
||||
|
||||
if (!submenu) {
|
||||
if (!submenu || item.eventsRegistered) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -61,17 +69,27 @@ const initSubmenus = () => {
|
|||
await preventOffScreen(submenu, true)
|
||||
})
|
||||
|
||||
item.addEventListener('mousemove', async (e: MouseEvent) => {
|
||||
await nextTick()
|
||||
const rect = submenu.getBoundingClientRect()
|
||||
safeAreaHeight.value = rect.height + 'px'
|
||||
safeAreaWidth.value = rect.x - e.clientX + 'px'
|
||||
safeAreaClipPath.value = `polygon(100% 0, 0 ${e.clientY - rect.top}px, 100% 100%)`
|
||||
})
|
||||
|
||||
item.addEventListener('mouseleave', () => {
|
||||
submenu.style.top = '0'
|
||||
submenu.style.bottom = 'auto'
|
||||
submenu.style.display = 'none'
|
||||
})
|
||||
|
||||
item.eventsRegistered = true
|
||||
})
|
||||
}
|
||||
|
||||
const open = async (_top = 0, _left = 0) => {
|
||||
top.value = _top
|
||||
left.value = _left
|
||||
const open = async (t = 0, l = 0) => {
|
||||
top.value = t
|
||||
left.value = l
|
||||
shown.value = true
|
||||
|
||||
await nextTick()
|
||||
|
@ -99,5 +117,17 @@ defineExpose({ open, close, shown })
|
|||
<style lang="scss" scoped>
|
||||
nav {
|
||||
user-select: none;
|
||||
|
||||
:deep(.has-sub)::after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
opacity: 0;
|
||||
width: v-bind(safeAreaWidth);
|
||||
height: v-bind(safeAreaHeight);
|
||||
clip-path: v-bind(safeAreaClipPath);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -386,29 +386,6 @@ menu {
|
|||
background-repeat: no-repeat;
|
||||
background-position: right 8px center;
|
||||
background-size: 10px;
|
||||
|
||||
&:hover {
|
||||
&::before, &::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 75%;
|
||||
z-index: 2;
|
||||
|
||||
animation: subMenuHoverHelp 1s;
|
||||
}
|
||||
|
||||
&::before {
|
||||
clip-path: polygon(100% 0, 0% 100%, 100% 100%);
|
||||
bottom: 100%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
clip-path: polygon(100% 0, 0 0, 100% 100%);
|
||||
top: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue