@webstudio-is/react-sdk 0.182.0 → 0.189.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
@@ -57,7 +57,6 @@ var generateRemixParams = (pathname) => {
57
57
  // src/css/global-rules.ts
58
58
  import { getFontFaces } from "@webstudio-is/fonts";
59
59
  var addGlobalRules = (sheet, { assets, assetBaseUrl }) => {
60
- sheet.addPlaintextRule("html {margin: 0; display: grid; min-height: 100%}");
61
60
  const fontAssets = [];
62
61
  for (const asset of assets.values()) {
63
62
  if (asset.type === "font") {
@@ -76,12 +75,31 @@ import {
76
75
  generateAtomic
77
76
  } from "@webstudio-is/css-engine";
78
77
  import {
78
+ ROOT_INSTANCE_ID,
79
79
  createScope,
80
80
  parseComponentName
81
81
  } from "@webstudio-is/sdk";
82
82
 
83
83
  // src/core-components.ts
84
- import { ListViewIcon, PaintBrushIcon } from "@webstudio-is/icons/svg";
84
+ import {
85
+ ListViewIcon,
86
+ PaintBrushIcon,
87
+ SettingsIcon
88
+ } from "@webstudio-is/icons/svg";
89
+ import { html } from "@webstudio-is/sdk/normalize.css";
90
+ var rootComponent = "ws:root";
91
+ var rootMeta = {
92
+ category: "hidden",
93
+ type: "container",
94
+ label: "Global Root",
95
+ icon: SettingsIcon,
96
+ presetStyle: {
97
+ html
98
+ }
99
+ };
100
+ var rootPropsMeta = {
101
+ props: {}
102
+ };
85
103
  var portalComponent = "Slot";
86
104
  var collectionComponent = "ws:collection";
87
105
  var collectionMeta = {
@@ -175,14 +193,16 @@ var descendantPropsMeta = {
175
193
  initialProps: ["selector"]
176
194
  };
177
195
  var coreMetas = {
196
+ [rootComponent]: rootMeta,
178
197
  [collectionComponent]: collectionMeta,
179
198
  [descendantComponent]: descendantMeta
180
199
  };
181
200
  var corePropsMetas = {
201
+ [rootComponent]: rootPropsMeta,
182
202
  [collectionComponent]: collectionPropsMeta,
183
203
  [descendantComponent]: descendantPropsMeta
184
204
  };
185
- var isCoreComponent = (component) => component === collectionComponent || component === descendantComponent;
205
+ var isCoreComponent = (component) => component === rootComponent || component === collectionComponent || component === descendantComponent;
186
206
 
187
207
  // src/css/css.ts
188
208
  import { kebabCase } from "change-case";
@@ -229,7 +249,8 @@ var generateCss = ({
229
249
  presetClasses.set(component, className);
230
250
  }
231
251
  for (const [tag, styles2] of presetStyle) {
232
- const rule = globalSheet.addNestingRule(`:where(${tag}.${className})`);
252
+ const selector = component === rootComponent ? ":root" : `:where(${tag}.${className})`;
253
+ const rule = globalSheet.addNestingRule(selector);
233
254
  for (const declaration of styles2) {
234
255
  rule.setDeclaration({
235
256
  breakpoint: "presets",
@@ -279,6 +300,11 @@ var generateCss = ({
279
300
  for (const selection of styleSourceSelections.values()) {
280
301
  let { instanceId } = selection;
281
302
  const { values } = selection;
303
+ if (instanceId === ROOT_INSTANCE_ID) {
304
+ const rule2 = sheet.addNestingRule(`:root`);
305
+ rule2.applyMixins(values);
306
+ continue;
307
+ }
282
308
  let descendantSuffix = "";
283
309
  const instance = instances.get(instanceId);
284
310
  if (instance?.component === descendantComponent) {
@@ -306,7 +332,7 @@ var generateCss = ({
306
332
  }
307
333
  if (atomic) {
308
334
  const { cssText } = generateAtomic(sheet, {
309
- getKey: (rule) => instanceByRule.get(rule) ?? "",
335
+ getKey: (rule) => instanceByRule.get(rule),
310
336
  transformValue: imageValueTransformer,
311
337
  classes
312
338
  });
@@ -320,120 +346,6 @@ ${sheet.cssText}`,
320
346
  };
321
347
  };
322
348
 
323
- // src/tree/create-elements-tree.tsx
324
- import {
325
- Fragment
326
- } from "react";
327
-
328
- // src/context.tsx
329
- import { createContext, useContext, useMemo } from "react";
330
- import { createJsonStringifyProxy, isPlainObject } from "@webstudio-is/sdk";
331
- var ReactSdkContext = createContext({
332
- assetBaseUrl: "/",
333
- imageBaseUrl: "/",
334
- imageLoader: ({ src }) => src,
335
- resources: {}
336
- });
337
-
338
- // src/tree/create-elements-tree.tsx
339
- import { jsx, jsxs } from "react/jsx-runtime";
340
- var createElementsTree = ({
341
- renderer,
342
- assetBaseUrl,
343
- imageBaseUrl,
344
- imageLoader,
345
- instances,
346
- rootInstanceId,
347
- Component,
348
- components
349
- }) => {
350
- const rootInstance = instances.get(rootInstanceId);
351
- if (rootInstance === void 0) {
352
- return null;
353
- }
354
- const rootInstanceSelector = [rootInstanceId];
355
- const root = createInstanceElement({
356
- Component,
357
- instance: rootInstance,
358
- instanceSelector: rootInstanceSelector,
359
- components
360
- });
361
- return /* @__PURE__ */ jsx(
362
- ReactSdkContext.Provider,
363
- {
364
- value: {
365
- renderer,
366
- imageLoader,
367
- assetBaseUrl,
368
- imageBaseUrl,
369
- resources: {}
370
- },
371
- children: root
372
- }
373
- );
374
- };
375
- var renderText = (text) => {
376
- const lines = text.split("\n");
377
- return lines.map((line, index) => /* @__PURE__ */ jsxs(Fragment, { children: [
378
- line,
379
- index < lines.length - 1 && /* @__PURE__ */ jsx("br", {})
380
- ] }, index));
381
- };
382
- var createInstanceChildrenElements = ({
383
- instances,
384
- instanceSelector,
385
- children,
386
- Component,
387
- components
388
- }) => {
389
- const elements = [];
390
- for (const child of children) {
391
- if (child.type === "text") {
392
- elements.push(renderText(child.value));
393
- continue;
394
- }
395
- if (child.type === "expression") {
396
- continue;
397
- }
398
- if (child.type === "id") {
399
- const childInstance = instances.get(child.value);
400
- if (childInstance === void 0) {
401
- continue;
402
- }
403
- const childInstanceSelector = [child.value, ...instanceSelector];
404
- const element = createInstanceElement({
405
- instance: childInstance,
406
- instanceSelector: childInstanceSelector,
407
- Component,
408
- components
409
- });
410
- elements.push(element);
411
- continue;
412
- }
413
- child;
414
- }
415
- if (elements.length === 0) {
416
- return;
417
- }
418
- return elements;
419
- };
420
- var createInstanceElement = ({
421
- Component,
422
- instance,
423
- instanceSelector,
424
- components
425
- }) => {
426
- return /* @__PURE__ */ jsx(
427
- Component,
428
- {
429
- instance,
430
- instanceSelector,
431
- components
432
- },
433
- instance.id
434
- );
435
- };
436
-
437
349
  // src/props.ts
438
350
  import {
439
351
  getPagePath,
@@ -536,6 +448,28 @@ var showAttribute = "data-ws-show";
536
448
  var indexAttribute = "data-ws-index";
537
449
  var collapsedAttribute = "data-ws-collapsed";
538
450
  var textContentAttribute = "data-ws-text-content";
451
+ var attributeNameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
452
+ var attributeNameChar = attributeNameStartChar + ":\\-0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
453
+ var validAttributeNameRegex = new RegExp(
454
+ // eslint-disable-next-line no-misleading-character-class
455
+ "^[" + attributeNameStartChar + "][" + attributeNameChar + "]*$"
456
+ );
457
+ var illegalAttributeNameCache = /* @__PURE__ */ new Map();
458
+ var validatedAttributeNameCache = /* @__PURE__ */ new Map();
459
+ var isAttributeNameSafe = (attributeName) => {
460
+ if (validatedAttributeNameCache.has(attributeName)) {
461
+ return true;
462
+ }
463
+ if (illegalAttributeNameCache.has(attributeName)) {
464
+ return false;
465
+ }
466
+ if (validAttributeNameRegex.test(attributeName)) {
467
+ validatedAttributeNameCache.set(attributeName, true);
468
+ return true;
469
+ }
470
+ illegalAttributeNameCache.set(attributeName, true);
471
+ return false;
472
+ };
539
473
 
540
474
  // src/prop-meta.ts
541
475
  import { z } from "zod";
@@ -1282,6 +1216,7 @@ var generatePropValue = ({
1282
1216
  prop;
1283
1217
  };
1284
1218
  var generateJsxElement = ({
1219
+ context = "jsx",
1285
1220
  scope,
1286
1221
  instance,
1287
1222
  props,
@@ -1303,7 +1238,8 @@ ${indexAttribute}="${index}"`;
1303
1238
  let conditionValue;
1304
1239
  let collectionDataValue;
1305
1240
  let collectionItemValue;
1306
- const classes = Array.from(classesMap?.get(instance.id) ?? []);
1241
+ const classMapArray = classesMap?.get(instance.id);
1242
+ const classes = classMapArray !== void 0 ? [JSON.stringify(classMapArray.join(" "))] : [];
1307
1243
  for (const prop of props.values()) {
1308
1244
  if (prop.instanceId !== instance.id) {
1309
1245
  continue;
@@ -1314,6 +1250,9 @@ ${indexAttribute}="${index}"`;
1314
1250
  dataSources,
1315
1251
  usedDataSources
1316
1252
  });
1253
+ if (isAttributeNameSafe(prop.name) === false) {
1254
+ continue;
1255
+ }
1317
1256
  if (prop.name === showAttribute) {
1318
1257
  if (propValue === "true") {
1319
1258
  continue;
@@ -1333,10 +1272,8 @@ ${indexAttribute}="${index}"`;
1333
1272
  }
1334
1273
  continue;
1335
1274
  }
1336
- if (prop.name === "className") {
1337
- if (prop.type === "string") {
1338
- classes.push(prop.value);
1339
- }
1275
+ if (prop.name === "className" && propValue !== void 0) {
1276
+ classes.push(propValue);
1340
1277
  continue;
1341
1278
  }
1342
1279
  if (propValue !== void 0) {
@@ -1346,7 +1283,7 @@ ${prop.name}={${propValue}}`;
1346
1283
  }
1347
1284
  if (classes.length !== 0) {
1348
1285
  generatedProps += `
1349
- className=${JSON.stringify(classes.join(" "))}`;
1286
+ className={${classes.join(` + " " + `)}}`;
1350
1287
  }
1351
1288
  let generatedElement = "";
1352
1289
  if (instance.component === collectionComponent) {
@@ -1379,7 +1316,13 @@ className=${JSON.stringify(classes.join(" "))}`;
1379
1316
  }
1380
1317
  if (conditionValue) {
1381
1318
  let conditionalElement = "";
1382
- conditionalElement += `{(${conditionValue}) &&
1319
+ let before = "";
1320
+ let after = "";
1321
+ if (context === "jsx") {
1322
+ before = "{";
1323
+ after = "}";
1324
+ }
1325
+ conditionalElement += `${before}(${conditionValue}) &&
1383
1326
  `;
1384
1327
  if (instance.component === collectionComponent) {
1385
1328
  conditionalElement += "<>\n";
@@ -1388,7 +1331,7 @@ className=${JSON.stringify(classes.join(" "))}`;
1388
1331
  } else {
1389
1332
  conditionalElement += generatedElement;
1390
1333
  }
1391
- conditionalElement += `}
1334
+ conditionalElement += `${after}
1392
1335
  `;
1393
1336
  return conditionalElement;
1394
1337
  }
@@ -1434,6 +1377,7 @@ var generateJsxChildren = ({
1434
1377
  continue;
1435
1378
  }
1436
1379
  generatedChildren += generateJsxElement({
1380
+ context: "jsx",
1437
1381
  scope,
1438
1382
  instance,
1439
1383
  props,
@@ -1476,6 +1420,7 @@ var generateWebstudioComponent = ({
1476
1420
  }
1477
1421
  const usedDataSources = /* @__PURE__ */ new Map();
1478
1422
  const generatedJsx = generateJsxElement({
1423
+ context: "expression",
1479
1424
  scope,
1480
1425
  instance,
1481
1426
  props,
@@ -1557,9 +1502,7 @@ export {
1557
1502
  componentCategories,
1558
1503
  coreMetas,
1559
1504
  corePropsMetas,
1560
- createElementsTree,
1561
1505
  createImageValueTransformer,
1562
- createInstanceChildrenElements,
1563
1506
  defaultStates,
1564
1507
  descendantComponent,
1565
1508
  generateCss,
@@ -1572,10 +1515,12 @@ export {
1572
1515
  getIndexesWithinAncestors,
1573
1516
  idAttribute,
1574
1517
  indexAttribute,
1518
+ isAttributeNameSafe,
1575
1519
  isCoreComponent,
1576
1520
  namespaceMeta,
1577
1521
  normalizeProps,
1578
1522
  portalComponent,
1523
+ rootComponent,
1579
1524
  selectorIdAttribute,
1580
1525
  showAttribute,
1581
1526
  stateCategories,
@@ -1,6 +1,7 @@
1
1
  import type { Instances, Instance, Props, Scope, DataSources, Prop } from "@webstudio-is/sdk";
2
2
  import type { IndexesWithinAncestors } from "./instance-utils";
3
- export declare const generateJsxElement: ({ scope, instance, props, dataSources, usedDataSources, indexesWithinAncestors, children, classesMap, }: {
3
+ export declare const generateJsxElement: ({ context, scope, instance, props, dataSources, usedDataSources, indexesWithinAncestors, children, classesMap, }: {
4
+ context?: "expression" | "jsx";
4
5
  scope: Scope;
5
6
  instance: Instance;
6
7
  props: Props;