From 402b847c7f68104953a43ddfe3127176d7ad3177 Mon Sep 17 00:00:00 2001 From: kdletters Date: Thu, 11 Jun 2026 01:52:47 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E6=94=B6=E5=8F=A3=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E7=A9=BA=E6=80=81=E4=B8=8E=E6=9A=97=E8=89=B2?= =?UTF-8?q?=E5=8A=A8=E4=BD=9C=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 视觉小说实体列表空态复用 PlatformEmptyState 角色素材工作室局部按钮改为委托 PlatformActionButton RPG大编辑器局部按钮改为委托 PlatformActionButton 更新 PlatformUiKit 收口文档与团队决策记录 --- .hermes/shared-memory/decision-log.md | 4 +-- ...】PlatformUiKit弹窗组件收口计划-2026-06-08.md | 3 ++- .../CustomWorldEntityEditorModal.test.tsx | 6 ++++- .../RpgCreationRoleAssetStudioModalImpl.tsx | 25 +++++++++++++------ .../RpgCreationEntityEditorShared.tsx | 23 +++++++++++++---- .../VisualNovelResultView.test.tsx | 12 ++++++--- .../VisualNovelResultView.tsx | 9 ++++--- 7 files changed, 59 insertions(+), 23 deletions(-) diff --git a/.hermes/shared-memory/decision-log.md b/.hermes/shared-memory/decision-log.md index 0a4ebd06..0673f046 100644 --- a/.hermes/shared-memory/decision-log.md +++ b/.hermes/shared-memory/decision-log.md @@ -2077,8 +2077,8 @@ - 决策:平台入口的创作前置泥点阻断提示只在 `platform-entry` 局部抽成 `src/components/platform-entry/PlatformDraftGenerationPointNoticeDialog.tsx`,并使用 `DraftGenerationPointNotice` union(`insufficient-points` / `balance-load-failed`)承接业务真相;不要在 `common/` 再抽一个泛化 `BlockingNoticeDialog`,否则会把 `PlatformAcknowledgeStatusDialog` 的样式透传再包装一层而不缩小调用面。 - 决策:`PlatformAsyncStatePanel` 从 profile modal 扩展到作品架类白底 panel;`CustomWorldCreationHub.tsx` 的作品架主体现在也统一走 `loadingState / emptyState / children` 三段 slot,但 error + 重试继续留在业务层外侧,不把共享组件扩成“banner + retry + content”全能状态机。后续白底作品架或列表 panel 若只是互斥的 `loading / empty / content`,优先直接复用这套骨架。 - 决策:`CopyFeedbackButton.tsx` 的 `actionSurface` 分支继续收口到 `PlatformActionButton`,`pill` 分支继续保留 `PlatformPillBadge` 风格;复制反馈按钮不再直接调用 `getPlatformActionButtonClassName` 手拼平台按钮基础 chrome。后续同类“复制状态机 + 平台动作按钮”组合优先直接复用 `CopyFeedbackButton`,不要在业务页重新混写图标、文案、aria 和动作按钮 class。 -- 决策:白底 / 暗色面板里的轻量空态和普通 CTA 继续向共享组件收口。`PuzzleResultView.tsx` 的缺草稿提示、`RpgCreationAssetDebugPanel.tsx` 的空诊断提示改为 `PlatformEmptyState`,`Match3DResultView.tsx` 的引用素材列表直接复用 `PlatformAssetPickerGrid` 自己的空态;`AdventureEntityModal.tsx` 的私聊按钮和 `InventoryPanel.tsx` 的锻造 / 合成按钮改为 `PlatformActionButton surface="editorDark"`,业务页只贴局部 sky / emerald 皮肤。后续白底子面板里的只读空态优先使用 `PlatformEmptyState surface="subpanel" size="inline"`,暗色编辑 / 运行面板里的普通动作优先使用 `PlatformActionButton surface="editorDark"`。 -- 验证方式:`npm run test -- src/components/common/PlatformAsyncStatePanel.test.tsx src/components/platform-entry/PlatformProfileReferralModal.test.tsx src/components/platform-entry/PlatformProfileWalletLedgerModal.test.tsx src/components/platform-entry/PlatformProfilePlayedWorksModal.test.tsx src/components/platform-entry/PlatformProfileTaskCenterModal.test.tsx src/components/platform-entry/PlatformProfileRechargeModal.test.tsx src/components/common/PlatformSegmentedTabs.test.tsx src/components/custom-world-home/CustomWorldCreationHub.test.tsx src/components/custom-world-home/CustomWorldCreationHub.interaction.test.tsx`、`npm run test -- src/components/common/PlatformModalCloseButton.test.tsx src/components/PixelCloseButton.test.tsx src/components/CharacterChatModal.test.tsx src/components/MapModal.test.tsx`、`npm run test -- src/components/common/useMudPointConfirmController.test.tsx src/components/match3d-result/Match3DResultView.test.tsx src/components/unified-creation/workspaces/PuzzleCreationWorkspace.interaction.test.tsx src/components/unified-creation/workspaces/Match3DCreationWorkspace.interaction.test.tsx src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx src/components/platform-entry/PlatformProfileRechargeModal.test.tsx src/components/CustomWorldEntityEditorModal.test.tsx src/components/rpg-creation-result/RpgCreationResultActionBar.test.tsx src/components/unified-creation/shared/PuzzleHistoryAssetPickerDialog.test.tsx src/components/puzzle-result/PuzzleResultView.test.tsx`、`npm run test -- src/components/common/CopyFeedbackButton.test.tsx src/components/common/PlatformActionButton.test.tsx src/components/AdventureEntityModal.test.tsx src/components/InventoryPanel.test.tsx src/components/rpg-creation-result/RpgCreationAssetDebugPanel.test.tsx`、`npm run typecheck`、`npm run check:encoding`、`git diff --check`。 +- 决策:白底 / 暗色面板里的轻量空态和普通 CTA 继续向共享组件收口。`PuzzleResultView.tsx` 的缺草稿提示、`RpgCreationAssetDebugPanel.tsx` 的空诊断提示、`VisualNovelEntityGrid` 的空实体列表都改为 `PlatformEmptyState`,`Match3DResultView.tsx` 的引用素材列表直接复用 `PlatformAssetPickerGrid` 自己的空态;`AdventureEntityModal.tsx` 的私聊按钮、`InventoryPanel.tsx` 的锻造 / 合成按钮,以及 `RpgCreationRoleAssetStudioModalImpl.tsx`、`RpgCreationEntityEditorShared.tsx` 里的局部 `ActionButton` 包装层都改为委托 `PlatformActionButton surface="editorDark"`。后续白底子面板里的只读空态优先使用 `PlatformEmptyState surface="subpanel" size="inline"`;暗色编辑 / 运行面板里的普通动作优先使用 `PlatformActionButton surface="editorDark"`,若业务仍需 `stopPropagation`、tone 映射或局部排版,可保留薄包装层,但不要再直接写原生 ` + ); } diff --git a/src/components/rpg-creation-editor/RpgCreationEntityEditorShared.tsx b/src/components/rpg-creation-editor/RpgCreationEntityEditorShared.tsx index af7c8236..6c7b4a3d 100644 --- a/src/components/rpg-creation-editor/RpgCreationEntityEditorShared.tsx +++ b/src/components/rpg-creation-editor/RpgCreationEntityEditorShared.tsx @@ -95,6 +95,7 @@ import { import { useAuthUi } from '../auth/AuthUiContext'; import { CharacterAnimator } from '../CharacterAnimator'; import { PlatformAcknowledgeStatusDialog } from '../common/PlatformAcknowledgeStatusDialog'; +import { PlatformActionButton } from '../common/PlatformActionButton'; import { PlatformAssetPickerGrid } from '../common/PlatformAssetPickerCard'; import { PlatformEmptyState } from '../common/PlatformEmptyState'; import { PlatformIconButton } from '../common/PlatformIconButton'; @@ -1665,16 +1666,22 @@ function ActionButton({ disabled?: boolean; className?: string; }) { + const buttonTone = + tone === 'sky' ? 'primary' : tone === 'rose' ? 'danger' : 'ghost'; const toneClassName = tone === 'sky' - ? 'border-sky-300/22 bg-sky-500/12 text-sky-50 hover:border-sky-200/40 hover:text-white' + ? 'border-sky-300/22 bg-sky-500/12 text-sky-50 hover:border-sky-200/40 hover:bg-sky-500/18 hover:text-white' : tone === 'rose' - ? 'border-rose-300/22 bg-rose-500/12 text-rose-50 hover:border-rose-200/40 hover:text-white' + ? 'border-rose-300/22 bg-rose-500/12 text-rose-50 hover:border-rose-200/40 hover:bg-rose-500/16 hover:text-white' : 'border-white/12 bg-black/20 text-zinc-200 hover:border-white/22 hover:text-white'; return ( - + ); } diff --git a/src/components/visual-novel-result/VisualNovelResultView.test.tsx b/src/components/visual-novel-result/VisualNovelResultView.test.tsx index 499ca8ac..ac1f9a69 100644 --- a/src/components/visual-novel-result/VisualNovelResultView.test.tsx +++ b/src/components/visual-novel-result/VisualNovelResultView.test.tsx @@ -113,7 +113,7 @@ test('visual novel entity list items use interactive PlatformSubpanel shells', a expect(characterCard.className).toContain('rounded-[1.25rem]'); }); -test('visual novel empty entity list uses PlatformSubpanel shell', async () => { +test('visual novel empty entity list uses PlatformEmptyState shell', async () => { const user = userEvent.setup(); const emptyCharacterDraft = { ...mockVisualNovelDraft, @@ -126,11 +126,17 @@ test('visual novel empty entity list uses PlatformSubpanel shell', async () => { await user.click(screen.getByRole('button', { name: '角色' })); - const emptyPanel = screen.getByText('暂无角色').closest('.platform-subpanel'); + const emptyPanel = screen + .getByText('暂无角色') + .closest('.platform-empty-state'); - expect(emptyPanel?.className).toContain('platform-subpanel'); + expect(emptyPanel?.className).toContain('platform-empty-state'); + expect(emptyPanel?.className).toContain('bg-white/74'); expect(emptyPanel?.className).toContain('rounded-[1.25rem]'); expect(emptyPanel?.className).toContain('min-h-32'); + expect(emptyPanel?.className).toContain( + 'text-[var(--platform-text-soft)]', + ); }); test('visual novel result opens complex editors as a dialog', async () => { diff --git a/src/components/visual-novel-result/VisualNovelResultView.tsx b/src/components/visual-novel-result/VisualNovelResultView.tsx index 7369f262..96d6b65b 100644 --- a/src/components/visual-novel-result/VisualNovelResultView.tsx +++ b/src/components/visual-novel-result/VisualNovelResultView.tsx @@ -1848,12 +1848,13 @@ function VisualNovelEntityGrid({ ))} {items.length <= 0 ? ( - {emptyText} - + ) : null}