Polish navigation and pipeline flow
This commit is contained in:
+33
-4
@@ -8,6 +8,7 @@
|
||||
============================================================ */
|
||||
|
||||
const ShellIcon = (name, opts) => window.IconKit ? window.IconKit.svg(name, opts) : '';
|
||||
const SHELL_SIDEBAR_COLLAPSED_KEY = 'airshelf:sidebar-collapsed';
|
||||
|
||||
const NAV = [
|
||||
{
|
||||
@@ -64,7 +65,7 @@ const SHELL_COMMANDS = [
|
||||
window.Shell = {
|
||||
render({ active = '', crumbs = [], balance = '¥327.40', topActions = '' } = {}) {
|
||||
const navHtml = NAV.map(n => `
|
||||
<a href="${n.href}" class="${active === n.id ? 'active' : ''}">
|
||||
<a href="${n.href}" class="${active === n.id ? 'active' : ''}" title="${n.label}" aria-label="${n.label}">
|
||||
${n.icon}
|
||||
<span>${n.label}</span>
|
||||
${n.badge ? `<span class="pill-mini">${n.badge}</span>` : ''}
|
||||
@@ -73,10 +74,16 @@ window.Shell = {
|
||||
|
||||
const sidebar = `
|
||||
<aside class="sidebar">
|
||||
<div class="brand">
|
||||
<img class="brand-logo" src="assets/logo.png" alt="Airshelf">
|
||||
<div class="sidebar-head">
|
||||
<a class="brand" href="index.html" aria-label="Airshelf 工作台">
|
||||
<span class="brand-clip"><img class="brand-logo" src="assets/logo.png" alt="Airshelf"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="search-box" onclick="Shell.openCommandPalette()">
|
||||
<button class="sidebar-toggle" type="button" onclick="Shell.toggleSidebarCollapse()" aria-label="收窄导航" title="收窄导航">
|
||||
<span class="sidebar-toggle-icon sidebar-toggle-icon--collapse">${ShellIcon('chevronLeft', { size: 18, strokeWidth: 1.8 })}</span>
|
||||
<span class="sidebar-toggle-icon sidebar-toggle-icon--expand">${ShellIcon('chevronRight', { size: 18, strokeWidth: 1.8 })}</span>
|
||||
</button>
|
||||
<div class="search-box" onclick="Shell.openCommandPalette()" title="搜索">
|
||||
${ShellIcon('search')}
|
||||
<input id="global-search" placeholder="搜索" readonly aria-label="打开全局搜索"/>
|
||||
<span class="kbd">Ctrl K</span>
|
||||
@@ -328,9 +335,11 @@ window.Shell = {
|
||||
const app = document.createElement('div');
|
||||
app.className = 'app';
|
||||
app.innerHTML = sidebar + `<main>${decorations}${topbar}<div class="content" id="page-content">${cornerMarks}</div></main>`;
|
||||
this.applySidebarCollapse(this.isSidebarCollapsed());
|
||||
|
||||
const src = document.getElementById('page');
|
||||
document.body.prepend(app);
|
||||
this.applySidebarCollapse(this.isSidebarCollapsed());
|
||||
if (src) {
|
||||
// 把页面 body 内容追加到 .content,保留 4 个 corner-mark SVG
|
||||
document.getElementById('page-content').insertAdjacentHTML('beforeend', src.innerHTML);
|
||||
@@ -352,6 +361,26 @@ window.Shell = {
|
||||
this._bindGlobalChrome();
|
||||
},
|
||||
|
||||
isSidebarCollapsed() {
|
||||
return localStorage.getItem(SHELL_SIDEBAR_COLLAPSED_KEY) === '1';
|
||||
},
|
||||
|
||||
applySidebarCollapse(collapsed) {
|
||||
document.body.classList.toggle('sidebar-collapsed', !!collapsed);
|
||||
const btn = document.querySelector('.sidebar-toggle');
|
||||
if (!btn) return;
|
||||
const label = collapsed ? '展开导航' : '收窄导航';
|
||||
btn.setAttribute('aria-label', label);
|
||||
btn.setAttribute('title', label);
|
||||
btn.setAttribute('aria-pressed', collapsed ? 'true' : 'false');
|
||||
},
|
||||
|
||||
toggleSidebarCollapse() {
|
||||
const next = !this.isSidebarCollapsed();
|
||||
localStorage.setItem(SHELL_SIDEBAR_COLLAPSED_KEY, next ? '1' : '0');
|
||||
this.applySidebarCollapse(next);
|
||||
},
|
||||
|
||||
_esc(s) {
|
||||
return String(s ?? '').replace(/[&<>"']/g, c => ({
|
||||
'&': '&', '<': '<', '>': '>', '"': '"', "'": '''
|
||||
|
||||
Reference in New Issue
Block a user