统一组件图标布局并完善选择吸附交互

This commit is contained in:
ljz committed 2026-08-06 23:35:50 +08:00
1 parent 40c72422ff
commit 7671418582
16 files changed
+4359 -598

No files matched your search

+103
View File
@@ -271,3 +271,106 @@ test("仅图标模式仍可拖入氦气介质并在画布显示专用图标", as
heliumCanvasSymbol.locator('[data-symbol-label="He"]'),
).toHaveText("He");
});
test("从组件库拖入时使用工作区图标作为待拖入预览", async ({ page }) => {
await page.goto("/");
await page.evaluate(() => {
const dataTransferPrototype = DataTransfer.prototype;
const originalSetDragImage = dataTransferPrototype.setDragImage;
dataTransferPrototype.setDragImage = function (
this: DataTransfer,
image: Element,
x: number,
y: number,
) {
const bounds = image.getBoundingClientRect();
const style = window.getComputedStyle(image);
const symbol = image.querySelector<HTMLElement>(".component-symbol");
const svg = image.querySelector<SVGSVGElement>(".component-symbol-svg");
(
window as Window & {
__componentDragPreview?: {
backgroundColor: string;
borderTopWidth: string;
hasLegacyCardLabel: boolean;
height: number;
hotspotX: number;
hotspotY: number;
rootClassName: string;
symbolClassName: string;
viewBox: string | null;
width: number;
};
}
).__componentDragPreview = {
backgroundColor: style.backgroundColor,
borderTopWidth: style.borderTopWidth,
hasLegacyCardLabel: Boolean(
image.querySelector(".component-drag-preview-label"),
),
height: bounds.height,
hotspotX: x,
hotspotY: y,
rootClassName: image.className,
symbolClassName: symbol?.className ?? "",
viewBox: svg?.getAttribute("viewBox") ?? null,
width: bounds.width,
};
dataTransferPrototype.setDragImage = originalSetDragImage;
return originalSetDragImage.call(this, image, x, y);
};
});
const heliumItem = page
.locator("aside.palette")
.getByRole("button", { name: "氦气介质定义", exact: true });
const canvas = page.locator(".flow-canvas .react-flow__pane");
await heliumItem.dragTo(canvas, {
targetPosition: { x: 420, y: 220 },
});
const preview = await page.evaluate(
() =>
(
window as Window & {
__componentDragPreview?: {
backgroundColor: string;
borderTopWidth: string;
hasLegacyCardLabel: boolean;
height: number;
hotspotX: number;
hotspotY: number;
rootClassName: string;
symbolClassName: string;
viewBox: string | null;
width: number;
};
}
).__componentDragPreview,
);
expect(preview).toBeDefined();
expect(preview!.rootClassName).toContain("component-drag-preview");
expect(preview!.symbolClassName).toContain("component-symbol-canvas");
expect(preview!.symbolClassName).not.toContain("component-symbol-palette");
expect(preview!.hasLegacyCardLabel).toBe(false);
expect(preview!.borderTopWidth).toBe("0px");
expect(preview!.backgroundColor).toBe("rgba(0, 0, 0, 0)");
expect(Math.abs(preview!.hotspotX - preview!.width / 2)).toBeLessThanOrEqual(0.5);
expect(Math.abs(preview!.hotspotY - preview!.height / 2)).toBeLessThanOrEqual(0.5);
const heliumNode = page.locator(
'.flow-canvas .react-flow__node[data-id="amesim_helium_medium_1"]',
);
const nodeBounds = await heliumNode.boundingBox();
expect(nodeBounds).not.toBeNull();
expect(preview!.width).toBeCloseTo(nodeBounds!.width, 1);
expect(preview!.height).toBeCloseTo(nodeBounds!.height, 1);
await expect
.poll(() =>
heliumNode
.locator(".component-symbol-canvas .component-symbol-svg")
.getAttribute("viewBox"),
)
.toBe(preview!.viewBox);
await expect(page.locator("body > .component-drag-preview")).toHaveCount(0);
});