- 渲染: 结果/过程分离(气泡只放最终结果,过程轮叙述+工具卡收进轨迹卡默认收起可展开——治『流式后正文消失』且不再 N 气泡打扰) - 渲染 P0: v-memo 定向 dep(只有真正渲染流式块的 item 失效,其余取占位) + renderItems 桶 memo(签名覆盖全消费输入,item 引用稳定) + 指纹 watch 降为 O(1) toolEpoch - TopBar 三处 O(n) messages computed 合并单次遍历;md 缓存改有界 LRU(除满即全清抖动);useTurnTrace 补 never 穷尽 + default;MessageItem 模板去重 - 无障碍(四批累计): 可点容器键盘化(含 role/tabindex/keydown/aria-expanded) + icon-only aria-label 约 60 处 + 装饰图标 aria-hidden + 52 个滚动容器 overscroll-behavior:contain + 设置开关聚焦可见环 + outline 零补偿站点补 :focus-visible - UX 走查项: 灵感 IDEA-10/11、知识 KNOW-6/7/9、项目详情 O8、审计 SA-4、设置 SA-6/26/27/28(脏表单/冗余 save/clamp/删除二次确认) - 文件查看专项: 切工程状态残留 F5/F6、FileTree 去重与展开反馈 F7/F15/F17、切文件头部残留 F18、R 状态着色 F19;FilePreview diff 文件头(---/+++)误当增删渲染修复 + 大纲行高亮死样式修复 + 图片失败文案 i18n 化 - 同步 IO 收口(异步上下文内阻塞): unattended 看板读写改 tokio::fs、fetch_url 探活改 spawn_blocking、http/generate_image 清理改 tokio::fs - 子代理 P3 批量: 任务书钉扎上限/截断文案区分父子语境/环境画像日期/temperature 可覆盖/model 回退上报/lang 透传 - crate 清理: df-execute·df-types 注释与格式、df-ideas 过时注释、df-nodes subflow 夸大描述、df-project 死变量
135 lines
5.6 KiB
CSS
135 lines
5.6 KiB
CSS
/* DevFlow 设置统一组件库(UX 重构阶段1)
|
|
各 Panel scoped 副本抽取到全局,消除 panel/setting 系列/toggle/btn 5/5+3/5 重复。
|
|
来源基准:GeneralPanel/KnowledgePanel scoped(已确认 CSS 一致)。
|
|
各 Panel scoped 仅保留特有样式:provider-card/dir-row/connection-card 等。 */
|
|
|
|
/* ===== 面板容器(5/5 Panel 重复) ===== */
|
|
.panel {
|
|
background: var(--df-bg-card);
|
|
border: 0.5px solid var(--df-border);
|
|
border-radius: var(--df-radius-lg);
|
|
padding: var(--df-pad-panel);
|
|
}
|
|
.panel-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: var(--df-gap-head);
|
|
}
|
|
.panel-header h2 { font-size: 15px; font-weight: 500; }
|
|
|
|
/* ===== 设置行容器(表单型 Panel 共用) ===== */
|
|
.general-settings { display: flex; flex-direction: column; }
|
|
/* 窄列(设置抽屉/面板窄态)三防线:gap 隔开 info 与 control;info min-width:0 允许收缩、
|
|
label/desc 文本按常规断行(多词换行,不逐字竖排);control 不被压缩挤扁 */
|
|
.setting-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 14px 0;
|
|
border-bottom: 0.5px solid var(--df-border);
|
|
}
|
|
.setting-row:last-child { border-bottom: none; }
|
|
.setting-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
|
|
.setting-label { font-size: 14px; font-weight: 500; color: var(--df-text); }
|
|
.setting-desc { font-size: 12px; color: var(--df-text-dim); }
|
|
.setting-control { display: flex; align-items: center; flex-shrink: 0; }
|
|
|
|
/* ===== 控件(5/5 Panel 重复) ===== */
|
|
/* 控件统一基准(padding/border/radius/font 对齐),各 type 仅差异化必要属性 */
|
|
.setting-select {
|
|
padding: 6px 12px;
|
|
background: var(--df-bg);
|
|
border: 0.5px solid var(--df-border);
|
|
border-radius: var(--df-radius-sm);
|
|
color: var(--df-text);
|
|
font-size: 13px;
|
|
outline: none;
|
|
cursor: pointer;
|
|
min-width: 160px;
|
|
}
|
|
.setting-select:focus { border-color: var(--df-accent); }
|
|
|
|
/* number input:窄,无 spinner 累赘外观,继承基准样式 */
|
|
.setting-number {
|
|
padding: 6px 12px;
|
|
background: var(--df-bg);
|
|
border: 0.5px solid var(--df-border);
|
|
border-radius: var(--df-radius-sm);
|
|
color: var(--df-text);
|
|
font-size: 13px;
|
|
font-family: inherit;
|
|
outline: none;
|
|
cursor: pointer;
|
|
min-width: 80px;
|
|
}
|
|
.setting-number:focus { border-color: var(--df-accent); }
|
|
/* 隐藏原生数字加减箭头(与文本框视觉统一;注释声明无 spinner 但此前漏了实现) */
|
|
.setting-number::-webkit-outer-spin-button,
|
|
.setting-number::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
|
|
.setting-number { -moz-appearance: textfield; appearance: textfield; }
|
|
|
|
/* text input:通用单行文本(目录/模型名/脚本名单) */
|
|
.setting-input {
|
|
padding: 6px 12px;
|
|
background: var(--df-bg);
|
|
border: 0.5px solid var(--df-border);
|
|
border-radius: var(--df-radius-sm);
|
|
color: var(--df-text);
|
|
font-size: 13px;
|
|
font-family: inherit;
|
|
outline: none;
|
|
min-width: 160px;
|
|
}
|
|
.setting-input:focus { border-color: var(--df-accent); }
|
|
.setting-input::placeholder { color: var(--df-text-dim); }
|
|
|
|
/* textarea:多行(自定义提示词等),垂直拉伸 */
|
|
.setting-textarea {
|
|
width: 100%;
|
|
padding: 8px 12px;
|
|
background: var(--df-bg);
|
|
border: 0.5px solid var(--df-border);
|
|
border-radius: var(--df-radius-sm);
|
|
color: var(--df-text);
|
|
font-size: 13px;
|
|
font-family: inherit;
|
|
line-height: 1.5;
|
|
outline: none;
|
|
resize: vertical;
|
|
min-height: 80px;
|
|
box-sizing: border-box;
|
|
}
|
|
.setting-textarea:focus { border-color: var(--df-accent); }
|
|
.setting-textarea::placeholder { color: var(--df-text-dim); }
|
|
|
|
/* Toggle(3/5 Panel 重复) */
|
|
.toggle { position: relative; display: inline-block; width: 40px; height: 22px; cursor: pointer; }
|
|
.toggle input { opacity: 0; width: 0; height: 0; }
|
|
/* 键盘聚焦可见环:原生 checkbox 被 opacity:0+零尺寸隐藏,global.css 的 :focus-visible 兜底
|
|
画在零尺寸 input 上不可见;把聚焦态转移到可见的 slider。用 :focus-visible(非 :focus-within)
|
|
保证鼠标点击不显环、仅 Tab 键盘导航出现;.toggle--sm 变体同匹配(.toggle 前缀)。
|
|
:focus{border-color} 仅覆盖 setting-select/input 等可见输入,覆盖不到这种视觉隐藏 checkbox。 */
|
|
.toggle input:focus-visible + .toggle-slider {
|
|
outline: 2px solid var(--df-accent);
|
|
outline-offset: 2px;
|
|
}
|
|
.toggle-slider { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: var(--df-border); border-radius: var(--df-radius-lg); transition: background 0.2s; }
|
|
.toggle-slider::before { content: ''; position: absolute; width: 16px; height: 16px; left: 3px; bottom: 3px; background: var(--df-text-dim); border-radius: 50%; transition: transform 0.2s, background 0.2s; }
|
|
.toggle input:checked + .toggle-slider { background: var(--df-accent); }
|
|
.toggle input:checked + .toggle-slider::before { transform: translateX(18px); background: #fff; }
|
|
|
|
/* ===== 按钮(原 Settings.vue,列表型 Panel 共用) ===== */
|
|
.btn { padding: 8px 16px; border: none; border-radius: var(--df-radius-sm); font-size: 13px; cursor: pointer; transition: background 0.15s, color 0.15s; }
|
|
.btn-primary { background: var(--df-accent); color: #fff; }
|
|
.btn-primary:hover { background: var(--df-accent-hover); }
|
|
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
.btn-ghost { background: transparent; color: var(--df-text-secondary); border: 0.5px solid var(--df-border); }
|
|
.btn-ghost:hover { background: var(--df-bg-card); color: var(--df-text); }
|
|
.btn-ghost:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
.btn-sm { padding: 4px 12px; font-size: 12px; }
|
|
|
|
/* ===== 空提示(列表型 Panel 共用) ===== */
|
|
.empty-hint { color: var(--df-text-dim); font-size: 13px; padding: 16px 0; text-align: center; }
|