Skip to content

Commit 4234f88

Browse files
authored
refactor: move canvas renderer into builder (#4382)
There is no need for canvas renderer in react-sdk. Moved into builder and slightly cleaned.
1 parent 9d04bf5 commit 4234f88

File tree

6 files changed

+120
-162
lines changed

6 files changed

+120
-162
lines changed

apps/builder/app/canvas/canvas.tsx

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import type { Instances } from "@webstudio-is/sdk";
55
import {
66
type Params,
77
type Components,
8-
createElementsTree,
98
coreMetas,
109
corePropsMetas,
1110
} from "@webstudio-is/react-sdk";
11+
import { ReactSdkContext } from "@webstudio-is/react-sdk/runtime";
1212
import * as baseComponents from "@webstudio-is/sdk-components-react";
1313
import * as baseComponentMetas from "@webstudio-is/sdk-components-react/metas";
1414
import * as baseComponentPropsMetas from "@webstudio-is/sdk-components-react/props";
@@ -66,6 +66,7 @@ import { useDebounceEffect } from "~/shared/hook-utils/use-debounce-effect";
6666
import { subscribeSelected } from "./instance-selected";
6767
import { subscribeScrollNewInstanceIntoView } from "./shared/scroll-new-instance-into-view";
6868
import { $selectedPage } from "~/shared/awareness";
69+
import { createInstanceElement } from "./elements";
6970

7071
registerContainers();
7172

@@ -108,18 +109,27 @@ const useElementsTree = (
108109
}
109110

110111
return useMemo(() => {
111-
return createElementsTree({
112-
renderer: isPreviewMode ? "preview" : "canvas",
113-
imageBaseUrl: params.imageBaseUrl,
114-
assetBaseUrl: params.assetBaseUrl,
115-
imageLoader,
116-
instances,
117-
rootInstanceId,
118-
Component: isPreviewMode
119-
? WebstudioComponentPreview
120-
: WebstudioComponentCanvas,
121-
components,
122-
});
112+
return (
113+
<ReactSdkContext.Provider
114+
value={{
115+
renderer: isPreviewMode ? "preview" : "canvas",
116+
imageBaseUrl: params.imageBaseUrl,
117+
assetBaseUrl: params.assetBaseUrl,
118+
imageLoader,
119+
resources: {},
120+
}}
121+
>
122+
{createInstanceElement({
123+
instances,
124+
instanceId: rootInstanceId,
125+
instanceSelector: [rootInstanceId],
126+
Component: isPreviewMode
127+
? WebstudioComponentPreview
128+
: WebstudioComponentCanvas,
129+
components,
130+
})}
131+
</ReactSdkContext.Provider>
132+
);
123133
}, [
124134
params,
125135
instances,
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import {
2+
Fragment,
3+
type ForwardRefExoticComponent,
4+
type RefAttributes,
5+
} from "react";
6+
import type { Instance, Instances } from "@webstudio-is/sdk";
7+
import type { Components } from "@webstudio-is/react-sdk";
8+
import type { InstanceSelector } from "~/shared/tree-utils";
9+
10+
export type WebstudioComponentProps = {
11+
instance: Instance;
12+
instanceSelector: Instance["id"][];
13+
components: Components;
14+
};
15+
16+
export const createInstanceElement = ({
17+
instances,
18+
instanceId,
19+
instanceSelector,
20+
Component,
21+
components,
22+
}: {
23+
instances: Instances;
24+
instanceId: Instance["id"];
25+
instanceSelector: InstanceSelector;
26+
Component: ForwardRefExoticComponent<
27+
WebstudioComponentProps & RefAttributes<HTMLElement>
28+
>;
29+
components: Components;
30+
}) => {
31+
const instance = instances.get(instanceId);
32+
if (instance === undefined) {
33+
return null;
34+
}
35+
return (
36+
<Component
37+
key={instance.id}
38+
instance={instance}
39+
instanceSelector={instanceSelector}
40+
components={components}
41+
/>
42+
);
43+
};
44+
45+
const renderText = (text: string): Array<JSX.Element> => {
46+
const lines = text.split("\n");
47+
return lines.map((line, index) => (
48+
<Fragment key={index}>
49+
{line}
50+
{index < lines.length - 1 && <br />}
51+
</Fragment>
52+
));
53+
};
54+
55+
export const createInstanceChildrenElements = ({
56+
instances,
57+
instanceSelector,
58+
children,
59+
Component,
60+
components,
61+
}: {
62+
instances: Instances;
63+
instanceSelector: InstanceSelector;
64+
children: Instance["children"];
65+
Component: ForwardRefExoticComponent<
66+
WebstudioComponentProps & RefAttributes<HTMLElement>
67+
>;
68+
components: Components;
69+
}) => {
70+
const elements = children.map((child) => {
71+
if (child.type === "text") {
72+
return renderText(child.value);
73+
}
74+
if (child.type === "expression") {
75+
return;
76+
}
77+
if (child.type === "id") {
78+
return createInstanceElement({
79+
instances,
80+
instanceId: child.value,
81+
instanceSelector: [child.value, ...instanceSelector],
82+
Component,
83+
components,
84+
});
85+
}
86+
child satisfies never;
87+
});
88+
// let empty children be coalesced with fallback
89+
if (elements.length === 0) {
90+
return;
91+
}
92+
return elements;
93+
};

apps/builder/app/canvas/features/webstudio-component/webstudio-component.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@ import { mergeRefs } from "@react-aria/utils";
1616
import type { Instance, Instances, Prop } from "@webstudio-is/sdk";
1717
import { findTreeInstanceIds } from "@webstudio-is/sdk";
1818
import {
19-
type WebstudioComponentProps,
2019
idAttribute,
2120
componentAttribute,
2221
showAttribute,
2322
selectorIdAttribute,
2423
indexAttribute,
2524
getIndexesWithinAncestors,
26-
createInstanceChildrenElements,
2725
collectionComponent,
2826
type AnyComponent,
2927
textContentAttribute,
@@ -48,6 +46,10 @@ import { getIsVisuallyHidden } from "~/shared/visually-hidden";
4846
import { serverSyncStore } from "~/shared/sync";
4947
import { TextEditor } from "../text-editor";
5048
import { $selectedPage } from "~/shared/awareness";
49+
import {
50+
createInstanceChildrenElements,
51+
type WebstudioComponentProps,
52+
} from "~/canvas/elements";
5153

5254
const ContentEditable = ({
5355
renderComponentWithRef,

packages/react-sdk/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
export * from "./remix";
22
export * from "./css/index";
3-
export * from "./tree/index";
43
export * from "./core-components";
54
export * from "./components/components-utils";
65
export { PropMeta } from "./prop-meta";

packages/react-sdk/src/tree/create-elements-tree.tsx

Lines changed: 0 additions & 145 deletions
This file was deleted.

packages/react-sdk/src/tree/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)