@webstudio-is/react-sdk 0.117.0 → 0.119.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/lib/index.js CHANGED
@@ -14,143 +14,79 @@ var addGlobalRules = (engine, { assets, assetBaseUrl }) => {
14
14
  }
15
15
  };
16
16
 
17
- // src/tree/create-elements-tree.tsx
18
- import {
19
- Fragment
20
- } from "react";
21
-
22
- // src/context.tsx
23
- import { createContext } from "react";
24
- var ReactSdkContext = createContext({
25
- assetBaseUrl: "/",
26
- imageBaseUrl: "/",
27
- imageLoader: ({ src }) => src,
28
- pagesPaths: /* @__PURE__ */ new Set()
29
- });
30
-
31
- // src/tree/create-elements-tree.tsx
32
- import { jsx, jsxs } from "react/jsx-runtime";
33
- var createElementsTree = ({
34
- renderer,
17
+ // src/props.ts
18
+ var normalizeProps = ({
19
+ props,
35
20
  assetBaseUrl,
36
- imageBaseUrl,
37
- imageLoader,
38
- instances,
39
- rootInstanceId,
40
- Component,
41
- components,
42
- scripts
43
- }) => {
44
- const rootInstance = instances.get(rootInstanceId);
45
- if (rootInstance === void 0) {
46
- return null;
47
- }
48
- const rootInstanceSelector = [rootInstanceId];
49
- const children = createInstanceChildrenElements({
50
- instances,
51
- instanceSelector: rootInstanceSelector,
52
- Component,
53
- children: rootInstance.children,
54
- components
55
- });
56
- const root = createInstanceElement({
57
- Component,
58
- instance: rootInstance,
59
- instanceSelector: rootInstanceSelector,
60
- children: [
61
- /* @__PURE__ */ jsxs(Fragment, { children: [
62
- children,
63
- scripts
64
- ] }, "children")
65
- ],
66
- components
67
- });
68
- return /* @__PURE__ */ jsx(
69
- ReactSdkContext.Provider,
70
- {
71
- value: {
72
- renderer,
73
- imageLoader,
74
- pagesPaths: /* @__PURE__ */ new Set(),
75
- assetBaseUrl,
76
- imageBaseUrl
77
- },
78
- children: root
79
- }
80
- );
81
- };
82
- var createInstanceChildrenElements = ({
83
- instances,
84
- instanceSelector,
85
- children,
86
- Component,
87
- components
21
+ assets,
22
+ pages
88
23
  }) => {
89
- const elements = [];
90
- for (const child of children) {
91
- if (child.type === "text") {
92
- elements.push(child.value);
24
+ const newProps = [];
25
+ for (const prop of props) {
26
+ if (prop.type === "asset") {
27
+ const assetId = prop.value;
28
+ const asset = assets.get(assetId);
29
+ if (asset === void 0) {
30
+ continue;
31
+ }
32
+ newProps.push({
33
+ id: prop.id,
34
+ name: prop.name,
35
+ required: prop.required,
36
+ instanceId: prop.instanceId,
37
+ type: "string",
38
+ value: `${assetBaseUrl}${asset.name}`
39
+ });
93
40
  continue;
94
41
  }
95
- const childInstance = instances.get(child.value);
96
- if (childInstance === void 0) {
42
+ if (prop.type === "page") {
43
+ let page;
44
+ let idProp;
45
+ if (typeof prop.value === "string") {
46
+ const pageId = prop.value;
47
+ page = pages.get(pageId);
48
+ } else {
49
+ const { pageId, instanceId } = prop.value;
50
+ page = pages.get(pageId);
51
+ idProp = props.find(
52
+ (prop2) => prop2.instanceId === instanceId && prop2.name === "id"
53
+ );
54
+ }
55
+ if (page === void 0) {
56
+ continue;
57
+ }
58
+ const url = new URL(page.path, "https://any-valid.url");
59
+ let value = url.pathname;
60
+ if (idProp?.type === "string") {
61
+ const hash = idProp.value;
62
+ url.hash = encodeURIComponent(hash);
63
+ value = `${url.pathname}${url.hash}`;
64
+ }
65
+ newProps.push({
66
+ id: prop.id,
67
+ name: prop.name,
68
+ required: prop.required,
69
+ instanceId: prop.instanceId,
70
+ type: "string",
71
+ value
72
+ });
97
73
  continue;
98
74
  }
99
- const childInstanceSelector = [child.value, ...instanceSelector];
100
- const children2 = createInstanceChildrenElements({
101
- instances,
102
- instanceSelector: childInstanceSelector,
103
- children: childInstance.children,
104
- Component,
105
- components
106
- });
107
- const element = createInstanceElement({
108
- instance: childInstance,
109
- instanceSelector: childInstanceSelector,
110
- Component,
111
- children: children2,
112
- components
113
- });
114
- elements.push(element);
75
+ newProps.push(prop);
115
76
  }
116
- return elements;
117
- };
118
- var createInstanceElement = ({
119
- Component,
120
- instance,
121
- instanceSelector,
122
- children = [],
123
- components
124
- }) => {
125
- return /* @__PURE__ */ jsx(
126
- Component,
127
- {
128
- instance,
129
- instanceSelector,
130
- components,
131
- children
132
- },
133
- instance.id
134
- );
135
- };
136
-
137
- // src/tree/webstudio-component.tsx
138
- import { Fragment as Fragment2 } from "react";
139
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
140
- var renderText = (text) => {
141
- const lines = text.split("\n");
142
- return lines.map((line, index) => /* @__PURE__ */ jsxs2(Fragment2, { children: [
143
- line,
144
- index < lines.length - 1 ? /* @__PURE__ */ jsx2("br", {}) : null
145
- ] }, index));
77
+ return newProps;
146
78
  };
147
- var renderWebstudioComponentChildren = (children) => {
148
- if (children === void 0 || children.length === 0) {
149
- return;
79
+ var getPropsByInstanceId = (props) => {
80
+ const propsByInstanceId = /* @__PURE__ */ new Map();
81
+ for (const prop of props.values()) {
82
+ let instanceProps = propsByInstanceId.get(prop.instanceId);
83
+ if (instanceProps === void 0) {
84
+ instanceProps = [];
85
+ propsByInstanceId.set(prop.instanceId, instanceProps);
86
+ }
87
+ instanceProps.push(prop);
150
88
  }
151
- return children.map((child) => {
152
- return typeof child === "string" ? renderText(child) : child;
153
- });
89
+ return propsByInstanceId;
154
90
  };
155
91
  var idAttribute = "data-ws-id";
156
92
  var selectorIdAttribute = "data-ws-selector";
@@ -158,6 +94,12 @@ var componentAttribute = "data-ws-component";
158
94
  var showAttribute = "data-ws-show";
159
95
  var indexAttribute = "data-ws-index";
160
96
  var collapsedAttribute = "data-ws-collapsed";
97
+ var getInstanceIdFromComponentProps = (props) => {
98
+ return props[idAttribute];
99
+ };
100
+ var getIndexWithinAncestorFromComponentProps = (props) => {
101
+ return props[indexAttribute];
102
+ };
161
103
 
162
104
  // src/css/style-rules.ts
163
105
  var getStyleRules = (styles, styleSourceSelections) => {
@@ -279,23 +221,150 @@ var generateCssText = (data, options) => {
279
221
  return engine.cssText;
280
222
  };
281
223
 
224
+ // src/tree/create-elements-tree.tsx
225
+ import {
226
+ Fragment
227
+ } from "react";
228
+
229
+ // src/context.tsx
230
+ import { createContext } from "react";
231
+ var ReactSdkContext = createContext({
232
+ assetBaseUrl: "/",
233
+ imageBaseUrl: "/",
234
+ imageLoader: ({ src }) => src,
235
+ pagesPaths: /* @__PURE__ */ new Set()
236
+ });
237
+
238
+ // src/tree/create-elements-tree.tsx
239
+ import { jsx, jsxs } from "react/jsx-runtime";
240
+ var createElementsTree = ({
241
+ renderer,
242
+ assetBaseUrl,
243
+ imageBaseUrl,
244
+ imageLoader,
245
+ instances,
246
+ rootInstanceId,
247
+ Component,
248
+ components
249
+ }) => {
250
+ const rootInstance = instances.get(rootInstanceId);
251
+ if (rootInstance === void 0) {
252
+ return null;
253
+ }
254
+ const rootInstanceSelector = [rootInstanceId];
255
+ const children = createInstanceChildrenElements({
256
+ instances,
257
+ instanceSelector: rootInstanceSelector,
258
+ Component,
259
+ children: rootInstance.children,
260
+ components
261
+ });
262
+ const root = createInstanceElement({
263
+ Component,
264
+ instance: rootInstance,
265
+ instanceSelector: rootInstanceSelector,
266
+ children,
267
+ components
268
+ });
269
+ return /* @__PURE__ */ jsx(
270
+ ReactSdkContext.Provider,
271
+ {
272
+ value: {
273
+ renderer,
274
+ imageLoader,
275
+ pagesPaths: /* @__PURE__ */ new Set(),
276
+ assetBaseUrl,
277
+ imageBaseUrl
278
+ },
279
+ children: root
280
+ }
281
+ );
282
+ };
283
+ var renderText = (text) => {
284
+ const lines = text.split("\n");
285
+ return lines.map((line, index) => /* @__PURE__ */ jsxs(Fragment, { children: [
286
+ line,
287
+ index < lines.length - 1 && /* @__PURE__ */ jsx("br", {})
288
+ ] }, index));
289
+ };
290
+ var createInstanceChildrenElements = ({
291
+ instances,
292
+ instanceSelector,
293
+ children,
294
+ Component,
295
+ components
296
+ }) => {
297
+ const elements = [];
298
+ for (const child of children) {
299
+ if (child.type === "text") {
300
+ elements.push(renderText(child.value));
301
+ continue;
302
+ }
303
+ const childInstance = instances.get(child.value);
304
+ if (childInstance === void 0) {
305
+ continue;
306
+ }
307
+ const childInstanceSelector = [child.value, ...instanceSelector];
308
+ const children2 = createInstanceChildrenElements({
309
+ instances,
310
+ instanceSelector: childInstanceSelector,
311
+ children: childInstance.children,
312
+ Component,
313
+ components
314
+ });
315
+ const element = createInstanceElement({
316
+ instance: childInstance,
317
+ instanceSelector: childInstanceSelector,
318
+ Component,
319
+ children: children2,
320
+ components
321
+ });
322
+ elements.push(element);
323
+ }
324
+ if (elements.length === 0) {
325
+ return;
326
+ }
327
+ return elements;
328
+ };
329
+ var createInstanceElement = ({
330
+ Component,
331
+ instance,
332
+ instanceSelector,
333
+ children,
334
+ components
335
+ }) => {
336
+ return /* @__PURE__ */ jsx(
337
+ Component,
338
+ {
339
+ instance,
340
+ instanceSelector,
341
+ components,
342
+ children
343
+ },
344
+ instance.id
345
+ );
346
+ };
347
+
282
348
  // src/app/root.tsx
283
349
  import { Links, Meta, Outlet as DefaultOutlet } from "@remix-run/react";
284
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
350
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
285
351
  var Root = ({
286
352
  Outlet = DefaultOutlet
287
353
  }) => {
288
- return /* @__PURE__ */ jsxs3("html", { lang: "en", children: [
289
- /* @__PURE__ */ jsxs3("head", { children: [
290
- /* @__PURE__ */ jsx3("meta", { charSet: "utf-8" }),
291
- /* @__PURE__ */ jsx3("meta", { name: "viewport", content: "width=device-width,initial-scale=1" }),
292
- /* @__PURE__ */ jsx3(Meta, {}),
293
- /* @__PURE__ */ jsx3(Links, {})
354
+ return /* @__PURE__ */ jsxs2("html", { lang: "en", children: [
355
+ /* @__PURE__ */ jsxs2("head", { children: [
356
+ /* @__PURE__ */ jsx2("meta", { charSet: "utf-8" }),
357
+ /* @__PURE__ */ jsx2("meta", { name: "viewport", content: "width=device-width,initial-scale=1" }),
358
+ /* @__PURE__ */ jsx2(Meta, {}),
359
+ /* @__PURE__ */ jsx2(Links, {})
294
360
  ] }),
295
- /* @__PURE__ */ jsx3(Outlet, {})
361
+ /* @__PURE__ */ jsx2(Outlet, {})
296
362
  ] });
297
363
  };
298
364
 
365
+ // src/core-components.ts
366
+ var collectionComponent = "ws:component";
367
+
299
368
  // src/prop-meta.ts
300
369
  import { z } from "zod";
301
370
  var common = {
@@ -405,13 +474,11 @@ var Url = z.object({
405
474
  type: z.literal("string"),
406
475
  defaultValue: z.string().optional()
407
476
  });
408
- var ObjectType = z.object({
477
+ var Json = z.object({
409
478
  ...common,
410
- control: z.literal("object"),
411
- // @todo not sure what type should be here
412
- // (we don't support Object yet, added for completeness)
413
- type: z.literal("Record<string, string>"),
414
- defaultValue: z.record(z.string()).optional()
479
+ control: z.literal("json"),
480
+ type: z.literal("json"),
481
+ defaultValue: z.unknown().optional()
415
482
  });
416
483
  var Date = z.object({
417
484
  ...common,
@@ -442,7 +509,7 @@ var PropMeta = z.union([
442
509
  InlineCheck,
443
510
  File,
444
511
  Url,
445
- ObjectType,
512
+ Json,
446
513
  Date,
447
514
  Action
448
515
  ]);
@@ -618,50 +685,15 @@ var generateDataSources = ({
618
685
  }
619
686
  }
620
687
  for (const prop of props.values()) {
621
- if (prop.type === "dataSource") {
622
- const dataSource = dataSources.get(prop.value);
623
- if (dataSource?.type !== "expression") {
624
- continue;
625
- }
626
- const name = scope.getName(prop.id, prop.name);
627
- output.set(prop.id, name);
628
- const code = validateExpression(dataSource.code, {
629
- optional: true,
630
- transformIdentifier: (identifier) => {
631
- const depId = decodeDataSourceVariable(identifier);
632
- const dep = depId ? dataSources.get(depId) : void 0;
633
- if (dep) {
634
- return scope.getName(dep.id, dep.name);
635
- }
636
- console.error(`Unknown dependency "${identifier}"`);
637
- return identifier;
638
- }
639
- });
640
- body += `let ${name} = (${code});
641
- `;
642
- }
643
- if (prop.type === "expression") {
644
- const name = scope.getName(prop.id, prop.name);
645
- output.set(prop.id, name);
646
- const code = validateExpression(prop.value, {
647
- transformIdentifier: (identifier) => {
648
- const depId = decodeDataSourceVariable(identifier);
649
- const dep = depId ? dataSources.get(depId) : void 0;
650
- if (dep) {
651
- return scope.getName(dep.id, dep.name);
652
- }
653
- console.error(`Unknown dependency "${identifier}"`);
654
- return identifier;
655
- }
656
- });
657
- body += `let ${name} = (${code});
658
- `;
688
+ if (prop.type === "parameter") {
689
+ output.delete(prop.value);
690
+ variables.delete(prop.value);
659
691
  }
660
692
  if (prop.type === "action") {
661
693
  const name = scope.getName(prop.id, prop.name);
662
694
  output.set(prop.id, name);
663
695
  const setters = /* @__PURE__ */ new Set();
664
- let args = void 0;
696
+ let args = [];
665
697
  let newCode = "";
666
698
  for (const value of prop.value) {
667
699
  args = value.args;
@@ -688,9 +720,6 @@ var generateDataSources = ({
688
720
  newCode += `
689
721
  `;
690
722
  }
691
- if (args === void 0) {
692
- continue;
693
- }
694
723
  if (typed) {
695
724
  args = args.map((arg) => `${arg}: any`);
696
725
  }
@@ -1093,87 +1122,6 @@ var WsComponentMeta = z3.object({
1093
1122
  order: z3.number().optional()
1094
1123
  });
1095
1124
 
1096
- // src/props.ts
1097
- var normalizeProps = ({
1098
- props,
1099
- assetBaseUrl,
1100
- assets,
1101
- pages
1102
- }) => {
1103
- const newProps = [];
1104
- for (const prop of props) {
1105
- if (prop.type === "asset") {
1106
- const assetId = prop.value;
1107
- const asset = assets.get(assetId);
1108
- if (asset === void 0) {
1109
- continue;
1110
- }
1111
- newProps.push({
1112
- id: prop.id,
1113
- name: prop.name,
1114
- required: prop.required,
1115
- instanceId: prop.instanceId,
1116
- type: "string",
1117
- value: `${assetBaseUrl}${asset.name}`
1118
- });
1119
- continue;
1120
- }
1121
- if (prop.type === "page") {
1122
- let page;
1123
- let idProp;
1124
- if (typeof prop.value === "string") {
1125
- const pageId = prop.value;
1126
- page = pages.get(pageId);
1127
- } else {
1128
- const { pageId, instanceId } = prop.value;
1129
- page = pages.get(pageId);
1130
- idProp = props.find(
1131
- (prop2) => prop2.instanceId === instanceId && prop2.name === "id"
1132
- );
1133
- }
1134
- if (page === void 0) {
1135
- continue;
1136
- }
1137
- const url = new URL(page.path, "https://any-valid.url");
1138
- let value = url.pathname;
1139
- if (idProp?.type === "string") {
1140
- const hash = idProp.value;
1141
- url.hash = encodeURIComponent(hash);
1142
- value = `${url.pathname}${url.hash}`;
1143
- }
1144
- newProps.push({
1145
- id: prop.id,
1146
- name: prop.name,
1147
- required: prop.required,
1148
- instanceId: prop.instanceId,
1149
- type: "string",
1150
- value
1151
- });
1152
- continue;
1153
- }
1154
- newProps.push(prop);
1155
- }
1156
- return newProps;
1157
- };
1158
- var getPropsByInstanceId = (props) => {
1159
- const propsByInstanceId = /* @__PURE__ */ new Map();
1160
- for (const prop of props.values()) {
1161
- let instanceProps = propsByInstanceId.get(prop.instanceId);
1162
- if (instanceProps === void 0) {
1163
- instanceProps = [];
1164
- propsByInstanceId.set(prop.instanceId, instanceProps);
1165
- }
1166
- instanceProps.push(prop);
1167
- }
1168
- return propsByInstanceId;
1169
- };
1170
- var getInstanceIdFromComponentProps = (props) => {
1171
- return props[idAttribute];
1172
- };
1173
- var getIndexWithinAncestorFromComponentProps = (props) => {
1174
- return props[indexAttribute];
1175
- };
1176
-
1177
1125
  // src/instance-utils.ts
1178
1126
  var getIndexesWithinAncestors = (metas, instances, rootIds) => {
1179
1127
  const ancestors = /* @__PURE__ */ new Set();
@@ -1265,6 +1213,43 @@ var generateUtilsExport = (siteData) => {
1265
1213
 
1266
1214
  // src/component-generator.ts
1267
1215
  import { parseComponentName } from "@webstudio-is/sdk";
1216
+ var generatePropValue = ({
1217
+ scope,
1218
+ prop,
1219
+ dataSources
1220
+ }) => {
1221
+ if (prop.type === "asset" || prop.type === "page") {
1222
+ return;
1223
+ }
1224
+ if (prop.type === "string" || prop.type === "number" || prop.type === "boolean" || prop.type === "string[]" || prop.type === "json") {
1225
+ return JSON.stringify(prop.value);
1226
+ }
1227
+ if (prop.type === "parameter") {
1228
+ const dataSource = dataSources.get(prop.value);
1229
+ if (dataSource === void 0) {
1230
+ return;
1231
+ }
1232
+ return scope.getName(dataSource.id, dataSource.name);
1233
+ }
1234
+ if (prop.type === "expression") {
1235
+ return validateExpression(prop.value, {
1236
+ // transpile to safely executable member expressions
1237
+ optional: true,
1238
+ transformIdentifier: (identifier) => {
1239
+ const depId = decodeDataSourceVariable(identifier);
1240
+ const dep = depId ? dataSources.get(depId) : void 0;
1241
+ if (dep) {
1242
+ return scope.getName(dep.id, dep.name);
1243
+ }
1244
+ return identifier;
1245
+ }
1246
+ });
1247
+ }
1248
+ if (prop.type === "action") {
1249
+ return scope.getName(prop.id, prop.name);
1250
+ }
1251
+ prop;
1252
+ };
1268
1253
  var generateJsxElement = ({
1269
1254
  scope,
1270
1255
  instance,
@@ -1273,7 +1258,6 @@ var generateJsxElement = ({
1273
1258
  indexesWithinAncestors,
1274
1259
  children
1275
1260
  }) => {
1276
- let conditionVariableName;
1277
1261
  let generatedProps = "";
1278
1262
  generatedProps += `
1279
1263
  ${idAttribute}=${JSON.stringify(instance.id)}`;
@@ -1286,93 +1270,72 @@ ${componentAttribute}=${JSON.stringify(
1286
1270
  generatedProps += `
1287
1271
  ${indexAttribute}="${index}"`;
1288
1272
  }
1273
+ let conditionValue;
1274
+ let collectionDataValue;
1275
+ let collectionItemValue;
1289
1276
  for (const prop of props.values()) {
1290
1277
  if (prop.instanceId !== instance.id) {
1291
1278
  continue;
1292
1279
  }
1280
+ const propValue = generatePropValue({ scope, prop, dataSources });
1293
1281
  if (prop.name === showAttribute) {
1294
- if (prop.type === "boolean" && prop.value === false) {
1295
- return "";
1296
- }
1297
- if (prop.type === "dataSource") {
1298
- const dataSourceId = prop.value;
1299
- const dataSource = dataSources.get(dataSourceId);
1300
- if (dataSource === void 0) {
1301
- continue;
1302
- }
1303
- if (dataSource.type === "variable") {
1304
- conditionVariableName = scope.getName(dataSource.id, dataSource.name);
1305
- }
1306
- if (dataSource.type === "expression") {
1307
- conditionVariableName = scope.getName(prop.id, prop.name);
1308
- }
1282
+ if (propValue === "true") {
1283
+ continue;
1309
1284
  }
1310
- if (prop.type === "expression") {
1311
- conditionVariableName = scope.getName(prop.id, prop.name);
1285
+ if (propValue === "false") {
1286
+ return "";
1312
1287
  }
1288
+ conditionValue = propValue;
1313
1289
  continue;
1314
1290
  }
1315
- if (prop.type === "string" || prop.type === "number" || prop.type === "boolean" || prop.type === "string[]" || prop.type === "json") {
1316
- generatedProps += `
1317
- ${prop.name}={${JSON.stringify(prop.value)}}`;
1318
- continue;
1319
- }
1320
- if (prop.type === "asset" || prop.type === "page") {
1321
- continue;
1322
- }
1323
- if (prop.type === "dataSource") {
1324
- const dataSourceId = prop.value;
1325
- const dataSource = dataSources.get(dataSourceId);
1326
- if (dataSource === void 0) {
1327
- continue;
1291
+ if (instance.component === collectionComponent) {
1292
+ if (prop.name === "data") {
1293
+ collectionDataValue = propValue;
1328
1294
  }
1329
- if (dataSource.type === "variable") {
1330
- const dataSourceVariable = scope.getName(
1331
- dataSource.id,
1332
- dataSource.name
1333
- );
1334
- generatedProps += `
1335
- ${prop.name}={${dataSourceVariable}}`;
1336
- }
1337
- if (dataSource.type === "expression") {
1338
- const dataSourceVariable = scope.getName(prop.id, prop.name);
1339
- generatedProps += `
1340
- ${prop.name}={${dataSourceVariable}}`;
1295
+ if (prop.name === "item") {
1296
+ collectionItemValue = propValue;
1341
1297
  }
1342
1298
  continue;
1343
1299
  }
1344
- if (prop.type === "expression") {
1345
- const propVariable = scope.getName(prop.id, prop.name);
1300
+ if (propValue !== void 0) {
1346
1301
  generatedProps += `
1347
- ${prop.name}={${propVariable}}`;
1348
- continue;
1302
+ ${prop.name}={${propValue}}`;
1349
1303
  }
1350
- if (prop.type === "action") {
1351
- const propVariable = scope.getName(prop.id, prop.name);
1352
- generatedProps += `
1353
- ${prop.name}={${propVariable}}`;
1354
- continue;
1355
- }
1356
- prop;
1357
1304
  }
1358
1305
  let generatedElement = "";
1359
- if (conditionVariableName) {
1360
- generatedElement += `{${conditionVariableName} &&
1306
+ if (conditionValue) {
1307
+ generatedElement += `{(${conditionValue}) &&
1361
1308
  `;
1362
1309
  }
1363
- const [_namespace, shortName] = parseComponentName(instance.component);
1364
- const componentVariable = scope.getName(instance.component, shortName);
1365
- if (instance.children.length === 0) {
1366
- generatedElement += `<${componentVariable}${generatedProps} />
1310
+ if (instance.component === collectionComponent) {
1311
+ if (collectionDataValue === void 0 || collectionItemValue === void 0) {
1312
+ return "";
1313
+ }
1314
+ const indexVariable = scope.getName(`${instance.id}-index`, "index");
1315
+ generatedElement += `{${collectionDataValue}.map((${collectionItemValue}, ${indexVariable}) =>
1367
1316
  `;
1368
- } else {
1369
- generatedElement += `<${componentVariable}${generatedProps}>
1317
+ generatedElement += `<Fragment key={${indexVariable}}>
1370
1318
  `;
1371
1319
  generatedElement += children;
1372
- generatedElement += `</${componentVariable}>
1320
+ generatedElement += `</Fragment>
1321
+ `;
1322
+ generatedElement += `)}
1373
1323
  `;
1324
+ } else {
1325
+ const [_namespace, shortName] = parseComponentName(instance.component);
1326
+ const componentVariable = scope.getName(instance.component, shortName);
1327
+ if (instance.children.length === 0) {
1328
+ generatedElement += `<${componentVariable}${generatedProps} />
1329
+ `;
1330
+ } else {
1331
+ generatedElement += `<${componentVariable}${generatedProps}>
1332
+ `;
1333
+ generatedElement += children;
1334
+ generatedElement += `</${componentVariable}>
1335
+ `;
1336
+ }
1374
1337
  }
1375
- if (conditionVariableName) {
1338
+ if (conditionValue) {
1376
1339
  generatedElement += `}
1377
1340
  `;
1378
1341
  }
@@ -1459,10 +1422,10 @@ var generatePageComponent = ({
1459
1422
  props,
1460
1423
  dataSources,
1461
1424
  indexesWithinAncestors
1462
- }) + "{props.scripts}\n"
1425
+ })
1463
1426
  });
1464
1427
  let generatedComponent = "";
1465
- generatedComponent += `const Page = (props: { scripts?: ReactNode }) => {
1428
+ generatedComponent += `const Page = () => {
1466
1429
  `;
1467
1430
  generatedComponent += `${generatedDataSources}`;
1468
1431
  generatedComponent += `return ${generatedJsx}`;
@@ -1481,6 +1444,7 @@ export {
1481
1444
  WsEmbedTemplate,
1482
1445
  addGlobalRules,
1483
1446
  collapsedAttribute,
1447
+ collectionComponent,
1484
1448
  componentAttribute,
1485
1449
  componentCategories,
1486
1450
  createElementsTree,
@@ -1506,7 +1470,6 @@ export {
1506
1470
  indexAttribute,
1507
1471
  namespaceMeta,
1508
1472
  normalizeProps,
1509
- renderWebstudioComponentChildren,
1510
1473
  selectorIdAttribute,
1511
1474
  showAttribute,
1512
1475
  stateCategories,
@@ -60,7 +60,7 @@ export declare const generateJsxElement: ({ scope, instance, props, dataSources,
60
60
  required?: boolean | undefined;
61
61
  } | {
62
62
  value: string;
63
- type: "dataSource";
63
+ type: "parameter";
64
64
  name: string;
65
65
  id: string;
66
66
  instanceId: string;
@@ -105,20 +105,10 @@ export declare const generateJsxElement: ({ scope, instance, props, dataSources,
105
105
  name: string;
106
106
  id: string;
107
107
  scopeInstanceId?: string | undefined;
108
- } | {
109
- code: string;
110
- type: "expression";
111
- name: string;
112
- id: string;
113
- scopeInstanceId?: string | undefined;
114
108
  }>;
115
109
  indexesWithinAncestors: IndexesWithinAncestors;
116
110
  children: string;
117
111
  }) => string;
118
- /**
119
- * Jsx element and children are generated separately to be able
120
- * to inject some scripts into Body if necessary
121
- */
122
112
  export declare const generateJsxChildren: ({ scope, children, instances, props, dataSources, indexesWithinAncestors, }: {
123
113
  scope: Scope;
124
114
  children: Instance["children"];
@@ -192,7 +182,7 @@ export declare const generateJsxChildren: ({ scope, children, instances, props,
192
182
  required?: boolean | undefined;
193
183
  } | {
194
184
  value: string;
195
- type: "dataSource";
185
+ type: "parameter";
196
186
  name: string;
197
187
  id: string;
198
188
  instanceId: string;
@@ -237,12 +227,6 @@ export declare const generateJsxChildren: ({ scope, children, instances, props,
237
227
  name: string;
238
228
  id: string;
239
229
  scopeInstanceId?: string | undefined;
240
- } | {
241
- code: string;
242
- type: "expression";
243
- name: string;
244
- id: string;
245
- scopeInstanceId?: string | undefined;
246
230
  }>;
247
231
  indexesWithinAncestors: IndexesWithinAncestors;
248
232
  }) => string;
@@ -319,7 +303,7 @@ export declare const generatePageComponent: ({ scope, rootInstanceId, instances,
319
303
  required?: boolean | undefined;
320
304
  } | {
321
305
  value: string;
322
- type: "dataSource";
306
+ type: "parameter";
323
307
  name: string;
324
308
  id: string;
325
309
  instanceId: string;
@@ -364,12 +348,6 @@ export declare const generatePageComponent: ({ scope, rootInstanceId, instances,
364
348
  name: string;
365
349
  id: string;
366
350
  scopeInstanceId?: string | undefined;
367
- } | {
368
- code: string;
369
- type: "expression";
370
- name: string;
371
- id: string;
372
- scopeInstanceId?: string | undefined;
373
351
  }>;
374
352
  indexesWithinAncestors: IndexesWithinAncestors;
375
353
  }) => string;
@@ -325,24 +325,24 @@ declare const WsComponentPropsMeta: z.ZodObject<{
325
325
  label?: string | undefined;
326
326
  description?: string | undefined;
327
327
  }>, z.ZodObject<{
328
- control: z.ZodLiteral<"object">;
329
- type: z.ZodLiteral<"Record<string, string>">;
330
- defaultValue: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
328
+ control: z.ZodLiteral<"json">;
329
+ type: z.ZodLiteral<"json">;
330
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
331
331
  label: z.ZodOptional<z.ZodString>;
332
332
  description: z.ZodOptional<z.ZodString>;
333
333
  required: z.ZodBoolean;
334
334
  }, "strip", z.ZodTypeAny, {
335
- type: "Record<string, string>";
335
+ type: "json";
336
336
  required: boolean;
337
- control: "object";
338
- defaultValue?: Record<string, string> | undefined;
337
+ control: "json";
338
+ defaultValue?: unknown;
339
339
  label?: string | undefined;
340
340
  description?: string | undefined;
341
341
  }, {
342
- type: "Record<string, string>";
342
+ type: "json";
343
343
  required: boolean;
344
- control: "object";
345
- defaultValue?: Record<string, string> | undefined;
344
+ control: "json";
345
+ defaultValue?: unknown;
346
346
  label?: string | undefined;
347
347
  description?: string | undefined;
348
348
  }>, z.ZodObject<{
@@ -498,10 +498,10 @@ declare const WsComponentPropsMeta: z.ZodObject<{
498
498
  label?: string | undefined;
499
499
  description?: string | undefined;
500
500
  } | {
501
- type: "Record<string, string>";
501
+ type: "json";
502
502
  required: boolean;
503
- control: "object";
504
- defaultValue?: Record<string, string> | undefined;
503
+ control: "json";
504
+ defaultValue?: unknown;
505
505
  label?: string | undefined;
506
506
  description?: string | undefined;
507
507
  } | {
@@ -629,10 +629,10 @@ declare const WsComponentPropsMeta: z.ZodObject<{
629
629
  label?: string | undefined;
630
630
  description?: string | undefined;
631
631
  } | {
632
- type: "Record<string, string>";
632
+ type: "json";
633
633
  required: boolean;
634
- control: "object";
635
- defaultValue?: Record<string, string> | undefined;
634
+ control: "json";
635
+ defaultValue?: unknown;
636
636
  label?: string | undefined;
637
637
  description?: string | undefined;
638
638
  } | {
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import { componentAttribute, idAttribute } from "../tree";
2
+ import { componentAttribute, idAttribute } from "../props";
3
3
  export type AnyComponent = React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & {
4
4
  [componentAttribute]: string;
5
5
  [idAttribute]: string;
@@ -0,0 +1 @@
1
+ export declare const collectionComponent = "ws:component";
@@ -2262,7 +2262,7 @@ export declare const generateDataFromEmbedTemplate: (treeTemplate: ({
2262
2262
  required?: boolean | undefined;
2263
2263
  } | {
2264
2264
  value: string;
2265
- type: "dataSource";
2265
+ type: "parameter";
2266
2266
  name: string;
2267
2267
  id: string;
2268
2268
  instanceId: string;
@@ -2286,7 +2286,7 @@ export declare const generateDataFromEmbedTemplate: (treeTemplate: ({
2286
2286
  instanceId: string;
2287
2287
  required?: boolean | undefined;
2288
2288
  })[];
2289
- dataSources: ({
2289
+ dataSources: {
2290
2290
  value: {
2291
2291
  value: number;
2292
2292
  type: "number";
@@ -2307,13 +2307,7 @@ export declare const generateDataFromEmbedTemplate: (treeTemplate: ({
2307
2307
  name: string;
2308
2308
  id: string;
2309
2309
  scopeInstanceId?: string | undefined;
2310
- } | {
2311
- code: string;
2312
- type: "expression";
2313
- name: string;
2314
- id: string;
2315
- scopeInstanceId?: string | undefined;
2316
- })[];
2310
+ }[];
2317
2311
  styleSourceSelections: {
2318
2312
  values: string[];
2319
2313
  instanceId: string;
@@ -39,12 +39,6 @@ export declare const generateDataSources: ({ scope, typed, dataSources, props, }
39
39
  name: string;
40
40
  id: string;
41
41
  scopeInstanceId?: string | undefined;
42
- } | {
43
- code: string;
44
- type: "expression";
45
- name: string;
46
- id: string;
47
- scopeInstanceId?: string | undefined;
48
42
  }>;
49
43
  props: Map<string, {
50
44
  value: number;
@@ -103,7 +97,7 @@ export declare const generateDataSources: ({ scope, typed, dataSources, props, }
103
97
  required?: boolean | undefined;
104
98
  } | {
105
99
  value: string;
106
- type: "dataSource";
100
+ type: "parameter";
107
101
  name: string;
108
102
  id: string;
109
103
  instanceId: string;
@@ -1,11 +1,12 @@
1
1
  export * from "./css/index";
2
2
  export * from "./tree/index";
3
3
  export * from "./app/index";
4
+ export * from "./core-components";
4
5
  export * from "./components/components-utils";
5
6
  export { PropMeta } from "./prop-meta";
6
7
  export { type WsComponentPropsMeta, type ComponentState, type PresetStyle, WsComponentMeta, componentCategories, stateCategories, defaultStates, } from "./components/component-meta";
7
8
  export * from "./embed-template";
8
- export { normalizeProps, getPropsByInstanceId, getInstanceIdFromComponentProps, getIndexWithinAncestorFromComponentProps, } from "./props";
9
+ export * from "./props";
9
10
  export { type Params, ReactSdkContext } from "./context";
10
11
  export { validateExpression, encodeDataSourceVariable, decodeDataSourceVariable, generateDataSources, } from "./expression";
11
12
  export { getIndexesWithinAncestors } from "./instance-utils";
@@ -330,24 +330,24 @@ export declare const PropMeta: z.ZodUnion<[z.ZodObject<{
330
330
  label?: string | undefined;
331
331
  description?: string | undefined;
332
332
  }>, z.ZodObject<{
333
- control: z.ZodLiteral<"object">;
334
- type: z.ZodLiteral<"Record<string, string>">;
335
- defaultValue: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
333
+ control: z.ZodLiteral<"json">;
334
+ type: z.ZodLiteral<"json">;
335
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
336
336
  label: z.ZodOptional<z.ZodString>;
337
337
  description: z.ZodOptional<z.ZodString>;
338
338
  required: z.ZodBoolean;
339
339
  }, "strip", z.ZodTypeAny, {
340
- type: "Record<string, string>";
340
+ type: "json";
341
341
  required: boolean;
342
- control: "object";
343
- defaultValue?: Record<string, string> | undefined;
342
+ control: "json";
343
+ defaultValue?: unknown;
344
344
  label?: string | undefined;
345
345
  description?: string | undefined;
346
346
  }, {
347
- type: "Record<string, string>";
347
+ type: "json";
348
348
  required: boolean;
349
- control: "object";
350
- defaultValue?: Record<string, string> | undefined;
349
+ control: "json";
350
+ defaultValue?: unknown;
351
351
  label?: string | undefined;
352
352
  description?: string | undefined;
353
353
  }>, z.ZodObject<{
@@ -110,7 +110,7 @@ export declare const normalizeProps: ({ props, assetBaseUrl, assets, pages, }: {
110
110
  required?: boolean | undefined;
111
111
  } | {
112
112
  value: string;
113
- type: "dataSource";
113
+ type: "parameter";
114
114
  name: string;
115
115
  id: string;
116
116
  instanceId: string;
@@ -191,7 +191,7 @@ export declare const getPropsByInstanceId: (props: Map<string, {
191
191
  required?: boolean | undefined;
192
192
  } | {
193
193
  value: string;
194
- type: "dataSource";
194
+ type: "parameter";
195
195
  name: string;
196
196
  id: string;
197
197
  instanceId: string;
@@ -215,5 +215,11 @@ export declare const getPropsByInstanceId: (props: Map<string, {
215
215
  instanceId: string;
216
216
  required?: boolean | undefined;
217
217
  }>) => PropsByInstanceId;
218
+ export declare const idAttribute: "data-ws-id";
219
+ export declare const selectorIdAttribute: "data-ws-selector";
220
+ export declare const componentAttribute: "data-ws-component";
221
+ export declare const showAttribute: "data-ws-show";
222
+ export declare const indexAttribute: "data-ws-index";
223
+ export declare const collapsedAttribute: "data-ws-collapsed";
218
224
  export declare const getInstanceIdFromComponentProps: (props: Record<string, unknown>) => string;
219
225
  export declare const getIndexWithinAncestorFromComponentProps: (props: Record<string, unknown>) => string | undefined;
@@ -1,10 +1,15 @@
1
- import { type ForwardRefExoticComponent, type RefAttributes, type ReactNode } from "react";
1
+ import { type ForwardRefExoticComponent, type ReactNode, type RefAttributes } from "react";
2
2
  import type { Instance, Instances } from "@webstudio-is/sdk";
3
3
  import type { Components } from "../components/components-utils";
4
4
  import { type Params } from "../context";
5
- import type { WebstudioComponentProps } from "./webstudio-component";
6
5
  import type { ImageLoader } from "@webstudio-is/image";
7
- export declare const createElementsTree: ({ renderer, assetBaseUrl, imageBaseUrl, imageLoader, instances, rootInstanceId, Component, components, scripts, }: Params & {
6
+ export type WebstudioComponentProps = {
7
+ instance: Instance;
8
+ instanceSelector: Instance["id"][];
9
+ children: ReactNode;
10
+ components: Components;
11
+ };
12
+ export declare const createElementsTree: ({ renderer, assetBaseUrl, imageBaseUrl, imageLoader, instances, rootInstanceId, Component, components, }: Params & {
8
13
  instances: Map<string, {
9
14
  type: "instance";
10
15
  id: string;
@@ -22,5 +27,4 @@ export declare const createElementsTree: ({ renderer, assetBaseUrl, imageBaseUrl
22
27
  rootInstanceId: Instance["id"];
23
28
  Component: ForwardRefExoticComponent<WebstudioComponentProps & RefAttributes<HTMLElement>>;
24
29
  components: Components;
25
- scripts?: ReactNode;
26
30
  }) => import("react/jsx-runtime").JSX.Element | null;
@@ -1,2 +1 @@
1
1
  export * from "./create-elements-tree";
2
- export * from "./webstudio-component";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webstudio-is/react-sdk",
3
- "version": "0.117.0",
3
+ "version": "0.119.0",
4
4
  "description": "Webstudio JavaScript / TypeScript API",
5
5
  "author": "Webstudio <github@webstudio.is>",
6
6
  "homepage": "https://webstudio.is",
@@ -33,10 +33,10 @@
33
33
  "jsep": "^1.3.8",
34
34
  "nanoid": "^5.0.1",
35
35
  "title-case": "^4.1.0",
36
- "@webstudio-is/css-engine": "0.117.0",
37
- "@webstudio-is/image": "0.117.0",
38
- "@webstudio-is/fonts": "0.117.0",
39
- "@webstudio-is/sdk": "0.117.0"
36
+ "@webstudio-is/css-engine": "0.119.0",
37
+ "@webstudio-is/image": "0.119.0",
38
+ "@webstudio-is/fonts": "0.119.0",
39
+ "@webstudio-is/sdk": "0.119.0"
40
40
  },
41
41
  "exports": {
42
42
  ".": {
@@ -1,16 +0,0 @@
1
- /// <reference types="react" />
2
- import type { Instance } from "@webstudio-is/sdk";
3
- import type { Components } from "../components/components-utils";
4
- export declare const renderWebstudioComponentChildren: (children: Array<JSX.Element | string> | undefined) => Array<JSX.Element | string | Array<JSX.Element | string>> | undefined;
5
- export type WebstudioComponentProps = {
6
- instance: Instance;
7
- instanceSelector: Instance["id"][];
8
- children: Array<JSX.Element | string>;
9
- components: Components;
10
- };
11
- export declare const idAttribute: "data-ws-id";
12
- export declare const selectorIdAttribute: "data-ws-selector";
13
- export declare const componentAttribute: "data-ws-component";
14
- export declare const showAttribute: "data-ws-show";
15
- export declare const indexAttribute: "data-ws-index";
16
- export declare const collapsedAttribute: "data-ws-collapsed";