@webstudio-is/react-sdk 0.87.0 → 0.88.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.
@@ -56,7 +56,7 @@ const renderComponentTemplate = ({
56
56
  throw new Error(`Unsupported prop ${props} with value ${value}`);
57
57
  });
58
58
  }
59
- const data = (0, import_embed_template.generateDataFromEmbedTemplate)(template, "base");
59
+ const data = (0, import_embed_template.generateDataFromEmbedTemplate)(template, metas, "base");
60
60
  const instances = [
61
61
  [
62
62
  "root",
@@ -46,6 +46,10 @@ const ComponentState = import_zod.z.object({
46
46
  selector: import_zod.z.string(),
47
47
  label: import_zod.z.string()
48
48
  });
49
+ const ComponentToken = import_zod.z.object({
50
+ variant: import_zod.z.optional(import_zod.z.string()),
51
+ styles: import_zod.z.array(import_embed_template.EmbedTemplateStyleDecl)
52
+ });
49
53
  const defaultStates = [
50
54
  { selector: ":hover", label: "Hover" },
51
55
  { selector: ":active", label: "Active" },
@@ -76,6 +80,7 @@ const WsComponentMeta = import_zod.z.object({
76
80
  description: import_zod.z.string().optional(),
77
81
  icon: import_zod.z.string(),
78
82
  presetStyle: import_zod.z.optional(import_zod.z.record(import_zod.z.string(), import_embed_template.EmbedTemplateStyleDecl)),
83
+ presetTokens: import_zod.z.optional(import_zod.z.record(import_zod.z.string(), ComponentToken)),
79
84
  states: import_zod.z.optional(import_zod.z.array(ComponentState)),
80
85
  template: import_zod.z.optional(import_embed_template.WsEmbedTemplate),
81
86
  order: import_zod.z.number().optional()
@@ -27,6 +27,8 @@ __export(embed_template_exports, {
27
27
  module.exports = __toCommonJS(embed_template_exports);
28
28
  var import_zod = require("zod");
29
29
  var import_nanoid = require("nanoid");
30
+ var import_title_case = require("title-case");
31
+ var import_no_case = require("no-case");
30
32
  var import_project_build = require("@webstudio-is/project-build");
31
33
  var import_css_data = require("@webstudio-is/css-data");
32
34
  var import_expression = require("./expression");
@@ -101,6 +103,7 @@ const EmbedTemplateInstance = import_zod.z.lazy(
101
103
  label: import_zod.z.optional(import_zod.z.string()),
102
104
  dataSources: import_zod.z.optional(import_zod.z.record(import_zod.z.string(), EmbedTemplateDataSource)),
103
105
  props: import_zod.z.optional(import_zod.z.array(EmbedTemplateProp)),
106
+ tokens: import_zod.z.optional(import_zod.z.array(import_zod.z.string())),
104
107
  styles: import_zod.z.optional(import_zod.z.array(EmbedTemplateStyleDecl)),
105
108
  children: WsEmbedTemplate
106
109
  })
@@ -124,7 +127,7 @@ const getDataSourceValue = (value) => {
124
127
  value;
125
128
  throw Error("Impossible case");
126
129
  };
127
- const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByRef, styleSourceSelections, styleSources, styles, defaultBreakpointId) => {
130
+ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByRef, styleSourceSelections, styleSources, styles, metas, defaultBreakpointId) => {
128
131
  const parentChildren = [];
129
132
  for (const item of treeTemplate) {
130
133
  if (item.type === "instance") {
@@ -207,16 +210,40 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
207
210
  props.push({ id: propId, instanceId, ...prop });
208
211
  }
209
212
  }
213
+ const styleSourceIds = [];
214
+ if (item.tokens) {
215
+ const meta = metas.get(item.component);
216
+ if (meta?.presetTokens) {
217
+ for (const name of item.tokens) {
218
+ const tokenValue = meta.presetTokens[name];
219
+ if (tokenValue) {
220
+ const styleSourceId = `${item.component}:${name}`;
221
+ styleSourceIds.push(styleSourceId);
222
+ styleSources.push({
223
+ type: "token",
224
+ id: styleSourceId,
225
+ name: (0, import_title_case.titleCase)((0, import_no_case.noCase)(name))
226
+ });
227
+ for (const styleDecl of tokenValue.styles) {
228
+ styles.push({
229
+ breakpointId: defaultBreakpointId,
230
+ styleSourceId,
231
+ state: styleDecl.state,
232
+ property: styleDecl.property,
233
+ value: styleDecl.value
234
+ });
235
+ }
236
+ }
237
+ }
238
+ }
239
+ }
210
240
  if (item.styles) {
211
241
  const styleSourceId = (0, import_nanoid.nanoid)();
212
242
  styleSources.push({
213
243
  type: "local",
214
244
  id: styleSourceId
215
245
  });
216
- styleSourceSelections.push({
217
- instanceId,
218
- values: [styleSourceId]
219
- });
246
+ styleSourceIds.push(styleSourceId);
220
247
  for (const styleDecl of item.styles) {
221
248
  styles.push({
222
249
  breakpointId: defaultBreakpointId,
@@ -227,6 +254,12 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
227
254
  });
228
255
  }
229
256
  }
257
+ if (styleSourceIds.length > 0) {
258
+ styleSourceSelections.push({
259
+ instanceId,
260
+ values: styleSourceIds
261
+ });
262
+ }
230
263
  const instance = {
231
264
  type: "instance",
232
265
  id: instanceId,
@@ -243,6 +276,7 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
243
276
  styleSourceSelections,
244
277
  styleSources,
245
278
  styles,
279
+ metas,
246
280
  defaultBreakpointId
247
281
  );
248
282
  parentChildren.push({
@@ -259,7 +293,7 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
259
293
  }
260
294
  return parentChildren;
261
295
  };
262
- const generateDataFromEmbedTemplate = (treeTemplate, defaultBreakpointId) => {
296
+ const generateDataFromEmbedTemplate = (treeTemplate, metas, defaultBreakpointId) => {
263
297
  const instances = [];
264
298
  const props = [];
265
299
  const dataSourceByRef = /* @__PURE__ */ new Map();
@@ -274,6 +308,7 @@ const generateDataFromEmbedTemplate = (treeTemplate, defaultBreakpointId) => {
274
308
  styleSourceSelections,
275
309
  styleSources,
276
310
  styles,
311
+ metas,
277
312
  defaultBreakpointId
278
313
  );
279
314
  return {
@@ -73,7 +73,7 @@ const generateUtilsExport = (siteData) => {
73
73
  new Set(executableValue.args),
74
74
  variables
75
75
  );
76
- const generatedFunction = `(_args: Map<string, any>, _variables: Map<string, any>) => { ${generatedCode} })`;
76
+ const generatedFunction = `(_args: Map<string, any>, _variables: Map<string, any>) => { ${generatedCode} }`;
77
77
  effectfulExpressionsEntries += `[${codeString}, ${generatedFunction}],
78
78
  `;
79
79
  }
package/lib/cjs/props.js CHANGED
@@ -50,7 +50,6 @@ const useInstanceProps = (instanceId) => {
50
50
  dataSourceValuesStore,
51
51
  executeEffectfulExpression,
52
52
  setDataSourceValues,
53
- renderer,
54
53
  indexesWithinAncestors
55
54
  } = (0, import_react.useContext)(import_context.ReactSdkContext);
56
55
  const index = indexesWithinAncestors.get(instanceId);
@@ -80,9 +79,6 @@ const useInstanceProps = (instanceId) => {
80
79
  }
81
80
  if (prop.type === "action") {
82
81
  instancePropsObject2[prop.name] = (...args) => {
83
- if (renderer === "canvas") {
84
- return;
85
- }
86
82
  for (const value of prop.value) {
87
83
  if (value.type === "execute") {
88
84
  const argsMap = /* @__PURE__ */ new Map();
@@ -109,7 +105,6 @@ const useInstanceProps = (instanceId) => {
109
105
  propsByInstanceIdStore,
110
106
  dataSourceValuesStore,
111
107
  instanceId,
112
- renderer,
113
108
  executeEffectfulExpression,
114
109
  setDataSourceValues,
115
110
  index
@@ -148,42 +143,47 @@ const resolveUrlProp = (instanceId, name, {
148
143
  if (instanceProps === void 0) {
149
144
  return;
150
145
  }
151
- for (const prop of instanceProps) {
152
- if (prop.name !== name) {
146
+ let prop = void 0;
147
+ for (const intanceProp of instanceProps) {
148
+ if (intanceProp.name !== name) {
153
149
  continue;
154
150
  }
155
- if (prop.type === "page") {
156
- if (typeof prop.value === "string") {
157
- const page2 = pages.get(prop.value);
158
- return page2 && { type: "page", page: page2 };
159
- }
160
- const { instanceId: instanceId2, pageId } = prop.value;
161
- const page = pages.get(pageId);
162
- if (page === void 0) {
163
- return;
164
- }
165
- const idProp = props.get(instanceId2)?.find((prop2) => prop2.name === "id");
166
- return {
167
- type: "page",
168
- page,
169
- instanceId: instanceId2,
170
- hash: idProp === void 0 || idProp.type !== "string" ? void 0 : idProp.value
171
- };
151
+ prop = intanceProp;
152
+ }
153
+ if (prop === void 0) {
154
+ return;
155
+ }
156
+ if (prop.type === "page") {
157
+ if (typeof prop.value === "string") {
158
+ const page2 = pages.get(prop.value);
159
+ return page2 && { type: "page", page: page2 };
172
160
  }
173
- if (prop.type === "string") {
174
- for (const page of pages.values()) {
175
- if (page.path === prop.value) {
176
- return { type: "page", page };
177
- }
178
- }
179
- return { type: "string", url: prop.value };
161
+ const { instanceId: instanceId2, pageId } = prop.value;
162
+ const page = pages.get(pageId);
163
+ if (page === void 0) {
164
+ return;
180
165
  }
181
- if (prop.type === "asset") {
182
- const asset = assets.get(prop.value);
183
- return asset && { type: "asset", asset };
166
+ const idProp = props.get(instanceId2)?.find((prop2) => prop2.name === "id");
167
+ return {
168
+ type: "page",
169
+ page,
170
+ instanceId: instanceId2,
171
+ hash: idProp === void 0 || idProp.type !== "string" ? void 0 : idProp.value
172
+ };
173
+ }
174
+ if (prop.type === "string") {
175
+ for (const page of pages.values()) {
176
+ if (page.path === prop.value) {
177
+ return { type: "page", page };
178
+ }
184
179
  }
185
- return;
180
+ return { type: "string", url: prop.value };
181
+ }
182
+ if (prop.type === "asset") {
183
+ const asset = assets.get(prop.value);
184
+ return asset && { type: "asset", asset };
186
185
  }
186
+ return;
187
187
  };
188
188
  const usePropUrl = (instanceId, name) => {
189
189
  const { propsByInstanceIdStore, pagesStore, assetsStore } = (0, import_react.useContext)(import_context.ReactSdkContext);
@@ -42,7 +42,7 @@ const renderComponentTemplate = ({
42
42
  throw new Error(`Unsupported prop ${props} with value ${value}`);
43
43
  });
44
44
  }
45
- const data = generateDataFromEmbedTemplate(template, "base");
45
+ const data = generateDataFromEmbedTemplate(template, metas, "base");
46
46
  const instances = [
47
47
  [
48
48
  "root",
@@ -20,6 +20,10 @@ const ComponentState = z.object({
20
20
  selector: z.string(),
21
21
  label: z.string()
22
22
  });
23
+ const ComponentToken = z.object({
24
+ variant: z.optional(z.string()),
25
+ styles: z.array(EmbedTemplateStyleDecl)
26
+ });
23
27
  const defaultStates = [
24
28
  { selector: ":hover", label: "Hover" },
25
29
  { selector: ":active", label: "Active" },
@@ -50,6 +54,7 @@ const WsComponentMeta = z.object({
50
54
  description: z.string().optional(),
51
55
  icon: z.string(),
52
56
  presetStyle: z.optional(z.record(z.string(), EmbedTemplateStyleDecl)),
57
+ presetTokens: z.optional(z.record(z.string(), ComponentToken)),
53
58
  states: z.optional(z.array(ComponentState)),
54
59
  template: z.optional(WsEmbedTemplate),
55
60
  order: z.number().optional()
@@ -1,5 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { nanoid } from "nanoid";
3
+ import { titleCase } from "title-case";
4
+ import { noCase } from "no-case";
3
5
  import {
4
6
  Instance,
5
7
  PropsList,
@@ -82,6 +84,7 @@ const EmbedTemplateInstance = z.lazy(
82
84
  label: z.optional(z.string()),
83
85
  dataSources: z.optional(z.record(z.string(), EmbedTemplateDataSource)),
84
86
  props: z.optional(z.array(EmbedTemplateProp)),
87
+ tokens: z.optional(z.array(z.string())),
85
88
  styles: z.optional(z.array(EmbedTemplateStyleDecl)),
86
89
  children: WsEmbedTemplate
87
90
  })
@@ -105,7 +108,7 @@ const getDataSourceValue = (value) => {
105
108
  value;
106
109
  throw Error("Impossible case");
107
110
  };
108
- const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByRef, styleSourceSelections, styleSources, styles, defaultBreakpointId) => {
111
+ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceByRef, styleSourceSelections, styleSources, styles, metas, defaultBreakpointId) => {
109
112
  const parentChildren = [];
110
113
  for (const item of treeTemplate) {
111
114
  if (item.type === "instance") {
@@ -188,16 +191,40 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
188
191
  props.push({ id: propId, instanceId, ...prop });
189
192
  }
190
193
  }
194
+ const styleSourceIds = [];
195
+ if (item.tokens) {
196
+ const meta = metas.get(item.component);
197
+ if (meta?.presetTokens) {
198
+ for (const name of item.tokens) {
199
+ const tokenValue = meta.presetTokens[name];
200
+ if (tokenValue) {
201
+ const styleSourceId = `${item.component}:${name}`;
202
+ styleSourceIds.push(styleSourceId);
203
+ styleSources.push({
204
+ type: "token",
205
+ id: styleSourceId,
206
+ name: titleCase(noCase(name))
207
+ });
208
+ for (const styleDecl of tokenValue.styles) {
209
+ styles.push({
210
+ breakpointId: defaultBreakpointId,
211
+ styleSourceId,
212
+ state: styleDecl.state,
213
+ property: styleDecl.property,
214
+ value: styleDecl.value
215
+ });
216
+ }
217
+ }
218
+ }
219
+ }
220
+ }
191
221
  if (item.styles) {
192
222
  const styleSourceId = nanoid();
193
223
  styleSources.push({
194
224
  type: "local",
195
225
  id: styleSourceId
196
226
  });
197
- styleSourceSelections.push({
198
- instanceId,
199
- values: [styleSourceId]
200
- });
227
+ styleSourceIds.push(styleSourceId);
201
228
  for (const styleDecl of item.styles) {
202
229
  styles.push({
203
230
  breakpointId: defaultBreakpointId,
@@ -208,6 +235,12 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
208
235
  });
209
236
  }
210
237
  }
238
+ if (styleSourceIds.length > 0) {
239
+ styleSourceSelections.push({
240
+ instanceId,
241
+ values: styleSourceIds
242
+ });
243
+ }
211
244
  const instance = {
212
245
  type: "instance",
213
246
  id: instanceId,
@@ -224,6 +257,7 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
224
257
  styleSourceSelections,
225
258
  styleSources,
226
259
  styles,
260
+ metas,
227
261
  defaultBreakpointId
228
262
  );
229
263
  parentChildren.push({
@@ -240,7 +274,7 @@ const createInstancesFromTemplate = (treeTemplate, instances, props, dataSourceB
240
274
  }
241
275
  return parentChildren;
242
276
  };
243
- const generateDataFromEmbedTemplate = (treeTemplate, defaultBreakpointId) => {
277
+ const generateDataFromEmbedTemplate = (treeTemplate, metas, defaultBreakpointId) => {
244
278
  const instances = [];
245
279
  const props = [];
246
280
  const dataSourceByRef = /* @__PURE__ */ new Map();
@@ -255,6 +289,7 @@ const generateDataFromEmbedTemplate = (treeTemplate, defaultBreakpointId) => {
255
289
  styleSourceSelections,
256
290
  styleSources,
257
291
  styles,
292
+ metas,
258
293
  defaultBreakpointId
259
294
  );
260
295
  return {
package/lib/generator.js CHANGED
@@ -56,7 +56,7 @@ const generateUtilsExport = (siteData) => {
56
56
  new Set(executableValue.args),
57
57
  variables
58
58
  );
59
- const generatedFunction = `(_args: Map<string, any>, _variables: Map<string, any>) => { ${generatedCode} })`;
59
+ const generatedFunction = `(_args: Map<string, any>, _variables: Map<string, any>) => { ${generatedCode} }`;
60
60
  effectfulExpressionsEntries += `[${codeString}, ${generatedFunction}],
61
61
  `;
62
62
  }
package/lib/props.js CHANGED
@@ -21,7 +21,6 @@ const useInstanceProps = (instanceId) => {
21
21
  dataSourceValuesStore,
22
22
  executeEffectfulExpression,
23
23
  setDataSourceValues,
24
- renderer,
25
24
  indexesWithinAncestors
26
25
  } = useContext(ReactSdkContext);
27
26
  const index = indexesWithinAncestors.get(instanceId);
@@ -51,9 +50,6 @@ const useInstanceProps = (instanceId) => {
51
50
  }
52
51
  if (prop.type === "action") {
53
52
  instancePropsObject2[prop.name] = (...args) => {
54
- if (renderer === "canvas") {
55
- return;
56
- }
57
53
  for (const value of prop.value) {
58
54
  if (value.type === "execute") {
59
55
  const argsMap = /* @__PURE__ */ new Map();
@@ -80,7 +76,6 @@ const useInstanceProps = (instanceId) => {
80
76
  propsByInstanceIdStore,
81
77
  dataSourceValuesStore,
82
78
  instanceId,
83
- renderer,
84
79
  executeEffectfulExpression,
85
80
  setDataSourceValues,
86
81
  index
@@ -119,42 +114,47 @@ const resolveUrlProp = (instanceId, name, {
119
114
  if (instanceProps === void 0) {
120
115
  return;
121
116
  }
122
- for (const prop of instanceProps) {
123
- if (prop.name !== name) {
117
+ let prop = void 0;
118
+ for (const intanceProp of instanceProps) {
119
+ if (intanceProp.name !== name) {
124
120
  continue;
125
121
  }
126
- if (prop.type === "page") {
127
- if (typeof prop.value === "string") {
128
- const page2 = pages.get(prop.value);
129
- return page2 && { type: "page", page: page2 };
130
- }
131
- const { instanceId: instanceId2, pageId } = prop.value;
132
- const page = pages.get(pageId);
133
- if (page === void 0) {
134
- return;
135
- }
136
- const idProp = props.get(instanceId2)?.find((prop2) => prop2.name === "id");
137
- return {
138
- type: "page",
139
- page,
140
- instanceId: instanceId2,
141
- hash: idProp === void 0 || idProp.type !== "string" ? void 0 : idProp.value
142
- };
122
+ prop = intanceProp;
123
+ }
124
+ if (prop === void 0) {
125
+ return;
126
+ }
127
+ if (prop.type === "page") {
128
+ if (typeof prop.value === "string") {
129
+ const page2 = pages.get(prop.value);
130
+ return page2 && { type: "page", page: page2 };
143
131
  }
144
- if (prop.type === "string") {
145
- for (const page of pages.values()) {
146
- if (page.path === prop.value) {
147
- return { type: "page", page };
148
- }
149
- }
150
- return { type: "string", url: prop.value };
132
+ const { instanceId: instanceId2, pageId } = prop.value;
133
+ const page = pages.get(pageId);
134
+ if (page === void 0) {
135
+ return;
151
136
  }
152
- if (prop.type === "asset") {
153
- const asset = assets.get(prop.value);
154
- return asset && { type: "asset", asset };
137
+ const idProp = props.get(instanceId2)?.find((prop2) => prop2.name === "id");
138
+ return {
139
+ type: "page",
140
+ page,
141
+ instanceId: instanceId2,
142
+ hash: idProp === void 0 || idProp.type !== "string" ? void 0 : idProp.value
143
+ };
144
+ }
145
+ if (prop.type === "string") {
146
+ for (const page of pages.values()) {
147
+ if (page.path === prop.value) {
148
+ return { type: "page", page };
149
+ }
155
150
  }
156
- return;
151
+ return { type: "string", url: prop.value };
152
+ }
153
+ if (prop.type === "asset") {
154
+ const asset = assets.get(prop.value);
155
+ return asset && { type: "asset", asset };
157
156
  }
157
+ return;
158
158
  };
159
159
  const usePropUrl = (instanceId, name) => {
160
160
  const { propsByInstanceIdStore, pagesStore, assetsStore } = useContext(ReactSdkContext);