@webstudio-is/react-sdk 0.81.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.
Files changed (49) hide show
  1. package/LICENSE +661 -21
  2. package/lib/cjs/components/component-meta.js +5 -0
  3. package/lib/cjs/components/components-utils.js +1 -0
  4. package/lib/cjs/css/index.js +0 -1
  5. package/lib/cjs/embed-template.js +30 -1
  6. package/lib/cjs/expression.js +47 -4
  7. package/lib/cjs/index.js +1 -0
  8. package/lib/cjs/props.js +6 -1
  9. package/lib/cjs/tree/root.js +1 -0
  10. package/lib/cjs/tree/webstudio-component.js +24 -10
  11. package/lib/components/component-meta.js +5 -0
  12. package/lib/components/components-utils.js +1 -0
  13. package/lib/css/index.js +0 -1
  14. package/lib/embed-template.js +38 -1
  15. package/lib/expression.js +47 -4
  16. package/lib/index.js +2 -0
  17. package/lib/props.js +6 -1
  18. package/lib/tree/create-elements-tree.js +3 -1
  19. package/lib/tree/root.js +8 -2
  20. package/lib/tree/webstudio-component.js +25 -11
  21. package/lib/types/app/root.d.ts +1 -2
  22. package/lib/types/components/component-meta.d.ts +16 -8
  23. package/lib/types/context.d.ts +1 -1
  24. package/lib/types/css/index.d.ts +0 -1
  25. package/lib/types/css/normalize.d.ts +47 -47
  26. package/lib/types/embed-template.d.ts +14 -1
  27. package/lib/types/expression.d.ts +3 -2
  28. package/lib/types/index.d.ts +1 -1
  29. package/lib/types/props.d.ts +1 -0
  30. package/lib/types/tree/create-elements-tree.d.ts +5 -5
  31. package/lib/types/tree/root.d.ts +4 -4
  32. package/lib/types/tree/webstudio-component.d.ts +15 -7
  33. package/package.json +14 -15
  34. package/src/components/component-meta.ts +5 -0
  35. package/src/context.tsx +1 -0
  36. package/src/css/index.ts +0 -1
  37. package/src/embed-template.test.ts +77 -1
  38. package/src/embed-template.ts +34 -1
  39. package/src/expression.test.ts +74 -6
  40. package/src/expression.ts +55 -2
  41. package/src/index.ts +1 -0
  42. package/src/props.ts +6 -1
  43. package/src/tree/create-elements-tree.tsx +17 -5
  44. package/src/tree/root.ts +14 -3
  45. package/src/tree/webstudio-component.tsx +41 -14
  46. package/lib/cjs/css/get-browser-style.js +0 -83
  47. package/lib/css/get-browser-style.js +0 -65
  48. package/lib/types/css/get-browser-style.d.ts +0 -2
  49. 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");
@@ -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
+ };
@@ -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);
@@ -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
- showAttribute: () => showAttribute
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
@@ -1,4 +1,3 @@
1
- export * from "./get-browser-style";
2
1
  export * from "./global-rules";
3
2
  export * from "./style-rules";
4
3
  export * from "./css";
@@ -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);
@@ -1,5 +1,7 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { Fragment } from "react";
2
+ import {
3
+ Fragment
4
+ } from "react";
3
5
  import { Scripts, ScrollRestoration } from "@remix-run/react";
4
6
  import {
5
7
  ReactSdkContext
package/lib/tree/root.js CHANGED
@@ -1,10 +1,16 @@
1
- import { useRef, useCallback } from "react";
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 { WebstudioComponent } from "./webstudio-component";
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
- showAttribute
66
+ selectorIdAttribute,
67
+ showAttribute,
68
+ splitPropsWithWebstudioAttributes
55
69
  };
@@ -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;