style: 统一列表首项留白并添加背景色过渡
This commit is contained in:
@@ -111,7 +111,7 @@ Oxfmt 不负责代码质量,Oxlint 不负责 Vue 的完整类型推导;Vue S
|
|||||||
- Tabs 例外保留底部分隔线,浅色和暗黑模式均区分导航与正文;选中下划线仍使用绿色。视觉风格工具栏将“图标+状态说明”与等高操作按钮分组,读取失败不再显示为“尚未创建”,锁定与未保存草稿的生成限制不变。
|
- Tabs 例外保留底部分隔线,浅色和暗黑模式均区分导航与正文;选中下划线仍使用绿色。视觉风格工具栏将“图标+状态说明”与等高操作按钮分组,读取失败不再显示为“尚未创建”,锁定与未保存草稿的生成限制不变。
|
||||||
- 剧本正文的执行记录/导出/进入拆解,以及拆解结果的 JSON 导出统一放在 `NTabs` 的 `suffix` 插槽,与标签垂直居中并共用底线。浅色 Tabs 分隔线单独加深,不影响其它组件的低边框风格;窄内容区由容器断点把操作放到下一行,标签仍使用内置横向滚动。
|
- 剧本正文的执行记录/导出/进入拆解,以及拆解结果的 JSON 导出统一放在 `NTabs` 的 `suffix` 插槽,与标签垂直居中并共用底线。浅色 Tabs 分隔线单独加深,不影响其它组件的低边框风格;窄内容区由容器断点把操作放到下一行,标签仍使用内置横向滚动。
|
||||||
- 拆解分镜区的剧集选择、节拍/镜头统计与“进入分镜设计”共用一条紧凑工具栏;“选择剧集”不拆行。选择器默认显示正文对应的真实剧集,轮询移除当前剧集时同步回退;没有剧情目标与情绪弧线时不保留空信息面板。
|
- 拆解分镜区的剧集选择、节拍/镜头统计与“进入分镜设计”共用一条紧凑工具栏;“选择剧集”不拆行。选择器默认显示正文对应的真实剧集,轮询移除当前剧集时同步回退;没有剧情目标与情绪弧线时不保留空信息面板。
|
||||||
- 拆解人物、场景、道具共用斑马纹列表:无底色行在鼠标悬停或内部控件获得键盘焦点时显示主题化灰底,已有条纹保持原样;触屏不启用悬停态,搜索后的条纹顺序按可见列表重新计算。
|
- 拆解人物、场景、道具共用斑马纹列表:无底色行在鼠标悬停或内部控件获得键盘焦点时显示主题化灰底,已有条纹保持原样;触屏不启用悬停态,搜索后的条纹顺序按可见列表重新计算。此类记录(含剧本角色设定)首项同样保留 20px 内边距,背景色使用 160ms 过渡,并遵循系统减少动态效果设置。
|
||||||
- 窄屏默认收起侧栏,目录与正文改用紧凑布局;执行记录仍可查看。长弹窗在自身内部滚动。
|
- 窄屏默认收起侧栏,目录与正文改用紧凑布局;执行记录仍可查看。长弹窗在自身内部滚动。
|
||||||
|
|
||||||
布局样式集中在 `src/admin.css`,业务排版保留在 `src/styles.css`。新增页面应使用 `WorkspacePage`(内容优先页开启 `compact`),低频操作使用 `WorkspaceTools`;避免通过 `body` 或 `window.scrollTo` 管理滚动。
|
布局样式集中在 `src/admin.css`,业务排版保留在 `src/styles.css`。新增页面应使用 `WorkspacePage`(内容优先页开启 `compact`),低频操作使用 `WorkspaceTools`;避免通过 `body` 或 `window.scrollTo` 管理滚动。
|
||||||
|
|||||||
@@ -162,6 +162,23 @@ describe('全站平面主题', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('斑马纹首项保留统一顶部留白,背景色平滑过渡并遵循减少动态效果设置', () => {
|
||||||
|
// DOM 环境不计算实际内边距,检查共享规则及之前覆盖首项留白的工具类。
|
||||||
|
const css = readFileSync('src/styles.css', 'utf8')
|
||||||
|
expect(css).toMatch(
|
||||||
|
/\.record-list > article\s*\{[^}]*padding:\s*20px;[^}]*transition:\s*background-color 160ms ease;/
|
||||||
|
)
|
||||||
|
expect(css).toMatch(
|
||||||
|
/@media \(prefers-reduced-motion: reduce\)[\s\S]*transition-duration:\s*0\.01ms !important;/
|
||||||
|
)
|
||||||
|
for (const file of [
|
||||||
|
'src/features/breakdown/components/SubjectList.vue',
|
||||||
|
'src/features/create-drama/CreateDramaPage.vue'
|
||||||
|
]) {
|
||||||
|
expect(readFileSync(file, 'utf8')).not.toContain('first:pt-0')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
it('所有页面不再通过工具类添加装饰边框或圆角', () => {
|
it('所有页面不再通过工具类添加装饰边框或圆角', () => {
|
||||||
const files = readdirSync('src', { recursive: true, encoding: 'utf8' }).filter(path => path.endsWith('.vue'))
|
const files = readdirSync('src', { recursive: true, encoding: 'utf8' }).filter(path => path.endsWith('.vue'))
|
||||||
for (const path of files) {
|
for (const path of files) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const filtered = computed(() =>
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="filtered.length" class="record-list subject-record-list">
|
<div v-if="filtered.length" class="record-list subject-record-list">
|
||||||
<article v-for="subject in filtered" :key="subject.profileId" class="py-5 first:pt-0">
|
<article v-for="subject in filtered" :key="subject.profileId">
|
||||||
<div class="mb-3 flex flex-wrap items-center gap-3">
|
<div class="mb-3 flex flex-wrap items-center gap-3">
|
||||||
<h3 class="font-semibold">{{ subject.name }}</h3>
|
<h3 class="font-semibold">{{ subject.name }}</h3>
|
||||||
<code class="subject-ref">{{ subject.ref }}</code
|
<code class="subject-ref">{{ subject.ref }}</code
|
||||||
|
|||||||
@@ -151,11 +151,7 @@ function exportScript() {
|
|||||||
<NScrollbar v-if="tab !== 'episodes'" class="panel-scroll"
|
<NScrollbar v-if="tab !== 'episodes'" class="panel-scroll"
|
||||||
><div v-if="tab === 'characters'" class="p-6 lg:p-8">
|
><div v-if="tab === 'characters'" class="p-6 lg:p-8">
|
||||||
<div v-if="project?.characters.length" class="record-list">
|
<div v-if="project?.characters.length" class="record-list">
|
||||||
<article
|
<article v-for="character in project.characters" :key="character.id">
|
||||||
v-for="character in project.characters"
|
|
||||||
:key="character.id"
|
|
||||||
class="py-5 first:pt-0"
|
|
||||||
>
|
|
||||||
<div class="mb-3 flex items-center gap-3">
|
<div class="mb-3 flex items-center gap-3">
|
||||||
<h3 class="text-lg font-semibold">{{ character.name }}</h3>
|
<h3 class="text-lg font-semibold">{{ character.name }}</h3>
|
||||||
<NTag size="small" :bordered="false">{{ character.role || '角色' }}</NTag
|
<NTag size="small" :bordered="false">{{ character.role || '角色' }}</NTag
|
||||||
|
|||||||
@@ -198,8 +198,10 @@
|
|||||||
--app-field-hover: var(--app-surface);
|
--app-field-hover: var(--app-surface);
|
||||||
background: var(--app-subtle);
|
background: var(--app-subtle);
|
||||||
}
|
}
|
||||||
|
/* 首项与其它条目统一内边距;只过渡背景,避免展开内容和文字发生位移动画。 */
|
||||||
.record-list > article {
|
.record-list > article {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
transition: background-color 160ms ease;
|
||||||
}
|
}
|
||||||
.record-list > article:nth-child(even) {
|
.record-list > article:nth-child(even) {
|
||||||
background: var(--app-subtle);
|
background: var(--app-subtle);
|
||||||
|
|||||||
Reference in New Issue
Block a user