返修资源卡完整名悬停入口并收短文档卡注释

- 完整资源名改挂在覆盖整卡、真正命中指针的选中按钮 title 上,名称条自身不再挂悬停不到的 title

- 无障碍名保持原有 aria-label 不变,长名仍是 CSS 单行省略

- 断言改为校验选中按钮 title,并钉住名称条不挂 title

- 文档卡分支注释只写当前行为,去掉旧实现说明
This commit is contained in:
2026-09-17 17:36:50 +08:00
parent 3ba6168c6a
commit 5c31ae91ca
4 changed files with 31 additions and 25 deletions
@@ -981,11 +981,7 @@ const ResourceCard = memo(function ResourceCard({
</span>
);
}
/**
* **** 3
* "卡面不显示无效正文片段" UI JSON
*
*/
/** 文档卡:卡面只给居中的文档图标,不铺正文。 */
if (isDocumentCard) {
return (
<span className="game-resource-card-document-visual">
@@ -1079,13 +1075,13 @@ const ResourceCard = memo(function ResourceCard({
manifest `localPath`
`assetName` `localPath`
label
CSS `title` `data-resource-name`
CSS `title`
`pointer-events: none``data-resource-name`
*/}
<span
className="game-resource-card-name"
data-resource-name={resource.label}
title={resource.label}
>
{resource.label}
</span>
@@ -1119,7 +1115,9 @@ const ResourceCard = memo(function ResourceCard({
aria-label={`选中资源:${categoryLabels[resource.category]} ${resource.label}`}
aria-pressed={selected}
data-resource-id={resource.id}
title="选中资源"
// 名称条 `pointer-events: none`,鼠标命中的是覆盖整卡的这颗按钮,
// 所以「长名可悬停读全」的完整名挂在这里;无障碍名仍是上面的 aria-label。
title={resource.label}
/>
{isMedia ? (
<button
@@ -2980,11 +2980,15 @@ export function registerProjectWorkbenchFoundationTests() {
let heroDetailButton = await findResourceSelectButton('hero.png');
const heroCard = heroDetailButton.closest('.game-resource-card');
// 卡面名称就是正式资源名(manifest `localPath` 的文件名,生成时来自 assetName、
// 重命名时同步改写),长名由 CSS 省略、完整名 `title` 上。
// 重命名时同步改写),长名由 CSS 省略、完整名挂在实际命中指针的整卡选中按钮 `title` 上。
const heroName = heroCard?.querySelector('.game-resource-card-name');
expect(heroName?.textContent).toBe('hero.png');
expect(heroName?.getAttribute('title')).toBe('hero.png');
expect(heroName?.getAttribute('data-resource-name')).toBe('hero.png');
expect(
heroCard
?.querySelector('.game-resource-card-select')
?.getAttribute('title'),
).toBe('hero.png');
// 卡面仍然只给"名称 + 类型",不铺完整路径与来源这类详细文本。
expect(heroCard?.textContent).not.toContain('assets/hero.png');
expect(heroCard?.textContent).not.toContain('Agent 生成');
@@ -4265,9 +4269,9 @@ export function registerProjectWorkbenchFoundationTests() {
expect(screen.queryByRole('toolbar', { name: '图片工具栏' })).toBeNull();
});
expect(
screen
.queryAllByTitle('选中资源')
.some((card) => card.getAttribute('aria-pressed') === 'true'),
Array.from(
document.querySelectorAll<HTMLElement>('.game-resource-card-select'),
).some((card) => card.getAttribute('aria-pressed') === 'true'),
).toBe(false);
});
@@ -202,15 +202,20 @@ async function openResourceBookCategory(label: string) {
);
}
/** 卡面名称节点断言:文本、`title` 与稳定 DOM 判据都是同一个正式资源名。 */
/**
* 卡面名称断言:名称条文本与稳定 DOM 判据是同一个正式资源名,**完整名挂在整卡选中按钮的
* `title` 上** —— 名称条 `pointer-events: none`,只有这颗覆盖整卡的按钮命中指针,
* 「悬停读全名」必须落在它身上才真的会出 tooltip。
*/
async function expectCardName(name: string) {
const card = (await findResourceSelectButton(name)).closest<HTMLElement>(
'.game-resource-card',
)!;
const selectButton = await findResourceSelectButton(name);
const card = selectButton.closest<HTMLElement>('.game-resource-card')!;
const nameNode = card.querySelector('.game-resource-card-name');
expect(nameNode?.textContent).toBe(name);
expect(nameNode?.getAttribute('title')).toBe(name);
expect(nameNode?.getAttribute('data-resource-name')).toBe(name);
// 名称条不挂 `title`:它悬停不到,挂上去就是一条永远不触发的死提示。
expect(nameNode?.getAttribute('title')).toBeNull();
expect(selectButton.getAttribute('title')).toBe(name);
return card;
}
@@ -231,16 +231,15 @@ describe('素材重命名前端链路', () => {
rendered.rerenderWith(renamedManifest);
await waitFor(() => {
const renamedCard = screen
.getByRole('button', {
name: '选中资源:角色与对象 hero-v2.png',
})
.closest('.game-resource-card');
const renamedSelect = screen.getByRole('button', {
name: '选中资源:角色与对象 hero-v2.png',
});
const renamedCard = renamedSelect.closest('.game-resource-card');
// 卡面名称与重命名后的 manifest `localPath` 同步:名称就是正式文件名的投影,
// 不存在第二份需要一起改的显示名。
// 不存在第二份需要一起改的显示名;完整名挂在命中指针的选中按钮 `title` 上
const nameNode = renamedCard?.querySelector('.game-resource-card-name');
expect(nameNode?.textContent).toBe('hero-v2.png');
expect(nameNode?.getAttribute('title')).toBe('hero-v2.png');
expect(renamedSelect.getAttribute('title')).toBe('hero-v2.png');
});
});