refactor: 统一主体与镜头目录并优化筛选工具栏布局
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { mount, type VueWrapper } from '@vue/test-utils'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { NButton } from 'naive-ui'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import DirectoryItem from './DirectoryItem.vue'
|
||||
|
||||
let wrapper: VueWrapper | undefined
|
||||
afterEach(() => wrapper?.unmount())
|
||||
|
||||
describe('统一目录条目', () => {
|
||||
it('编号、长标题和多项状态各占独立层级,沿用 Naive 按钮', () => {
|
||||
const title = '雨夜霓虹街全景与记忆当铺外的人群和闪烁灯牌'
|
||||
wrapper = mount(DirectoryItem, {
|
||||
props: { active: false },
|
||||
slots: {
|
||||
eyebrow: 'BEAT 2 / SHOT 3',
|
||||
default: title,
|
||||
meta: '<span class="directory-status">设计已保存</span><span class="directory-status">待状态</span>'
|
||||
}
|
||||
})
|
||||
expect(wrapper.getComponent(NButton).props()).toMatchObject({ quaternary: true, block: true })
|
||||
expect(wrapper.get('button').attributes('type')).toBe('button')
|
||||
expect(wrapper.get('.directory-item-eyebrow').text()).toBe('BEAT 2 / SHOT 3')
|
||||
expect(wrapper.get('.directory-item-title').text()).toBe(title)
|
||||
expect(wrapper.get('.directory-item-meta').findAll('.directory-status')).toHaveLength(2)
|
||||
expect(wrapper.find('.truncate').exists()).toBe(false)
|
||||
expect(wrapper.findAll('.directory-item-body > span')).toHaveLength(3)
|
||||
})
|
||||
|
||||
it('点击透传给业务层,选中态与无障碍属性保持同步', async () => {
|
||||
const onClick = vi.fn<() => void>()
|
||||
wrapper = mount(DirectoryItem, { props: { active: false }, attrs: { onClick }, slots: { default: '林默' } })
|
||||
await wrapper.get('button').trigger('click')
|
||||
expect(onClick).toHaveBeenCalledOnce()
|
||||
expect(wrapper.attributes('aria-current')).toBeUndefined()
|
||||
await wrapper.setProps({ active: true })
|
||||
expect(wrapper.get('button').classes()).toContain('selected')
|
||||
expect(wrapper.attributes('aria-current')).toBe('true')
|
||||
expect(wrapper.find('.directory-item-eyebrow').exists()).toBe(false)
|
||||
expect(wrapper.find('.directory-item-meta').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('显式保护最小高度、留白、换行和窄屏横向条目,避免旧按钮样式重新挤压目录', () => {
|
||||
// DOM 环境不计算视觉几何;这些约束不能替代浏览器验收。
|
||||
const css = readFileSync('src/admin.css', 'utf8')
|
||||
expect(css).toMatch(/\.n-button\.directory-item\s*\{[^}]*min-height:\s*88px;[^}]*padding:\s*12px 14px/)
|
||||
expect(css).toMatch(/\.directory-item-body\s*\{[^}]*flex-direction:\s*column;[^}]*gap:\s*7px/)
|
||||
expect(css).toMatch(/\.directory-item-title\s*\{[^}]*overflow-wrap:\s*anywhere/)
|
||||
expect(css).toMatch(/\.directory-list-content\s*\{[^}]*flex-direction:\s*row;[^}]*width:\s*max-content/)
|
||||
expect(css).toContain('grid-template-columns: clamp(240px, 22%, 280px) minmax(0, 1fr)')
|
||||
})
|
||||
|
||||
it('导出工具栏与筛选器使用受约束的网格,不让 Tabs 和 Select 默认宽度强制换行', () => {
|
||||
const css = readFileSync('src/admin.css', 'utf8')
|
||||
expect(css).toMatch(/\.result-toolbar\s*\{[^}]*grid-template-columns:\s*minmax\(0, 1fr\) auto/)
|
||||
expect(css).toMatch(
|
||||
/\.form-image-filters\s*\{[^}]*grid-template-columns:\s*minmax\(200px, 360px\) 152px minmax\(260px, 1fr\) auto/
|
||||
)
|
||||
expect(css).toMatch(
|
||||
/@container \(max-width: 900px\)\s*\{\s*\.form-image-filters\s*\{[^}]*minmax\(0, 1fr\) 152px/
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import { NButton } from 'naive-ui'
|
||||
|
||||
/** 统一主体与镜头目录条目:编号、标题、状态各占独立层级,不裁切长标题。 */
|
||||
defineProps<{ active: boolean }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NButton
|
||||
quaternary
|
||||
block
|
||||
class="directory-item"
|
||||
:class="{ selected: active }"
|
||||
:aria-current="active ? 'true' : undefined"
|
||||
>
|
||||
<span class="directory-item-body">
|
||||
<span v-if="$slots.eyebrow" class="directory-item-eyebrow"><slot name="eyebrow" /></span>
|
||||
<span class="directory-item-title"><slot /></span>
|
||||
<span v-if="$slots.meta" class="directory-item-meta"><slot name="meta" /></span>
|
||||
</span>
|
||||
</NButton>
|
||||
</template>
|
||||
@@ -3,3 +3,4 @@ export { default as AppDialog } from './AppDialog.vue'
|
||||
export { default as EmptyState } from './EmptyState.vue'
|
||||
export { default as StatusBadge } from './StatusBadge.vue'
|
||||
export { default as AssetImage } from './AssetImage.vue'
|
||||
export { default as DirectoryItem } from './DirectoryItem.vue'
|
||||
|
||||
Reference in New Issue
Block a user