feat: 外观支持自定义 CSS/JS,并升级发帖工作台与积分存量看板

后台可注入全站 CSS/JS(SSR 生效,CSS 可热换);发帖/编辑改为锁一屏工作室;经济看板增加存量健康度;主题令牌与弹层误关一并收紧。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-18 04:16:32 +08:00
parent fa713bfc3f
commit 5f7193042f
41 changed files with 2297 additions and 873 deletions

View File

@@ -91,13 +91,14 @@ export default function BoardPicker({
}
};
const empty = !loading && !selected;
const label = loading
? "加载板块…"
: selected
? selected.name
: boards.length === 0
? "暂无可用板块"
: "选择板块";
: "请选择板块";
const colorIdx = selected
? boardColorIndex(selected, selectedIdx)
@@ -108,19 +109,28 @@ export default function BoardPicker({
<button
id={id}
type="button"
className="j13-board-trigger"
className={`j13-board-trigger${empty ? " is-empty" : ""}`}
disabled={disabled || loading || boards.length === 0}
aria-haspopup="listbox"
aria-expanded={open}
aria-controls={listId}
aria-invalid={empty || undefined}
onClick={() => setOpen((v) => !v)}
onKeyDown={onTriggerKeyDown}
>
<span className={`j13-board-trigger-ico av-${colorIdx}`} aria-hidden>
<span
className={`j13-board-trigger-ico${selected ? ` av-${colorIdx}` : " is-placeholder"}`}
aria-hidden
>
{(selected?.name || "板").slice(0, 1)}
</span>
<span className="flex-1 min-w-0 truncate font-semibold text-[14px]">
{label}
<span className="j13-board-trigger-copy">
<span className="j13-board-trigger-name">{label}</span>
{empty ? (
<span className="j13-board-trigger-hint">发布前必须选择</span>
) : loading ? (
<span className="j13-board-trigger-hint">正在加载</span>
) : null}
</span>
<ChevronDown
size={16}