统一 Airshelf 界面组件与图标
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
(function () {
|
||||
const PATHS = {
|
||||
home: '<path d="M3 10.5 12 3l9 7.5"/><path d="M5 10v10h14V10"/><path d="M9 20v-6h6v6"/>',
|
||||
package: '<path d="M11 21.7a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.7l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.7Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/><path d="m7.5 4.3 9 5.1"/>',
|
||||
boxes: '<path d="M11 21.7a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.7l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.7Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/><path d="m7.5 4.3 9 5.1"/>',
|
||||
clapperboard: '<path d="m12.3 3.5 3 4"/><path d="M20.2 6 3 11l-.9-2.4a2 2 0 0 1 1.3-2.5l13.5-4a2 2 0 0 1 2.5 1.3Z"/><path d="m6.2 5.3 3.1 3.9"/><path d="M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z"/>',
|
||||
film: '<path d="m12.3 3.5 3 4"/><path d="M20.2 6 3 11l-.9-2.4a2 2 0 0 1 1.3-2.5l13.5-4a2 2 0 0 1 2.5 1.3Z"/><path d="m6.2 5.3 3.1 3.9"/><path d="M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z"/>',
|
||||
video: '<path d="m16 13 5.2 3.1a.5.5 0 0 0 .8-.4V8.3a.5.5 0 0 0-.8-.4L16 11"/><rect x="2" y="6" width="14" height="12" rx="2"/>',
|
||||
sparkles: '<path d="M12 3l1.7 4.6L18 9l-4.3 1.4L12 15l-1.7-4.6L6 9l4.3-1.4L12 3Z"/><path d="M19 15l.9 2.1L22 18l-2.1.9L19 21l-.9-2.1L16 18l2.1-.9L19 15Z"/>',
|
||||
images: '<rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.1-3.1a2 2 0 0 0-2.8 0L6 21"/>',
|
||||
library: '<rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.1-3.1a2 2 0 0 0-2.8 0L6 21"/>',
|
||||
users: '<path d="M16 21v-2a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v2"/><circle cx="9.5" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
|
||||
wallet: '<rect x="3" y="6" width="18" height="13" rx="2"/><path d="M3 10h18"/><path d="M16 14h2"/>',
|
||||
creditCard: '<rect x="2" y="5" width="20" height="14" rx="2"/><path d="M2 10h20"/>',
|
||||
settings: '<path d="M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Z"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.2a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.2A1.7 1.7 0 0 0 4.7 9a1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3 1.7 1.7 0 0 0 1.1-1.5V3a2 2 0 1 1 4 0v.2a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8 1.7 1.7 0 0 0 1.5 1h.1a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1Z"/>',
|
||||
airshelf: '<path d="M4.5 19 12 4.5 19.5 19"/><path d="M8 14h8"/><path d="M7 17h10"/><path d="M9.5 10.3c1.5-1.2 3.5-1.2 5 0"/>',
|
||||
flame: '<path d="M8.5 14.5c0-2 1.5-3.4 3.5-5.5.4 2.2 2.8 3.1 2.8 5.6a3.3 3.3 0 0 1-6.3-.1Z"/><path d="M12 22c4 0 7-2.8 7-7 0-4.7-3.3-7.3-5-12-2 3.3-7 6-7 12a5 5 0 0 0 5 7Z"/>',
|
||||
search: '<circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/>',
|
||||
bell: '<path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10 21a2 2 0 0 0 4 0"/>',
|
||||
list: '<path d="M8 6h13"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M3 6h.01"/><path d="M3 12h.01"/><path d="M3 18h.01"/>',
|
||||
check: '<path d="M20 6 9 17l-5-5"/>',
|
||||
x: '<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',
|
||||
plus: '<path d="M12 5v14"/><path d="M5 12h14"/>',
|
||||
productPlus: '<path d="M12 22V12"/><path d="M16 17h6"/><path d="M19 14v6"/><path d="M21 10.5V8a2 2 0 0 0-1-1.7l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.7l7 4a2 2 0 0 0 2 0l1.7-1"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="m7.5 4.3 9 5.1"/>',
|
||||
arrowRight: '<path d="M5 12h14"/><path d="m12 5 7 7-7 7"/>',
|
||||
arrowLeft: '<path d="M19 12H5"/><path d="m12 19-7-7 7-7"/>',
|
||||
arrowUp: '<path d="M12 19V5"/><path d="m5 12 7-7 7 7"/>',
|
||||
chevronDown: '<path d="m6 9 6 6 6-6"/>',
|
||||
rotateCcw: '<path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 4v5h5"/>',
|
||||
download: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/>',
|
||||
upload: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m17 8-5-5-5 5"/><path d="M12 3v12"/>',
|
||||
moreHorizontal: '<circle cx="5" cy="12" r="1.6" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.6" fill="currentColor" stroke="none"/><circle cx="19" cy="12" r="1.6" fill="currentColor" stroke="none"/>',
|
||||
trash: '<path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="m19 6-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/>',
|
||||
edit: '<path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5Z"/>',
|
||||
play: '<path d="m6 4 14 8-14 8Z"/>',
|
||||
clock: '<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>',
|
||||
alertCircle: '<circle cx="12" cy="12" r="9"/><path d="M12 8v4"/><path d="M12 16h.01"/>',
|
||||
info: '<circle cx="12" cy="12" r="9"/><path d="M12 11v5"/><path d="M12 8h.01"/>',
|
||||
shieldCheck: '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z"/><path d="m9 12 2 2 4-4"/>',
|
||||
messageCircle: '<path d="M21 11.5a8.5 8.5 0 0 1-12.5 7.5L3 20l1-5.5A8.5 8.5 0 1 1 21 11.5Z"/>',
|
||||
mail: '<rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 6 9-6"/>',
|
||||
lock: '<rect x="3" y="11" width="18" height="10" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>',
|
||||
eye: '<path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/>',
|
||||
image: '<rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.1-3.1a2 2 0 0 0-2.8 0L6 21"/>',
|
||||
grid: '<rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/>',
|
||||
copy: '<rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>',
|
||||
save: '<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2Z"/><path d="M17 21v-8H7v8"/><path d="M7 3v5h8"/>',
|
||||
userPlus: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M19 8v6"/><path d="M22 11h-6"/>',
|
||||
helpCircle: '<circle cx="12" cy="12" r="9"/><path d="M9.5 9a2.5 2.5 0 0 1 5 0c0 1.5-2.5 2-2.5 4"/><path d="M12 17h.01"/>'
|
||||
};
|
||||
|
||||
const ALIASES = {
|
||||
dashboard: 'home',
|
||||
products: 'package',
|
||||
projects: 'clapperboard',
|
||||
assetFactory: 'sparkles',
|
||||
account: 'creditCard',
|
||||
billing: 'creditCard',
|
||||
team: 'users',
|
||||
queue: 'list',
|
||||
arrow: 'arrowRight',
|
||||
back: 'arrowLeft',
|
||||
close: 'x',
|
||||
rerun: 'rotateCcw',
|
||||
more: 'moreHorizontal',
|
||||
danger: 'alertCircle'
|
||||
};
|
||||
|
||||
function svg(name, opts) {
|
||||
opts = opts || {};
|
||||
const key = ALIASES[name] || name;
|
||||
const body = PATHS[key] || PATHS.helpCircle;
|
||||
const size = opts.size || 16;
|
||||
const strokeWidth = opts.strokeWidth || 1.5;
|
||||
const className = ['ui-icon', opts.className || ''].join(' ').trim();
|
||||
const label = opts.label ? ` role="img" aria-label="${escapeAttr(opts.label)}"` : ' aria-hidden="true"';
|
||||
return `<svg class="${className}" data-icon="${key}" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="${strokeWidth}" stroke-linecap="round" stroke-linejoin="round" focusable="false"${label}>${body}</svg>`;
|
||||
}
|
||||
|
||||
function escapeAttr(value) {
|
||||
return String(value).replace(/[&<>"']/g, c => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]));
|
||||
}
|
||||
|
||||
window.IconKit = {
|
||||
svg,
|
||||
names: () => Object.keys(PATHS),
|
||||
has: name => !!PATHS[ALIASES[name] || name]
|
||||
};
|
||||
})();
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
+64
-14
@@ -1,5 +1,5 @@
|
||||
/* ============================================================
|
||||
流·Studio · Restraint V2.1 · Firecrawl-aligned · 纯净版
|
||||
Airshelf · Restraint V2.1 · Firecrawl-aligned · 纯净版
|
||||
============================================================
|
||||
严格遵循 DESIGN_SPEC_V2.md V2.1 · 不含任何 V1/V2 legacy alias
|
||||
============================================================ */
|
||||
@@ -115,11 +115,11 @@
|
||||
--r-pill: 999px;
|
||||
|
||||
/* ===== Font · 关键:--font-mono 必须含 PuHuiTi 中文 fallback ===== */
|
||||
/* Inter / JetBrains Mono 都不含 CJK 字形。
|
||||
/* Inter 不含 CJK 字形。
|
||||
字体链按字符级 fallthrough,中文字符会找下一个候选 —— 必须包含 PuHuiTi。 */
|
||||
--font-sans: 'Inter', 'Alibaba PuHuiTi', 'PingFang SC', 'Microsoft YaHei', system-ui, sans-serif;
|
||||
--font-inter: 'Inter', system-ui, sans-serif;
|
||||
--font-mono: 'JetBrains Mono', 'Geist Mono', ui-monospace, 'Alibaba PuHuiTi', 'PingFang SC', 'Microsoft YaHei', monospace;
|
||||
--font-mono: 'Inter', 'Alibaba PuHuiTi', 'PingFang SC', 'Microsoft YaHei', system-ui, sans-serif;
|
||||
|
||||
/* ===== Transition ===== */
|
||||
--t-fast: 100ms ease;
|
||||
@@ -161,6 +161,52 @@ button { font: inherit; cursor: pointer; border: 0; background: none; color: inh
|
||||
input, textarea, select { font: inherit; color: inherit; outline: none; }
|
||||
img, svg, video { display: block; max-width: 100%; }
|
||||
|
||||
/* ─── Icon system · Lucide-line only ─── */
|
||||
:root {
|
||||
--icon-stroke: 1.5;
|
||||
--icon-xs: 12px;
|
||||
--icon-s: 14px;
|
||||
--icon-m: 16px;
|
||||
--icon-l: 20px;
|
||||
--icon-xl: 24px;
|
||||
}
|
||||
.ui-icon {
|
||||
width: var(--icon-m);
|
||||
height: var(--icon-m);
|
||||
flex: 0 0 auto;
|
||||
display: block;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: var(--icon-stroke);
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
.ui-icon * { vector-effect: non-scaling-stroke; }
|
||||
.ui-icon [stroke="none"] {
|
||||
fill: currentColor;
|
||||
stroke: none;
|
||||
}
|
||||
:where(nav a, .search-box, .balance-chip, .queue-chip, .icon-btn, .btn, .chip, .toolbar, .page-head, .toast, .modal, .drawer, .card-del-btn, .row-more, .gen-img-btn, .shortcut, .empty-state) svg:not(.corner):not(.quote-icon) {
|
||||
flex: 0 0 auto;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: var(--icon-stroke);
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
:where(nav a, .search-box, .balance-chip, .queue-chip, .icon-btn, .btn, .chip, .toolbar, .page-head, .toast, .modal, .drawer, .card-del-btn, .row-more, .gen-img-btn, .shortcut, .empty-state) svg:not(.corner):not(.quote-icon) [fill="currentColor"] {
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
}
|
||||
:where(nav a, .search-box, .balance-chip, .queue-chip, .icon-btn, .btn, .chip, .toolbar, .page-head, .toast, .modal, .drawer, .card-del-btn, .row-more, .gen-img-btn, .shortcut, .empty-state) svg:not(.corner):not(.quote-icon) [stroke="none"] {
|
||||
fill: currentColor;
|
||||
stroke: none;
|
||||
}
|
||||
.row-more svg circle {
|
||||
fill: currentColor !important;
|
||||
stroke: none !important;
|
||||
}
|
||||
|
||||
.num, .tnum { font-variant-numeric: tabular-nums; }
|
||||
.mono { font-family: var(--font-mono); }
|
||||
.muted { color: var(--black-alpha-56); }
|
||||
@@ -185,8 +231,8 @@ aside.sidebar {
|
||||
overflow-y: auto;
|
||||
}
|
||||
.brand { display: flex; align-items: center; gap: 10px; padding: 6px 8px 16px; }
|
||||
.flame { width: 22px; height: 22px; color: var(--heat); }
|
||||
.flame svg { width: 100%; height: 100%; }
|
||||
.brand-mark, .flame { width: 22px; height: 22px; color: var(--heat); }
|
||||
.brand-mark svg, .flame svg { width: 100%; height: 100%; }
|
||||
.brand .name { font-weight: 600; font-size: 18px; letter-spacing: -.012em; color: var(--accent-black); }
|
||||
|
||||
/* sidebar search · Ctrl K Inter Bold 平铺 */
|
||||
@@ -203,7 +249,7 @@ aside.sidebar {
|
||||
}
|
||||
.search-box:hover { border-color: var(--black-alpha-24); }
|
||||
.search-box:focus-within { border-color: var(--heat-40); box-shadow: inset 0 0 0 1px var(--heat-40); }
|
||||
.search-box svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--black-alpha-56); }
|
||||
.search-box svg { width: var(--icon-m); height: var(--icon-m); flex-shrink: 0; color: var(--black-alpha-56); }
|
||||
.search-box input {
|
||||
flex: 1; min-width: 0;
|
||||
border: 0; background: transparent;
|
||||
@@ -242,7 +288,7 @@ nav a {
|
||||
}
|
||||
nav a:hover { background: var(--black-alpha-4); color: var(--accent-black); }
|
||||
nav a.active { background: var(--heat-12); color: var(--heat); }
|
||||
nav a svg { width: 14px; height: 14px; opacity: .85; }
|
||||
nav a svg { width: var(--icon-m); height: var(--icon-m); opacity: .85; }
|
||||
nav a.active svg { opacity: 1; }
|
||||
nav a .pill-mini {
|
||||
margin-left: auto;
|
||||
@@ -330,20 +376,20 @@ main { position: relative; background: var(--background-base); min-width: 0; }
|
||||
}
|
||||
.balance-chip:hover { background: var(--black-alpha-4); border-color: var(--black-alpha-24); }
|
||||
.balance-chip strong { color: var(--accent-black); font-weight: 600; font-variant-numeric: tabular-nums; }
|
||||
.balance-chip svg { width: 13px; height: 13px; color: var(--heat); }
|
||||
.balance-chip svg { width: var(--icon-m); height: var(--icon-m); color: var(--heat); }
|
||||
.icon-btn {
|
||||
width: 36px; height: 36px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border-faint);
|
||||
border-radius: var(--r-md);
|
||||
border-radius: var(--r-pill);
|
||||
color: var(--black-alpha-56);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
transition: background var(--t-base), border-color var(--t-base), color var(--t-base);
|
||||
}
|
||||
.icon-btn:hover { background: var(--black-alpha-4); color: var(--accent-black); border-color: var(--black-alpha-24); }
|
||||
.icon-btn svg { width: 15px; height: 15px; }
|
||||
.icon-btn svg { width: var(--icon-m); height: var(--icon-m); }
|
||||
.icon-btn .dot-noti {
|
||||
position: absolute; top: 8px; right: 9px;
|
||||
width: 7px; height: 7px; border-radius: 50%;
|
||||
@@ -376,7 +422,7 @@ main { position: relative; background: var(--background-base); min-width: 0; }
|
||||
}
|
||||
.queue-chip:hover { background: var(--black-alpha-4); border-color: var(--black-alpha-24); }
|
||||
.queue-chip[hidden] { display: none; }
|
||||
.queue-chip svg { width: 14px; height: 14px; color: var(--black-alpha-56); }
|
||||
.queue-chip svg { width: var(--icon-m); height: var(--icon-m); color: var(--black-alpha-56); }
|
||||
.queue-chip .count {
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
height: 20px; min-width: 20px; padding: 0 6px;
|
||||
@@ -441,7 +487,8 @@ main { position: relative; background: var(--background-base); min-width: 0; }
|
||||
padding: 0 20px;
|
||||
font-size: 13.5px;
|
||||
}
|
||||
.page-head .actions > .btn svg { width: 14px; height: 14px; }
|
||||
.page-head .actions > .btn svg { width: var(--icon-s); height: var(--icon-s); }
|
||||
.page-head .actions > .btn.btn-create svg { width: var(--icon-m); height: var(--icon-m); }
|
||||
|
||||
.section-h { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 14px; }
|
||||
.section-h h2 { font-size: 16px; font-weight: 600; letter-spacing: -.01em; color: var(--accent-black); }
|
||||
@@ -482,7 +529,7 @@ main { position: relative; background: var(--background-base); min-width: 0; }
|
||||
background: var(--black-alpha-5);
|
||||
border-color: var(--black-alpha-12);
|
||||
}
|
||||
.btn svg { width: 13px; height: 13px; }
|
||||
.btn svg { width: var(--icon-s); height: var(--icon-s); }
|
||||
.btn[hidden] { display: none; }
|
||||
|
||||
.btn-primary {
|
||||
@@ -1588,7 +1635,10 @@ table.t tbody tr:hover { background: var(--black-alpha-4); }
|
||||
.product-card:has(.tri-missing-badge:hover),
|
||||
.product-card:has(.tri-missing-badge:focus-within),
|
||||
.asset-card:has(.tri-missing-badge:hover),
|
||||
.asset-card:has(.tri-missing-badge:focus-within) {
|
||||
.asset-card:has(.tri-missing-badge:focus-within),
|
||||
.asset-card-2:has(.tri-missing-badge:hover),
|
||||
.asset-card-2:has(.tri-missing-badge:focus-within) {
|
||||
overflow: visible;
|
||||
z-index: 5;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
+19
-17
@@ -1,5 +1,5 @@
|
||||
/* ============================================================
|
||||
流·Studio · Shell renderer V2.1
|
||||
Airshelf · Shell renderer V2.1
|
||||
渲染 sidebar / topbar / 网格背景装饰 / Toast / Modal helpers
|
||||
每个页面调用 Shell.render({ active, crumbs, balance, topActions })
|
||||
|
||||
@@ -7,38 +7,40 @@
|
||||
- sidebar 搜索 ⌘K → "Ctrl K" Inter Bold 平铺(无 kbd 边框)
|
||||
============================================================ */
|
||||
|
||||
const ShellIcon = (name, opts) => window.IconKit ? window.IconKit.svg(name, opts) : '';
|
||||
|
||||
const NAV = [
|
||||
{
|
||||
id: 'dashboard', label: '工作台', href: 'index.html',
|
||||
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M3 12 12 3l9 9"/><path d="M5 10v10h14V10"/></svg>'
|
||||
icon: ShellIcon('home')
|
||||
},
|
||||
{
|
||||
id: 'products', label: '商品库', href: 'products.html', badge: '7',
|
||||
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="m3 7 9-4 9 4-9 4-9-4z"/><path d="m3 12 9 4 9-4M3 17l9 4 9-4"/></svg>'
|
||||
icon: ShellIcon('package')
|
||||
},
|
||||
{
|
||||
id: 'projects', label: '视频项目', href: 'projects.html', badge: '8',
|
||||
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="4" width="18" height="16"/><path d="M7 4v16M16 4v16M3 9h18M3 15h18"/></svg>'
|
||||
icon: ShellIcon('clapperboard')
|
||||
},
|
||||
{
|
||||
id: 'asset-factory', label: '图片生成', href: 'asset-factory.html',
|
||||
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l1.7 4.6L18 9l-4.3 1.4L12 15l-1.7-4.6L6 9l4.3-1.4L12 3z"/><path d="M19 16l.85 2.3L22 19l-2.15.7L19 22l-.85-2.3L16 19l2.15-.7L19 16z"/></svg>'
|
||||
icon: ShellIcon('sparkles')
|
||||
},
|
||||
{
|
||||
id: 'library', label: '资产库', href: 'library.html',
|
||||
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="4" width="6" height="16"/><rect x="11" y="4" width="4" height="16"/><rect x="17" y="6" width="4" height="14"/></svg>'
|
||||
icon: ShellIcon('images')
|
||||
},
|
||||
{
|
||||
id: 'team', label: '团队', href: 'team.html',
|
||||
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="9" cy="8" r="3"/><circle cx="17" cy="9" r="2.5"/><path d="M3 19c0-3 2.7-5 6-5s6 2 6 5M14 19c.5-2.4 2.4-4 5-4 .8 0 1.5.2 2 .5"/></svg>'
|
||||
icon: ShellIcon('users')
|
||||
},
|
||||
{
|
||||
id: 'account', label: '消费', href: 'account.html',
|
||||
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="6" width="18" height="13" rx="2"/><path d="M3 10h18M16 14h2"/></svg>'
|
||||
icon: ShellIcon('creditCard')
|
||||
},
|
||||
{
|
||||
id: 'settings', label: '设置', href: 'settings.html',
|
||||
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8 2 2 0 0 1-2.8 2.8 1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5 2 2 0 0 1-4 0 1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3 2 2 0 0 1-2.8-2.8 1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1 2 2 0 0 1 0-4 1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8 2 2 0 0 1 2.8-2.8 1.7 1.7 0 0 0 1.8.3 1.7 1.7 0 0 0 1-1.5 2 2 0 0 1 4 0 1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3 2 2 0 0 1 2.8 2.8 1.7 1.7 0 0 0-.3 1.8 1.7 1.7 0 0 0 1.5 1 2 2 0 0 1 0 4 1.7 1.7 0 0 0-1.5 1.1Z"/></svg>'
|
||||
icon: ShellIcon('settings')
|
||||
}
|
||||
];
|
||||
|
||||
@@ -55,11 +57,11 @@ window.Shell = {
|
||||
const sidebar = `
|
||||
<aside class="sidebar">
|
||||
<div class="brand">
|
||||
<div class="flame"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2c1 3 4 5 4 9a4 4 0 0 1-4 4 4 4 0 0 1-4-4 5 5 0 0 1 1.5-3.5C10.5 6 11.5 4 12 2zm-1 13c0 2 1 3 1 5 1-1 3-2 3-5 0-1.5-1-2-2-3-1 1-2 2-2 3z"/></svg></div>
|
||||
<div><div class="name">流·Studio</div></div>
|
||||
<div class="brand-mark">${ShellIcon('airshelf', { size: 22 })}</div>
|
||||
<div><div class="name">Airshelf</div></div>
|
||||
</div>
|
||||
<div class="search-box" onclick="document.getElementById('global-search').focus()">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>
|
||||
${ShellIcon('search')}
|
||||
<input id="global-search" placeholder="搜索"/>
|
||||
<span class="kbd">Ctrl K</span>
|
||||
</div>
|
||||
@@ -90,16 +92,16 @@ window.Shell = {
|
||||
${crumbHtml}
|
||||
<div class="right">
|
||||
<span class="balance-chip" onclick="location.href='account.html'">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="9"/><path d="M12 7v10M9 10h4a1.5 1.5 0 0 1 0 3h-3a1.5 1.5 0 0 0 0 3h4"/></svg>
|
||||
${ShellIcon('creditCard')}
|
||||
余额 <strong>${balance}</strong>
|
||||
</span>
|
||||
<button class="queue-chip" onclick="Shell.toast('任务队列', '3 个进行中')" hidden>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18M3 12h18M3 18h18"/></svg>
|
||||
${ShellIcon('list')}
|
||||
任务队列
|
||||
<span class="count">3</span>
|
||||
</button>
|
||||
<button class="icon-btn" onclick="location.href='messages.html'" title="消息中心">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9M10 21a2 2 0 0 0 4 0"/></svg>
|
||||
${ShellIcon('bell')}
|
||||
<span class="count-noti">12</span>
|
||||
</button>
|
||||
<div class="topbar-avatar" onclick="Shell.toast('账户菜单', '李 · li@shop.com')" title="账户">
|
||||
@@ -120,7 +122,7 @@ window.Shell = {
|
||||
|
||||
const toastHtml = `
|
||||
<div class="toast" id="__toast">
|
||||
<div class="ic-t"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg></div>
|
||||
<div class="ic-t">${ShellIcon('check')}</div>
|
||||
<div class="txt" id="__toast-txt">操作成功<span class="mono">[ 200 OK ]</span></div>
|
||||
</div>
|
||||
`;
|
||||
@@ -129,7 +131,7 @@ window.Shell = {
|
||||
const lightboxHtml = `
|
||||
<div class="np-lightbox" id="np-lightbox" onclick="Shell._closeLightbox()">
|
||||
<button class="lb-x" type="button" onclick="event.stopPropagation();Shell._closeLightbox()">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M18 6L6 18M6 6l12 12"/></svg>
|
||||
${ShellIcon('x')}
|
||||
</button>
|
||||
<img id="np-lightbox-img" alt="">
|
||||
<span class="lb-name" id="np-lightbox-name"></span>
|
||||
|
||||
Reference in New Issue
Block a user