收口作品详情点赞按钮

为 PlatformActionButton 增加 accentSoft tone

将作品详情点赞按钮迁移到 PlatformActionButton

删除作品详情点赞按钮本地 chrome CSS

补充公共按钮和作品详情点赞断言

更新 PlatformUiKit 文档和 Hermes 决策记录
This commit is contained in:
2026-06-10 15:08:42 +08:00
parent 694b2fa209
commit e612b13b88
8 changed files with 55 additions and 38 deletions

View File

@@ -55,9 +55,10 @@
- 2026-06-10 追加:`PlatformModalCloseButton variant="editorDark"` 承接 RPG 暗色弹窗中非像素风的圆形 X 关闭入口,根节点固定带 `platform-modal-close-button--editor-dark` 稳定类名;自定义选择弹窗头部关闭按钮已迁移,并补齐 `aria-label`,业务 JSX 不再手写暗色关闭按钮边框、底色、hover 和默认 X 图标。验证命令:`npm run test -- src/components/common/PlatformModalCloseButton.test.tsx src/components/SelectionCustomizationModals.test.tsx` - 2026-06-10 追加:`PlatformModalCloseButton variant="editorDark"` 承接 RPG 暗色弹窗中非像素风的圆形 X 关闭入口,根节点固定带 `platform-modal-close-button--editor-dark` 稳定类名;自定义选择弹窗头部关闭按钮已迁移,并补齐 `aria-label`,业务 JSX 不再手写暗色关闭按钮边框、底色、hover 和默认 X 图标。验证命令:`npm run test -- src/components/common/PlatformModalCloseButton.test.tsx src/components/SelectionCustomizationModals.test.tsx`
- 2026-06-10 追加:`PlatformModalCloseButton variant="pixel"` 承接 `UnifiedModal variant="pixel"` 头部圆形关闭入口;`UnifiedModal` 只选择 `platformIcon / pixel` 变体并保留 closeDisabled、Backdrop、Escape 和 portal 语义,不再手写 X 图标、aria 和关闭按钮 class。验证命令`npm run test -- src/components/common/UnifiedModal.test.tsx src/components/common/PlatformModalCloseButton.test.tsx src/components/common/UnifiedConfirmDialog.test.tsx` - 2026-06-10 追加:`PlatformModalCloseButton variant="pixel"` 承接 `UnifiedModal variant="pixel"` 头部圆形关闭入口;`UnifiedModal` 只选择 `platformIcon / pixel` 变体并保留 closeDisabled、Backdrop、Escape 和 portal 语义,不再手写 X 图标、aria 和关闭按钮 class。验证命令`npm run test -- src/components/common/UnifiedModal.test.tsx src/components/common/PlatformModalCloseButton.test.tsx src/components/common/UnifiedConfirmDialog.test.tsx`
- 2026-06-09 追加RPG 大编辑器暗色面板内的保存和角色槽动作继续走本地 `ActionButton`,不再混用白底平台 `platform-button` class平台白底动作收口和编辑器暗色动作收口保持两套视觉边界。 - 2026-06-09 追加RPG 大编辑器暗色面板内的保存和角色槽动作继续走本地 `ActionButton`,不再混用白底平台 `platform-button` class平台白底动作收口和编辑器暗色动作收口保持两套视觉边界。
- 2026-06-10 追加:`PlatformActionButton surface="editorDark"` 承接 RPG 暗色弹窗 / 运行面板里的普通取消、确认、刷新和编组动作,支持 `size="xxs"``tone="success" | "warning"``tone="accent"` 承接暗色壳层内的琥珀实心 CTA。角色自定义 footer、自定义世界生成 footer、地图切换确认、营地编组普通动作和角色聊天刷新动作已迁移。暗色可选项卡仍使用 `PlatformDarkOptionCard`,像素风发送 / 强品牌动作继续保留专用布局。验证命令:`npm run test -- src/components/common/platformActionButtonModel.test.ts src/components/common/PlatformActionButton.test.tsx src/components/SelectionCustomizationModals.test.tsx src/components/CompanionCampModal.test.tsx src/components/MapModal.test.tsx src/components/CharacterChatModal.test.tsx` - 2026-06-10 追加:`PlatformActionButton surface="editorDark"` 承接 RPG 暗色弹窗 / 运行面板里的普通取消、确认、刷新和编组动作,支持 `size="xxs"``tone="success" | "warning"``tone="accent"` 承接暗色壳层内的琥珀实心 CTA`tone="accentSoft"` 承接依赖局部 accent 变量的柔和强调按钮。角色自定义 footer、自定义世界生成 footer、地图切换确认、营地编组普通动作和角色聊天刷新动作已迁移。暗色可选项卡仍使用 `PlatformDarkOptionCard`,像素风发送 / 强品牌动作继续保留专用布局。验证命令:`npm run test -- src/components/common/platformActionButtonModel.test.ts src/components/common/PlatformActionButton.test.tsx src/components/SelectionCustomizationModals.test.tsx src/components/CompanionCampModal.test.tsx src/components/MapModal.test.tsx src/components/CharacterChatModal.test.tsx`
- 2026-06-10 追加RPG 大编辑器里的当前角色、可选角色、预设背景和场景连接关系等暗色信息面板通过本地 `EditorInfoPanel` 复用 `PlatformSubpanel surface="dark"`;有右侧动作的面板也只向适配器传 actions不再在业务 JSX 中重复手写暗色面板边框、底色、圆角、标题行和内容间距。验证命令:`npm run test -- src/components/CustomWorldEntityEditorModal.test.tsx -t "场景编辑器会在场景内展示槽位化多幕配置并保存"` - 2026-06-10 追加RPG 大编辑器里的当前角色、可选角色、预设背景和场景连接关系等暗色信息面板通过本地 `EditorInfoPanel` 复用 `PlatformSubpanel surface="dark"`;有右侧动作的面板也只向适配器传 actions不再在业务 JSX 中重复手写暗色面板边框、底色、圆角、标题行和内容间距。验证命令:`npm run test -- src/components/CustomWorldEntityEditorModal.test.tsx -t "场景编辑器会在场景内展示槽位化多幕配置并保存"`
- 2026-06-10 追加:作品详情底部“作品改造 / 作品编辑”和“启动”使用 `PlatformActionButton surface="platform" shape="pill" size="lg" fullWidth`;详情页保留 `platform-work-detail__remix / start` 局部 class 控制 sticky 底部栏位置、比例和品牌背景。验证命令:`npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx` - 2026-06-10 追加:作品详情底部“作品改造 / 作品编辑”和“启动”使用 `PlatformActionButton surface="platform" shape="pill" size="lg" fullWidth`;详情页保留 `platform-work-detail__remix / start` 局部 class 控制 sticky 底部栏位置、比例和品牌背景。验证命令:`npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx`
- 2026-06-10 追加:作品详情点赞按钮使用 `PlatformActionButton tone="accentSoft"`;详情页只保留纵向排布、尺寸和 `--platform-action-accent` 局部变量,不再手写点赞按钮边框、底色、文字和阴影 chrome。验证命令`npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx src/components/common/platformActionButtonModel.test.ts`
- 2026-06-09 追加:大鱼吃小鱼结果页白底平台动作迁移到 `PlatformActionButton shape="pill" size="xs"`;资产工坊关闭 / 生成正式图、关卡主图 / 待机 / 移动入口和场地背景生成只保留业务回调,深色 hero 返回 / 测试 / 发布按钮继续保留玩法品牌布局。 - 2026-06-09 追加:大鱼吃小鱼结果页白底平台动作迁移到 `PlatformActionButton shape="pill" size="xs"`;资产工坊关闭 / 生成正式图、关卡主图 / 待机 / 移动入口和场地背景生成只保留业务回调,深色 hero 返回 / 测试 / 发布按钮继续保留玩法品牌布局。
- 2026-06-10 追加:反馈页“查看反馈与投诉记录”这类页面内次级文本动作使用 `PlatformActionButton tone="ghost" shape="pill" size="xs"`;反馈页只保留提示回调,不再手写居中、字号、内边距和冷色文本按钮 class。验证命令`npm run test -- src/components/platform-entry/PlatformFeedbackView.test.tsx src/components/common/PlatformActionButton.test.tsx` - 2026-06-10 追加:反馈页“查看反馈与投诉记录”这类页面内次级文本动作使用 `PlatformActionButton tone="ghost" shape="pill" size="xs"`;反馈页只保留提示回调,不再手写居中、字号、内边距和冷色文本按钮 class。验证命令`npm run test -- src/components/platform-entry/PlatformFeedbackView.test.tsx src/components/common/PlatformActionButton.test.tsx`
- 2026-06-10 追加:创作中心作品卡积分激励的“领取积分 / 领取中”按钮使用 `PlatformActionButton tone="secondary" size="xxs"`;作品卡保留 `creation-work-card-incentive__button` 局部 class 承接三列布局、移动端跨列、紧凑高度和玻璃底,同时保留点击 / 键盘冒泡拦截,避免触发整卡打开。验证命令:`npm run test -- src/components/custom-world-home/CustomWorldCreationHub.interaction.test.tsx src/components/custom-world-home/CustomWorldCreationHub.test.tsx src/components/common/PlatformActionButton.test.tsx src/index.test.ts` - 2026-06-10 追加:创作中心作品卡积分激励的“领取积分 / 领取中”按钮使用 `PlatformActionButton tone="secondary" size="xxs"`;作品卡保留 `creation-work-card-incentive__button` 局部 class 承接三列布局、移动端跨列、紧凑高度和玻璃底,同时保留点击 / 键盘冒泡拦截,避免触发整卡打开。验证命令:`npm run test -- src/components/custom-world-home/CustomWorldCreationHub.interaction.test.tsx src/components/custom-world-home/CustomWorldCreationHub.test.tsx src/components/common/PlatformActionButton.test.tsx src/index.test.ts`
@@ -234,6 +235,7 @@
- 2026-06-10 验证补充creative-agent 首页抽屉空态和首页错误提示收口后,补跑 `npm run test -- src/components/creative-agent/CreativeAgentHome.test.tsx src/components/common/PlatformEmptyState.test.tsx src/components/common/PlatformStatusMessage.test.tsx` - 2026-06-10 验证补充creative-agent 首页抽屉空态和首页错误提示收口后,补跑 `npm run test -- src/components/creative-agent/CreativeAgentHome.test.tsx src/components/common/PlatformEmptyState.test.tsx src/components/common/PlatformStatusMessage.test.tsx`
- 2026-06-10 验证补充:作品详情顶部和封面轮播图标按钮收口补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformIconButton.test.tsx` - 2026-06-10 验证补充:作品详情顶部和封面轮播图标按钮收口补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformIconButton.test.tsx`
- 2026-06-10 验证补充:作品详情底部启动 / 改造动作收口补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx` - 2026-06-10 验证补充:作品详情底部启动 / 改造动作收口补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx`
- 2026-06-10 验证补充:作品详情点赞按钮收口补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx src/components/common/platformActionButtonModel.test.ts`
- 2026-06-10 验证补充:平台作品详情主题标签和作品号复制 chip 收口后,补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformPillBadge.test.tsx src/components/common/CopyCodeButton.test.tsx` - 2026-06-10 验证补充:平台作品详情主题标签和作品号复制 chip 收口后,补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformPillBadge.test.tsx src/components/common/CopyCodeButton.test.tsx`
- 2026-06-10 验证补充:平台作品详情分享复制反馈按状态映射到 `PlatformStatusMessage surface="platform"` 后,补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformStatusMessage.test.tsx` - 2026-06-10 验证补充:平台作品详情分享复制反馈按状态映射到 `PlatformStatusMessage surface="platform"` 后,补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformStatusMessage.test.tsx`
- 2026-06-10 验证补充:大鱼吃小鱼结果页缺草稿空态收口补跑 `npm run test -- src/components/big-fish-result/BigFishResultView.test.tsx src/components/common/PlatformEmptyState.test.tsx` - 2026-06-10 验证补充:大鱼吃小鱼结果页缺草稿空态收口补跑 `npm run test -- src/components/big-fish-result/BigFishResultView.test.tsx src/components/common/PlatformEmptyState.test.tsx`

View File

@@ -123,9 +123,10 @@
- `PlatformTagEditor`:接收 `title``tags``disabled``maxTags``error``addLabel``generateLabel``inputLabel``inputPlaceholder``emptyLabel``parseInput``onChange`、可选 `onGenerate` / `generateIcon``radius``padding``tone="amber" | "warm"`内部持有新增输入态统一处理标签去重、添加、删除、Enter 提交、Escape 取消、空态、可选 AI 生成按钮和错误提示。拼图结果页作品标签、敲木鱼结果页主题标签和抓大鹅结果页作品标签已先迁移。后续结果页只保留业务标签规范化函数和写回回调,不再重复手写 tag chip、删除按钮、输入框、添加 / 取消按钮和 AI 生成按钮。 - `PlatformTagEditor`:接收 `title``tags``disabled``maxTags``error``addLabel``generateLabel``inputLabel``inputPlaceholder``emptyLabel``parseInput``onChange`、可选 `onGenerate` / `generateIcon``radius``padding``tone="amber" | "warm"`内部持有新增输入态统一处理标签去重、添加、删除、Enter 提交、Escape 取消、空态、可选 AI 生成按钮和错误提示。拼图结果页作品标签、敲木鱼结果页主题标签和抓大鹅结果页作品标签已先迁移。后续结果页只保留业务标签规范化函数和写回回调,不再重复手写 tag chip、删除按钮、输入框、添加 / 取消按钮和 AI 生成按钮。
- `PlatformTagEditor` 补充:新增输入行外壳继续由 `PlatformSubpanel surface="soft" padding="tight"` 承接,输入框由 `PlatformTextField` 承接;标签编辑 Module 内部也遵守公共输入 / 子面板分工,不再把白底 input chrome 写成本地 class。 - `PlatformTagEditor` 补充:新增输入行外壳继续由 `PlatformSubpanel surface="soft" padding="tight"` 承接,输入框由 `PlatformTextField` 承接;标签编辑 Module 内部也遵守公共输入 / 子面板分工,不再把白底 input chrome 写成本地 class。
- `PlatformAssetPickerCard`:接收 `imageSrc``imageAlt`、可选 `assetTitle` / `subtitle``surface="platform" | "editorDark"``selectLabel``selected``disabled``onClick``aria-label``cardRadiusClassName``imageShellClassName``imageClassName``bodyClassName`;图片读取统一走 `ResolvedAssetImage`按钮禁用态、选中态、边框、hover、缩略图外壳和可选卡片内选择按钮由 Module 统一控制,`assetTitle` 专指卡片内展示标题,不占用原生 button `title` 属性。`PlatformAssetPickerGrid`:接收素材数组、读取 / 错误 / 空态、`getKey``getImageSrc``getImageAlt``getTitle``getSubtitle``getAriaLabel``isSelected``cardClassName``onSelect`;默认组合 `PlatformStatusMessage``PlatformEmptyState``PlatformAssetPickerCard`,业务页只保留素材字段映射、文案、选中判断和选择回调,不再重复手写缩略图卡片、选中 ring、虚线读取 / 空态和网格 JSX。白底平台弹窗使用默认 `platform` surfaceRPG 大编辑器等暗色弹窗使用 `editorDark`,并通过 `imageShellClassName` 保留场景横图比例。视觉小说等同一弹窗里混有上传 / AI 生成错误时,可继续由外层错误条承接动作错误,只把历史素材读取 / 空态 / 网格交给 `PlatformAssetPickerGrid` - `PlatformAssetPickerCard`:接收 `imageSrc``imageAlt`、可选 `assetTitle` / `subtitle``surface="platform" | "editorDark"``selectLabel``selected``disabled``onClick``aria-label``cardRadiusClassName``imageShellClassName``imageClassName``bodyClassName`;图片读取统一走 `ResolvedAssetImage`按钮禁用态、选中态、边框、hover、缩略图外壳和可选卡片内选择按钮由 Module 统一控制,`assetTitle` 专指卡片内展示标题,不占用原生 button `title` 属性。`PlatformAssetPickerGrid`:接收素材数组、读取 / 错误 / 空态、`getKey``getImageSrc``getImageAlt``getTitle``getSubtitle``getAriaLabel``isSelected``cardClassName``onSelect`;默认组合 `PlatformStatusMessage``PlatformEmptyState``PlatformAssetPickerCard`,业务页只保留素材字段映射、文案、选中判断和选择回调,不再重复手写缩略图卡片、选中 ring、虚线读取 / 空态和网格 JSX。白底平台弹窗使用默认 `platform` surfaceRPG 大编辑器等暗色弹窗使用 `editorDark`,并通过 `imageShellClassName` 保留场景横图比例。视觉小说等同一弹窗里混有上传 / AI 生成错误时,可继续由外层错误条承接动作错误,只把历史素材读取 / 空态 / 网格交给 `PlatformAssetPickerGrid`
- `PlatformActionButton`:接收 `tone="primary" | "secondary" | "ghost" | "danger" | "success" | "warning" | "accent"``surface="platform" | "profile" | "editorDark"``size="xxs" | "xs" | "sm" | "md" | "lg"``shape="default" | "pill"``align="center" | "start"``fullWidth``children` 和原生 button props`surface="platform"` 复用 `platform-button` 样式族,`surface="profile"` 的主按钮复用个人中心 `platform-primary-button``surface="editorDark"` 统一承接 RPG 暗色弹窗 / 运行面板里的普通取消、确认、刷新和编组动作,`tone="accent"` 承接琥珀实心 CTA根节点固定带 `platform-action-button--accent` 稳定类名。认证表单的 48px 高按钮使用 `size="lg"`,暗色微型刷新 / 工具动作使用 `size="xxs" shape="pill"`,需要文件上传等 label 语义时使用 `asChild="label"` 复用同一套按钮外观,不把上传控件改成普通 button。推荐回复、列表内动作等需要左对齐时使用 `align="start"`,不要在业务 JSX 中重复写 `justify-start text-left`;创作中心错误重试、反馈页 header 返回和暗色次要动作等普通 ghost 动作同样走 `tone="ghost"``shape="pill"`,不在业务 JSX 中直接拼按钮 class。复制按钮仍使用 `CopyFeedbackButton`,可选项按钮卡仍使用 `PlatformDarkOptionCard`,像素风发送 / 强品牌动作继续保留专用布局。 - `PlatformActionButton`:接收 `tone="primary" | "secondary" | "ghost" | "danger" | "success" | "warning" | "accent" | "accentSoft"``surface="platform" | "profile" | "editorDark"``size="xxs" | "xs" | "sm" | "md" | "lg"``shape="default" | "pill"``align="center" | "start"``fullWidth``children` 和原生 button props`surface="platform"` 复用 `platform-button` 样式族,`surface="profile"` 的主按钮复用个人中心 `platform-primary-button``surface="editorDark"` 统一承接 RPG 暗色弹窗 / 运行面板里的普通取消、确认、刷新和编组动作,`tone="accent"` 承接琥珀实心 CTA`tone="accentSoft"` 承接带局部 accent 变量的柔和强调按钮,根节点固定带 `platform-action-button--accent` / `platform-action-button--accent-soft` 稳定类名。认证表单的 48px 高按钮使用 `size="lg"`,暗色微型刷新 / 工具动作使用 `size="xxs" shape="pill"`,需要文件上传等 label 语义时使用 `asChild="label"` 复用同一套按钮外观,不把上传控件改成普通 button。推荐回复、列表内动作等需要左对齐时使用 `align="start"`,不要在业务 JSX 中重复写 `justify-start text-left`;创作中心错误重试、反馈页 header 返回和暗色次要动作等普通 ghost 动作同样走 `tone="ghost"``shape="pill"`,不在业务 JSX 中直接拼按钮 class。复制按钮仍使用 `CopyFeedbackButton`,可选项按钮卡仍使用 `PlatformDarkOptionCard`,像素风发送 / 强品牌动作继续保留专用布局。
- `PlatformActionButton` 补充:反馈页内的“查看反馈与投诉记录”这类页面内次级文本动作使用 `tone="ghost" shape="pill" size="xs"`;业务组件只保留点击反馈,不再手写居中、字号、内边距和冷色文本按钮 class。 - `PlatformActionButton` 补充:反馈页内的“查看反馈与投诉记录”这类页面内次级文本动作使用 `tone="ghost" shape="pill" size="xs"`;业务组件只保留点击反馈,不再手写居中、字号、内边距和冷色文本按钮 class。
- `PlatformActionButton` 补充:作品详情底部“作品改造 / 作品编辑”和“启动”使用 `surface="platform" shape="pill" size="lg" fullWidth`,保留 `platform-work-detail__remix / start` 局部 class 控制 sticky 底部栏位置、比例和品牌背景。 - `PlatformActionButton` 补充:作品详情底部“作品改造 / 作品编辑”和“启动”使用 `surface="platform" shape="pill" size="lg" fullWidth`,保留 `platform-work-detail__remix / start` 局部 class 控制 sticky 底部栏位置、比例和品牌背景。
- `PlatformActionButton` 补充:作品详情点赞按钮使用 `tone="accentSoft"` 并通过局部 `--platform-action-accent` 变量复用柔和强调 chrome详情页只保留纵向排布、尺寸和可访问名称不再手写点赞按钮边框、底色、文字和阴影。
- `PlatformActionButton` 补充:创作中心作品卡积分激励的“领取积分 / 领取中”按钮使用 `tone="secondary" size="xxs"`;作品卡保留 `creation-work-card-incentive__button` 局部 class 控制三列布局、移动端跨列、紧凑高度和玻璃底,不再手写原生按钮 chrome。 - `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。 - `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 必须使用不同可访问名称,避免业务测试或读屏用户只能看到多个同名“上传参考图”入口。 - `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 必须使用不同可访问名称,避免业务测试或读屏用户只能看到多个同名“上传参考图”入口。
@@ -273,6 +274,7 @@
- `npm run test -- src/components/creation-agent/CreationAgentWorkspace.test.tsx src/components/common/PlatformIconButton.test.tsx` - `npm run test -- src/components/creation-agent/CreationAgentWorkspace.test.tsx src/components/common/PlatformIconButton.test.tsx`
- `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformIconButton.test.tsx` - `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformIconButton.test.tsx`
- `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx` - `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx`
- `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx src/components/common/platformActionButtonModel.test.ts`
- `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformPillBadge.test.tsx src/components/common/CopyCodeButton.test.tsx` - `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformPillBadge.test.tsx src/components/common/CopyCodeButton.test.tsx`
- `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformStatusMessage.test.tsx` - `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformStatusMessage.test.tsx`
- `npm run test -- src/components/common/PlatformIconBadge.test.tsx` - `npm run test -- src/components/common/PlatformIconBadge.test.tsx`

View File

@@ -90,3 +90,22 @@ test('supports accent action tone', () => {
expect(button.className).toContain('h-12'); expect(button.className).toContain('h-12');
expect(button.className).toContain('w-full'); expect(button.className).toContain('w-full');
}); });
test('supports accent soft action tone', () => {
render(
<PlatformActionButton
tone="accentSoft"
className="[--platform-action-accent:var(--platform-work-like-accent,#c7653d)]"
>
</PlatformActionButton>,
);
const button = screen.getByRole('button', { name: '点赞' });
expect(button.className).toContain('platform-action-button--accent-soft');
expect(button.className).toContain('[color:var(--platform-action-accent,#c7653d)]');
expect(button.className).toContain(
'[--platform-action-accent:var(--platform-work-like-accent,#c7653d)]',
);
});

View File

@@ -75,3 +75,16 @@ test('builds accent action button class names', () => {
expect(className).toContain('h-12'); expect(className).toContain('h-12');
expect(className).toContain('w-full'); expect(className).toContain('w-full');
}); });
test('builds accent soft action button class names', () => {
const className = getPlatformActionButtonClassName({
tone: 'accentSoft',
shape: 'pill',
size: 'xs',
});
expect(className).toContain('platform-action-button--accent-soft');
expect(className).toContain('[color:var(--platform-action-accent,#c7653d)]');
expect(className).toContain('rounded-full');
expect(className).toContain('text-xs');
});

View File

@@ -5,7 +5,8 @@ export type PlatformActionButtonTone =
| 'danger' | 'danger'
| 'success' | 'success'
| 'warning' | 'warning'
| 'accent'; | 'accent'
| 'accentSoft';
export type PlatformActionButtonSurface = 'platform' | 'profile' | 'editorDark'; export type PlatformActionButtonSurface = 'platform' | 'profile' | 'editorDark';
export type PlatformActionButtonSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg'; export type PlatformActionButtonSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg';
export type PlatformActionButtonShape = 'default' | 'pill'; export type PlatformActionButtonShape = 'default' | 'pill';
@@ -23,6 +24,8 @@ const PLATFORM_ACTION_BUTTON_PLATFORM_TONE_CLASS: Record<
warning: 'platform-button platform-button--secondary', warning: 'platform-button platform-button--secondary',
accent: accent:
'platform-action-button platform-action-button--accent border border-amber-200/70 bg-amber-200 text-slate-950 hover:bg-amber-100', 'platform-action-button platform-action-button--accent border border-amber-200/70 bg-amber-200 text-slate-950 hover:bg-amber-100',
accentSoft:
'platform-action-button platform-action-button--accent-soft [border-color:color-mix(in_srgb,var(--platform-action-accent,#c7653d)_24%,transparent)] [background:color-mix(in_srgb,var(--platform-action-accent,#c7653d)_10%,var(--platform-panel-fill)_90%)] [color:var(--platform-action-accent,#c7653d)] [box-shadow:0_0.55rem_1.2rem_color-mix(in_srgb,var(--platform-action-accent,#c7653d)_10%,transparent)]',
}; };
const PLATFORM_ACTION_BUTTON_PROFILE_TONE_CLASS: Record< const PLATFORM_ACTION_BUTTON_PROFILE_TONE_CLASS: Record<
@@ -37,6 +40,8 @@ const PLATFORM_ACTION_BUTTON_PROFILE_TONE_CLASS: Record<
warning: 'platform-button platform-button--secondary', warning: 'platform-button platform-button--secondary',
accent: accent:
'platform-action-button platform-action-button--accent border border-amber-200/70 bg-amber-200 text-slate-950 hover:bg-amber-100', 'platform-action-button platform-action-button--accent border border-amber-200/70 bg-amber-200 text-slate-950 hover:bg-amber-100',
accentSoft:
'platform-action-button platform-action-button--accent-soft [border-color:color-mix(in_srgb,var(--platform-action-accent,#c7653d)_24%,transparent)] [background:color-mix(in_srgb,var(--platform-action-accent,#c7653d)_10%,var(--platform-panel-fill)_90%)] [color:var(--platform-action-accent,#c7653d)] [box-shadow:0_0.55rem_1.2rem_color-mix(in_srgb,var(--platform-action-accent,#c7653d)_10%,transparent)]',
}; };
const PLATFORM_ACTION_BUTTON_EDITOR_DARK_TONE_CLASS: Record< const PLATFORM_ACTION_BUTTON_EDITOR_DARK_TONE_CLASS: Record<
@@ -57,6 +62,8 @@ const PLATFORM_ACTION_BUTTON_EDITOR_DARK_TONE_CLASS: Record<
'platform-action-button platform-action-button--editor-dark border border-amber-300/30 bg-amber-500/20 text-amber-50 hover:bg-amber-500/25', 'platform-action-button platform-action-button--editor-dark border border-amber-300/30 bg-amber-500/20 text-amber-50 hover:bg-amber-500/25',
accent: accent:
'platform-action-button platform-action-button--accent border border-amber-200/70 bg-amber-200 text-slate-950 hover:bg-amber-100', 'platform-action-button platform-action-button--accent border border-amber-200/70 bg-amber-200 text-slate-950 hover:bg-amber-100',
accentSoft:
'platform-action-button platform-action-button--accent-soft [border-color:color-mix(in_srgb,var(--platform-action-accent,#c7653d)_24%,transparent)] [background:color-mix(in_srgb,var(--platform-action-accent,#c7653d)_10%,rgba(0,0,0,0.72)_90%)] [color:var(--platform-action-accent,#f5c36a)] [box-shadow:0_0.55rem_1.2rem_color-mix(in_srgb,var(--platform-action-accent,#f5c36a)_10%,transparent)]',
}; };
const PLATFORM_ACTION_BUTTON_SIZE_CLASS: Record< const PLATFORM_ACTION_BUTTON_SIZE_CLASS: Record<

View File

@@ -153,7 +153,11 @@ test('PlatformWorkDetailView renders compact stats and date time', () => {
expect(screen.getByRole('button', { name: '分享' }).className).toContain( expect(screen.getByRole('button', { name: '分享' }).className).toContain(
'platform-icon-button', 'platform-icon-button',
); );
expect(screen.getByRole('button', { name: '点赞 4赞' })).toBeTruthy(); const likeButton = screen.getByRole('button', { name: '点赞 4赞' });
expect(likeButton).toBeTruthy();
expect(likeButton.className).toContain('platform-action-button--accent-soft');
expect(likeButton.className).toContain('platform-work-detail__like');
expect(likeButton.className).toContain('flex-col');
const remixAction = screen.getByRole('button', { name: '作品改造' }); const remixAction = screen.getByRole('button', { name: '作品改造' });
const startAction = screen.getByRole('button', { name: '启动' }); const startAction = screen.getByRole('button', { name: '启动' });
expect(remixAction.className).toContain('platform-button'); expect(remixAction.className).toContain('platform-button');

View File

@@ -378,17 +378,18 @@ export function PlatformWorkDetailView({
</span> </span>
</div> </div>
</div> </div>
<button <PlatformActionButton
type="button" type="button"
className="platform-work-detail__like" tone="accentSoft"
onClick={onLike} onClick={onLike}
disabled={isBusy} disabled={isBusy}
aria-label={`点赞 ${formatCompactCount(stats.likeCount)}`} aria-label={`点赞 ${formatCompactCount(stats.likeCount)}`}
title="点赞" title="点赞"
className="platform-work-detail__like min-w-[5.2rem] flex-col gap-1 px-3 py-2.5 text-[0.8125rem] [--platform-action-accent:var(--platform-work-like-accent,#c7653d)]"
> >
<Heart className="h-5 w-5 fill-current" /> <Heart className="h-5 w-5 fill-current" />
</button> </PlatformActionButton>
</div> </div>
<div className="platform-work-detail__stats"> <div className="platform-work-detail__stats">

View File

@@ -8524,37 +8524,6 @@ button {
white-space: nowrap; white-space: nowrap;
} }
.platform-work-detail__like {
display: inline-flex;
min-width: 5.2rem;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.25rem;
border: 1px solid
color-mix(
in srgb,
var(--platform-work-like-accent, #c7653d) 24%,
transparent
);
border-radius: 1rem;
background: color-mix(
in srgb,
var(--platform-work-like-accent, #c7653d) 10%,
var(--platform-panel-fill) 90%
);
color: var(--platform-work-like-accent, #c7653d);
padding: 0.6rem 0.75rem;
font-size: 0.8125rem;
font-weight: 900;
box-shadow: 0 0.55rem 1.2rem
color-mix(
in srgb,
var(--platform-work-like-accent, #c7653d) 10%,
transparent
);
}
.platform-work-detail__remix:disabled, .platform-work-detail__remix:disabled,
.platform-work-detail__start:disabled { .platform-work-detail__start:disabled {
cursor: not-allowed; cursor: not-allowed;