继续收口首页导航行与暗色弹窗底栏
将首页排行行与分类行切换为 PlatformNavigableListItem 将 NPC 交易详情与地图切场确认底栏收口到 PlatformDarkModalFooter 补充首页与弹窗回归测试并更新 PlatformUiKit 收口计划与共享决策记录
This commit is contained in:
@@ -82,6 +82,7 @@ test('目标场景确认面板复用暗色琥珀 PlatformSubpanel 和胶囊标
|
||||
const panel = screen.getByTestId('map-target-scene-panel');
|
||||
const currentSummary = screen.getByTestId('map-current-scene-summary');
|
||||
const nextSummary = screen.getByTestId('map-next-scene-summary');
|
||||
const footer = screen.getByTestId('map-travel-footer');
|
||||
const labelBadge = within(panel).getByText(destinationLabel);
|
||||
const cancelButton = screen.getByRole('button', { name: '取消' });
|
||||
const confirmButton = screen.getByRole('button', { name: '确认前往' });
|
||||
@@ -96,6 +97,8 @@ test('目标场景确认面板复用暗色琥珀 PlatformSubpanel 和胶囊标
|
||||
expect(currentSummary.className).toContain('bg-black/25');
|
||||
expect(nextSummary.className).toContain('border-white/10');
|
||||
expect(nextSummary.className).toContain('bg-black/25');
|
||||
expect(footer.className).toContain('platform-dark-modal-footer');
|
||||
expect(footer.className).toContain('border-t');
|
||||
expect(cancelButton.className).toContain(
|
||||
'platform-action-button--editor-dark',
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useResolvedAssetReadUrl } from '../hooks/useResolvedAssetReadUrl';
|
||||
import { ScenePresetInfo, WorldType } from '../types';
|
||||
import { CHROME_ICONS, getNineSliceStyle, UI_CHROME } from '../uiAssets';
|
||||
import { PlatformActionButton } from './common/PlatformActionButton';
|
||||
import { PlatformDarkModalFooter } from './common/PlatformDarkModalFooter';
|
||||
import { PlatformPillBadge } from './common/PlatformPillBadge';
|
||||
import { PlatformSubpanel } from './common/PlatformSubpanel';
|
||||
import { PixelCloseButton } from './PixelCloseButton';
|
||||
@@ -441,26 +442,26 @@ export function MapModal({
|
||||
</PlatformSubpanel>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
<PlatformActionButton
|
||||
surface="editorDark"
|
||||
tone="ghost"
|
||||
size="xs"
|
||||
onClick={() => setPendingScene(null)}
|
||||
>
|
||||
取消
|
||||
</PlatformActionButton>
|
||||
<PlatformActionButton
|
||||
surface="editorDark"
|
||||
tone={isTraveling || !canTravel ? 'ghost' : 'warning'}
|
||||
size="xs"
|
||||
disabled={isTraveling || !canTravel}
|
||||
onClick={confirmTravel}
|
||||
>
|
||||
{isTraveling ? '切换中...' : canTravel ? '确认前往' : '当前不可切换'}
|
||||
</PlatformActionButton>
|
||||
</div>
|
||||
</div>
|
||||
<PlatformDarkModalFooter data-testid="map-travel-footer">
|
||||
<PlatformActionButton
|
||||
surface="editorDark"
|
||||
tone="ghost"
|
||||
size="xs"
|
||||
onClick={() => setPendingScene(null)}
|
||||
>
|
||||
取消
|
||||
</PlatformActionButton>
|
||||
<PlatformActionButton
|
||||
surface="editorDark"
|
||||
tone={isTraveling || !canTravel ? 'ghost' : 'warning'}
|
||||
size="xs"
|
||||
disabled={isTraveling || !canTravel}
|
||||
onClick={confirmTravel}
|
||||
>
|
||||
{isTraveling ? '切换中...' : canTravel ? '确认前往' : '当前不可切换'}
|
||||
</PlatformActionButton>
|
||||
</PlatformDarkModalFooter>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
@@ -311,8 +311,12 @@ test('NPC 弹窗标准 dark footer CTA 复用 PlatformActionButton', async () =>
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /月壳/ }));
|
||||
|
||||
const tradeDetailFooter = screen.getByTestId('npc-trade-detail-footer');
|
||||
const closeButton = screen.getByRole('button', { name: '关闭' });
|
||||
|
||||
expect(tradeDetailFooter.className).toContain('platform-dark-modal-footer');
|
||||
expect(tradeDetailFooter.className).toContain('px-5');
|
||||
expect(tradeDetailFooter.className).toContain('py-4');
|
||||
expect(closeButton.className).toContain('platform-action-button--editor-dark');
|
||||
expect(closeButton.className).toContain('rounded-2xl');
|
||||
});
|
||||
|
||||
@@ -560,17 +560,21 @@ export function NpcModals({ gameState, npcUi }: NpcModalsProps) {
|
||||
</PlatformStatusMessage>
|
||||
)}
|
||||
|
||||
<div className="flex justify-end">
|
||||
<PlatformActionButton
|
||||
surface="editorDark"
|
||||
tone="secondary"
|
||||
size="xs"
|
||||
onClick={() => setTradeDetail(null)}
|
||||
>
|
||||
关闭
|
||||
</PlatformActionButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<PlatformDarkModalFooter
|
||||
padding="roomy"
|
||||
data-testid="npc-trade-detail-footer"
|
||||
>
|
||||
<PlatformActionButton
|
||||
surface="editorDark"
|
||||
tone="secondary"
|
||||
size="xs"
|
||||
onClick={() => setTradeDetail(null)}
|
||||
>
|
||||
关闭
|
||||
</PlatformActionButton>
|
||||
</PlatformDarkModalFooter>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
@@ -5416,7 +5416,11 @@ test('mobile home moves category shelf into game category channel', async () =>
|
||||
expect(screen.getAllByText('分类').length).toBeGreaterThan(0);
|
||||
expect(screen.getByRole('button', { name: /筛选/u })).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: '奇幻' })).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: /奇幻拼图,试玩/u })).toBeTruthy();
|
||||
const categoryEntryButton = screen.getByRole('button', {
|
||||
name: /奇幻拼图,试玩/u,
|
||||
});
|
||||
expect(categoryEntryButton).toBeTruthy();
|
||||
expect(categoryEntryButton.className).toContain('platform-navigable-list-item');
|
||||
expect(container.querySelector('.platform-category-game-list')).toBeTruthy();
|
||||
expect(container.querySelector('.platform-category-game-item')).toBeTruthy();
|
||||
expect(
|
||||
@@ -5590,4 +5594,8 @@ test('ranking rows limit displayed work name and show two short tags on the thir
|
||||
expect(within(rankingPanel!).getByText('古风机关')).toBeTruthy();
|
||||
expect(within(rankingPanel!).queryByText(/2026-04-29/u)).toBeNull();
|
||||
expect(within(rankingPanel!).queryByText('拼图玩家')).toBeNull();
|
||||
expect(
|
||||
within(rankingPanel!).getByRole('button', { name: /关键词逍遥游拼图/u })
|
||||
.className,
|
||||
).toContain('platform-navigable-list-item');
|
||||
});
|
||||
|
||||
@@ -2003,24 +2003,32 @@ function PlatformRankingItem({
|
||||
: '进入';
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
<PlatformNavigableListItem
|
||||
onClick={onClick}
|
||||
className="platform-ranking-item w-full text-left"
|
||||
align="center"
|
||||
className="platform-ranking-item"
|
||||
leadingClassName="flex items-center gap-3"
|
||||
leading={
|
||||
<>
|
||||
<div className="platform-ranking-item__rank">{rank}</div>
|
||||
<div className="platform-ranking-item__cover">
|
||||
{coverImage ? (
|
||||
<PlatformWorkCoverArtwork
|
||||
entry={entry}
|
||||
imageSrc={coverImage}
|
||||
alt={entry.worldName}
|
||||
className="h-full w-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<div className="h-full w-full bg-[radial-gradient(circle_at_24%_18%,rgba(255,255,255,0.24),transparent_30%),linear-gradient(135deg,rgba(255,118,117,0.42),rgba(89,164,255,0.34))]" />
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
trailing={
|
||||
<span className="platform-ranking-item__action">{actionLabel}</span>
|
||||
}
|
||||
>
|
||||
<div className="platform-ranking-item__rank">{rank}</div>
|
||||
<div className="platform-ranking-item__cover">
|
||||
{coverImage ? (
|
||||
<PlatformWorkCoverArtwork
|
||||
entry={entry}
|
||||
imageSrc={coverImage}
|
||||
alt={entry.worldName}
|
||||
className="h-full w-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<div className="h-full w-full bg-[radial-gradient(circle_at_24%_18%,rgba(255,255,255,0.24),transparent_30%),linear-gradient(135deg,rgba(255,118,117,0.42),rgba(89,164,255,0.34))]" />
|
||||
)}
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="line-clamp-1 break-words text-base font-black leading-tight text-[var(--platform-text-strong)]">
|
||||
{displayName}
|
||||
@@ -2041,8 +2049,7 @@ function PlatformRankingItem({
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<span className="platform-ranking-item__action">{actionLabel}</span>
|
||||
</button>
|
||||
</PlatformNavigableListItem>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2071,49 +2078,46 @@ function PlatformCategoryGameItem({
|
||||
entry.summaryText || entry.subtitle || `${displayName} 正在等待摘要。`;
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
<PlatformNavigableListItem
|
||||
onClick={onClick}
|
||||
aria-label={`${entry.worldName},${actionLabel}`}
|
||||
align="center"
|
||||
className="platform-category-game-item"
|
||||
bodyClassName="platform-category-game-item__body"
|
||||
leading={
|
||||
<div className="platform-category-game-item__cover">
|
||||
{coverImage ? (
|
||||
<PlatformWorkCoverArtwork
|
||||
entry={entry}
|
||||
imageSrc={coverImage}
|
||||
alt={entry.worldName}
|
||||
className="h-full w-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<div className="h-full w-full bg-[radial-gradient(circle_at_24%_18%,rgba(255,255,255,0.26),transparent_32%),linear-gradient(135deg,rgba(255,118,117,0.44),rgba(89,164,255,0.36))]" />
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
trailing={
|
||||
<span className="platform-category-game-item__action">{actionLabel}</span>
|
||||
}
|
||||
>
|
||||
<div className="platform-category-game-item__cover">
|
||||
{coverImage ? (
|
||||
<PlatformWorkCoverArtwork
|
||||
entry={entry}
|
||||
imageSrc={coverImage}
|
||||
alt={entry.worldName}
|
||||
className="h-full w-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<div className="h-full w-full bg-[radial-gradient(circle_at_24%_18%,rgba(255,255,255,0.26),transparent_32%),linear-gradient(135deg,rgba(255,118,117,0.44),rgba(89,164,255,0.36))]" />
|
||||
)}
|
||||
<div className="platform-category-game-item__title-row">
|
||||
<span className="platform-category-game-item__title">{displayName}</span>
|
||||
<span className="platform-category-game-item__badge">公开</span>
|
||||
</div>
|
||||
|
||||
<div className="platform-category-game-item__body">
|
||||
<div className="platform-category-game-item__title-row">
|
||||
<span className="platform-category-game-item__title">
|
||||
{displayName}
|
||||
</span>
|
||||
<span className="platform-category-game-item__badge">公开</span>
|
||||
</div>
|
||||
|
||||
<div className="platform-category-game-item__meta">
|
||||
<span className="platform-category-game-item__metric">
|
||||
<Star className="h-3.5 w-3.5 fill-current" />
|
||||
<span>{formatPlatformCompactCount(metric.value)}</span>
|
||||
</span>
|
||||
<span>{metric.label}</span>
|
||||
{metaParts.length > 0 ? <span>{metaParts.join(' · ')}</span> : null}
|
||||
</div>
|
||||
|
||||
<div className="platform-category-game-item__summary">
|
||||
{summaryText}
|
||||
</div>
|
||||
<div className="platform-category-game-item__meta">
|
||||
<span className="platform-category-game-item__metric">
|
||||
<Star className="h-3.5 w-3.5 fill-current" />
|
||||
<span>{formatPlatformCompactCount(metric.value)}</span>
|
||||
</span>
|
||||
<span>{metric.label}</span>
|
||||
{metaParts.length > 0 ? <span>{metaParts.join(' · ')}</span> : null}
|
||||
</div>
|
||||
|
||||
<span className="platform-category-game-item__action">{actionLabel}</span>
|
||||
</button>
|
||||
<div className="platform-category-game-item__summary">{summaryText}</div>
|
||||
</PlatformNavigableListItem>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user