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>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { nextTick, onMounted, ref } from "vue";
|
import { nextTick, onMounted, ref, watch } from "vue";
|
||||||
import MkMenu from "./MkMenu.vue";
|
import MkMenu from "./MkMenu.vue";
|
||||||
import type { MenuItem } from "@/types/menu";
|
import type { MenuItem } from "@/types/menu";
|
||||||
|
|
||||||
|
@ -35,7 +35,13 @@ const align = "left";
|
||||||
function setPosition() {
|
function setPosition() {
|
||||||
const rootRect = props.rootElement.getBoundingClientRect();
|
const rootRect = props.rootElement.getBoundingClientRect();
|
||||||
const rect = props.targetElement.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;
|
const top = rect.top - rootRect.top - 8;
|
||||||
el.value!.style.left = `${left}px`;
|
el.value!.style.left = `${left}px`;
|
||||||
el.value!.style.top = `${top}px`;
|
el.value!.style.top = `${top}px`;
|
||||||
|
@ -56,6 +62,15 @@ onMounted(() => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.items,
|
||||||
|
() => {
|
||||||
|
nextTick(() => {
|
||||||
|
setPosition();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
checkHit: (ev: MouseEvent) => {
|
checkHit: (ev: MouseEvent) => {
|
||||||
return ev.target === el.value || el.value?.contains(ev.target as Node);
|
return ev.target === el.value || el.value?.contains(ev.target as Node);
|
||||||
|
|
|
@ -250,7 +250,7 @@ const align = () => {
|
||||||
if (props.anchor.x === "center") {
|
if (props.anchor.x === "center") {
|
||||||
left = x + props.src.offsetWidth / 2 - width / 2;
|
left = x + props.src.offsetWidth / 2 - width / 2;
|
||||||
} else if (props.anchor.x === "left") {
|
} else if (props.anchor.x === "left") {
|
||||||
// TODO
|
left = x + props.src.offsetWidth - width;
|
||||||
} else if (props.anchor.x === "right") {
|
} else if (props.anchor.x === "right") {
|
||||||
left = x + props.src.offsetWidth;
|
left = x + props.src.offsetWidth;
|
||||||
}
|
}
|
||||||
|
@ -317,6 +317,9 @@ const align = () => {
|
||||||
top = MARGIN;
|
top = MARGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (left > window.innerWidth - width - MARGIN) {
|
||||||
|
left = window.innerWidth - width - MARGIN;
|
||||||
|
}
|
||||||
if (left < 0) {
|
if (left < 0) {
|
||||||
left = 0;
|
left = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
:z-priority="'high'"
|
:z-priority="'high'"
|
||||||
:src="src"
|
:src="src"
|
||||||
:transparent-bg="true"
|
:transparent-bg="true"
|
||||||
|
:anchor
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
@click="modal?.close()"
|
@click="modal?.close()"
|
||||||
@closed="emit('closed')"
|
@closed="emit('closed')"
|
||||||
|
@ -36,6 +37,10 @@ defineProps<{
|
||||||
width?: number;
|
width?: number;
|
||||||
viaKeyboard?: boolean;
|
viaKeyboard?: boolean;
|
||||||
src?: HTMLElement | null;
|
src?: HTMLElement | null;
|
||||||
|
anchor?: {
|
||||||
|
x: "left" | "center" | "right";
|
||||||
|
y: "top" | "center" | "bottom";
|
||||||
|
};
|
||||||
noReturnFocus?;
|
noReturnFocus?;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
|
|
@ -916,6 +916,10 @@ export function popupMenu(
|
||||||
width?: number;
|
width?: number;
|
||||||
viaKeyboard?: boolean;
|
viaKeyboard?: boolean;
|
||||||
noReturnFocus?: boolean;
|
noReturnFocus?: boolean;
|
||||||
|
anchor?: {
|
||||||
|
x: "left" | "center" | "right";
|
||||||
|
y: "top" | "center" | "bottom";
|
||||||
|
};
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
return new Promise<void>((resolve, _reject) => {
|
return new Promise<void>((resolve, _reject) => {
|
||||||
|
@ -929,6 +933,7 @@ export function popupMenu(
|
||||||
{
|
{
|
||||||
items,
|
items,
|
||||||
src,
|
src,
|
||||||
|
anchor: options?.anchor,
|
||||||
width: options?.width,
|
width: options?.width,
|
||||||
align: options?.align,
|
align: options?.align,
|
||||||
viaKeyboard: options?.viaKeyboard,
|
viaKeyboard: options?.viaKeyboard,
|
||||||
|
|
Loading…
Reference in a new issue