refactor: 设置面板改为右侧抽屉,修复布局跳动问题

- ConfigPanel 重写为 Drawer:右侧 320px 滑入面板 + 半透明遮罩
- 设置按钮始终可见,不依赖连接状态
- 抽屉不推挤主布局,点击遮罩或✕关闭
- 设置项分组显示,带功能描述文案

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-06-13 16:54:57 +08:00
parent 093dc26fa0
commit f17c3c24a7
3 changed files with 158 additions and 63 deletions

View File

@@ -1,5 +1,5 @@
// ============================================================
// ConfigPanel — 会话配置面板
// ConfigPanel — 右侧抽屉式配置面板
// 职责TTS 开关、detail level 切换、语言选择
// ============================================================
@@ -13,43 +13,60 @@ interface ConfigPanelProps {
export function ConfigPanel({ config, onUpdate, onClose }: ConfigPanelProps) {
return (
<div className="config-panel">
<div className="config-panel__header">
<span></span>
<button className="config-panel__close" onClick={onClose}></button>
<div className="drawer-overlay" onClick={onClose}>
<div className="drawer" onClick={(e) => e.stopPropagation()}>
<div className="drawer__header">
<span className="drawer__title"></span>
<button className="drawer__close" onClick={onClose}></button>
</div>
<div className="drawer__body">
<div className="config-group">
<div className="config-group__title"></div>
<label className="config-row">
<div className="config-row__info">
<span className="config-row__label"></span>
<span className="config-row__desc">AI </span>
</div>
<input
type="checkbox"
checked={config.ttsEnabled}
onChange={(e) => onUpdate({ ttsEnabled: e.target.checked })}
/>
</label>
<label className="config-row">
<div className="config-row__info">
<span className="config-row__label"></span>
<span className="config-row__desc"></span>
</div>
<select
value={config.detailLevel}
onChange={(e) => onUpdate({ detailLevel: e.target.value as "low" | "high" })}
>
<option value="low"></option>
<option value="high"></option>
</select>
</label>
<label className="config-row">
<div className="config-row__info">
<span className="config-row__label"></span>
<span className="config-row__desc"></span>
</div>
<select
value={config.language}
onChange={(e) => onUpdate({ language: e.target.value })}
>
<option value="zh-CN"></option>
<option value="en-US">English</option>
<option value="ja-JP"></option>
</select>
</label>
</div>
</div>
</div>
<label className="config-row">
<span></span>
<input
type="checkbox"
checked={config.ttsEnabled}
onChange={(e) => onUpdate({ ttsEnabled: e.target.checked })}
/>
</label>
<label className="config-row">
<span></span>
<select
value={config.detailLevel}
onChange={(e) => onUpdate({ detailLevel: e.target.value as "low" | "high" })}
>
<option value="low"></option>
<option value="high"></option>
</select>
</label>
<label className="config-row">
<span></span>
<select
value={config.language}
onChange={(e) => onUpdate({ language: e.target.value })}
>
<option value="zh-CN"></option>
<option value="en-US">English</option>
<option value="ja-JP"></option>
</select>
</label>
</div>
);
}