refactor: 主题选择改为调色盘图标+下拉菜单

- 🎨 图标按钮点击弹出下拉菜单
- 4 个中文主题选项:赤红合成/霓虹青蓝/琥珀终端/紫雾迷离
- 每项带彩色色块指示
- 当前主题高亮显示
- 点击外部自动关闭下拉
This commit is contained in:
Youzini-afk
2026-03-24 17:43:41 +08:00
parent 4288705117
commit 2240ad5e77
3 changed files with 118 additions and 38 deletions

View File

@@ -7,11 +7,24 @@
<span>ST-BME 记忆图谱</span>
<span class="bme-panel-subtitle" id="bme-panel-status">SYSTEM_ACTIVE</span>
</div>
<div class="bme-theme-palette">
<button class="bme-theme-dot" data-theme="crimson" title="赤红" style="--dot-color: #e94560"></button>
<button class="bme-theme-dot" data-theme="cyan" title="青蓝" style="--dot-color: #00e5ff"></button>
<button class="bme-theme-dot" data-theme="amber" title="琥珀" style="--dot-color: #ffb300"></button>
<button class="bme-theme-dot" data-theme="violet" title="紫雾" style="--dot-color: #b388ff"></button>
<div class="bme-theme-picker">
<button class="bme-theme-picker-btn" id="bme-theme-picker-btn" title="切换主题">
<i class="fa-solid fa-palette"></i>
</button>
<div class="bme-theme-dropdown" id="bme-theme-dropdown">
<button class="bme-theme-option" data-theme="crimson">
<span class="bme-theme-swatch" style="background: #e94560"></span>赤红合成
</button>
<button class="bme-theme-option" data-theme="cyan">
<span class="bme-theme-swatch" style="background: #00e5ff"></span>霓虹青蓝
</button>
<button class="bme-theme-option" data-theme="amber">
<span class="bme-theme-swatch" style="background: #ffb300"></span>琥珀终端
</button>
<button class="bme-theme-option" data-theme="violet">
<span class="bme-theme-swatch" style="background: #b388ff"></span>紫雾迷离
</button>
</div>
</div>
<button class="bme-panel-close" id="bme-panel-close" title="关闭">
<i class="fa-solid fa-xmark"></i>

View File

@@ -633,8 +633,8 @@ function _refreshConfigTab() {
_setInputValue("bme-setting-compress-prompt", settings.compressPrompt || DEFAULT_PROMPTS.compress);
_setInputValue("bme-setting-synopsis-prompt", settings.synopsisPrompt || DEFAULT_PROMPTS.synopsis);
_setInputValue("bme-setting-reflection-prompt", settings.reflectionPrompt || DEFAULT_PROMPTS.reflection);
// 主题调色盘高亮
_highlightThemeDot(settings.panelTheme || "crimson");
// 主题下拉菜单高亮
_highlightThemeOption(settings.panelTheme || "crimson");
}
function _bindConfigControls() {
@@ -721,15 +721,29 @@ function _bindConfigControls() {
bindText("bme-setting-reflection-prompt", (value) =>
_updateSettings?.({ reflectionPrompt: value }),
);
// 主题调色盘点击
panelEl.querySelectorAll(".bme-theme-dot").forEach((dot) => {
dot.addEventListener("click", () => {
const theme = dot.dataset.theme;
if (!theme) return;
_updateSettings?.({ panelTheme: theme });
_highlightThemeDot(theme);
// 主题下拉菜单
const pickerBtn = document.getElementById("bme-theme-picker-btn");
const dropdown = document.getElementById("bme-theme-dropdown");
if (pickerBtn && dropdown) {
pickerBtn.addEventListener("click", (e) => {
e.stopPropagation();
dropdown.classList.toggle("open");
});
});
dropdown.querySelectorAll(".bme-theme-option").forEach((opt) => {
opt.addEventListener("click", () => {
const theme = opt.dataset.theme;
if (!theme) return;
_updateSettings?.({ panelTheme: theme });
_highlightThemeOption(theme);
dropdown.classList.remove("open");
});
});
// 点击外部关闭
document.addEventListener("click", () => {
dropdown.classList.remove("open");
});
dropdown.addEventListener("click", (e) => e.stopPropagation());
}
document.getElementById("bme-test-llm")?.addEventListener("click", async () => {
await _actionHandlers.testMemoryLLM?.();
@@ -775,10 +789,10 @@ function _setText(id, text) {
if (el) el.textContent = String(text);
}
function _highlightThemeDot(themeName) {
function _highlightThemeOption(themeName) {
if (!panelEl) return;
panelEl.querySelectorAll(".bme-theme-dot").forEach((dot) => {
dot.classList.toggle("active", dot.dataset.theme === themeName);
panelEl.querySelectorAll(".bme-theme-option").forEach((opt) => {
opt.classList.toggle("active", opt.dataset.theme === themeName);
});
}

View File

@@ -202,33 +202,86 @@
font-weight: 400;
}
.bme-theme-palette {
.bme-theme-picker {
position: relative;
margin-right: 4px;
}
.bme-theme-picker-btn {
width: 28px;
height: 28px;
display: flex;
align-items: center;
gap: 6px;
margin-right: 8px;
}
.bme-theme-dot {
width: 16px;
height: 16px;
border-radius: 50%;
border: 2px solid transparent;
background: var(--dot-color);
justify-content: center;
border: none;
background: transparent;
color: var(--bme-on-surface-dim);
cursor: pointer;
padding: 0;
transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
box-shadow: 0 0 0 0 transparent;
border-radius: 4px;
font-size: 14px;
transition: all 0.15s;
}
.bme-theme-dot:hover {
transform: scale(1.2);
box-shadow: 0 0 6px var(--dot-color);
.bme-theme-picker-btn:hover {
background: var(--bme-surface-highest);
color: var(--bme-primary);
}
.bme-theme-dot.active {
border-color: var(--bme-on-surface, #e4e1e6);
box-shadow: 0 0 8px var(--dot-color);
.bme-theme-dropdown {
display: none;
position: absolute;
top: 100%;
right: 0;
margin-top: 6px;
background: var(--bme-surface-container, #1f1f22);
border: 1px solid var(--bme-border);
border-radius: 8px;
padding: 4px;
min-width: 130px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
z-index: 100;
animation: bme-dropdown-in 0.12s ease-out;
}
.bme-theme-dropdown.open {
display: block;
}
@keyframes bme-dropdown-in {
from { opacity: 0; transform: translateY(-4px); }
to { opacity: 1; transform: translateY(0); }
}
.bme-theme-option {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 7px 10px;
border: none;
background: transparent;
color: var(--bme-on-surface);
font-size: 12.5px;
cursor: pointer;
border-radius: 5px;
transition: background 0.12s;
white-space: nowrap;
}
.bme-theme-option:hover {
background: var(--bme-surface-high);
}
.bme-theme-option.active {
background: var(--bme-primary-dim);
color: var(--bme-primary-text);
}
.bme-theme-swatch {
width: 10px;
height: 10px;
border-radius: 50%;
flex-shrink: 0;
}
.bme-panel-close {