import { render } from "@testing-library/react";
import type * as React from "react";
import { vi } from "vitest";
import { defineToolcraft } from "../../schema/define-toolcraft";
import type { ToolcraftProductSceneBoundsProvider } from "../../scene";
import type { ToolcraftInitialState } from "../../state/types";
import { ToolcraftRoot } from "../app-shell/toolcraft-root";
import { useToolcraft } from "../app-shell/use-toolcraft";
import { CanvasShell } from "./canvas-shell";
import { ToolcraftProductSceneBoundsBoundary } from "./product-scene-surface";
export function createSchema() {
return defineToolcraft({
canvas: {
enabled: true,
size: { width: 300, height: 200, unit: "px" },
upload: true,
},
panels: {},
persistence: { storage: "none" },
});
}
export function createIntrinsicMediaSchema() {
return defineToolcraft({
canvas: {
enabled: true,
sizing: { mode: "intrinsic-media" },
upload: true,
},
panels: {},
persistence: { storage: "none" },
});
}
export function createBackgroundSchema() {
return defineToolcraft({
canvas: {
enabled: true,
size: { width: 300, height: 200, unit: "px" },
sizing: { mode: "editable-output" },
upload: true,
},
panels: {
controls: {
sections: [
{
controls: {
includeBackground: {
defaultValue: true,
target: "export.includeBackground",
type: "switch",
},
background: {
defaultValue: "#D4CECA",
target: "appearance.background",
type: "color",
},
},
title: "Background",
},
],
title: "Controls",
},
},
persistence: { storage: "none" },
});
}
export function createUploadDefaultSchema() {
return defineToolcraft({
canvas: {
enabled: true,
upload: true,
},
panels: {},
persistence: { storage: "none" },
});
}
export function CanvasStateProbe() {
const { state } = useToolcraft();
const firstImage = state.mediaAssets.find(
(asset) => asset.assetKind === "image",
);
return (
<>
{state.canvas.offset.x},{state.canvas.offset.y}
{state.canvas.zoom}
{state.mediaAssets.length}
{firstImage?.size?.width ?? 0},{firstImage?.size?.height ?? 0}
{state.mediaAssets.map((asset) => asset.sourceTarget ?? "none").join(",")}
{state.mediaAssets.map((asset) => asset.assetKind).join(",")}
>
);
}
export function mockCanvasRect(canvas: HTMLElement): void {
vi.spyOn(canvas, "getBoundingClientRect").mockReturnValue({
bottom: 600,
height: 600,
left: 0,
right: 800,
toJSON: () => ({}),
top: 0,
width: 800,
x: 0,
y: 0,
});
}
type RenderCanvasShellOptions = {
afterCanvas?: React.ReactNode;
children?: React.ReactNode;
frameProps?: React.HTMLAttributes;
infiniteCanvasContent?: React.ReactNode;
initialState?: ToolcraftInitialState;
productSceneBoundsProvider?: ToolcraftProductSceneBoundsProvider;
schema?: ReturnType;
};
export function renderCanvasShell({
afterCanvas,
children,
frameProps,
infiniteCanvasContent,
initialState,
productSceneBoundsProvider,
schema = createSchema(),
}: RenderCanvasShellOptions = {}) {
const { style, ...restFrameProps } = frameProps ?? {};
return render(
{children}
{afterCanvas}
,
);
}