diff --git a/apps/builder/app/shared/nano-states/components.ts b/apps/builder/app/shared/nano-states/components.ts index fb558e936d..29988b060b 100644 --- a/apps/builder/app/shared/nano-states/components.ts +++ b/apps/builder/app/shared/nano-states/components.ts @@ -1,7 +1,7 @@ import type { ExoticComponent } from "react"; import { atom } from "nanostores"; import { - namespaceEmbedTemplateComponents, + namespaceMeta, type AnyComponent, type WsComponentMeta, type WsComponentPropsMeta, @@ -43,15 +43,12 @@ export const registerComponentLibrary = ({ const prevMetas = registeredComponentMetasStore.get(); const nextMetas = new Map(prevMetas); for (const [componentName, meta] of Object.entries(metas)) { - const newMeta = { ...meta }; - if (meta.template !== undefined && namespace !== undefined) { - meta.template = namespaceEmbedTemplateComponents( - meta.template, - namespace, - new Set(Object.keys(metas)) - ); - } - nextMetas.set(`${prefix}${componentName}`, newMeta); + nextMetas.set( + `${prefix}${componentName}`, + namespace === undefined + ? meta + : namespaceMeta(meta, namespace, new Set(Object.keys(metas))) + ); } registeredComponentMetasStore.set(nextMetas); diff --git a/packages/react-sdk/src/embed-template.test.ts b/packages/react-sdk/src/embed-template.test.ts index 21432a7113..5e9e980192 100644 --- a/packages/react-sdk/src/embed-template.test.ts +++ b/packages/react-sdk/src/embed-template.test.ts @@ -1,8 +1,5 @@ import { expect, test } from "@jest/globals"; -import { - generateDataFromEmbedTemplate, - namespaceEmbedTemplateComponents, -} from "./embed-template"; +import { generateDataFromEmbedTemplate, namespaceMeta } from "./embed-template"; import { showAttribute } from "./tree"; const expectString = expect.any(String); @@ -493,48 +490,62 @@ test("generate data for embedding from action props", () => { test("add namespace to selected components in embed template", () => { expect( - namespaceEmbedTemplateComponents( - [ - { - type: "instance", - component: "Tooltip", - children: [ - { type: "text", value: "Some text" }, - { - type: "instance", - component: "Box", - children: [ - { - type: "instance", - component: "Button", - children: [], - }, - ], - }, - ], - }, - ], + namespaceMeta( + { + type: "container", + label: "", + icon: "", + requiredAncestors: ["Button", "Box"], + invalidAncestors: ["Tooltip"], + template: [ + { + type: "instance", + component: "Tooltip", + children: [ + { type: "text", value: "Some text" }, + { + type: "instance", + component: "Box", + children: [ + { + type: "instance", + component: "Button", + children: [], + }, + ], + }, + ], + }, + ], + }, "my-namespace", new Set(["Tooltip", "Button"]) ) - ).toEqual([ - { - type: "instance", - component: "my-namespace:Tooltip", - children: [ - { type: "text", value: "Some text" }, - { - type: "instance", - component: "Box", - children: [ - { - type: "instance", - component: "my-namespace:Button", - children: [], - }, - ], - }, - ], - }, - ]); + ).toEqual({ + type: "container", + label: "", + icon: "", + requiredAncestors: ["my-namespace:Button", "Box"], + invalidAncestors: ["my-namespace:Tooltip"], + template: [ + { + type: "instance", + component: "my-namespace:Tooltip", + children: [ + { type: "text", value: "Some text" }, + { + type: "instance", + component: "Box", + children: [ + { + type: "instance", + component: "my-namespace:Button", + children: [], + }, + ], + }, + ], + }, + ], + }); }); diff --git a/packages/react-sdk/src/embed-template.ts b/packages/react-sdk/src/embed-template.ts index 4777b14e75..96bcdfc009 100644 --- a/packages/react-sdk/src/embed-template.ts +++ b/packages/react-sdk/src/embed-template.ts @@ -13,6 +13,7 @@ import { import { StyleValue, type StyleProperty } from "@webstudio-is/css-data"; import type { Simplify } from "type-fest"; import { encodeDataSourceVariable, validateExpression } from "./expression"; +import type { WsComponentMeta } from "./components/component-meta"; const EmbedTemplateText = z.object({ type: z.literal("text"), @@ -337,7 +338,7 @@ export type EmbedTemplateData = ReturnType< typeof generateDataFromEmbedTemplate >; -export const namespaceEmbedTemplateComponents = ( +const namespaceEmbedTemplateComponents = ( template: WsEmbedTemplate, namespace: string, components: Set @@ -362,3 +363,29 @@ export const namespaceEmbedTemplateComponents = ( throw Error("Impossible case"); }); }; + +export const namespaceMeta = ( + meta: WsComponentMeta, + namespace: string, + components: Set +) => { + const newMeta = { ...meta }; + if (newMeta.requiredAncestors) { + newMeta.requiredAncestors = newMeta.requiredAncestors.map((component) => + components.has(component) ? `${namespace}:${component}` : component + ); + } + if (newMeta.invalidAncestors) { + newMeta.invalidAncestors = newMeta.invalidAncestors.map((component) => + components.has(component) ? `${namespace}:${component}` : component + ); + } + if (newMeta.template) { + newMeta.template = namespaceEmbedTemplateComponents( + newMeta.template, + namespace, + components + ); + } + return newMeta; +};