fix(ui): 工作区切换器层级提升至遮罩之上,直板机窄屏居中悬浮

- ws-switcher/ws-menu-floating 均为 Teleport 到 body 的 fixed 浮层,
  z-index 1500/1600 低于移动端侧边栏遮罩 mobile-panel-overlay(2000,
  带 backdrop-filter 模糊),手机端在侧边栏打开切换器被压在模糊层下;
  提升至 2300/2400(与对话项菜单同级、二级菜单高于父面板)
- 视口 < 480px(直板机竖屏)时面板右侧与入口下方均无合适空间,
  改为屏幕居中悬浮;加 max-width: calc(100vw - 16px) 防极端窄屏溢出

Co-authored-by: Astrion powered by Kimi-K3 <astrion-agent@users.noreply.github.com>
This commit is contained in:
JOJO 2026-08-30 10:59:45 +08:00
parent 395a9467ec
commit f51a46bf9b

View File

@ -224,6 +224,9 @@ const bottomFading = ref(false);
/* ---------- 浮层定位:锚定入口按钮,夹紧在视口内 ---------- */ /* ---------- 浮层定位:锚定入口按钮,夹紧在视口内 ---------- */
const POPOVER_WIDTH = 300; const POPOVER_WIDTH = 300;
/*
直接屏幕居中悬浮类似原生 action sheet 的居中弹窗模式 */
const CENTER_LAYOUT_MAX_VW = 480;
const popoverStyle = ref<Record<string, string>>({}); const popoverStyle = ref<Record<string, string>>({});
const updatePosition = () => { const updatePosition = () => {
@ -235,8 +238,12 @@ const updatePosition = () => {
let left = anchor.right + 8; let left = anchor.right + 8;
let top = anchor.top - 6; let top = anchor.top - 6;
if (vw < CENTER_LAYOUT_MAX_VW) {
/* 直板机窄屏:屏幕居中悬浮 */
left = Math.max(8, (vw - POPOVER_WIDTH) / 2);
top = Math.max(8, (vh - popH) / 2);
} else if (left + POPOVER_WIDTH > vw - 8) {
/* 右侧空间不足(如移动端全屏侧边栏)→ 改为在入口下方展开 */ /* 右侧空间不足(如移动端全屏侧边栏)→ 改为在入口下方展开 */
if (left + POPOVER_WIDTH > vw - 8) {
left = Math.max(8, Math.min(anchor.left, vw - POPOVER_WIDTH - 8)); left = Math.max(8, Math.min(anchor.left, vw - POPOVER_WIDTH - 8));
top = anchor.bottom + 6; top = anchor.bottom + 6;
} }
@ -475,8 +482,13 @@ onBeforeUnmount(() => {
.ws-switcher { .ws-switcher {
--ws-row-h: 50px; --ws-row-h: 50px;
position: fixed; position: fixed;
z-index: 1500; /* Teleport body .mobile-panel-overlayz-index: 2000
backdrop-filter 模糊否则手机端在侧边栏里打开切换器会被压在模糊层下面
与对话项菜单 conversation-actions-menu--fixed 同级 */
z-index: 2300;
width: 300px; width: 300px;
/* 极端窄屏(宽度不足 316px 的老设备/窗口模式)兜底,防水平溢出 */
max-width: calc(100vw - 16px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border: 1px solid var(--border-default); border: 1px solid var(--border-default);
@ -855,10 +867,11 @@ onBeforeUnmount(() => {
gap: 8px; gap: 8px;
} }
/* 「…」浮动菜单Teleport 到 bodyfixed 定位逃逸裁切) */ /* Teleport bodyfixed
.ws-switcherz-index: 2300内打开必须高于父面板 */
.ws-menu-floating { .ws-menu-floating {
position: fixed; position: fixed;
z-index: 1600; z-index: 2400;
min-width: 136px; min-width: 136px;
padding: 4px; padding: 4px;
border: 1px solid var(--border-default); border: 1px solid var(--border-default);