Merge branch 'fix/menu-position' into 'develop'
fix: Prevent menu from overflowing off screen Co-authored-by: Lhcfl <Lhcfl@outlook.com> See merge request firefish/firefish!10885
This commit is contained in:
commit
0cdf8dbcda
4 changed files with 31 additions and 3 deletions
|
@ -12,7 +12,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onMounted, ref } from "vue";
|
||||
import { nextTick, onMounted, ref, watch } from "vue";
|
||||
import MkMenu from "./MkMenu.vue";
|
||||
import type { MenuItem } from "@/types/menu";
|
||||
|
||||
|
@ -35,7 +35,13 @@ const align = "left";
|
|||
function setPosition() {
|
||||
const rootRect = props.rootElement.getBoundingClientRect();
|
||||
const rect = props.targetElement.getBoundingClientRect();
|
||||
const left = props.targetElement.offsetWidth;
|
||||
let left = props.targetElement.offsetWidth;
|
||||
if (rootRect.x + left > window.innerWidth - rect.width) {
|
||||
left = -rect.width;
|
||||
}
|
||||
if (rect.x + left < 0) {
|
||||
left = -rect.x;
|
||||
}
|
||||
const top = rect.top - rootRect.top - 8;
|
||||
el.value!.style.left = `${left}px`;
|
||||
el.value!.style.top = `${top}px`;
|
||||
|
@ -56,6 +62,15 @@ onMounted(() => {
|
|||
});
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.items,
|
||||
() => {
|
||||
nextTick(() => {
|
||||
setPosition();
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
checkHit: (ev: MouseEvent) => {
|
||||
return ev.target === el.value || el.value?.contains(ev.target as Node);
|
||||
|
|
|
@ -250,7 +250,7 @@ const align = () => {
|
|||
if (props.anchor.x === "center") {
|
||||
left = x + props.src.offsetWidth / 2 - width / 2;
|
||||
} else if (props.anchor.x === "left") {
|
||||
// TODO
|
||||
left = x + props.src.offsetWidth - width;
|
||||
} else if (props.anchor.x === "right") {
|
||||
left = x + props.src.offsetWidth;
|
||||
}
|
||||
|
@ -317,6 +317,9 @@ const align = () => {
|
|||
top = MARGIN;
|
||||
}
|
||||
|
||||
if (left > window.innerWidth - width - MARGIN) {
|
||||
left = window.innerWidth - width - MARGIN;
|
||||
}
|
||||
if (left < 0) {
|
||||
left = 0;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
:z-priority="'high'"
|
||||
:src="src"
|
||||
:transparent-bg="true"
|
||||
:anchor
|
||||
tabindex="-1"
|
||||
@click="modal?.close()"
|
||||
@closed="emit('closed')"
|
||||
|
@ -36,6 +37,10 @@ defineProps<{
|
|||
width?: number;
|
||||
viaKeyboard?: boolean;
|
||||
src?: HTMLElement | null;
|
||||
anchor?: {
|
||||
x: "left" | "center" | "right";
|
||||
y: "top" | "center" | "bottom";
|
||||
};
|
||||
noReturnFocus?;
|
||||
}>();
|
||||
|
||||
|
|
|
@ -916,6 +916,10 @@ export function popupMenu(
|
|||
width?: number;
|
||||
viaKeyboard?: boolean;
|
||||
noReturnFocus?: boolean;
|
||||
anchor?: {
|
||||
x: "left" | "center" | "right";
|
||||
y: "top" | "center" | "bottom";
|
||||
};
|
||||
},
|
||||
) {
|
||||
return new Promise<void>((resolve, _reject) => {
|
||||
|
@ -929,6 +933,7 @@ export function popupMenu(
|
|||
{
|
||||
items,
|
||||
src,
|
||||
anchor: options?.anchor,
|
||||
width: options?.width,
|
||||
align: options?.align,
|
||||
viaKeyboard: options?.viaKeyboard,
|
||||
|
|
Loading…
Reference in a new issue