namespace Ananta.Server.App.Admin; /// /// Presentation only: 简易 / 详细 两档显示模式,从捐赠端 7k-v0.6 的 /// Ananta.App/Admin/AdminViewModeParts.cs 移植过来。 /// /// 设计原则(照搬捐赠端注释):Hide prose only —— 只藏散文, /// 控件 / 标签 / 实时结果 / 报错一律保留。所以规则里带两层守卫: /// ① :not(:has(控件…)) 段落里万一嵌了按钮就不会被藏; /// ② :not([role=status]) 带 ARIA live 的「加载中 / 加载失败」状态行必须留着, /// 否则简易模式下报错会被一起藏掉(规则 249:每次点击都必须有回显)。 /// /// 三个片段分别进 <style>、顶栏、<script>,JS 自举,不需要额外接线。 /// 默认简易(body 初始就带 gm-simple),**不持久化**:每次打开都回简易。 /// internal static class AdminViewModeParts { internal const string Css = """ /* ---- 简易 / 详细 显示模式 ---- */ .gm-view-mode{display:flex;align-items:center;gap:7px;white-space:nowrap} .gm-view-mode .lbl{font-size:11.5px;color:var(--txt-3)} .gm-view-switch{position:relative;display:block;width:44px;height:24px;margin:0;cursor:pointer;flex:0 0 auto} .gm-view-switch input[type=checkbox]{position:absolute;inset:0;width:100%;height:100%;opacity:0;margin:0;cursor:pointer;z-index:1} .gm-view-track{display:block;height:24px;box-sizing:border-box;border-radius:18px; background:#1a212b;border:1px solid var(--line);pointer-events:none;transition:background .15s,border-color .15s} .gm-view-track:before{content:'';position:absolute;left:3px;top:3px;width:18px;height:18px;border-radius:50%; background:var(--txt-3);transition:transform .15s,background .15s} .gm-view-switch input:checked+.gm-view-track{background:var(--acc);border-color:var(--acc)} .gm-view-switch input:checked+.gm-view-track:before{transform:translateX(20px);background:#fff} .gm-view-switch input:focus-visible+.gm-view-track{outline:2px solid var(--acc);outline-offset:3px} /* 当前档位的文字高亮 */ body.gm-simple #gmSimpleLabel,body:not(.gm-simple) #gmDetailedLabel{color:var(--acc);font-weight:600} /* 只藏散文。控件 / 标签 / 实时结果 / 报错一律保留。 ⛑ :is(...) 与 :not(...) 之间【不能换行/newline】——CSS 里换行 = 后代组合器, 会变成「藏段落里的 /」而不是「藏段落」,散文一个都藏不掉(踩过)。 :has 守卫也顺带保护「以后有人在说明段落里加按钮」的情况。 */ body.gm-simple :is(.sec p, .hint, details.help, .gm-detail-only):not(:has(input,select,textarea,button,a,[role=button],[role=switch],[role=status],[aria-live],[tabindex])):not([role=status]):not([aria-live]){display:none!important} /* 空的输出黑窗(占位文字 "> 就绪 — 等待操作")在简易模式下也收起来。 ⛑ 只藏【空】的:一旦 JS 往里写了结果,:empty 不成立,窗口立刻回来 —— 规则 249「每次点击都必须有回显」不能破。 */ body.gm-simple pre:empty{display:none!important} /* 调参说明文字:车流 / 人流两张卡是 JS 动态渲染的(renderTraffic / renderCrowd / renderCrowdTypes),第三列那串中文没有 class ⇒ 上面的 :is() 命中不了,单独靠 .gm-tip 收。 ⛑ 以后新增的动态说明一律套 class="gm-tip",简易模式自动跟随。 地铁图的图例 / 副标题(MetroCardParts 的 .mm-*)同理。 */ body.gm-simple :is(.gm-tip,.mm-sub,.mm-legend,.mm-dir){display:none!important} @media(prefers-reduced-motion:reduce){.gm-view-track:before{transition:none}} """; internal const string Card = """
简易 详细
"""; internal const string Script = """ (()=>{ const sw=document.getElementById('gmDetailedMode'); if(!sw) return; function apply(){ const simple=!sw.checked; document.body.classList.toggle('gm-simple',simple); // 简易 = 最少装饰:侧栏跟着收起(详细则展开) document.body.classList.toggle('collapsed',simple); } // 每次打开(含 bfcache 前进/后退)都回简易;不记住上次的偏好 function reset(){ sw.checked=false; apply(); } sw.addEventListener('change',apply); window.addEventListener('pageshow',reset); reset(); })(); """; }