diff --git a/TRACKING.md b/TRACKING.md
index f11e3191..34f12248 100644
--- a/TRACKING.md
+++ b/TRACKING.md
@@ -100,3 +100,4 @@
- 2026-06-14 组件复用修正:编辑器生成输入框的“参考图”按钮改为复用 `PlatformIconButton variant="surfaceFloating"`,用 children 承载短标签,仅保留生成器局部尺寸和浅灰覆盖;验证命令:`npm run test -- src/components/image-editor/ImageCanvasEditorView.test.tsx src/components/common/PlatformIconButton.test.tsx`、`npm run typecheck`。
- 2026-06-14 组件复用修正:编辑器生成图右上角元数据角标改为复用 `PlatformIconButton asChild="spanButton"`,保留嵌套在图层按钮内的合法 DOM 结构,同时把 Enter / Space 键盘触发和 `darkMini` chrome 收口到共享组件;验证命令:`npm run test -- src/components/common/PlatformIconButton.test.tsx src/components/image-editor/ImageCanvasEditorView.test.tsx`、`npm run typecheck`。
- 2026-06-14 组件复用修正:编辑器画布内生成输入框和“修改图片”弹窗提示词改为复用 `PlatformTextField variant="textarea"`,删除编辑器里按标签选择器手写 textarea 基础输入 chrome 的做法,仅保留生成器局部尺寸和 Lovart 式覆盖;验证命令:`npm run test -- src/components/image-editor/ImageCanvasEditorView.test.tsx src/components/common/PlatformTextField.test.tsx`、`npm run typecheck`。
+- 2026-06-14 组件复用修正:新增 `PlatformInlineOptionButton`,编辑器生成输入框里的比例和模型选择 pill 改为复用平台内联选项按钮原语,删除两个局部按钮重复维护基础 inline chrome 的做法;验证命令:`npm run test -- src/components/common/PlatformInlineOptionButton.test.tsx src/components/image-editor/ImageCanvasEditorView.test.tsx`、`npm run typecheck`。
diff --git a/src/components/common/PlatformInlineOptionButton.test.tsx b/src/components/common/PlatformInlineOptionButton.test.tsx
new file mode 100644
index 00000000..ec136ac2
--- /dev/null
+++ b/src/components/common/PlatformInlineOptionButton.test.tsx
@@ -0,0 +1,46 @@
+/* @vitest-environment jsdom */
+
+import { fireEvent, render, screen } from '@testing-library/react';
+import { ChevronDown } from 'lucide-react';
+import { expect, test, vi } from 'vitest';
+
+import { PlatformInlineOptionButton } from './PlatformInlineOptionButton';
+
+test('renders shared inline option button chrome', () => {
+ const onClick = vi.fn();
+ render(
+ }
+ onClick={onClick}
+ >
+ 1:1
+ ,
+ );
+
+ const button = screen.getByRole('button', { name: '生成比例 1:1' });
+
+ expect(button.className).toContain('platform-inline-option-button');
+ expect(button.className).toContain('bg-transparent');
+ expect(button.className).toContain('local-option');
+ expect(button.textContent).toContain('1:1');
+
+ fireEvent.click(button);
+
+ expect(onClick).toHaveBeenCalledTimes(1);
+});
+
+test('keeps disabled state and default button type', () => {
+ render(
+
+ GPT Image
+ ,
+ );
+
+ const button = screen.getByRole('button', { name: '模型' });
+
+ expect(button.getAttribute('type')).toBe('button');
+ expect(button).toHaveProperty('disabled', true);
+ expect(button.className).toContain('disabled:cursor-not-allowed');
+});
diff --git a/src/components/common/PlatformInlineOptionButton.tsx b/src/components/common/PlatformInlineOptionButton.tsx
new file mode 100644
index 00000000..96f35ee7
--- /dev/null
+++ b/src/components/common/PlatformInlineOptionButton.tsx
@@ -0,0 +1,39 @@
+import type { ButtonHTMLAttributes, ReactNode } from 'react';
+
+type PlatformInlineOptionButtonProps = Omit<
+ ButtonHTMLAttributes,
+ 'children'
+> & {
+ children: ReactNode;
+ trailingIcon?: ReactNode;
+};
+
+/**
+ * 平台内联选项按钮。
+ * 统一承接工具面板里“当前选项 + 下拉箭头”这类轻量 pill 动作。
+ */
+export function PlatformInlineOptionButton({
+ children,
+ trailingIcon,
+ className,
+ type = 'button',
+ ...buttonProps
+}: PlatformInlineOptionButtonProps) {
+ const actionClassName = [
+ 'platform-inline-option-button inline-flex items-center justify-center border-0 bg-transparent text-sm font-black text-slate-700 transition-colors hover:text-slate-950 disabled:cursor-not-allowed disabled:opacity-55',
+ className,
+ ]
+ .filter(Boolean)
+ .join(' ');
+
+ return (
+
+ );
+}
diff --git a/src/components/image-editor/ImageCanvasEditorView.test.tsx b/src/components/image-editor/ImageCanvasEditorView.test.tsx
index 8fb6e515..6f866f78 100644
--- a/src/components/image-editor/ImageCanvasEditorView.test.tsx
+++ b/src/components/image-editor/ImageCanvasEditorView.test.tsx
@@ -742,8 +742,16 @@ describe('ImageCanvasEditorView', () => {
expect(generatePrompt.className).toContain(
'image-canvas-editor__generation-prompt',
);
- expect(within(generateDialog).getByRole('button', { name: '生成比例 1:1 2k 1张' })).toBeTruthy();
- expect(within(generateDialog).getByRole('button', { name: '生成模型 GPT Image' })).toBeTruthy();
+ expect(
+ within(generateDialog).getByRole('button', {
+ name: '生成比例 1:1 2k 1张',
+ }).className,
+ ).toContain('platform-inline-option-button');
+ expect(
+ within(generateDialog).getByRole('button', {
+ name: '生成模型 GPT Image',
+ }).className,
+ ).toContain('platform-inline-option-button');
expect(within(generateDialog).getByRole('button', { name: '生成' }).className).toContain(
'platform-button',
);
diff --git a/src/components/image-editor/ImageCanvasEditorView.tsx b/src/components/image-editor/ImageCanvasEditorView.tsx
index 829af070..1fa0b47e 100644
--- a/src/components/image-editor/ImageCanvasEditorView.tsx
+++ b/src/components/image-editor/ImageCanvasEditorView.tsx
@@ -70,6 +70,7 @@ import {
PlatformFloatingMenuItem,
} from '../common/PlatformFloatingMenu';
import { PlatformIconButton } from '../common/PlatformIconButton';
+import { PlatformInlineOptionButton } from '../common/PlatformInlineOptionButton';
import { PlatformStatusMessage } from '../common/PlatformStatusMessage';
import { PlatformTextField } from '../common/PlatformTextField';
import { UnifiedModal } from '../common/UnifiedModal';
@@ -2816,26 +2817,24 @@ export function ImageCanvasEditorView() {
}
/>
-
-
+