mirror of
https://github.com/Gloridust/WechatOnCloud.git
synced 2026-06-16 19:53:53 +08:00
feat(admin): 实例「管理」菜单改为悬浮图层展开
绝对定位悬浮层(从按钮下方浮出),不再撑高卡片/顶走下方内容;展开时卡片 overflow:visible + z-index:5(盖住下方/同列卡片,仍低于弹窗);加点击外部 / 点击菜单项自动关闭。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -887,7 +887,17 @@ function InstanceAdminCard({
|
||||
const installed = wx.installed && wx.phase !== 'downloading';
|
||||
const offline = inst.runtime !== 'running';
|
||||
const working = !!acting || busy; // 生命周期操作中 或 微信下载/更新中 → 锁住卡片
|
||||
const [menuOpen, setMenuOpen] = useState(false); // 「管理」折叠菜单是否展开
|
||||
const [menuOpen, setMenuOpen] = useState(false); // 「管理」菜单是否展开(悬浮层,不占文档流)
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
// 悬浮下拉:点击菜单外部时关闭
|
||||
useEffect(() => {
|
||||
if (!menuOpen) return;
|
||||
const onDocDown = (e: MouseEvent) => {
|
||||
if (menuRef.current && !menuRef.current.contains(e.target as Node)) setMenuOpen(false);
|
||||
};
|
||||
document.addEventListener('mousedown', onDocDown);
|
||||
return () => document.removeEventListener('mousedown', onDocDown);
|
||||
}, [menuOpen]);
|
||||
|
||||
let badge: { text: string; cls: string };
|
||||
if (acting) badge = { text: '处理中', cls: 'tag-busy' };
|
||||
@@ -905,7 +915,7 @@ function InstanceAdminCard({
|
||||
else sub = '微信尚未安装';
|
||||
|
||||
return (
|
||||
<div className="inst-card">
|
||||
<div className={'inst-card' + (menuOpen ? ' open-menu' : '')}>
|
||||
<div className="inst-head">
|
||||
<span className="inst-name">{inst.name}</span>
|
||||
<span className={'tag ' + badge.cls}>{badge.text}</span>
|
||||
@@ -939,13 +949,14 @@ function InstanceAdminCard({
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="inst-menu-wrap" ref={menuRef}>
|
||||
<button className={'inst-menu-toggle' + (menuOpen ? ' open' : '')} onClick={() => setMenuOpen((v) => !v)}>
|
||||
<span>管理</span>
|
||||
<span className="inst-menu-caret">{CaretIcon}</span>
|
||||
</button>
|
||||
|
||||
{menuOpen && (
|
||||
<div className="inst-menu">
|
||||
<div className="inst-menu" onClick={() => setMenuOpen(false)}>
|
||||
<div className="inst-menu-group">
|
||||
<div className="inst-menu-label">运维</div>
|
||||
<div className="inst-menu-items">
|
||||
@@ -998,6 +1009,7 @@ function InstanceAdminCard({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -307,7 +307,6 @@ button {
|
||||
|
||||
/* 实例卡片操作:「管理」分类折叠菜单(默认收起,点开按运维/设置/危险分组展开文字操作) */
|
||||
.inst-menu-toggle {
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
display: flex;
|
||||
@@ -335,11 +334,24 @@ button {
|
||||
.inst-menu-toggle.open .inst-menu-caret {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
/* 「管理」菜单:绝对定位悬浮层,浮在下方内容之上,不把卡片撑高、不顶走后面的内容 */
|
||||
.inst-menu-wrap {
|
||||
position: relative;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.inst-menu {
|
||||
margin-top: 8px;
|
||||
position: absolute;
|
||||
top: calc(100% + 6px);
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
padding: 10px;
|
||||
background: var(--surface);
|
||||
border-radius: var(--r-small);
|
||||
box-shadow: 0 6px 22px rgba(var(--shadow) / 0.26), 0 2px 6px rgba(var(--shadow) / 0.18);
|
||||
animation: inst-menu-in 0.16s ease;
|
||||
}
|
||||
@keyframes inst-menu-in {
|
||||
@@ -928,6 +940,11 @@ button {
|
||||
.inst-card > * {
|
||||
position: relative;
|
||||
}
|
||||
/* 菜单展开时:放开裁剪让悬浮层露出,并抬升层级盖住下方/同列卡片(仍低于弹窗 z-index 20) */
|
||||
.inst-card.open-menu {
|
||||
overflow: visible;
|
||||
z-index: 5;
|
||||
}
|
||||
.inst-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user