@webstudio-is/react-sdk 0.82.0 → 0.83.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -21
- package/lib/cjs/components/component-meta.js +5 -0
- package/lib/cjs/components/components-utils.js +1 -0
- package/lib/cjs/css/index.js +0 -1
- package/lib/cjs/embed-template.js +30 -1
- package/lib/cjs/expression.js +47 -4
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/props.js +6 -1
- package/lib/cjs/tree/root.js +1 -0
- package/lib/cjs/tree/webstudio-component.js +24 -10
- package/lib/components/component-meta.js +5 -0
- package/lib/components/components-utils.js +1 -0
- package/lib/css/index.js +0 -1
- package/lib/embed-template.js +38 -1
- package/lib/expression.js +47 -4
- package/lib/index.js +2 -0
- package/lib/props.js +6 -1
- package/lib/tree/create-elements-tree.js +3 -1
- package/lib/tree/root.js +8 -2
- package/lib/tree/webstudio-component.js +25 -11
- package/lib/types/app/root.d.ts +1 -2
- package/lib/types/components/component-meta.d.ts +11 -8
- package/lib/types/context.d.ts +1 -1
- package/lib/types/css/index.d.ts +0 -1
- package/lib/types/css/normalize.d.ts +47 -47
- package/lib/types/embed-template.d.ts +14 -1
- package/lib/types/expression.d.ts +3 -2
- package/lib/types/index.d.ts +1 -1
- package/lib/types/props.d.ts +1 -0
- package/lib/types/tree/create-elements-tree.d.ts +5 -5
- package/lib/types/tree/root.d.ts +4 -4
- package/lib/types/tree/webstudio-component.d.ts +15 -7
- package/package.json +14 -15
- package/src/components/component-meta.ts +5 -0
- package/src/context.tsx +1 -0
- package/src/css/index.ts +0 -1
- package/src/embed-template.test.ts +77 -1
- package/src/embed-template.ts +34 -1
- package/src/expression.test.ts +74 -6
- package/src/expression.ts +55 -2
- package/src/index.ts +1 -0
- package/src/props.ts +6 -1
- package/src/tree/create-elements-tree.tsx +17 -5
- package/src/tree/root.ts +14 -3
- package/src/tree/webstudio-component.tsx +41 -14
- package/lib/cjs/css/get-browser-style.js +0 -83
- package/lib/css/get-browser-style.js +0 -65
- package/lib/types/css/get-browser-style.d.ts +0 -2
- package/src/css/get-browser-style.ts +0 -81
|
@@ -37,6 +37,7 @@ const componentCategories = [
|
|
|
37
37
|
"text",
|
|
38
38
|
"media",
|
|
39
39
|
"forms",
|
|
40
|
+
"radix",
|
|
40
41
|
"hidden"
|
|
41
42
|
];
|
|
42
43
|
const stateCategories = ["states", "component-states"];
|
|
@@ -62,6 +63,10 @@ const WsComponentMeta = import_zod.z.object({
|
|
|
62
63
|
requiredAncestors: import_zod.z.optional(import_zod.z.array(import_zod.z.string())),
|
|
63
64
|
invalidAncestors: import_zod.z.optional(import_zod.z.array(import_zod.z.string())),
|
|
64
65
|
stylable: import_zod.z.optional(import_zod.z.boolean()),
|
|
66
|
+
// specifies whether the instance can be deleted,
|
|
67
|
+
// copied or dragged out of its parent instance
|
|
68
|
+
// true by default
|
|
69
|
+
detachable: import_zod.z.optional(import_zod.z.boolean()),
|
|
65
70
|
label: import_zod.z.string(),
|
|
66
71
|
description: import_zod.z.string().optional(),
|
|
67
72
|
icon: import_zod.z.string(),
|
|
@@ -14,3 +14,4 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
14
14
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
15
|
var components_utils_exports = {};
|
|
16
16
|
module.exports = __toCommonJS(components_utils_exports);
|
|
17
|
+
var import_tree = require("../tree");
|
package/lib/cjs/css/index.js
CHANGED
|
@@ -15,7 +15,6 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
|
|
|
15
15
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
16
16
|
var css_exports = {};
|
|
17
17
|
module.exports = __toCommonJS(css_exports);
|
|
18
|
-
__reExport(css_exports, require("./get-browser-style"), module.exports);
|
|
19
18
|
__reExport(css_exports, require("./global-rules"), module.exports);
|
|
20
19
|
__reExport(css_exports, require("./style-rules"), module.exports);
|
|
21
20
|
__reExport(css_exports, require("./css"), module.exports);
|
|
@@ -21,11 +21,13 @@ __export(embed_template_exports, {
|
|
|
21
21
|
EmbedTemplateInstance: () => EmbedTemplateInstance,
|
|
22
22
|
EmbedTemplateStyleDecl: () => EmbedTemplateStyleDecl,
|
|
23
23
|
WsEmbedTemplate: () => WsEmbedTemplate,
|
|
24
|
-
generateDataFromEmbedTemplate: () => generateDataFromEmbedTemplate
|
|
24
|
+
generateDataFromEmbedTemplate: () => generateDataFromEmbedTemplate,
|
|
25
|
+
namespaceEmbedTemplateComponents: () => namespaceEmbedTemplateComponents
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(embed_template_exports);
|
|
27
28
|
var import_zod = require("zod");
|
|
28
29
|
var import_nanoid = require("nanoid");
|
|
30
|
+
var import_project_build = require("@webstudio-is/project-build");
|
|
29
31
|
var import_css_data = require("@webstudio-is/css-data");
|
|
30
32
|
var import_expression = require("./expression");
|
|
31
33
|
const EmbedTemplateText = import_zod.z.object({
|
|
@@ -75,6 +77,7 @@ const EmbedTemplateProp = import_zod.z.union([
|
|
|
75
77
|
value: import_zod.z.array(
|
|
76
78
|
import_zod.z.object({
|
|
77
79
|
type: import_zod.z.literal("execute"),
|
|
80
|
+
args: import_zod.z.optional(import_zod.z.array(import_zod.z.string())),
|
|
78
81
|
code: import_zod.z.string()
|
|
79
82
|
})
|
|
80
83
|
)
|
|
@@ -115,12 +118,17 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
|
|
|
115
118
|
type: "action",
|
|
116
119
|
name: prop.name,
|
|
117
120
|
value: prop.value.map((value) => {
|
|
121
|
+
const args = value.args ?? [];
|
|
118
122
|
return {
|
|
119
123
|
type: "execute",
|
|
124
|
+
args,
|
|
120
125
|
// replace all references with variable names
|
|
121
126
|
code: (0, import_expression.validateExpression)(value.code, {
|
|
122
127
|
effectful: true,
|
|
123
128
|
transformIdentifier: (ref) => {
|
|
129
|
+
if (args.includes(ref)) {
|
|
130
|
+
return ref;
|
|
131
|
+
}
|
|
124
132
|
const id = dataSourceByRef.get(ref)?.id ?? ref;
|
|
125
133
|
return (0, import_expression.encodeDataSourceVariable)(id);
|
|
126
134
|
}
|
|
@@ -256,3 +264,24 @@ const generateDataFromEmbedTemplate = (treeTemplate, defaultBreakpointId) => {
|
|
|
256
264
|
styles
|
|
257
265
|
};
|
|
258
266
|
};
|
|
267
|
+
const namespaceEmbedTemplateComponents = (template, namespace, components) => {
|
|
268
|
+
return template.map((item) => {
|
|
269
|
+
if (item.type === "text") {
|
|
270
|
+
return item;
|
|
271
|
+
}
|
|
272
|
+
if (item.type === "instance") {
|
|
273
|
+
const prefix = components.has(item.component) ? `${namespace}:` : "";
|
|
274
|
+
return {
|
|
275
|
+
...item,
|
|
276
|
+
component: `${prefix}${item.component}`,
|
|
277
|
+
children: namespaceEmbedTemplateComponents(
|
|
278
|
+
item.children,
|
|
279
|
+
namespace,
|
|
280
|
+
components
|
|
281
|
+
)
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
item;
|
|
285
|
+
throw Error("Impossible case");
|
|
286
|
+
});
|
|
287
|
+
};
|
package/lib/cjs/expression.js
CHANGED
|
@@ -28,6 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
var expression_exports = {};
|
|
30
30
|
__export(expression_exports, {
|
|
31
|
+
computeExpressionsDependencies: () => computeExpressionsDependencies,
|
|
31
32
|
decodeDataSourceVariable: () => decodeDataSourceVariable,
|
|
32
33
|
decodeVariablesMap: () => decodeVariablesMap,
|
|
33
34
|
encodeDataSourceVariable: () => encodeDataSourceVariable,
|
|
@@ -249,12 +250,15 @@ const executeComputingExpressions = (expressions, variables) => {
|
|
|
249
250
|
const values = executeFn(variables);
|
|
250
251
|
return values;
|
|
251
252
|
};
|
|
252
|
-
const generateEffectfulExpression = (code, allowedVariables) => {
|
|
253
|
+
const generateEffectfulExpression = (code, args, allowedVariables) => {
|
|
253
254
|
const inputVariables = /* @__PURE__ */ new Set();
|
|
254
255
|
const outputVariables = /* @__PURE__ */ new Set();
|
|
255
256
|
validateExpression(code, {
|
|
256
257
|
effectful: true,
|
|
257
258
|
transformIdentifier: (identifier, assignee) => {
|
|
259
|
+
if (args.has(identifier)) {
|
|
260
|
+
return identifier;
|
|
261
|
+
}
|
|
258
262
|
if (allowedVariables.has(identifier)) {
|
|
259
263
|
if (assignee) {
|
|
260
264
|
outputVariables.add(identifier);
|
|
@@ -267,6 +271,10 @@ const generateEffectfulExpression = (code, allowedVariables) => {
|
|
|
267
271
|
}
|
|
268
272
|
});
|
|
269
273
|
let generatedCode = "";
|
|
274
|
+
for (const id of args) {
|
|
275
|
+
generatedCode += `let ${id} = _args.get('${id}');
|
|
276
|
+
`;
|
|
277
|
+
}
|
|
270
278
|
for (const id of inputVariables) {
|
|
271
279
|
generatedCode += `let ${id} = _variables.get('${id}');
|
|
272
280
|
`;
|
|
@@ -288,15 +296,50 @@ const generateEffectfulExpression = (code, allowedVariables) => {
|
|
|
288
296
|
generatedCode += `]);`;
|
|
289
297
|
return generatedCode;
|
|
290
298
|
};
|
|
291
|
-
const executeEffectfulExpression = (code, variables) => {
|
|
299
|
+
const executeEffectfulExpression = (code, args, variables) => {
|
|
292
300
|
const generatedCode = generateEffectfulExpression(
|
|
293
301
|
code,
|
|
302
|
+
new Set(args.keys()),
|
|
294
303
|
new Set(variables.keys())
|
|
295
304
|
);
|
|
296
|
-
const executeFn = new Function("_variables", generatedCode);
|
|
297
|
-
const values = executeFn(variables);
|
|
305
|
+
const executeFn = new Function("_variables", "_args", generatedCode);
|
|
306
|
+
const values = executeFn(variables, args);
|
|
298
307
|
return values;
|
|
299
308
|
};
|
|
309
|
+
const computeExpressionDependencies = (expressions, expressionId, dependencies) => {
|
|
310
|
+
const depsById = dependencies.get(expressionId);
|
|
311
|
+
if (depsById) {
|
|
312
|
+
return depsById;
|
|
313
|
+
}
|
|
314
|
+
const parentDeps = /* @__PURE__ */ new Set();
|
|
315
|
+
const code = expressions.get(expressionId);
|
|
316
|
+
if (code === void 0) {
|
|
317
|
+
return parentDeps;
|
|
318
|
+
}
|
|
319
|
+
dependencies.set(expressionId, parentDeps);
|
|
320
|
+
validateExpression(code, {
|
|
321
|
+
transformIdentifier: (id) => {
|
|
322
|
+
parentDeps.add(id);
|
|
323
|
+
const childDeps = computeExpressionDependencies(
|
|
324
|
+
expressions,
|
|
325
|
+
id,
|
|
326
|
+
dependencies
|
|
327
|
+
);
|
|
328
|
+
for (const depId of childDeps) {
|
|
329
|
+
parentDeps.add(depId);
|
|
330
|
+
}
|
|
331
|
+
return id;
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
return parentDeps;
|
|
335
|
+
};
|
|
336
|
+
const computeExpressionsDependencies = (expressions) => {
|
|
337
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
338
|
+
for (const id of expressions.keys()) {
|
|
339
|
+
computeExpressionDependencies(expressions, id, dependencies);
|
|
340
|
+
}
|
|
341
|
+
return dependencies;
|
|
342
|
+
};
|
|
300
343
|
const dataSourceVariablePrefix = "$ws$dataSource$";
|
|
301
344
|
const encodeDataSourceVariable = (id) => {
|
|
302
345
|
const encoded = id.replaceAll("-", "__DASH__");
|
package/lib/cjs/index.js
CHANGED
|
@@ -21,6 +21,7 @@ var src_exports = {};
|
|
|
21
21
|
__export(src_exports, {
|
|
22
22
|
ReactSdkContext: () => import_context.ReactSdkContext,
|
|
23
23
|
componentCategories: () => import_component_meta.componentCategories,
|
|
24
|
+
computeExpressionsDependencies: () => import_expression.computeExpressionsDependencies,
|
|
24
25
|
decodeDataSourceVariable: () => import_expression.decodeDataSourceVariable,
|
|
25
26
|
decodeVariablesMap: () => import_expression.decodeVariablesMap,
|
|
26
27
|
defaultStates: () => import_component_meta.defaultStates,
|
package/lib/cjs/props.js
CHANGED
|
@@ -73,14 +73,19 @@ const useInstanceProps = (instanceId) => {
|
|
|
73
73
|
continue;
|
|
74
74
|
}
|
|
75
75
|
if (prop.type === "action") {
|
|
76
|
-
instancePropsObject2[prop.name] = () => {
|
|
76
|
+
instancePropsObject2[prop.name] = (...args) => {
|
|
77
77
|
if (renderer === "canvas") {
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
80
|
for (const value of prop.value) {
|
|
81
81
|
if (value.type === "execute") {
|
|
82
|
+
const argsMap = /* @__PURE__ */ new Map();
|
|
83
|
+
for (const [i, name] of value.args.entries()) {
|
|
84
|
+
argsMap.set(name, args[i]);
|
|
85
|
+
}
|
|
82
86
|
const newValues = executeEffectfulExpression(
|
|
83
87
|
value.code,
|
|
88
|
+
argsMap,
|
|
84
89
|
dataSourceValues
|
|
85
90
|
);
|
|
86
91
|
setDataSourceValues(newValues);
|
package/lib/cjs/tree/root.js
CHANGED
|
@@ -23,6 +23,7 @@ __export(root_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(root_exports);
|
|
24
24
|
var import_react = require("react");
|
|
25
25
|
var import_nanostores = require("nanostores");
|
|
26
|
+
var import_project_build = require("@webstudio-is/project-build");
|
|
26
27
|
var import_create_elements_tree = require("./create-elements-tree");
|
|
27
28
|
var import_webstudio_component = require("./webstudio-component");
|
|
28
29
|
var import_props = require("../props");
|
|
@@ -23,7 +23,9 @@ __export(webstudio_component_exports, {
|
|
|
23
23
|
componentAttribute: () => componentAttribute,
|
|
24
24
|
idAttribute: () => idAttribute,
|
|
25
25
|
renderWebstudioComponentChildren: () => renderWebstudioComponentChildren,
|
|
26
|
-
|
|
26
|
+
selectorIdAttribute: () => selectorIdAttribute,
|
|
27
|
+
showAttribute: () => showAttribute,
|
|
28
|
+
splitPropsWithWebstudioAttributes: () => splitPropsWithWebstudioAttributes
|
|
27
29
|
});
|
|
28
30
|
module.exports = __toCommonJS(webstudio_component_exports);
|
|
29
31
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -44,13 +46,7 @@ const renderWebstudioComponentChildren = (children) => {
|
|
|
44
46
|
return typeof child === "string" ? renderText(child) : child;
|
|
45
47
|
});
|
|
46
48
|
};
|
|
47
|
-
const WebstudioComponent = ({
|
|
48
|
-
instance,
|
|
49
|
-
instanceSelector,
|
|
50
|
-
children,
|
|
51
|
-
components,
|
|
52
|
-
...rest
|
|
53
|
-
}) => {
|
|
49
|
+
const WebstudioComponent = (0, import_react.forwardRef)(({ instance, instanceSelector, children, components, ...rest }, ref) => {
|
|
54
50
|
const { [showAttribute]: show = true, ...instanceProps } = (0, import_props.useInstanceProps)(
|
|
55
51
|
instance.id
|
|
56
52
|
);
|
|
@@ -67,9 +63,27 @@ const WebstudioComponent = ({
|
|
|
67
63
|
if (Component === void 0) {
|
|
68
64
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, {});
|
|
69
65
|
}
|
|
70
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { ...props, children: renderWebstudioComponentChildren(children) });
|
|
71
|
-
};
|
|
66
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { ...props, ref, children: renderWebstudioComponentChildren(children) });
|
|
67
|
+
});
|
|
72
68
|
const idAttribute = "data-ws-id";
|
|
69
|
+
const selectorIdAttribute = "data-ws-selector";
|
|
73
70
|
const componentAttribute = "data-ws-component";
|
|
74
71
|
const showAttribute = "data-ws-show";
|
|
75
72
|
const collapsedAttribute = "data-ws-collapsed";
|
|
73
|
+
const splitPropsWithWebstudioAttributes = ({
|
|
74
|
+
[idAttribute]: idAttributeValue,
|
|
75
|
+
[componentAttribute]: componentAttributeValue,
|
|
76
|
+
[showAttribute]: showAttributeValue,
|
|
77
|
+
[collapsedAttribute]: collapsedAttributeValue,
|
|
78
|
+
[selectorIdAttribute]: parentIdAttributeValue,
|
|
79
|
+
...props
|
|
80
|
+
}) => [
|
|
81
|
+
{
|
|
82
|
+
[idAttribute]: idAttributeValue,
|
|
83
|
+
[componentAttribute]: componentAttributeValue,
|
|
84
|
+
[showAttribute]: showAttributeValue,
|
|
85
|
+
[collapsedAttribute]: collapsedAttributeValue,
|
|
86
|
+
[selectorIdAttribute]: parentIdAttributeValue
|
|
87
|
+
},
|
|
88
|
+
props
|
|
89
|
+
];
|
|
@@ -11,6 +11,7 @@ const componentCategories = [
|
|
|
11
11
|
"text",
|
|
12
12
|
"media",
|
|
13
13
|
"forms",
|
|
14
|
+
"radix",
|
|
14
15
|
"hidden"
|
|
15
16
|
];
|
|
16
17
|
const stateCategories = ["states", "component-states"];
|
|
@@ -36,6 +37,10 @@ const WsComponentMeta = z.object({
|
|
|
36
37
|
requiredAncestors: z.optional(z.array(z.string())),
|
|
37
38
|
invalidAncestors: z.optional(z.array(z.string())),
|
|
38
39
|
stylable: z.optional(z.boolean()),
|
|
40
|
+
// specifies whether the instance can be deleted,
|
|
41
|
+
// copied or dragged out of its parent instance
|
|
42
|
+
// true by default
|
|
43
|
+
detachable: z.optional(z.boolean()),
|
|
39
44
|
label: z.string(),
|
|
40
45
|
description: z.string().optional(),
|
|
41
46
|
icon: z.string(),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { componentAttribute, idAttribute } from "../tree";
|
package/lib/css/index.js
CHANGED
package/lib/embed-template.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { nanoid } from "nanoid";
|
|
3
|
+
import {
|
|
4
|
+
Instance,
|
|
5
|
+
PropsList,
|
|
6
|
+
StyleSourceSelectionsList,
|
|
7
|
+
StyleSourcesList,
|
|
8
|
+
StylesList,
|
|
9
|
+
Breakpoint,
|
|
10
|
+
DataSource
|
|
11
|
+
} from "@webstudio-is/project-build";
|
|
3
12
|
import { StyleValue } from "@webstudio-is/css-data";
|
|
4
13
|
import { encodeDataSourceVariable, validateExpression } from "./expression";
|
|
5
14
|
const EmbedTemplateText = z.object({
|
|
@@ -49,6 +58,7 @@ const EmbedTemplateProp = z.union([
|
|
|
49
58
|
value: z.array(
|
|
50
59
|
z.object({
|
|
51
60
|
type: z.literal("execute"),
|
|
61
|
+
args: z.optional(z.array(z.string())),
|
|
52
62
|
code: z.string()
|
|
53
63
|
})
|
|
54
64
|
)
|
|
@@ -89,12 +99,17 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
|
|
|
89
99
|
type: "action",
|
|
90
100
|
name: prop.name,
|
|
91
101
|
value: prop.value.map((value) => {
|
|
102
|
+
const args = value.args ?? [];
|
|
92
103
|
return {
|
|
93
104
|
type: "execute",
|
|
105
|
+
args,
|
|
94
106
|
// replace all references with variable names
|
|
95
107
|
code: validateExpression(value.code, {
|
|
96
108
|
effectful: true,
|
|
97
109
|
transformIdentifier: (ref) => {
|
|
110
|
+
if (args.includes(ref)) {
|
|
111
|
+
return ref;
|
|
112
|
+
}
|
|
98
113
|
const id = dataSourceByRef.get(ref)?.id ?? ref;
|
|
99
114
|
return encodeDataSourceVariable(id);
|
|
100
115
|
}
|
|
@@ -230,9 +245,31 @@ const generateDataFromEmbedTemplate = (treeTemplate, defaultBreakpointId) => {
|
|
|
230
245
|
styles
|
|
231
246
|
};
|
|
232
247
|
};
|
|
248
|
+
const namespaceEmbedTemplateComponents = (template, namespace, components) => {
|
|
249
|
+
return template.map((item) => {
|
|
250
|
+
if (item.type === "text") {
|
|
251
|
+
return item;
|
|
252
|
+
}
|
|
253
|
+
if (item.type === "instance") {
|
|
254
|
+
const prefix = components.has(item.component) ? `${namespace}:` : "";
|
|
255
|
+
return {
|
|
256
|
+
...item,
|
|
257
|
+
component: `${prefix}${item.component}`,
|
|
258
|
+
children: namespaceEmbedTemplateComponents(
|
|
259
|
+
item.children,
|
|
260
|
+
namespace,
|
|
261
|
+
components
|
|
262
|
+
)
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
item;
|
|
266
|
+
throw Error("Impossible case");
|
|
267
|
+
});
|
|
268
|
+
};
|
|
233
269
|
export {
|
|
234
270
|
EmbedTemplateInstance,
|
|
235
271
|
EmbedTemplateStyleDecl,
|
|
236
272
|
WsEmbedTemplate,
|
|
237
|
-
generateDataFromEmbedTemplate
|
|
273
|
+
generateDataFromEmbedTemplate,
|
|
274
|
+
namespaceEmbedTemplateComponents
|
|
238
275
|
};
|
package/lib/expression.js
CHANGED
|
@@ -208,12 +208,15 @@ const executeComputingExpressions = (expressions, variables) => {
|
|
|
208
208
|
const values = executeFn(variables);
|
|
209
209
|
return values;
|
|
210
210
|
};
|
|
211
|
-
const generateEffectfulExpression = (code, allowedVariables) => {
|
|
211
|
+
const generateEffectfulExpression = (code, args, allowedVariables) => {
|
|
212
212
|
const inputVariables = /* @__PURE__ */ new Set();
|
|
213
213
|
const outputVariables = /* @__PURE__ */ new Set();
|
|
214
214
|
validateExpression(code, {
|
|
215
215
|
effectful: true,
|
|
216
216
|
transformIdentifier: (identifier, assignee) => {
|
|
217
|
+
if (args.has(identifier)) {
|
|
218
|
+
return identifier;
|
|
219
|
+
}
|
|
217
220
|
if (allowedVariables.has(identifier)) {
|
|
218
221
|
if (assignee) {
|
|
219
222
|
outputVariables.add(identifier);
|
|
@@ -226,6 +229,10 @@ const generateEffectfulExpression = (code, allowedVariables) => {
|
|
|
226
229
|
}
|
|
227
230
|
});
|
|
228
231
|
let generatedCode = "";
|
|
232
|
+
for (const id of args) {
|
|
233
|
+
generatedCode += `let ${id} = _args.get('${id}');
|
|
234
|
+
`;
|
|
235
|
+
}
|
|
229
236
|
for (const id of inputVariables) {
|
|
230
237
|
generatedCode += `let ${id} = _variables.get('${id}');
|
|
231
238
|
`;
|
|
@@ -247,15 +254,50 @@ const generateEffectfulExpression = (code, allowedVariables) => {
|
|
|
247
254
|
generatedCode += `]);`;
|
|
248
255
|
return generatedCode;
|
|
249
256
|
};
|
|
250
|
-
const executeEffectfulExpression = (code, variables) => {
|
|
257
|
+
const executeEffectfulExpression = (code, args, variables) => {
|
|
251
258
|
const generatedCode = generateEffectfulExpression(
|
|
252
259
|
code,
|
|
260
|
+
new Set(args.keys()),
|
|
253
261
|
new Set(variables.keys())
|
|
254
262
|
);
|
|
255
|
-
const executeFn = new Function("_variables", generatedCode);
|
|
256
|
-
const values = executeFn(variables);
|
|
263
|
+
const executeFn = new Function("_variables", "_args", generatedCode);
|
|
264
|
+
const values = executeFn(variables, args);
|
|
257
265
|
return values;
|
|
258
266
|
};
|
|
267
|
+
const computeExpressionDependencies = (expressions, expressionId, dependencies) => {
|
|
268
|
+
const depsById = dependencies.get(expressionId);
|
|
269
|
+
if (depsById) {
|
|
270
|
+
return depsById;
|
|
271
|
+
}
|
|
272
|
+
const parentDeps = /* @__PURE__ */ new Set();
|
|
273
|
+
const code = expressions.get(expressionId);
|
|
274
|
+
if (code === void 0) {
|
|
275
|
+
return parentDeps;
|
|
276
|
+
}
|
|
277
|
+
dependencies.set(expressionId, parentDeps);
|
|
278
|
+
validateExpression(code, {
|
|
279
|
+
transformIdentifier: (id) => {
|
|
280
|
+
parentDeps.add(id);
|
|
281
|
+
const childDeps = computeExpressionDependencies(
|
|
282
|
+
expressions,
|
|
283
|
+
id,
|
|
284
|
+
dependencies
|
|
285
|
+
);
|
|
286
|
+
for (const depId of childDeps) {
|
|
287
|
+
parentDeps.add(depId);
|
|
288
|
+
}
|
|
289
|
+
return id;
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
return parentDeps;
|
|
293
|
+
};
|
|
294
|
+
const computeExpressionsDependencies = (expressions) => {
|
|
295
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
296
|
+
for (const id of expressions.keys()) {
|
|
297
|
+
computeExpressionDependencies(expressions, id, dependencies);
|
|
298
|
+
}
|
|
299
|
+
return dependencies;
|
|
300
|
+
};
|
|
259
301
|
const dataSourceVariablePrefix = "$ws$dataSource$";
|
|
260
302
|
const encodeDataSourceVariable = (id) => {
|
|
261
303
|
const encoded = id.replaceAll("-", "__DASH__");
|
|
@@ -286,6 +328,7 @@ const decodeVariablesMap = (values) => {
|
|
|
286
328
|
return decodedValues;
|
|
287
329
|
};
|
|
288
330
|
export {
|
|
331
|
+
computeExpressionsDependencies,
|
|
289
332
|
decodeDataSourceVariable,
|
|
290
333
|
decodeVariablesMap,
|
|
291
334
|
encodeDataSourceVariable,
|
package/lib/index.js
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
executeComputingExpressions,
|
|
23
23
|
generateEffectfulExpression,
|
|
24
24
|
executeEffectfulExpression,
|
|
25
|
+
computeExpressionsDependencies,
|
|
25
26
|
encodeDataSourceVariable,
|
|
26
27
|
encodeVariablesMap,
|
|
27
28
|
decodeDataSourceVariable,
|
|
@@ -30,6 +31,7 @@ import {
|
|
|
30
31
|
export {
|
|
31
32
|
ReactSdkContext,
|
|
32
33
|
componentCategories,
|
|
34
|
+
computeExpressionsDependencies,
|
|
33
35
|
decodeDataSourceVariable,
|
|
34
36
|
decodeVariablesMap,
|
|
35
37
|
defaultStates,
|
package/lib/props.js
CHANGED
|
@@ -45,14 +45,19 @@ const useInstanceProps = (instanceId) => {
|
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
47
47
|
if (prop.type === "action") {
|
|
48
|
-
instancePropsObject2[prop.name] = () => {
|
|
48
|
+
instancePropsObject2[prop.name] = (...args) => {
|
|
49
49
|
if (renderer === "canvas") {
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
52
|
for (const value of prop.value) {
|
|
53
53
|
if (value.type === "execute") {
|
|
54
|
+
const argsMap = /* @__PURE__ */ new Map();
|
|
55
|
+
for (const [i, name] of value.args.entries()) {
|
|
56
|
+
argsMap.set(name, args[i]);
|
|
57
|
+
}
|
|
54
58
|
const newValues = executeEffectfulExpression(
|
|
55
59
|
value.code,
|
|
60
|
+
argsMap,
|
|
56
61
|
dataSourceValues
|
|
57
62
|
);
|
|
58
63
|
setDataSourceValues(newValues);
|
package/lib/tree/root.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
useRef,
|
|
3
|
+
useCallback
|
|
4
|
+
} from "react";
|
|
2
5
|
import {
|
|
3
6
|
atom,
|
|
4
7
|
computed
|
|
5
8
|
} from "nanostores";
|
|
9
|
+
import {} from "@webstudio-is/project-build";
|
|
6
10
|
import { createElementsTree } from "./create-elements-tree";
|
|
7
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
WebstudioComponent
|
|
13
|
+
} from "./webstudio-component";
|
|
8
14
|
import { getPropsByInstanceId } from "../props";
|
|
9
15
|
const InstanceRoot = ({
|
|
10
16
|
data,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Fragment as Fragment2 } from "react";
|
|
2
|
+
import { Fragment as Fragment2, forwardRef } from "react";
|
|
3
3
|
import { useInstanceProps } from "../props";
|
|
4
4
|
const renderText = (text) => {
|
|
5
5
|
const lines = text.split("\n");
|
|
@@ -16,13 +16,7 @@ const renderWebstudioComponentChildren = (children) => {
|
|
|
16
16
|
return typeof child === "string" ? renderText(child) : child;
|
|
17
17
|
});
|
|
18
18
|
};
|
|
19
|
-
const WebstudioComponent = ({
|
|
20
|
-
instance,
|
|
21
|
-
instanceSelector,
|
|
22
|
-
children,
|
|
23
|
-
components,
|
|
24
|
-
...rest
|
|
25
|
-
}) => {
|
|
19
|
+
const WebstudioComponent = forwardRef(({ instance, instanceSelector, children, components, ...rest }, ref) => {
|
|
26
20
|
const { [showAttribute]: show = true, ...instanceProps } = useInstanceProps(
|
|
27
21
|
instance.id
|
|
28
22
|
);
|
|
@@ -39,17 +33,37 @@ const WebstudioComponent = ({
|
|
|
39
33
|
if (Component === void 0) {
|
|
40
34
|
return /* @__PURE__ */ jsx(Fragment, {});
|
|
41
35
|
}
|
|
42
|
-
return /* @__PURE__ */ jsx(Component, { ...props, children: renderWebstudioComponentChildren(children) });
|
|
43
|
-
};
|
|
36
|
+
return /* @__PURE__ */ jsx(Component, { ...props, ref, children: renderWebstudioComponentChildren(children) });
|
|
37
|
+
});
|
|
44
38
|
const idAttribute = "data-ws-id";
|
|
39
|
+
const selectorIdAttribute = "data-ws-selector";
|
|
45
40
|
const componentAttribute = "data-ws-component";
|
|
46
41
|
const showAttribute = "data-ws-show";
|
|
47
42
|
const collapsedAttribute = "data-ws-collapsed";
|
|
43
|
+
const splitPropsWithWebstudioAttributes = ({
|
|
44
|
+
[idAttribute]: idAttributeValue,
|
|
45
|
+
[componentAttribute]: componentAttributeValue,
|
|
46
|
+
[showAttribute]: showAttributeValue,
|
|
47
|
+
[collapsedAttribute]: collapsedAttributeValue,
|
|
48
|
+
[selectorIdAttribute]: parentIdAttributeValue,
|
|
49
|
+
...props
|
|
50
|
+
}) => [
|
|
51
|
+
{
|
|
52
|
+
[idAttribute]: idAttributeValue,
|
|
53
|
+
[componentAttribute]: componentAttributeValue,
|
|
54
|
+
[showAttribute]: showAttributeValue,
|
|
55
|
+
[collapsedAttribute]: collapsedAttributeValue,
|
|
56
|
+
[selectorIdAttribute]: parentIdAttributeValue
|
|
57
|
+
},
|
|
58
|
+
props
|
|
59
|
+
];
|
|
48
60
|
export {
|
|
49
61
|
WebstudioComponent,
|
|
50
62
|
collapsedAttribute,
|
|
51
63
|
componentAttribute,
|
|
52
64
|
idAttribute,
|
|
53
65
|
renderWebstudioComponentChildren,
|
|
54
|
-
|
|
66
|
+
selectorIdAttribute,
|
|
67
|
+
showAttribute,
|
|
68
|
+
splitPropsWithWebstudioAttributes
|
|
55
69
|
};
|
package/lib/types/app/root.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { Outlet as DefaultOutlet } from "@remix-run/react";
|
|
3
2
|
/**
|
|
4
3
|
* We are using Outlet prop from index layout when user renders site from a subdomain.
|
|
5
4
|
*/
|
|
6
5
|
export declare const Root: ({ Outlet, }: {
|
|
7
6
|
Outlet: typeof DefaultOutlet;
|
|
8
|
-
}) => JSX.Element;
|
|
7
|
+
}) => import("react/jsx-runtime").JSX.Element;
|