fix(ui): 手机端权限切换菜单防溢出,溢出时改为屏幕水平居中
锚点在输入栏左下而菜单较宽(250/350px),right:0 右对齐导致菜单左缘算出负数跑出屏幕外。打开时测量锚点位置与菜单宽度:右对齐不溢出屏幕左缘则保持现状;溢出则换算水平偏移让菜单相对屏幕居中,垂直方向保持锚点上方不变。仅 ≤768px 断点生效,监听 resize 重算
This commit is contained in:
parent
b55f4a811d
commit
c4f5ef8c56
@ -499,7 +499,7 @@
|
||||
>
|
||||
<span>{{ $t('input.versionControl') }}</span>
|
||||
</button>
|
||||
<div class="permission-switcher__block">
|
||||
<div ref="permissionBlockEl" class="permission-switcher__block">
|
||||
<button
|
||||
type="button"
|
||||
class="permission-switcher__btn"
|
||||
@ -535,8 +535,13 @@
|
||||
</button>
|
||||
<div
|
||||
v-if="permissionMenuOpen"
|
||||
ref="permissionMenuEl"
|
||||
class="permission-switcher__menu"
|
||||
:class="{ 'permission-switcher__menu--split': executionModeEnabled }"
|
||||
:class="{
|
||||
'permission-switcher__menu--split': executionModeEnabled,
|
||||
'permission-switcher__menu--centered': permissionMenuCentered,
|
||||
}"
|
||||
:style="permissionMenuCentered ? { left: permissionMenuCenteredLeft, right: 'auto' } : undefined"
|
||||
>
|
||||
<div
|
||||
class="permission-switcher__group"
|
||||
@ -3391,6 +3396,45 @@ const executionModeLocked = computed(
|
||||
() => permissionLockedByPlan.value || executionLockedByRestricted.value
|
||||
);
|
||||
|
||||
/**
|
||||
* 手机端权限菜单防溢出定位:优先右对齐锚点(right: 0),若菜单左缘会溢出屏幕
|
||||
* (锚点在输入栏左下而菜单较宽时典型发生)则改为相对屏幕水平居中,垂直方向
|
||||
* 保持锚点上方不变(inline left 为相对锚点容器的偏移换算)。仅 ≤768px 断点启用。
|
||||
*/
|
||||
const permissionBlockEl = ref<HTMLElement | null>(null);
|
||||
const permissionMenuEl = ref<HTMLElement | null>(null);
|
||||
const permissionMenuCentered = ref(false);
|
||||
const permissionMenuCenteredLeft = ref('0px');
|
||||
|
||||
async function updatePermissionMenuPosition() {
|
||||
permissionMenuCentered.value = false;
|
||||
if (!props.permissionMenuOpen) return;
|
||||
if (!window.matchMedia('(max-width: 768px)').matches) return;
|
||||
await nextTick();
|
||||
const block = permissionBlockEl.value;
|
||||
const menu = permissionMenuEl.value;
|
||||
if (!block || !menu) return;
|
||||
const anchorRect = block.getBoundingClientRect();
|
||||
const menuWidth = menu.offsetWidth;
|
||||
const safeMargin = 8;
|
||||
if (anchorRect.right - menuWidth < safeMargin) {
|
||||
const centeredLeft = (window.innerWidth - menuWidth) / 2 - anchorRect.left;
|
||||
permissionMenuCenteredLeft.value = `${Math.round(centeredLeft)}px`;
|
||||
permissionMenuCentered.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
function onWindowResizeRepositionMenu() {
|
||||
if (props.permissionMenuOpen) void updatePermissionMenuPosition();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.permissionMenuOpen,
|
||||
(open) => {
|
||||
if (open) void updatePermissionMenuPosition();
|
||||
}
|
||||
);
|
||||
|
||||
const currentExecutionShortLabel = computed(() => {
|
||||
void currentLocale.value;
|
||||
const mode = String(props.currentExecutionMode || '');
|
||||
@ -3588,6 +3632,7 @@ watch(
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', closeProjectGitMenu);
|
||||
window.addEventListener('resize', onWindowResizeRepositionMenu);
|
||||
adjustTextareaSize();
|
||||
nextTick(() => {
|
||||
emitComposerHeight();
|
||||
@ -3611,6 +3656,7 @@ onMounted(() => {
|
||||
onBeforeUnmount(() => {
|
||||
stopVoiceRecording();
|
||||
document.removeEventListener('click', closeProjectGitMenu);
|
||||
window.removeEventListener('resize', onWindowResizeRepositionMenu);
|
||||
editor.value?.destroy();
|
||||
runtimeQueueItemRefs.forEach((el) => {
|
||||
if (el) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user