@webstudio-is/react-sdk 0.123.0 → 0.125.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/README.md CHANGED
@@ -1,4 +1,4 @@
1
1
  # Webstudio SDK
2
2
 
3
- Webstudio SDK is a TypeScript API that lets you use your Webstudio site or some components in your custom codebase or just render a complete Remix Document.
3
+ Webstudio SDK is a TypeScript API that lets you use your Webstudio project or some components in your custom codebase or just render a complete Remix Document.
4
4
  It is currently under development, but feel free to play with the the current [landing site](https://github.com/webstudio-is/webstudio-landing)
package/lib/index.js CHANGED
@@ -1,7 +1,61 @@
1
+ // src/remix.ts
2
+ var getRemixSegment = (segment) => {
3
+ if (segment === "*") {
4
+ return "$";
5
+ }
6
+ const match = segment.match(/^:(?<name>\w+)(?<modifier>\*|\?)?$/);
7
+ const name = match?.groups?.name;
8
+ const modifier = match?.groups?.modifier;
9
+ if (name) {
10
+ if (modifier === "*") {
11
+ return "$";
12
+ }
13
+ if (modifier === "?") {
14
+ return `($${name})`;
15
+ }
16
+ return `$${name}`;
17
+ }
18
+ return `[${segment}]`;
19
+ };
20
+ var generateRemixRoute = (pathname) => {
21
+ if (pathname.startsWith("/")) {
22
+ pathname = pathname.slice(1);
23
+ }
24
+ if (pathname === "") {
25
+ return `_index`;
26
+ }
27
+ const base = pathname.split("/").map(getRemixSegment).join(".");
28
+ const tail = pathname.endsWith("*") ? "" : "._index";
29
+ return `${base}${tail}`;
30
+ };
31
+ var generateRemixParams = (pathname) => {
32
+ const name = pathname.match(/:(?<name>\w+)\*$/)?.groups?.name;
33
+ let generated = "";
34
+ generated += `export const getRemixParams = ({ ...params }: Params): Params => {
35
+ `;
36
+ if (name) {
37
+ generated += ` params["${name}"] = params["*"]
38
+ `;
39
+ generated += ` delete params["*"]
40
+ `;
41
+ }
42
+ if (pathname.endsWith("/*")) {
43
+ generated += ` params[0] = params["*"]
44
+ `;
45
+ generated += ` delete params["*"]
46
+ `;
47
+ }
48
+ generated += ` return params
49
+ `;
50
+ generated += `}
51
+ `;
52
+ return generated;
53
+ };
54
+
1
55
  // src/css/global-rules.ts
2
56
  import { getFontFaces } from "@webstudio-is/fonts";
3
- var addGlobalRules = (engine, { assets, assetBaseUrl }) => {
4
- engine.addPlaintextRule("html {margin: 0; display: grid; min-height: 100%}");
57
+ var addGlobalRules = (sheet, { assets, assetBaseUrl }) => {
58
+ sheet.addPlaintextRule("html {margin: 0; display: grid; min-height: 100%}");
5
59
  const fontAssets = [];
6
60
  for (const asset of assets.values()) {
7
61
  if (asset.type === "font") {
@@ -10,7 +64,7 @@ var addGlobalRules = (engine, { assets, assetBaseUrl }) => {
10
64
  }
11
65
  const fontFaces = getFontFaces(fontAssets, { assetBaseUrl });
12
66
  for (const fontFace of fontFaces) {
13
- engine.addFontFaceRule(fontFace);
67
+ sheet.addFontFaceRule(fontFace);
14
68
  }
15
69
  };
16
70
 
@@ -82,6 +136,7 @@ var componentAttribute = "data-ws-component";
82
136
  var showAttribute = "data-ws-show";
83
137
  var indexAttribute = "data-ws-index";
84
138
  var collapsedAttribute = "data-ws-collapsed";
139
+ var textContentAttribute = "data-ws-text-content";
85
140
  var getInstanceIdFromComponentProps = (props) => {
86
141
  return props[idAttribute];
87
142
  };
@@ -153,14 +208,16 @@ var getPresetStyleRules = (component, presetStyle) => {
153
208
  };
154
209
 
155
210
  // src/css/css.ts
156
- import { createCssEngine } from "@webstudio-is/css-engine";
157
- var createImageValueTransformer = (assets, options) => (styleValue) => {
211
+ import {
212
+ createRegularStyleSheet,
213
+ createAtomicStyleSheet
214
+ } from "@webstudio-is/css-engine";
215
+ var createImageValueTransformer = (assets, { assetBaseUrl }) => (styleValue) => {
158
216
  if (styleValue.type === "image" && styleValue.value.type === "asset") {
159
217
  const asset = assets.get(styleValue.value.value);
160
218
  if (asset === void 0) {
161
219
  return { type: "keyword", value: "none" };
162
220
  }
163
- const { assetBaseUrl } = options;
164
221
  const url = `${assetBaseUrl}${asset.name}`;
165
222
  return {
166
223
  type: "image",
@@ -172,18 +229,17 @@ var createImageValueTransformer = (assets, options) => (styleValue) => {
172
229
  };
173
230
  }
174
231
  };
175
- var generateCssText = (data, options) => {
232
+ var generateCss = (data, { assetBaseUrl, atomic = false }) => {
176
233
  const assets = new Map(data.assets.map((asset) => [asset.id, asset]));
177
234
  const breakpoints = new Map(data.breakpoints);
178
235
  const styles = new Map(data.styles);
179
236
  const styleSourceSelections = new Map(data.styleSourceSelections);
180
- const engine = createCssEngine({ name: "ssr" });
181
- addGlobalRules(engine, {
182
- assets,
183
- assetBaseUrl: options.assetBaseUrl
184
- });
237
+ const classesMap = /* @__PURE__ */ new Map();
238
+ const regularSheet = createRegularStyleSheet({ name: "ssr-regular" });
239
+ const atomicSheet = atomic ? createAtomicStyleSheet({ name: "ssr-atomic" }) : void 0;
240
+ addGlobalRules(regularSheet, { assets, assetBaseUrl });
185
241
  for (const breakpoint of breakpoints.values()) {
186
- engine.addMediaRule(breakpoint.id, breakpoint);
242
+ (atomicSheet ?? regularSheet).addMediaRule(breakpoint.id, breakpoint);
187
243
  }
188
244
  for (const [component, meta] of data.componentMetas) {
189
245
  const presetStyle = meta.presetStyle;
@@ -192,21 +248,36 @@ var generateCssText = (data, options) => {
192
248
  }
193
249
  const rules = getPresetStyleRules(component, presetStyle);
194
250
  for (const [selector, style] of rules) {
195
- engine.addStyleRule(selector, { style });
251
+ regularSheet.addStyleRule({ style }, selector);
196
252
  }
197
253
  }
198
254
  const styleRules = getStyleRules(styles, styleSourceSelections);
255
+ const imageValueTransformer = createImageValueTransformer(assets, {
256
+ assetBaseUrl
257
+ });
199
258
  for (const { breakpointId, instanceId, state, style } of styleRules) {
200
- engine.addStyleRule(
259
+ if (atomicSheet) {
260
+ const { classes } = atomicSheet.addStyleRule(
261
+ { breakpoint: breakpointId, style },
262
+ state,
263
+ imageValueTransformer
264
+ );
265
+ classesMap.set(instanceId, [
266
+ ...classesMap.get(instanceId) ?? [],
267
+ ...classes
268
+ ]);
269
+ continue;
270
+ }
271
+ regularSheet.addStyleRule(
272
+ { breakpoint: breakpointId, style },
201
273
  `[${idAttribute}="${instanceId}"]${state ?? ""}`,
202
- {
203
- breakpoint: breakpointId,
204
- style
205
- },
206
- createImageValueTransformer(assets, options)
274
+ imageValueTransformer
207
275
  );
208
276
  }
209
- return engine.cssText;
277
+ return {
278
+ cssText: regularSheet.cssText + (atomicSheet?.cssText ?? ""),
279
+ classesMap
280
+ };
210
281
  };
211
282
 
212
283
  // src/tree/create-elements-tree.tsx
@@ -280,18 +351,25 @@ var createInstanceChildrenElements = ({
280
351
  elements.push(renderText(child.value));
281
352
  continue;
282
353
  }
283
- const childInstance = instances.get(child.value);
284
- if (childInstance === void 0) {
354
+ if (child.type === "expression") {
285
355
  continue;
286
356
  }
287
- const childInstanceSelector = [child.value, ...instanceSelector];
288
- const element = createInstanceElement({
289
- instance: childInstance,
290
- instanceSelector: childInstanceSelector,
291
- Component,
292
- components
293
- });
294
- elements.push(element);
357
+ if (child.type === "id") {
358
+ const childInstance = instances.get(child.value);
359
+ if (childInstance === void 0) {
360
+ continue;
361
+ }
362
+ const childInstanceSelector = [child.value, ...instanceSelector];
363
+ const element = createInstanceElement({
364
+ instance: childInstance,
365
+ instanceSelector: childInstanceSelector,
366
+ Component,
367
+ components
368
+ });
369
+ elements.push(element);
370
+ continue;
371
+ }
372
+ child;
295
373
  }
296
374
  if (elements.length === 0) {
297
375
  return;
@@ -333,7 +411,7 @@ var Root = ({
333
411
  };
334
412
 
335
413
  // src/core-components.ts
336
- import { ListIcon } from "@webstudio-is/icons/svg";
414
+ import { ListViewIcon } from "@webstudio-is/icons/svg";
337
415
  var portalComponent = "Slot";
338
416
  var collectionComponent = "ws:collection";
339
417
  var collectionMeta = {
@@ -341,7 +419,7 @@ var collectionMeta = {
341
419
  order: 7,
342
420
  type: "container",
343
421
  label: "Collection",
344
- icon: ListIcon,
422
+ icon: ListViewIcon,
345
423
  stylable: false,
346
424
  template: [
347
425
  {
@@ -520,6 +598,12 @@ var Action = z.object({
520
598
  type: z.literal("action"),
521
599
  defaultValue: z.undefined().optional()
522
600
  });
601
+ var TextContent = z.object({
602
+ ...common,
603
+ control: z.literal("textContent"),
604
+ type: z.literal("string"),
605
+ defaultValue: z.string().optional()
606
+ });
523
607
  var PropMeta = z.union([
524
608
  Number,
525
609
  Range,
@@ -537,7 +621,8 @@ var PropMeta = z.union([
537
621
  Url,
538
622
  Json,
539
623
  Date,
540
- Action
624
+ Action,
625
+ TextContent
541
626
  ]);
542
627
 
543
628
  // src/components/component-meta.ts
@@ -689,6 +774,26 @@ var decodeDataSourceVariable = (name) => {
689
774
  }
690
775
  return;
691
776
  };
777
+ var generateExpression = ({
778
+ expression,
779
+ dataSources,
780
+ scope
781
+ }) => {
782
+ return validateExpression(expression, {
783
+ // parse any expression
784
+ effectful: true,
785
+ // transpile to safely executable member expressions
786
+ optional: true,
787
+ transformIdentifier: (identifier) => {
788
+ const depId = decodeDataSourceVariable(identifier);
789
+ const dep = depId ? dataSources.get(depId) : void 0;
790
+ if (dep) {
791
+ return scope.getName(dep.id, dep.name);
792
+ }
793
+ return identifier;
794
+ }
795
+ });
796
+ };
692
797
  var generateDataSources = ({
693
798
  scope,
694
799
  typed = false,
@@ -1276,17 +1381,10 @@ var generatePropValue = ({
1276
1381
  return scope.getName(dataSource.id, dataSource.name);
1277
1382
  }
1278
1383
  if (prop.type === "expression") {
1279
- return validateExpression(prop.value, {
1280
- // transpile to safely executable member expressions
1281
- optional: true,
1282
- transformIdentifier: (identifier) => {
1283
- const depId = decodeDataSourceVariable(identifier);
1284
- const dep = depId ? dataSources.get(depId) : void 0;
1285
- if (dep) {
1286
- return scope.getName(dep.id, dep.name);
1287
- }
1288
- return identifier;
1289
- }
1384
+ return generateExpression({
1385
+ expression: prop.value,
1386
+ dataSources,
1387
+ scope
1290
1388
  });
1291
1389
  }
1292
1390
  if (prop.type === "action") {
@@ -1300,7 +1398,8 @@ var generateJsxElement = ({
1300
1398
  props,
1301
1399
  dataSources,
1302
1400
  indexesWithinAncestors,
1303
- children
1401
+ children,
1402
+ classesMap
1304
1403
  }) => {
1305
1404
  let generatedProps = "";
1306
1405
  generatedProps += `
@@ -1317,6 +1416,7 @@ ${indexAttribute}="${index}"`;
1317
1416
  let conditionValue;
1318
1417
  let collectionDataValue;
1319
1418
  let collectionItemValue;
1419
+ const classes = Array.from(classesMap?.get(instance.id) ?? []);
1320
1420
  for (const prop of props.values()) {
1321
1421
  if (prop.instanceId !== instance.id) {
1322
1422
  continue;
@@ -1341,11 +1441,21 @@ ${indexAttribute}="${index}"`;
1341
1441
  }
1342
1442
  continue;
1343
1443
  }
1444
+ if (prop.name === "className") {
1445
+ if (prop.type === "string") {
1446
+ classes.push(prop.value);
1447
+ }
1448
+ continue;
1449
+ }
1344
1450
  if (propValue !== void 0) {
1345
1451
  generatedProps += `
1346
1452
  ${prop.name}={${propValue}}`;
1347
1453
  }
1348
1454
  }
1455
+ if (classes.length !== 0) {
1456
+ generatedProps += `
1457
+ className=${JSON.stringify(classes.join(" "))}`;
1458
+ }
1349
1459
  let generatedElement = "";
1350
1460
  if (conditionValue) {
1351
1461
  generatedElement += `{(${conditionValue}) &&
@@ -1356,7 +1466,7 @@ ${prop.name}={${propValue}}`;
1356
1466
  return "";
1357
1467
  }
1358
1468
  const indexVariable = scope.getName(`${instance.id}-index`, "index");
1359
- generatedElement += `{${collectionDataValue}.map((${collectionItemValue}, ${indexVariable}) =>
1469
+ generatedElement += `{${collectionDataValue}?.map((${collectionItemValue}: any, ${indexVariable}: number) =>
1360
1470
  `;
1361
1471
  generatedElement += `<Fragment key={${indexVariable}}>
1362
1472
  `;
@@ -1391,7 +1501,8 @@ var generateJsxChildren = ({
1391
1501
  instances,
1392
1502
  props,
1393
1503
  dataSources,
1394
- indexesWithinAncestors
1504
+ indexesWithinAncestors,
1505
+ classesMap
1395
1506
  }) => {
1396
1507
  let generatedChildren = "";
1397
1508
  for (const child of children) {
@@ -1401,6 +1512,16 @@ var generateJsxChildren = ({
1401
1512
  `);
1402
1513
  continue;
1403
1514
  }
1515
+ if (child.type === "expression") {
1516
+ const expression = generateExpression({
1517
+ expression: child.value,
1518
+ dataSources,
1519
+ scope
1520
+ });
1521
+ generatedChildren = `{${expression}}
1522
+ `;
1523
+ continue;
1524
+ }
1404
1525
  if (child.type === "id") {
1405
1526
  const instanceId = child.value;
1406
1527
  const instance = instances.get(instanceId);
@@ -1413,7 +1534,9 @@ var generateJsxChildren = ({
1413
1534
  props,
1414
1535
  dataSources,
1415
1536
  indexesWithinAncestors,
1537
+ classesMap,
1416
1538
  children: generateJsxChildren({
1539
+ classesMap,
1417
1540
  scope,
1418
1541
  children: instance.children,
1419
1542
  instances,
@@ -1430,27 +1553,52 @@ var generateJsxChildren = ({
1430
1553
  };
1431
1554
  var generatePageComponent = ({
1432
1555
  scope,
1433
- rootInstanceId,
1556
+ page,
1434
1557
  instances,
1435
1558
  props,
1436
1559
  dataSources,
1437
- indexesWithinAncestors
1560
+ indexesWithinAncestors,
1561
+ classesMap
1438
1562
  }) => {
1439
- const instance = instances.get(rootInstanceId);
1563
+ const instance = instances.get(page.rootInstanceId);
1440
1564
  if (instance === void 0) {
1441
1565
  return "";
1442
1566
  }
1443
- const { variables, body: dataSourcesBody } = generateDataSources({
1567
+ const { body: dataSourcesBody } = generateDataSources({
1444
1568
  typed: true,
1445
1569
  scope,
1446
1570
  dataSources,
1447
1571
  props
1448
1572
  });
1449
1573
  let generatedDataSources = "";
1450
- for (const { valueName, setterName, initialValue } of variables.values()) {
1451
- const initialValueString = JSON.stringify(initialValue);
1452
- generatedDataSources += `let [${valueName}, ${setterName}] = useState<any>(${initialValueString})
1574
+ for (const dataSource of dataSources.values()) {
1575
+ if (dataSource.type === "variable") {
1576
+ const valueName = scope.getName(dataSource.id, dataSource.name);
1577
+ const setterName = scope.getName(
1578
+ `set$${dataSource.id}`,
1579
+ `set$${dataSource.name}`
1580
+ );
1581
+ const initialValue = dataSource.value.value;
1582
+ const initialValueString = JSON.stringify(initialValue);
1583
+ generatedDataSources += `let [${valueName}, ${setterName}] = useState<any>(${initialValueString})
1453
1584
  `;
1585
+ }
1586
+ if (dataSource.type === "parameter") {
1587
+ if (dataSource.id === page.pathVariableId) {
1588
+ const valueName = scope.getName(dataSource.id, dataSource.name);
1589
+ generatedDataSources += `let ${valueName} = _props.params
1590
+ `;
1591
+ }
1592
+ }
1593
+ if (dataSource.type === "resource") {
1594
+ const valueName = scope.getName(dataSource.id, dataSource.name);
1595
+ const resourceName = scope.getName(
1596
+ dataSource.resourceId,
1597
+ dataSource.name
1598
+ );
1599
+ generatedDataSources += `let ${valueName}: any = _props.resources["${resourceName}"]
1600
+ `;
1601
+ }
1454
1602
  }
1455
1603
  generatedDataSources += dataSourcesBody;
1456
1604
  const generatedJsx = generateJsxElement({
@@ -1459,17 +1607,23 @@ var generatePageComponent = ({
1459
1607
  props,
1460
1608
  dataSources,
1461
1609
  indexesWithinAncestors,
1610
+ classesMap,
1462
1611
  children: generateJsxChildren({
1463
1612
  scope,
1464
1613
  children: instance.children,
1465
1614
  instances,
1466
1615
  props,
1467
1616
  dataSources,
1468
- indexesWithinAncestors
1617
+ indexesWithinAncestors,
1618
+ classesMap
1469
1619
  })
1470
1620
  });
1471
1621
  let generatedComponent = "";
1472
- generatedComponent += `const Page = () => {
1622
+ generatedComponent += `type Params = Record<string, string | undefined>
1623
+ `;
1624
+ generatedComponent += `type Resources = Record<string, unknown>
1625
+ `;
1626
+ generatedComponent += `const Page = (_props: { params: Params, resources: Resources }) => {
1473
1627
  `;
1474
1628
  generatedComponent += `${generatedDataSources}`;
1475
1629
  generatedComponent += `return ${generatedJsx}`;
@@ -1477,6 +1631,112 @@ var generatePageComponent = ({
1477
1631
  `;
1478
1632
  return generatedComponent;
1479
1633
  };
1634
+
1635
+ // src/resources-generator.ts
1636
+ var generateResourcesLoader = ({
1637
+ scope,
1638
+ page,
1639
+ dataSources,
1640
+ resources
1641
+ }) => {
1642
+ let generatedVariables = "";
1643
+ let generatedOutput = "";
1644
+ let generatedLoaders = "";
1645
+ let hasResources = false;
1646
+ for (const dataSource of dataSources.values()) {
1647
+ if (dataSource.type === "variable") {
1648
+ const name = scope.getName(dataSource.id, dataSource.name);
1649
+ const value = JSON.stringify(dataSource.value.value);
1650
+ generatedVariables += `let ${name} = ${value}
1651
+ `;
1652
+ }
1653
+ if (dataSource.type === "parameter") {
1654
+ if (dataSource.id !== page.pathVariableId) {
1655
+ continue;
1656
+ }
1657
+ const name = scope.getName(dataSource.id, dataSource.name);
1658
+ generatedVariables += `const ${name} = _props.params
1659
+ `;
1660
+ }
1661
+ if (dataSource.type === "resource") {
1662
+ const resource = resources.get(dataSource.resourceId);
1663
+ if (resource === void 0) {
1664
+ continue;
1665
+ }
1666
+ hasResources = true;
1667
+ const resourceName = scope.getName(resource.id, dataSource.name);
1668
+ generatedOutput += `${resourceName},
1669
+ `;
1670
+ generatedLoaders += `loadResource({
1671
+ `;
1672
+ generatedLoaders += `id: "${resource.id}",
1673
+ `;
1674
+ generatedLoaders += `name: ${JSON.stringify(resource.name)},
1675
+ `;
1676
+ const url = generateExpression({
1677
+ expression: resource.url,
1678
+ dataSources,
1679
+ scope
1680
+ });
1681
+ generatedLoaders += `url: ${url},
1682
+ `;
1683
+ generatedLoaders += `method: "${resource.method}",
1684
+ `;
1685
+ generatedLoaders += `headers: [
1686
+ `;
1687
+ for (const header of resource.headers) {
1688
+ const value = generateExpression({
1689
+ expression: header.value,
1690
+ dataSources,
1691
+ scope
1692
+ });
1693
+ generatedLoaders += `{ name: "${header.name}", value: ${value} },
1694
+ `;
1695
+ }
1696
+ generatedLoaders += `],
1697
+ `;
1698
+ if (resource.body !== void 0 && resource.body.length > 0) {
1699
+ const body = generateExpression({
1700
+ expression: resource.body,
1701
+ dataSources,
1702
+ scope
1703
+ });
1704
+ generatedLoaders += `body: ${body},
1705
+ `;
1706
+ }
1707
+ generatedLoaders += `}),
1708
+ `;
1709
+ }
1710
+ }
1711
+ let generated = "";
1712
+ if (hasResources) {
1713
+ generated += `import { loadResource } from "@webstudio-is/sdk";
1714
+ `;
1715
+ }
1716
+ generated += `type Params = Record<string, string | undefined>
1717
+ `;
1718
+ generated += `export const loadResources = async (_props: { params: Params }) => {
1719
+ `;
1720
+ if (hasResources) {
1721
+ generated += generatedVariables;
1722
+ generated += `const [
1723
+ `;
1724
+ generated += generatedOutput;
1725
+ generated += `] = await Promise.all([
1726
+ `;
1727
+ generated += generatedLoaders;
1728
+ generated += `])
1729
+ `;
1730
+ }
1731
+ generated += `return {
1732
+ `;
1733
+ generated += generatedOutput;
1734
+ generated += `} as Record<string, unknown>
1735
+ `;
1736
+ generated += `}
1737
+ `;
1738
+ return generated;
1739
+ };
1480
1740
  export {
1481
1741
  EmbedTemplateInstance,
1482
1742
  EmbedTemplateProp,
@@ -1499,12 +1759,15 @@ export {
1499
1759
  decodeDataSourceVariable,
1500
1760
  defaultStates,
1501
1761
  encodeDataSourceVariable,
1502
- generateCssText,
1762
+ generateCss,
1503
1763
  generateDataFromEmbedTemplate,
1504
1764
  generateDataSources,
1505
1765
  generateJsxChildren,
1506
1766
  generateJsxElement,
1507
1767
  generatePageComponent,
1768
+ generateRemixParams,
1769
+ generateRemixRoute,
1770
+ generateResourcesLoader,
1508
1771
  generateUtilsExport,
1509
1772
  getClosestInstance,
1510
1773
  getIndexWithinAncestorFromComponentProps,
@@ -1520,5 +1783,6 @@ export {
1520
1783
  selectorIdAttribute,
1521
1784
  showAttribute,
1522
1785
  stateCategories,
1786
+ textContentAttribute,
1523
1787
  validateExpression
1524
1788
  };
@@ -1,6 +1,6 @@
1
1
  import { Outlet as DefaultOutlet } from "@remix-run/react";
2
2
  /**
3
- * We are using Outlet prop from index layout when user renders site from a subdomain.
3
+ * We are using Outlet prop from index layout when user renders project from a subdomain.
4
4
  */
5
5
  export declare const Root: ({ Outlet, }: {
6
6
  Outlet: typeof DefaultOutlet;
@@ -1,6 +1,6 @@
1
- import type { Instances, Instance, Props, Scope, DataSources } from "@webstudio-is/sdk";
1
+ import type { Instances, Instance, Props, Scope, DataSources, Page } from "@webstudio-is/sdk";
2
2
  import type { IndexesWithinAncestors } from "./instance-utils";
3
- export declare const generateJsxElement: ({ scope, instance, props, dataSources, indexesWithinAncestors, children, }: {
3
+ export declare const generateJsxElement: ({ scope, instance, props, dataSources, indexesWithinAncestors, children, classesMap, }: {
4
4
  scope: Scope;
5
5
  instance: Instance;
6
6
  props: Map<string, {
@@ -110,24 +110,34 @@ export declare const generateJsxElement: ({ scope, instance, props, dataSources,
110
110
  name: string;
111
111
  id: string;
112
112
  scopeInstanceId?: string | undefined;
113
+ } | {
114
+ type: "resource";
115
+ name: string;
116
+ id: string;
117
+ resourceId: string;
118
+ scopeInstanceId?: string | undefined;
113
119
  }>;
114
120
  indexesWithinAncestors: IndexesWithinAncestors;
115
121
  children: string;
122
+ classesMap?: Map<string, string[]> | undefined;
116
123
  }) => string;
117
- export declare const generateJsxChildren: ({ scope, children, instances, props, dataSources, indexesWithinAncestors, }: {
124
+ export declare const generateJsxChildren: ({ scope, children, instances, props, dataSources, indexesWithinAncestors, classesMap, }: {
118
125
  scope: Scope;
119
126
  children: Instance["children"];
120
127
  instances: Map<string, {
121
128
  type: "instance";
122
129
  id: string;
123
- component: string;
124
130
  children: ({
125
131
  value: string;
126
132
  type: "text";
127
133
  } | {
128
134
  value: string;
129
135
  type: "id";
136
+ } | {
137
+ value: string;
138
+ type: "expression";
130
139
  })[];
140
+ component: string;
131
141
  label?: string | undefined;
132
142
  }>;
133
143
  props: Map<string, {
@@ -237,23 +247,33 @@ export declare const generateJsxChildren: ({ scope, children, instances, props,
237
247
  name: string;
238
248
  id: string;
239
249
  scopeInstanceId?: string | undefined;
250
+ } | {
251
+ type: "resource";
252
+ name: string;
253
+ id: string;
254
+ resourceId: string;
255
+ scopeInstanceId?: string | undefined;
240
256
  }>;
241
257
  indexesWithinAncestors: IndexesWithinAncestors;
258
+ classesMap?: Map<string, string[]> | undefined;
242
259
  }) => string;
243
- export declare const generatePageComponent: ({ scope, rootInstanceId, instances, props, dataSources, indexesWithinAncestors, }: {
260
+ export declare const generatePageComponent: ({ scope, page, instances, props, dataSources, indexesWithinAncestors, classesMap, }: {
244
261
  scope: Scope;
245
- rootInstanceId: Instance["id"];
262
+ page: Page;
246
263
  instances: Map<string, {
247
264
  type: "instance";
248
265
  id: string;
249
- component: string;
250
266
  children: ({
251
267
  value: string;
252
268
  type: "text";
253
269
  } | {
254
270
  value: string;
255
271
  type: "id";
272
+ } | {
273
+ value: string;
274
+ type: "expression";
256
275
  })[];
276
+ component: string;
257
277
  label?: string | undefined;
258
278
  }>;
259
279
  props: Map<string, {
@@ -363,6 +383,13 @@ export declare const generatePageComponent: ({ scope, rootInstanceId, instances,
363
383
  name: string;
364
384
  id: string;
365
385
  scopeInstanceId?: string | undefined;
386
+ } | {
387
+ type: "resource";
388
+ name: string;
389
+ id: string;
390
+ resourceId: string;
391
+ scopeInstanceId?: string | undefined;
366
392
  }>;
367
393
  indexesWithinAncestors: IndexesWithinAncestors;
394
+ classesMap: Map<string, Array<string>>;
368
395
  }) => string;
@@ -387,6 +387,27 @@ declare const WsComponentPropsMeta: z.ZodObject<{
387
387
  defaultValue?: undefined;
388
388
  label?: string | undefined;
389
389
  description?: string | undefined;
390
+ }>, z.ZodObject<{
391
+ control: z.ZodLiteral<"textContent">;
392
+ type: z.ZodLiteral<"string">;
393
+ defaultValue: z.ZodOptional<z.ZodString>;
394
+ label: z.ZodOptional<z.ZodString>;
395
+ description: z.ZodOptional<z.ZodString>;
396
+ required: z.ZodBoolean;
397
+ }, "strip", z.ZodTypeAny, {
398
+ type: "string";
399
+ required: boolean;
400
+ control: "textContent";
401
+ defaultValue?: string | undefined;
402
+ label?: string | undefined;
403
+ description?: string | undefined;
404
+ }, {
405
+ type: "string";
406
+ required: boolean;
407
+ control: "textContent";
408
+ defaultValue?: string | undefined;
409
+ label?: string | undefined;
410
+ description?: string | undefined;
390
411
  }>]>>;
391
412
  initialProps: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
392
413
  }, "strip", z.ZodTypeAny, {
@@ -518,6 +539,13 @@ declare const WsComponentPropsMeta: z.ZodObject<{
518
539
  defaultValue?: undefined;
519
540
  label?: string | undefined;
520
541
  description?: string | undefined;
542
+ } | {
543
+ type: "string";
544
+ required: boolean;
545
+ control: "textContent";
546
+ defaultValue?: string | undefined;
547
+ label?: string | undefined;
548
+ description?: string | undefined;
521
549
  }>;
522
550
  initialProps?: string[] | undefined;
523
551
  }, {
@@ -649,6 +677,13 @@ declare const WsComponentPropsMeta: z.ZodObject<{
649
677
  defaultValue?: undefined;
650
678
  label?: string | undefined;
651
679
  description?: string | undefined;
680
+ } | {
681
+ type: "string";
682
+ required: boolean;
683
+ control: "textContent";
684
+ defaultValue?: string | undefined;
685
+ label?: string | undefined;
686
+ description?: string | undefined;
652
687
  }>;
653
688
  initialProps?: string[] | undefined;
654
689
  }>;
@@ -134,6 +134,13 @@ export declare const corePropsMetas: {
134
134
  defaultValue?: undefined;
135
135
  label?: string | undefined;
136
136
  description?: string | undefined;
137
+ } | {
138
+ type: "string";
139
+ required: boolean;
140
+ control: "textContent";
141
+ defaultValue?: string | undefined;
142
+ label?: string | undefined;
143
+ description?: string | undefined;
137
144
  }>;
138
145
  initialProps?: string[] | undefined;
139
146
  };
@@ -10,6 +10,7 @@ type Data = {
10
10
  };
11
11
  type CssOptions = {
12
12
  assetBaseUrl: string;
13
+ atomic: boolean;
13
14
  };
14
15
  export declare const createImageValueTransformer: (assets: Map<string, {
15
16
  type: "font";
@@ -58,6 +59,11 @@ export declare const createImageValueTransformer: (assets: Map<string, {
58
59
  size: number;
59
60
  description: string | null;
60
61
  createdAt: string;
61
- }>, options: CssOptions) => TransformValue;
62
- export declare const generateCssText: (data: Data, options: CssOptions) => string;
62
+ }>, { assetBaseUrl }: {
63
+ assetBaseUrl: string;
64
+ }) => TransformValue;
65
+ export declare const generateCss: (data: Data, { assetBaseUrl, atomic }: CssOptions) => {
66
+ cssText: string;
67
+ classesMap: Map<string, string[]>;
68
+ };
63
69
  export {};
@@ -1,6 +1,6 @@
1
- import type { CssEngine } from "@webstudio-is/css-engine";
1
+ import type { StyleSheetAtomic, StyleSheetRegular } from "@webstudio-is/css-engine";
2
2
  import type { Assets } from "@webstudio-is/sdk";
3
- export declare const addGlobalRules: (engine: CssEngine, { assets, assetBaseUrl }: {
3
+ export declare const addGlobalRules: (sheet: StyleSheetRegular | StyleSheetAtomic, { assets, assetBaseUrl }: {
4
4
  assets: Map<string, {
5
5
  type: "font";
6
6
  name: string;
@@ -2215,18 +2215,24 @@ export declare const generateDataFromEmbedTemplate: (treeTemplate: ({
2215
2215
  } | {
2216
2216
  value: string;
2217
2217
  type: "id";
2218
+ } | {
2219
+ value: string;
2220
+ type: "expression";
2218
2221
  })[];
2219
2222
  instances: {
2220
2223
  type: "instance";
2221
2224
  id: string;
2222
- component: string;
2223
2225
  children: ({
2224
2226
  value: string;
2225
2227
  type: "text";
2226
2228
  } | {
2227
2229
  value: string;
2228
2230
  type: "id";
2231
+ } | {
2232
+ value: string;
2233
+ type: "expression";
2229
2234
  })[];
2235
+ component: string;
2230
2236
  label?: string | undefined;
2231
2237
  }[];
2232
2238
  props: ({
@@ -2336,6 +2342,12 @@ export declare const generateDataFromEmbedTemplate: (treeTemplate: ({
2336
2342
  name: string;
2337
2343
  id: string;
2338
2344
  scopeInstanceId?: string | undefined;
2345
+ } | {
2346
+ type: "resource";
2347
+ name: string;
2348
+ id: string;
2349
+ resourceId: string;
2350
+ scopeInstanceId?: string | undefined;
2339
2351
  })[];
2340
2352
  styleSourceSelections: {
2341
2353
  values: string[];
@@ -14,6 +14,43 @@ export declare const validateExpression: (code: string, options?: {
14
14
  }) => string;
15
15
  export declare const encodeDataSourceVariable: (id: string) => string;
16
16
  export declare const decodeDataSourceVariable: (name: string) => string | undefined;
17
+ export declare const generateExpression: ({ expression, dataSources, scope, }: {
18
+ expression: string;
19
+ dataSources: Map<string, {
20
+ value: {
21
+ value: number;
22
+ type: "number";
23
+ } | {
24
+ value: string;
25
+ type: "string";
26
+ } | {
27
+ value: boolean;
28
+ type: "boolean";
29
+ } | {
30
+ value: string[];
31
+ type: "string[]";
32
+ } | {
33
+ type: "json";
34
+ value?: unknown;
35
+ };
36
+ type: "variable";
37
+ name: string;
38
+ id: string;
39
+ scopeInstanceId?: string | undefined;
40
+ } | {
41
+ type: "parameter";
42
+ name: string;
43
+ id: string;
44
+ scopeInstanceId?: string | undefined;
45
+ } | {
46
+ type: "resource";
47
+ name: string;
48
+ id: string;
49
+ resourceId: string;
50
+ scopeInstanceId?: string | undefined;
51
+ }>;
52
+ scope: Scope;
53
+ }) => string;
17
54
  type VariableName = string;
18
55
  export declare const generateDataSources: ({ scope, typed, dataSources, props, }: {
19
56
  scope: Scope;
@@ -44,6 +81,12 @@ export declare const generateDataSources: ({ scope, typed, dataSources, props, }
44
81
  name: string;
45
82
  id: string;
46
83
  scopeInstanceId?: string | undefined;
84
+ } | {
85
+ type: "resource";
86
+ name: string;
87
+ id: string;
88
+ resourceId: string;
89
+ scopeInstanceId?: string | undefined;
47
90
  }>;
48
91
  props: Map<string, {
49
92
  value: number;
@@ -28,14 +28,17 @@ export type Hook = {
28
28
  export declare const getClosestInstance: (instancePath: InstancePath, currentInstance: Instance, closestComponent: Instance["component"]) => {
29
29
  type: "instance";
30
30
  id: string;
31
- component: string;
32
31
  children: ({
33
32
  value: string;
34
33
  type: "text";
35
34
  } | {
36
35
  value: string;
37
36
  type: "id";
37
+ } | {
38
+ value: string;
39
+ type: "expression";
38
40
  })[];
41
+ component: string;
39
42
  label?: string | undefined;
40
43
  } | undefined;
41
44
  export {};
@@ -1,3 +1,4 @@
1
+ export * from "./remix";
1
2
  export * from "./css/index";
2
3
  export * from "./tree/index";
3
4
  export * from "./app/index";
@@ -13,3 +14,4 @@ export { getIndexesWithinAncestors } from "./instance-utils";
13
14
  export * from "./hook";
14
15
  export { generateUtilsExport } from "./generator";
15
16
  export { generatePageComponent, generateJsxElement, generateJsxChildren, } from "./component-generator";
17
+ export { generateResourcesLoader } from "./resources-generator";
@@ -4,13 +4,16 @@ export type IndexesWithinAncestors = Map<Instance["id"], number>;
4
4
  export declare const getIndexesWithinAncestors: (metas: Map<Instance["component"], WsComponentMeta>, instances: Map<string, {
5
5
  type: "instance";
6
6
  id: string;
7
- component: string;
8
7
  children: ({
9
8
  value: string;
10
9
  type: "text";
11
10
  } | {
12
11
  value: string;
13
12
  type: "id";
13
+ } | {
14
+ value: string;
15
+ type: "expression";
14
16
  })[];
17
+ component: string;
15
18
  label?: string | undefined;
16
19
  }>, rootIds: Instance["id"][]) => IndexesWithinAncestors;
@@ -392,5 +392,26 @@ export declare const PropMeta: z.ZodUnion<[z.ZodObject<{
392
392
  defaultValue?: undefined;
393
393
  label?: string | undefined;
394
394
  description?: string | undefined;
395
+ }>, z.ZodObject<{
396
+ control: z.ZodLiteral<"textContent">;
397
+ type: z.ZodLiteral<"string">;
398
+ defaultValue: z.ZodOptional<z.ZodString>;
399
+ label: z.ZodOptional<z.ZodString>;
400
+ description: z.ZodOptional<z.ZodString>;
401
+ required: z.ZodBoolean;
402
+ }, "strip", z.ZodTypeAny, {
403
+ type: "string";
404
+ required: boolean;
405
+ control: "textContent";
406
+ defaultValue?: string | undefined;
407
+ label?: string | undefined;
408
+ description?: string | undefined;
409
+ }, {
410
+ type: "string";
411
+ required: boolean;
412
+ control: "textContent";
413
+ defaultValue?: string | undefined;
414
+ label?: string | undefined;
415
+ description?: string | undefined;
395
416
  }>]>;
396
417
  export type PropMeta = z.infer<typeof PropMeta>;
@@ -139,5 +139,6 @@ export declare const componentAttribute: "data-ws-component";
139
139
  export declare const showAttribute: "data-ws-show";
140
140
  export declare const indexAttribute: "data-ws-index";
141
141
  export declare const collapsedAttribute: "data-ws-collapsed";
142
+ export declare const textContentAttribute: "data-ws-text-content";
142
143
  export declare const getInstanceIdFromComponentProps: (props: Record<string, unknown>) => string;
143
144
  export declare const getIndexWithinAncestorFromComponentProps: (props: Record<string, unknown>) => string | undefined;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * transforms url pattern subset to remix route format
3
+ *
4
+ * /:name/ -> .$name. - named dynamic segment
5
+ * /:name?/ -> .($name). - optional dynamic segment
6
+ * /* -> .$ - splat in the end of pattern
7
+ * /:name* -> .$ - named splat which gets specified name at runtime
8
+ *
9
+ */
10
+ export declare const generateRemixRoute: (pathname: string) => string;
11
+ /**
12
+ * generates a function to convert remix params to compatible with url pattern groups
13
+ *
14
+ * for /:name* pattern
15
+ * params["*"] is replaced with params["name"]
16
+ *
17
+ * for /* pattern
18
+ * params["*"] is replaced with params[0]
19
+ */
20
+ export declare const generateRemixParams: (pathname: string) => string;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,49 @@
1
+ import type { DataSources, Page, Resources, Scope } from "@webstudio-is/sdk";
2
+ export declare const generateResourcesLoader: ({ scope, page, dataSources, resources, }: {
3
+ scope: Scope;
4
+ page: Page;
5
+ dataSources: Map<string, {
6
+ value: {
7
+ value: number;
8
+ type: "number";
9
+ } | {
10
+ value: string;
11
+ type: "string";
12
+ } | {
13
+ value: boolean;
14
+ type: "boolean";
15
+ } | {
16
+ value: string[];
17
+ type: "string[]";
18
+ } | {
19
+ type: "json";
20
+ value?: unknown;
21
+ };
22
+ type: "variable";
23
+ name: string;
24
+ id: string;
25
+ scopeInstanceId?: string | undefined;
26
+ } | {
27
+ type: "parameter";
28
+ name: string;
29
+ id: string;
30
+ scopeInstanceId?: string | undefined;
31
+ } | {
32
+ type: "resource";
33
+ name: string;
34
+ id: string;
35
+ resourceId: string;
36
+ scopeInstanceId?: string | undefined;
37
+ }>;
38
+ resources: Map<string, {
39
+ name: string;
40
+ id: string;
41
+ method: "get" | "post" | "put" | "delete";
42
+ url: string;
43
+ headers: {
44
+ value: string;
45
+ name: string;
46
+ }[];
47
+ body?: string | undefined;
48
+ }>;
49
+ }) => string;
@@ -0,0 +1 @@
1
+ export {};
@@ -13,14 +13,17 @@ export declare const createElementsTree: ({ renderer, assetBaseUrl, imageBaseUrl
13
13
  instances: Map<string, {
14
14
  type: "instance";
15
15
  id: string;
16
- component: string;
17
16
  children: ({
18
17
  value: string;
19
18
  type: "text";
20
19
  } | {
21
20
  value: string;
22
21
  type: "id";
22
+ } | {
23
+ value: string;
24
+ type: "expression";
23
25
  })[];
26
+ component: string;
24
27
  label?: string | undefined;
25
28
  }>;
26
29
  imageLoader: ImageLoader;
@@ -32,14 +35,17 @@ export declare const createInstanceChildrenElements: ({ instances, instanceSelec
32
35
  instances: Map<string, {
33
36
  type: "instance";
34
37
  id: string;
35
- component: string;
36
38
  children: ({
37
39
  value: string;
38
40
  type: "text";
39
41
  } | {
40
42
  value: string;
41
43
  type: "id";
44
+ } | {
45
+ value: string;
46
+ type: "expression";
42
47
  })[];
48
+ component: string;
43
49
  label?: string | undefined;
44
50
  }>;
45
51
  instanceSelector: InstanceSelector;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webstudio-is/react-sdk",
3
- "version": "0.123.0",
3
+ "version": "0.125.0",
4
4
  "description": "Webstudio JavaScript / TypeScript API",
5
5
  "author": "Webstudio <github@webstudio.is>",
6
6
  "homepage": "https://webstudio.is",
@@ -33,11 +33,11 @@
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.123.0",
37
- "@webstudio-is/icons": "^0.123.0",
38
- "@webstudio-is/fonts": "0.123.0",
39
- "@webstudio-is/image": "0.123.0",
40
- "@webstudio-is/sdk": "0.123.0"
36
+ "@webstudio-is/fonts": "0.125.0",
37
+ "@webstudio-is/icons": "^0.125.0",
38
+ "@webstudio-is/image": "0.125.0",
39
+ "@webstudio-is/sdk": "0.125.0",
40
+ "@webstudio-is/css-engine": "0.125.0"
41
41
  },
42
42
  "exports": {
43
43
  ".": {