fix: align note thumbnails with content edges

Remove extra top and left padding from the note record index so thumbnails align with the content area. Draw keyboard focus outlines inward to keep them visible within the scroll viewport, and cover alignment in the Electron layout regression test.

Release note: Note thumbnails now align with the content area, and keyboard focus outlines remain visible at the list edges.
This commit is contained in:
mesalogo
2026-09-23 23:03:09 +08:00
parent cebd513da8
commit 344008aaec
3 changed files with 10 additions and 3 deletions
+1 -1
View File
@@ -766,7 +766,7 @@ GoodBuddy 是可调整窗口大小的桌面应用。响应式设计优先保证
- 左侧记录索引默认 `168px`,可拖动右边界在 `140–320px` 内调整栏宽,缩略图随列宽等比适配。开关独立位于详情标题左侧,提供 `aria-controls`、展开状态和动作提示;收起后完全移除索引列、分隔条、间隙、边框及轨道,不占宽度,隐藏内容不可聚焦。右侧 AI 评论独立显示、滚动和收起,不与索引共享页签。每条记录一个导航项:画布显示真实首页缩略图及总页数,文字显示摘要,两者均显示类型和时间。两侧分别记住桌面展开状态和宽度,共用原有布局偏好;宽布局分隔条共用样式及 `separator` 语义,方向键每次调整 `16px`,Home、End 跳到当前上下限。两侧宽度按可用空间协调限制,为主区保留至少 `300px`,窗口缩小时不覆盖保存的偏好。内容容器不超过 `800px` 时索引默认隐藏,由同一标题栏按钮开闭标题栏下方固定 `168px` 的抽屉,不显示调宽分隔条;标题栏自身保留控件高度,不保留轨道。选择记录或按 Escape 后关闭,Escape 将焦点返回开关。AI 移至底部,高度不超过可用布局的 40% 且最多 `280px`,不显示分隔条。
AI 评论的唯一显隐入口位于页面右上角,使用紧凑面板图标按钮;展开时应用共享选中样式,图标随显示或隐藏动作切换,并提供对应的工具提示、可访问名称、`aria-expanded` 和 `aria-controls`。评论面板内部不再显示重复的“AI 评论”标题或隐藏按钮行,保留区域的可访问名称、评论方向选择及各记录的分析操作。
- 笔记详情的内部记录索引使用透明底色,与主内容表面连续,仅保留细调宽分隔线。每条索引记录保留 `1px` 的 `--border-subtle` 淡边框,不加卡片底色或阴影,悬停使用轻微次级底色;选中记录使用淡蓝背景和左侧 `3px` 蓝色内侧标记,悬停时保留选中态。缩略图保留纸张边界,键盘焦点环与强制颜色模式选中边框保持可见。窄屏抽屉使用不透明的主内容表面,避免下层正文透出;深色主题沿用语义令牌。
- 笔记详情的标题、正文和记录流不再包裹额外的大外框,记录流容器不加内边距;每条已保存记录使用一层 `1px` 的 `--border-subtle` 淡边框和 `--radius-control` 圆角,保留透明底色与记录间留白,不加阴影或头部下划线。记录编辑时保留输入区边框、页面安全边距及 AI 区域分隔。此规则仅作用于笔记详情,不改变卡片总览与待办独立布局。
- 笔记详情的标题、正文和记录流不再包裹额外的大外框,记录流容器不加内边距;缩略图列表顶部与正文区顶部对齐,左边界与索引栏左边界对齐,仅在右侧和底部保留 `8px` 留白,键盘焦点环向内绘制以避免滚动容器裁切。每条已保存记录使用一层 `1px` 的 `--border-subtle` 淡边框和 `--radius-control` 圆角,保留透明底色与记录间留白,不加阴影或头部下划线。记录编辑时保留输入区边框、页面安全边距及 AI 区域分隔。此规则仅作用于笔记详情,不改变卡片总览与待办独立布局。
- 画布新建、编辑和只读态统一保留 `12px` 内容间距;详情中已保存画布去掉预览外框和工具栏底色、下划线,保留灰色画布衬底与白色纸张,编辑态保留编辑器边框。记录头部操作按内容宽度排列,空间不足时自然换行。文字新建的保存区与编辑器属于同一卡片,空白编辑区使用最小高度,不随容器百分比高度拉长。文字工具栏图标、菜单和原生滚动条须跟随主题。
- 整篇笔记的置顶、取消置顶和删除放在卡片的“更多”菜单,标题编辑区不重复提供入口。按钮在悬停、键盘聚焦或菜单展开时显示,触屏设备常显;菜单沿用会话列表样式,通过 Portal 避免滚动区域裁切,支持方向键、Home、End 和 Escape。删除在菜单内二次确认并说明笔记标题及全部记录;打开菜单不进入详情。
- 左侧“魔法笔记”入口可显示未完成待办数量。数量为 0 时隐藏徽标,超过 99 时显示 `99+`,可访问名称仍说明精确数量;勾选、取消勾选以及 Agent / MCP 对笔记清单的写入都必须刷新数量。
+2 -2
View File
@@ -1382,7 +1382,7 @@
}
}
.magic-note-records { display: grid; gap: var(--space-3); padding: var(--space-2); }
.magic-note-records { display: grid; gap: var(--space-3); padding: 0 var(--space-2) var(--space-2) 0; }
.magic-note-records[hidden] { display: none; }
.magic-note-record {
display: grid;
@@ -1405,7 +1405,7 @@
@media (forced-colors: active) {
.magic-note-record[aria-current="true"] { border-color: Highlight; }
}
.magic-note-record:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.magic-note-record:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.magic-note-record time { color: var(--text-secondary); font-size: var(--font-caption); }
.magic-note-record__summary { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.magic-note-record__image { display: block; min-width: 0; text-align: center; }
@@ -78,6 +78,9 @@ it('resizes record columns with native Electron input and preserves desktop widt
await js('document.documentElement.dataset.theme = "light"'); await settle();
const index = '.magic-notes-index-pane', handle = '.magic-notes-index-resize-handle', stream = '.magic-notes-stream-pane';
assert.equal((await rect(index)).width, 168);
const firstRecord = await rect('.magic-note-record');
assert.equal(firstRecord.x, (await rect(index)).x, 'Thumbnails align with the left pane edge');
assert.equal(firstRecord.y, (await rect(stream)).y, 'Thumbnails align with the top of the note content');
await drag(handle, 80); const dragged = (await rect(index)).width; assert(dragged > 240 && dragged < 260, 'Dragged index width: ' + dragged);
await key(handle, 'Home'); assert.equal((await rect(index)).width, 140);
await key(handle, 'Right'); assert.equal((await rect(index)).width, 156);
@@ -107,6 +110,10 @@ it('resizes record columns with native Electron input and preserves desktop widt
await screenshot('magic-notes-narrow');
win.setContentSize(1280, 800); await settle(); await settle();
assert.equal((await rect(index)).width, withoutAi);
await key('.magic-note-record', 'Tab');
await js('document.querySelector(".magic-note-record").focus()');
assert(await js('document.querySelector(".magic-note-record").matches(":focus-visible")'));
assert.equal(await js('getComputedStyle(document.querySelector(".magic-note-record")).outlineOffset'), '-2px', 'Focus outline stays inside the scroll viewport');
await js('document.querySelector(' + JSON.stringify(editor) + ').focus()');
await win.webContents.insertText('Composer growth check\\n'.repeat(30)); await settle();
const grownHeight = (await rect(editor)).height;