diff --git a/.hermes/shared-memory/decision-log.md b/.hermes/shared-memory/decision-log.md index 7a11319c..478cd318 100644 --- a/.hermes/shared-memory/decision-log.md +++ b/.hermes/shared-memory/decision-log.md @@ -293,6 +293,7 @@ - 2026-06-10 验证补充:creative-agent 模板 / hero / 目标就绪图标圆槽收口补跑 `npm run test -- src/components/common/PlatformIconBadge.test.tsx src/components/creative-agent/CreativeAgentWorkspace.test.tsx src/components/creative-agent/CreativeAgentTemplateConfirmPanel.test.tsx`。 - 2026-06-10 验证补充:创作类型弹层锁定卡小圆锁图标收口补跑 `npm run test -- src/components/common/PlatformIconBadge.test.tsx src/components/platform-entry/PlatformEntryCreationTypeModal.test.tsx`。 - 2026-06-10 验证补充:大鱼吃小鱼发布失败弹窗危险图标槽收口补跑 `npm run test -- src/components/common/PlatformIconBadge.test.tsx src/components/big-fish-result/BigFishResultView.test.tsx -t "shows publish failures in a dismissible modal"`。 +- 2026-06-10 追加:`PlatformIconBadge` 根节点固定带 `platform-icon-badge` 稳定类名;个人中心充值结果弹窗和支付确认遮罩里的 56px 圆形图标槽使用 `PlatformIconBadge size="xl"` 并保留局部 `bg-white/10` 与状态文字色覆盖,支付弹窗不再手写圆形图标容器。验证命令:`npm run test -- src/components/common/PlatformIconBadge.test.tsx`、`npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "confirms virtual payment after returning without hash result|releases submitting state after cancelled wechat pay result"`。 - 2026-06-10 验证补充:宝贝识物工作台静态玩法预览卡和图标槽收口补跑 `npm run test -- src/components/common/PlatformSubpanel.test.tsx src/components/common/PlatformIconBadge.test.tsx src/components/edutainment-creation/BabyObjectMatchWorkspace.test.tsx`。 - 2026-06-10 验证补充:通用创作图片面板空主图上传占位图标槽收口补跑 `npm run test -- src/components/common/PlatformIconBadge.test.tsx src/components/common/CreativeImageInputPanel.test.tsx`。 - 2026-06-10 验证补充:GameCanvas 宝箱遭遇图标槽收口到 `PlatformIconBadge size="xxl" shape="xl" tone="darkAmber"` 后,补跑 `npm run test -- src/components/common/PlatformIconBadge.test.tsx src/components/game-canvas/GameCanvasEntityLayer.test.tsx`。 diff --git a/docs/technical/【前端架构】PlatformUiKit弹窗组件收口计划-2026-06-08.md b/docs/technical/【前端架构】PlatformUiKit弹窗组件收口计划-2026-06-08.md index db1618f8..8b45c4d3 100644 --- a/docs/technical/【前端架构】PlatformUiKit弹窗组件收口计划-2026-06-08.md +++ b/docs/technical/【前端架构】PlatformUiKit弹窗组件收口计划-2026-06-08.md @@ -139,8 +139,9 @@ - `PlatformActionButton` 补充:创作中心作品卡积分激励的“领取积分 / 领取中”按钮使用 `tone="secondary" size="xxs"`;作品卡保留 `creation-work-card-incentive__button` 局部 class 控制三列布局、移动端跨列、紧凑高度和玻璃底,不再手写原生按钮 chrome。 - `PlatformActionButton` 补充:拼图首访 onboarding 生成 / 登录 CTA 使用 `surface="editorDark" tone="accent" size="lg" fullWidth`,跳过按钮使用 `surface="editorDark" tone="ghost" shape="pill"` 并只保留右上角定位 class;首访页不再手写按钮基础 chrome。 - `PlatformIconButton`:接收 `label`、`icon`、可选 `children`、可选 `variant="platformIcon" | "surfaceFloating" | "darkMini"`、`title`、`className`、`asChild="label"` 和原生 button / label props;默认 `platformIcon` 用于平台弹窗 header、搜索结果弹窗、工具栏、结果页选项删除等普通图标动作按钮,也用于保持 file input 原生语义的图标上传 label;`surfaceFloating` 用于通用创作图片面板里覆盖在图片或输入区上的白底圆形图标动作,短文案入口通过 `children` 渲染可见短标签但仍由 `label` 提供可访问名称;`darkMini` 用于上传预览卡右上角等覆盖在缩略图上的暗色小型图标动作。creation-agent composer 中的上传文档 / 上传参考图入口使用默认 `platformIcon`,只保留动态 label、title、busy 和 picker 回调;作品详情顶部返回 / 分享与封面轮播上一张 / 下一张入口也使用默认 `platformIcon`,并通过局部 class 保留详情页专属位置和尺寸。发送按钮、点赞按钮、带复制三态或强品牌动作继续保留专用布局。关闭语义复杂或属于个人中心 / 浮层关闭按钮时仍优先使用 `PlatformModalCloseButton`,带复制三态时使用 `CopyFeedbackButton`。同一面板内存在主图上传和提示词参考图上传时,两个 file input 必须使用不同可访问名称,避免业务测试或读屏用户只能看到多个同名“上传参考图”入口。 -- `PlatformIconBadge`:接收 `icon`、可选 `label`、`size="xs" | "sm" | "base" | "md" | "lg" | "xl" | "xxl"`、`shape="circle" | "rounded" | "xl"`、`tone="neutral" | "soft" | "softBright" | "hero" | "heroMuted" | "darkAmber" | "success" | "danger"` 和 `className`;统一承接非交互图标槽的中性 / 柔和 / hero / 暗色琥珀 / 成功 / 危险底色、文字色、尺寸、圆角和 `aria-hidden` / `aria-label`。视觉小说 runtime 面板标题、存档列表项,creative-agent 模板卡 / 模板确认 / 顶部 hero / 目标就绪 / 过程条目图标圆槽,创作类型弹层锁定卡小圆锁图标,大鱼吃小鱼发布失败弹窗图标槽,通用创作图片面板空主图上传占位图标槽,拼图结果页智能修订条图标槽,以及 GameCanvas 宝箱遭遇图标槽已先迁移。后续同类图标槽不再重复手写 `grid h-* w-*`、`inline-flex h-* w-* items-center justify-center`、`rounded-full`、`rounded-[0.85rem]`、`rounded-2xl`、neutral token class、白底柔和小圆槽、暗色琥珀图标槽或危险提示红色圆槽。 +- `PlatformIconBadge`:接收 `icon`、可选 `label`、`size="xs" | "sm" | "base" | "md" | "lg" | "xl" | "xxl"`、`shape="circle" | "rounded" | "xl"`、`tone="neutral" | "soft" | "softBright" | "hero" | "heroMuted" | "darkAmber" | "success" | "danger"` 和 `className`;统一承接非交互图标槽的中性 / 柔和 / hero / 暗色琥珀 / 成功 / 危险底色、文字色、尺寸、圆角和 `aria-hidden` / `aria-label`。根节点固定带 `platform-icon-badge` 稳定类名,业务测试可断言共享图标槽接入。视觉小说 runtime 面板标题、存档列表项,creative-agent 模板卡 / 模板确认 / 顶部 hero / 目标就绪 / 过程条目图标圆槽,创作类型弹层锁定卡小圆锁图标,大鱼吃小鱼发布失败弹窗图标槽,通用创作图片面板空主图上传占位图标槽,拼图结果页智能修订条图标槽,以及 GameCanvas 宝箱遭遇图标槽已先迁移。后续同类图标槽不再重复手写 `grid h-* w-*`、`inline-flex h-* w-* items-center justify-center`、`rounded-full`、`rounded-[0.85rem]`、`rounded-2xl`、neutral token class、白底柔和小圆槽、暗色琥珀图标槽或危险提示红色圆槽。 - `PlatformIconBadge` 补充:宝贝识物工作台玩法预览卡内礼物图标槽使用 `size="xl" shape="rounded" tone="softBright"`,业务页只保留玩法色和投影覆盖,不再手写 `grid h-14 w-14 place-items-center rounded-* bg-white/*`。 +- `PlatformIconBadge` 补充:个人中心充值结果弹窗和支付确认遮罩里的 56px 圆形图标槽使用 `size="xl"` 并通过局部 `bg-white/10`、状态文字色 class 覆盖;弹窗只保留支付结果文案、支付状态图标和确认动作,不再手写 `flex h-14 w-14 items-center justify-center rounded-full bg-white/10` 图标容器。 - `PlatformUploadTile`:接收 `label`、可选 `hint`、`icon`、`size="square" | "compact" | "panel"`、`surface="platform" | "editorDark"`、`showLabel`、`disabled`、`className`、`asChild="label"` 和原生 button / label props;默认渲染 `type="button"` 的平台虚线上传方块,`compact + showLabel={false}` 用于工作台里的纯图标虚线新增入口,`panel` 用于整行上传说明入口,`editorDark` 用于 RPG 大编辑器等暗色弹窗。label 模式保留 file input 原生关联语义,禁用时写入 `aria-disabled` 并阻断 label 默认点击。反馈页上传凭证、敲木鱼工作台新增功德词条入口、RPG 大编辑器参考图入口、角色素材工作室参考图入口和封面上传入口已迁移,后续图片 / 附件上传方块或紧凑虚线新增入口只保留业务选择文件 / 新增动作,不再重复写虚线入口 chrome。 - `PlatformUploadPreviewCard`:接收 `imageSrc`、`imageAlt`、`removeLabel`、可选 `layout="square" | "inline"`、`surface="platform" | "editorDark"`、`caption`、`previewLabel`、`onPreview`、`onRemove`、`disabled`、`resolveAsset`、`imageRefreshKey`、`className`、`imageClassName`、`imageShellClassName`、`captionClassName`、`previewButtonProps`、`removeIcon` 和 `removeButtonProps`;默认 `square` 渲染平台缩略图壳、`object-cover` 预览图、可选标题行和可选移除按钮,square 右上移除按钮复用 `PlatformIconButton variant="darkMini"`,`inline + platform` 通过 `PlatformSubpanel surface="soft" padding="row"` 渲染白底横向已选素材条,`inline + editorDark` 通过 `PlatformSubpanel surface="dark" padding="row"` 渲染暗色编辑器横向参考图条。需要点击预览的参考图传 `previewLabel/onPreview`,需要 generated / OSS 资产换签的缩略图传 `resolveAsset`,需要展示文件名 / 素材名的参考图传 `caption`,不要在业务 JSX 中额外包一层缩略图标题栏或横向参考图条。反馈页上传凭证预览、通用创作图片面板的提示词参考图缩略图、抓大鹅封面编辑参考图缩略图、通用输入 Composer、creation-agent 已选参考图条、拼图结果页关卡引用图横条和 RPG 大编辑器参考图预览条已迁移,后续上传预览只保留素材数据、预览回调和删除回调,不在业务 JSX 中重复写预览卡 chrome。 - `PlatformPillSwitch`:接收 `label`、`checked`、`disabled`、`className` 和原生 input props;内部固定 `role="switch"`、`type="checkbox"` 和 `sr-only` 输入,视觉层统一白底胶囊、开关轨道、圆点位置、hover / 禁用态。通用创作图片面板和抓大鹅封面编辑的 `AI重绘` 已迁移,后续同类胶囊开关只传受控 checked / onChange,不再手写 switch 轨道和圆点。 @@ -259,6 +260,7 @@ - `npm run test -- src/components/MapModal.test.tsx src/components/common/PlatformSubpanel.test.tsx src/components/common/PlatformPillBadge.test.tsx` - `npm run test -- src/components/common/PlatformOverlayBadge.test.tsx src/components/common/PlatformSlotBadge.test.tsx` - `npm run test -- src/components/common/PlatformQuantityBadge.test.tsx` +- `npm run test -- src/components/common/PlatformIconBadge.test.tsx` - `npm run test -- src/components/common/PlatformSubpanel.test.tsx` - `npm run test -- src/components/common/PlatformPillBadge.test.tsx src/components/rpg-runtime-panels/RpgAdventurePanel.test.tsx src/components/rpg-runtime-panels/RpgAdventurePanel.questOffer.test.tsx` - `npm run test -- src/components/rpg-runtime-panels/RpgAdventurePanel.questOffer.test.tsx -t "quest offer accept button reuses the shared accepted-quest follow-up chain"` @@ -270,6 +272,7 @@ - `npm run test -- src/components/common/PlatformPillBadge.test.tsx src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "wallet ledger|profile played modal summary"` - `npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "profile recharge modal trusts per-product first bonus display after points recharge"` - `npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "profile community shortcut shows reward subtitle and invited users"` +- `npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "confirms virtual payment after returning without hash result|releases submitting state after cancelled wechat pay result"` - `npm run test -- src/components/common/PlatformSubpanel.test.tsx` - `npm run test -- src/components/common/PlatformPillBadge.test.tsx` - `npm run test -- src/components/common/CopyFeedbackMessage.test.tsx` diff --git a/src/components/common/PlatformIconBadge.test.tsx b/src/components/common/PlatformIconBadge.test.tsx index e96962f2..468fd10d 100644 --- a/src/components/common/PlatformIconBadge.test.tsx +++ b/src/components/common/PlatformIconBadge.test.tsx @@ -11,6 +11,7 @@ test('renders neutral circular icon badge by default', () => { const badge = document.querySelector('[aria-hidden="true"]'); + expect(badge?.className).toContain('platform-icon-badge'); expect(badge?.className).toContain('h-9'); expect(badge?.className).toContain('rounded-full'); expect(badge?.className).toContain('bg-[var(--platform-neutral-bg)]'); diff --git a/src/components/common/PlatformIconBadge.tsx b/src/components/common/PlatformIconBadge.tsx index b45eae62..611dd07a 100644 --- a/src/components/common/PlatformIconBadge.tsx +++ b/src/components/common/PlatformIconBadge.tsx @@ -69,6 +69,7 @@ export function PlatformIconBadge({ aria-label={label} aria-hidden={label ? undefined : true} className={[ + 'platform-icon-badge', 'grid shrink-0 place-items-center', PLATFORM_ICON_BADGE_SIZE_CLASS[size], PLATFORM_ICON_BADGE_SHAPE_CLASS[shape], diff --git a/src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx b/src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx index 0f42aa1f..1ed70113 100644 --- a/src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx +++ b/src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx @@ -2173,7 +2173,11 @@ test('profile recharge modal confirms virtual payment after returning without ha act(() => { window.dispatchEvent(new PageTransitionEvent('pageshow')); }); - expect(screen.getByRole('dialog', { name: '正在确认支付' })).toBeTruthy(); + const confirmingDialog = screen.getByRole('dialog', { name: '正在确认支付' }); + expect(confirmingDialog).toBeTruthy(); + expect( + confirmingDialog.querySelector('.platform-icon-badge')?.className, + ).toContain('h-14'); await waitFor(() => { expect(mockConfirmWechatRpgProfileRechargeOrder).toHaveBeenCalledWith( 'order-wechat-no-hash-paid', @@ -2442,6 +2446,10 @@ test('profile recharge modal releases submitting state after cancelled wechat pa expect( await screen.findByRole('dialog', { name: '支付已取消' }), ).toBeTruthy(); + const cancelDialog = screen.getByRole('dialog', { name: '支付已取消' }); + expect( + cancelDialog.querySelector('.platform-icon-badge')?.className, + ).toContain('platform-icon-badge'); expect(screen.getByText('本次没有扣款,账户状态未发生变化。')).toBeTruthy(); await waitFor(() => { expect( diff --git a/src/components/rpg-entry/RpgEntryHomeView.tsx b/src/components/rpg-entry/RpgEntryHomeView.tsx index a13f5584..7b00c8c8 100644 --- a/src/components/rpg-entry/RpgEntryHomeView.tsx +++ b/src/components/rpg-entry/RpgEntryHomeView.tsx @@ -123,6 +123,7 @@ import { import { PlatformActionButton } from '../common/PlatformActionButton'; import { PlatformEmptyState } from '../common/PlatformEmptyState'; import { PlatformFieldLabel } from '../common/PlatformFieldLabel'; +import { PlatformIconBadge } from '../common/PlatformIconBadge'; import { PlatformIconButton } from '../common/PlatformIconButton'; import { PlatformModalCloseButton } from '../common/PlatformModalCloseButton'; import { PlatformPillBadge } from '../common/PlatformPillBadge'; @@ -3297,11 +3298,12 @@ function RechargePaymentResultModal({ className="platform-modal-shell platform-remap-surface w-full max-w-sm overflow-hidden rounded-[1.4rem]" >