调整 UI 编辑器调试入口

将组件绑定调试按钮与状态提示移入左侧输入面板

移除右下角重复的调试浮层
This commit is contained in:
2026-08-17 14:41:18 +08:00
parent 5f1c69f532
commit fb7cfa42c7
3 changed files with 26 additions and 76 deletions
@@ -1,4 +1,4 @@
import { Image as ImageIcon, Plus } from 'lucide-react';
import { Image as ImageIcon, Plus, ScanSearch } from 'lucide-react';
import type { UiEditorPageController } from '../useUiEditorPage';
import { ImportOverview } from './ImportOverview';
@@ -27,6 +27,22 @@ export function InputSidebar({
return (
<aside className="min-h-0 overflow-y-auto border-r border-(--platform-subpanel-border) bg-(--platform-subpanel-fill) p-3">
<div className="mb-3 grid gap-2">
<button
type="button"
className="inline-flex items-center gap-1.5 rounded-lg bg-orange-500 px-3 py-2 text-left text-xs font-semibold text-white"
onClick={controller.checkPrerequisites}
>
<ScanSearch size={14} />
</button>
<button
type="button"
className="rounded-lg bg-emerald-600 px-3 py-2 text-left text-xs font-semibold text-white disabled:cursor-wait disabled:opacity-60"
onClick={() => void controller.bindComponents()}
disabled={controller.isBinding || controller.editor.isLocked}
title="调试:绑定组件"
>
{controller.isBinding ? '组件绑定中…' : '绑定组件'}
</button>
<button
type="button"
className="rounded-lg bg-violet-600 px-3 py-2 text-left text-xs font-semibold text-white disabled:cursor-wait disabled:opacity-60"
@@ -73,6 +89,11 @@ export function InputSidebar({
{controller.suggestionStatus}
</p>
) : null}
{controller.bindingStatus ? (
<p className="m-0 rounded-lg border border-(--platform-subpanel-border) bg-(--platform-subpanel-fill) px-3 py-2 text-xs">
{controller.bindingStatus}
</p>
) : null}
</div>
<section className="rounded-xl border border-(--platform-subpanel-border) bg-white/35 p-3">
<div className="flex items-center justify-between">
@@ -12,7 +12,7 @@ import {
CanvasWorld,
ZoomControls,
} from '@genarrative/image-canvas-react';
import { Image as ImageIcon, Minus, Plus, ScanSearch } from 'lucide-react';
import { Image as ImageIcon, Minus, Plus } from 'lucide-react';
import {
type PointerEvent as ReactPointerEvent,
useCallback,
@@ -59,11 +59,7 @@ export function PreviewWorkspace({
return null;
}
return { width, height };
}, [
activeImage?.pixel_size[0],
activeImage?.pixel_size[1],
activeImage?.pixels_per_unit,
]);
}, [activeImage]);
const nodeInteractions = useNodeTransformInteraction({
activeImageId,
@@ -125,6 +121,8 @@ export function PreviewWorkspace({
useEffect(() => {
fitToCanvas();
controller.clearNodeSelection();
// This effect intentionally follows the active image, not every controller render.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [activeImageId, fitToCanvas]);
useEffect(() => {
@@ -406,13 +404,6 @@ export function PreviewWorkspace({
>
</button>
<button
type="button"
className="inline-flex items-center gap-1.5 rounded-lg bg-orange-500 px-3 py-2 text-xs font-semibold text-white"
onClick={controller.checkPrerequisites}
>
<ScanSearch size={14} />
</button>
</footer>
</section>
);
@@ -156,68 +156,6 @@ export default function UiEditorPage({
</button>
</div>
</ThemedModal>
<div className="fixed bottom-4 right-4 z-30 flex max-w-xs flex-col items-end gap-2">
{controller.suggestionStatus ? (
<p className="rounded-lg border border-(--platform-subpanel-border) bg-(--platform-subpanel-fill) px-3 py-2 text-xs shadow-lg">
{controller.suggestionStatus}
</p>
) : null}
{controller.recognitionStatus ? (
<p className="rounded-lg border border-(--platform-subpanel-border) bg-(--platform-subpanel-fill) px-3 py-2 text-xs shadow-lg">
{controller.recognitionStatus}
</p>
) : null}
{controller.mergeStatus ? (
<p className="rounded-lg border border-(--platform-subpanel-border) bg-(--platform-subpanel-fill) px-3 py-2 text-xs shadow-lg">
{controller.mergeStatus}
</p>
) : null}
{controller.bindingStatus ? (
<p className="rounded-lg border border-(--platform-subpanel-border) bg-(--platform-subpanel-fill) px-3 py-2 text-xs shadow-lg">
{controller.bindingStatus}
</p>
) : null}
<button
type="button"
className="rounded-full bg-emerald-600 px-4 py-3 text-sm font-semibold text-white shadow-lg transition hover:bg-emerald-700 disabled:cursor-wait disabled:opacity-60"
onClick={() => void controller.bindComponents()}
disabled={controller.isBinding || controller.editor.isLocked}
title="调试:绑定组件"
>
{controller.isBinding ? '组件绑定中…' : '绑定组件'}
</button>
<button
type="button"
className="rounded-full bg-violet-600 px-4 py-3 text-sm font-semibold text-white shadow-lg transition hover:bg-violet-700 disabled:cursor-wait disabled:opacity-60"
onClick={() => void controller.mergeUi()}
disabled={
controller.isMerging ||
controller.editor.isLocked ||
controller.editor.state.ui_trees.length === 0
}
title="调试:合并 UI 树"
>
{controller.isMerging ? '界面树合并中…' : '合并 UI 树'}
</button>
<button
type="button"
className="rounded-full bg-blue-600 px-4 py-3 text-sm font-semibold text-white shadow-lg transition hover:bg-blue-700 disabled:cursor-wait disabled:opacity-60"
onClick={() => void controller.recognizeUi()}
disabled={controller.isRecognizing || controller.editor.isLocked}
title="调试:识别 UI 结构"
>
{controller.isRecognizing ? '结构识别中…' : '识别 UI 结构'}
</button>
<button
type="button"
className="rounded-full bg-orange-500 px-4 py-3 text-sm font-semibold text-white shadow-lg transition hover:bg-orange-600 disabled:cursor-wait disabled:opacity-60"
onClick={() => void controller.suggestUiDesignSemantics()}
disabled={controller.isSuggesting || controller.editor.isLocked}
title="调试:识别参考图语义"
>
{controller.isSuggesting ? '识别中…' : '识别参考图语义'}
</button>
</div>
</main>
);
}