59 lines
3.9 KiB
TypeScript
59 lines
3.9 KiB
TypeScript
/** 采集浮窗只负责展示与折叠,登录、采集和页面跳转交由内容脚本处理。 */
|
|
export function renderCollectorPanel(
|
|
root: ShadowRoot,
|
|
authenticated: boolean,
|
|
minimized: boolean,
|
|
onToggle: (minimized: boolean) => void,
|
|
onAction: (kind: string) => void,
|
|
) {
|
|
root.innerHTML = `
|
|
<style>
|
|
:host{all:initial}
|
|
.collector{font:14px -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#1f2937}
|
|
button{box-sizing:border-box;cursor:pointer}
|
|
button:focus-visible{outline:3px solid #93c5fd;outline-offset:3px}
|
|
.box{width:156px;padding:12px;background:#fff;border-radius:12px;box-shadow:0 8px 28px #0003}
|
|
.head{display:flex;justify-content:space-between;align-items:center;font-weight:700;margin-bottom:10px;gap:8px}
|
|
.minimize{display:inline-flex;align-items:center;justify-content:center;flex:0 0 24px;width:24px;height:24px;padding:0;border:0;border-radius:50%;background:#f3f4f6;color:#4b5563}
|
|
.minimize:hover{background:#e5e7eb;color:#1f2937}
|
|
.minimize svg{width:14px;height:14px;pointer-events:none}
|
|
.btn{display:block;width:100%;border:0;border-radius:18px;padding:9px 8px;margin:7px 0;background:#2878f0;color:#fff;font-weight:600}
|
|
.btn.primary{background:#ff5353}
|
|
.link{display:block;width:100%;border:0;background:transparent;color:#1668dc;padding:5px}
|
|
.hint{font-size:12px;color:#6b7280;text-align:center;margin-top:6px;overflow-wrap:anywhere}
|
|
.launcher{display:none;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:0;border-radius:50%;background:#2878f0;color:#fff;box-shadow:0 4px 16px #0003;font:700 20px -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}
|
|
.launcher:hover{background:#1668dc}
|
|
.is-minimized .box{display:none}
|
|
.is-minimized .launcher{display:inline-flex}
|
|
</style>
|
|
<div class="collector${minimized ? ' is-minimized' : ''}">
|
|
<div class="box" id="atlas-collector-panel">
|
|
<div class="head">
|
|
<span>Atlas ERP</span>
|
|
<button class="minimize" type="button" aria-label="最小化采集窗口" title="最小化采集窗口">
|
|
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12h14" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
|
|
</button>
|
|
</div>
|
|
${authenticated
|
|
? '<button class="btn primary" type="button" data-action="edit">编辑上架</button><button class="btn" type="button" data-action="collect">采集商品</button><button class="link" type="button" data-action="erp">进入 ERP</button>'
|
|
: '<button class="btn primary" type="button" data-action="login">登录 Atlas ERP</button>'}
|
|
<div class="hint" data-hint></div>
|
|
</div>
|
|
<button class="launcher" type="button" aria-label="展开采集窗口" title="展开采集窗口" aria-controls="atlas-collector-panel" aria-expanded="${!minimized}">A</button>
|
|
</div>`;
|
|
const panel = root.querySelector<HTMLElement>('.collector')!;
|
|
const minimize = root.querySelector<HTMLButtonElement>('.minimize')!;
|
|
const launcher = root.querySelector<HTMLButtonElement>('.launcher')!;
|
|
const toggle = (next: boolean) => {
|
|
panel.classList.toggle('is-minimized', next);
|
|
launcher.setAttribute('aria-expanded', String(!next));
|
|
onToggle(next);
|
|
(next ? launcher : minimize).focus();
|
|
};
|
|
minimize.addEventListener('click', () => toggle(true));
|
|
launcher.addEventListener('click', () => toggle(false));
|
|
root.querySelectorAll<HTMLButtonElement>('[data-action]').forEach((button) =>
|
|
button.addEventListener('click', () => onAction(button.dataset.action ?? '')),
|
|
);
|
|
}
|