style: 统一导航与目录的直角满行布局

This commit is contained in:
GouJ
2026-09-01 19:18:00 +08:00
parent 565442c9b1
commit ad37c8ab7c
6 changed files with 44 additions and 10 deletions
+1
View File
@@ -94,6 +94,7 @@ Oxfmt 不负责代码质量,Oxlint 不负责 Vue 的完整类型推导;Vue S
- 拆解页固定精简状态栏与结果标签,设置、预览及恢复操作收进“拆解设置与恢复”面板;人物、场景、道具、分镜和任务明细共用独立结果滚动区,执行记录单独滚动。结果区占满剩余高度,切换标签回到顶部,轮询刷新或开关设置不重置阅读位置;失败与校验提示在面板关闭时仍然可见。
- 剧集正文按编号连续展示全部已写入剧集;点击目录定位正文,滚动正文同步高亮并保持当前目录项可见。目录分行显示集数和完整标题,执行记录可按需展开。切换角色/世界观等标签不会销毁阅读器或重置位置。
- 主体身份、分镜设计和镜头生产共用 `DirectoryItem`:编号、完整标题和状态分层展示,桌面目录为 240–280px,窄屏改为可横向滚动的条目。目录标题与筛选固定,只有列表滚动。拆解结果的导出按钮与标签同排右对齐;形态图片筛选按内容区宽度自动排成一行或两列网格。
- 侧栏导航与主体/剧集/镜头目录采用直角满行背景,移除列表两侧的内缩,悬停和选中态都铺满所在列。条目内部保留文字间距;窄屏横向目录仍保持独立滚动,不影响表单与弹窗的圆角。
- 身份、分镜、生产与图库的批量配置、说明和诊断统一放入 `WorkspaceTools`Naive UI Drawer),按需覆盖当前工作区,不挤压列表。面板支持 Esc 或关闭按钮;关闭不会取消任务或清除配置。历史回执可从入口查看,新回执主动打开诊断;查询错误始终在外层可见。
- 生产步骤的操作按钮保留上下间距;`ConfirmAction` 用稳定根元素承接外部间距,避免多根弹窗组件吞掉 `class`
- 右上角提供浅色、暗黑、跟随系统三种模式,默认跟随系统,选择保存在本机浏览器。存储被禁用时仍可在当前会话切换。
+12 -8
View File
@@ -61,6 +61,12 @@ body {
.admin-sider {
height: 100%;
}
/* Naive 菜单背景默认左右内缩 8px;只铺满导航行,不改图标与文字缩进。 */
.admin-sider .n-menu .n-menu-item-content::before {
left: 0;
right: 0;
border-radius: 0;
}
.admin-brand {
display: flex;
align-items: center;
@@ -452,11 +458,11 @@ body {
display: flex;
flex-direction: column;
gap: 8px;
padding: 8px 10px 16px;
padding: 8px 0 16px;
}
.directory-group-heading {
flex-shrink: 0;
padding: 14px 6px 2px;
padding: 14px 14px 2px;
font:
11px/1.6 ui-monospace,
monospace;
@@ -472,7 +478,7 @@ body {
height: auto;
min-height: 88px;
padding: 12px 14px;
border-radius: 5px;
border-radius: 0;
white-space: normal;
text-align: left;
}
@@ -673,14 +679,15 @@ body {
display: flex;
flex-direction: column;
gap: 6px;
padding: 4px 10px 18px;
padding: 4px 0 18px;
}
.n-button.reader-episode-link {
flex-shrink: 0;
width: 100%;
height: auto;
min-height: 64px;
padding: 12px 14px;
border-radius: 5px;
border-radius: 0;
color: var(--app-muted);
white-space: normal;
text-align: left;
@@ -762,9 +769,6 @@ body {
padding: 16px 12px 12px;
flex-wrap: wrap;
}
.reader-directory-content {
padding-inline: 6px;
}
.n-button.reader-episode-link {
padding: 12px 10px;
}
+20
View File
@@ -50,6 +50,26 @@ describe('统一目录条目', () => {
expect(css).toContain('grid-template-columns: clamp(240px, 22%, 280px) minmax(0, 1fr)')
})
it('侧栏与主体、镜头、剧集目录统一直角满行,保留文字内边距和移动端滚动', () => {
// happy-dom 无法计算伪元素几何,保护实际控制选中背景宽度的 CSS 规则。
const css = readFileSync('src/admin.css', 'utf8')
expect(css).toMatch(
/\.admin-sider \.n-menu \.n-menu-item-content::before\s*\{[^}]*left:\s*0;[^}]*right:\s*0;[^}]*border-radius:\s*0/
)
expect(css).toMatch(/\.directory-list-content\s*\{[^}]*padding:\s*8px 0 16px/)
expect(css).toMatch(/\.reader-directory-content\s*\{[^}]*padding:\s*4px 0 18px/)
expect(css).not.toMatch(/\.reader-directory-content\s*\{[^}]*padding-inline:\s*[1-9]/)
for (const selector of ['directory-item', 'reader-episode-link']) {
expect(css).toMatch(
new RegExp(
`\\.n-button\\.${selector}\\s*\\{[^}]*width:\\s*100%;[^}]*padding:\\s*12px 14px;[^}]*border-radius:\\s*0`
)
)
}
expect(css).toMatch(/\.directory-group-heading\s*\{[^}]*padding:\s*14px 14px 2px/)
expect(css).toMatch(/\.directory-list-content\s*\{[^}]*flex-direction:\s*row;[^}]*width:\s*max-content/)
})
it('导出工具栏与筛选器使用受约束的网格,不让 Tabs 和 Select 默认宽度强制换行', () => {
const css = readFileSync('src/admin.css', 'utf8')
expect(css).toMatch(/\.result-toolbar\s*\{[^}]*grid-template-columns:\s*minmax\(0, 1fr\) auto/)
+1 -1
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { NButton } from 'naive-ui'
/** 统一主体与镜头目录条目:编号、标题、状态各占独立层级,不裁切长标题。 */
/** 统一直角、横向铺满的主体与镜头目录;保留内部留白及完整标题。 */
defineProps<{ active: boolean }>()
</script>
+8 -1
View File
@@ -113,7 +113,14 @@ describe('微信风格明暗主题', () => {
errorColor: tokens.danger
})
expect(Layout).toMatchObject({ color: tokens.body, headerColor: tokens.surface, siderColor: tokens.subtle })
expect(Menu).toMatchObject({ itemColorActive: tokens.selected, itemTextColorActive: tokens['accent-text'] })
expect(Menu).toMatchObject({
borderRadius: '0px',
itemColorActive: tokens.selected,
itemColorActiveCollapsed: tokens.selected,
itemTextColorActive: tokens['accent-text']
})
// 圆角调整只用于导航,表单、普通按钮和弹窗仍保留原有主题。
expect(common?.borderRadius).toBe('6px')
expect(Button?.textColorPrimary).toBe(tokens['on-accent'])
for (const background of [common!.primaryColor!, common!.primaryColorHover!, common!.primaryColorPressed!]) {
expect(contrast(String(Button!.textColorPrimary), background)).toBeGreaterThanOrEqual(4.5)
+2
View File
@@ -94,8 +94,10 @@ export function useTheme() {
siderColor: subtle
},
Menu: {
borderRadius: '0px',
itemColorActive: selected,
itemColorActiveHover: selected,
itemColorActiveCollapsed: selected,
itemColorHover: dark ? '#2c2c2c' : '#e8e8e8',
itemTextColorActive: accentText,
itemTextColorActiveHover: accentText,