style: 区分主体条纹与形态块背景
This commit is contained in:
@@ -178,6 +178,60 @@ describe('拆解页内容滚动', () => {
|
||||
expect(css + readFileSync('src/styles.css', 'utf8')).not.toContain('.search-field')
|
||||
})
|
||||
|
||||
it.each([
|
||||
['人物', 'character'],
|
||||
['场景', 'scene'],
|
||||
['道具', 'prop']
|
||||
] as const)('%s 的奇偶主体展开后均使用独立形态块,搜索重排不影响形态归属', async (label, module) => {
|
||||
const record = checkpoint()
|
||||
// 前两个主体各准备两种形态,覆盖奇偶条纹和默认标签,不调用模型接口。
|
||||
record.state.breakdownResult!.subjectForms = [0, 1].flatMap(subjectIndex =>
|
||||
[0, 1].map(formIndex => ({
|
||||
formId: `${module}-${subjectIndex}-form-${formIndex}`,
|
||||
profileId: `${module}-${subjectIndex}`,
|
||||
type: module,
|
||||
name: `主体 ${subjectIndex + 1} 形态 ${formIndex + 1}`,
|
||||
isDefault: formIndex === 0,
|
||||
description: '形态描述',
|
||||
appearancePrompt: '形态提示词'
|
||||
}))
|
||||
)
|
||||
mountPage([record])
|
||||
await selectTab(label)
|
||||
const articles = wrapper!.findAll('.subject-record-list > article')
|
||||
for (const index of [0, 1]) {
|
||||
const article = articles[index]!
|
||||
await article.get('.n-collapse-item__header-main').trigger('click')
|
||||
await flushPromises()
|
||||
const cards = article.findAll('.subject-form-card')
|
||||
expect(cards).toHaveLength(2)
|
||||
expect(cards[0]!.get('.n-tag').text()).toBe('默认')
|
||||
for (const card of cards) {
|
||||
expect(card.classes()).not.toContain('surface-inset')
|
||||
expect(card.text()).toContain(`主体 ${index + 1} 形态`)
|
||||
expect(card.text()).toContain('形态描述')
|
||||
expect(card.text()).toContain('形态提示词')
|
||||
}
|
||||
}
|
||||
// 原偶数主体过滤后成为首项,仍由当前 DOM 的奇偶选择器决定内外层底色。
|
||||
await wrapper!.get('input[aria-label="搜索主体"]').setValue(`@${module}1`)
|
||||
const first = wrapper!.get('.subject-record-list > article')
|
||||
expect(first.findAll('.subject-form-card')).toHaveLength(2)
|
||||
expect(first.get('.subject-form-card').text()).toContain('主体 2 形态 1')
|
||||
})
|
||||
|
||||
it('形态块在两种主体条纹上采用相反灰阶,以间距分组且没有整块悬停态', () => {
|
||||
// DOM 环境不提供真实主题绘制,检查奇偶行底色、内边距和状态选择器契约。
|
||||
const css = readFileSync('src/styles.css', 'utf8')
|
||||
expect(css).toMatch(
|
||||
/\.subject-form-card\s*\{[^}]*margin-top:\s*12px;[^}]*padding:\s*16px;[^}]*background:\s*var\(--app-subtle\);/
|
||||
)
|
||||
expect(css).toMatch(
|
||||
/\.subject-record-list > article:nth-child\(even\) \.subject-form-card\s*\{\s*background:\s*var\(--app-control\);/
|
||||
)
|
||||
expect(css).not.toMatch(/\.subject-form-card[^{}]*(?::hover|:focus-within)/)
|
||||
})
|
||||
|
||||
it('主体奇数行常驻原悬停底色,偶数行不变,整行不再随鼠标或焦点变色', () => {
|
||||
// DOM 环境无法模拟浏览器 :hover 命中;检查静态底色与无整行交互选择器的契约。
|
||||
const css = readFileSync('src/styles.css', 'utf8')
|
||||
|
||||
@@ -70,9 +70,9 @@ const filtered = computed(() =>
|
||||
<div
|
||||
v-for="form in forms.filter(item => item.profileId === subject.profileId)"
|
||||
:key="form.formId"
|
||||
class="mt-3 surface-inset p-4"
|
||||
class="subject-form-card"
|
||||
>
|
||||
<p class="text-sm font-medium">
|
||||
<p class="flex flex-wrap items-center gap-2 text-sm font-medium">
|
||||
{{ form.formName || form.name
|
||||
}}<NTag v-if="form.isDefault" size="small" :bordered="false">默认</NTag>
|
||||
</p>
|
||||
|
||||
@@ -210,6 +210,17 @@
|
||||
.subject-record-list > article:nth-child(odd) {
|
||||
background: var(--app-control);
|
||||
}
|
||||
/* 形态块与所在主体条纹使用相反灰阶,避免偶数行内外同色;不增加边框或悬停态。 */
|
||||
.subject-form-card {
|
||||
margin-top: 12px;
|
||||
padding: 16px;
|
||||
min-width: 0;
|
||||
overflow-wrap: anywhere;
|
||||
background: var(--app-subtle);
|
||||
}
|
||||
.subject-record-list > article:nth-child(even) .subject-form-card {
|
||||
background: var(--app-control);
|
||||
}
|
||||
|
||||
.table-scroll {
|
||||
overflow: hidden;
|
||||
|
||||
Reference in New Issue
Block a user