@contentful/experiences-visual-editor-react 0.0.1-alpha.7 → 0.0.1-alpha.9
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/dist/index.js +405 -222
- package/dist/index.js.map +1 -1
- package/dist/renderApp.js +565 -334
- package/dist/renderApp.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -11,8 +11,8 @@ import { produce } from 'immer';
|
|
|
11
11
|
import { createPortal } from 'react-dom';
|
|
12
12
|
import { v4 } from 'uuid';
|
|
13
13
|
|
|
14
|
-
var css_248z$
|
|
15
|
-
styleInject(css_248z$
|
|
14
|
+
var css_248z$8 = "html,\nbody {\n margin: 0;\n padding: 0;\n}\n\n/*\n * All of these variables are tokens from Forma-36 and should not be adjusted as these\n * are global variables that may affect multiple places.\n * As our customers may use other design libraries, we try to avoid overlapping global\n * variables by always using the prefix `--exp-builder-` inside this SDK.\n */\n\n:root {\n /* Color tokens from Forma 36: https://f36.contentful.com/tokens/color-system */\n --exp-builder-blue100: #e8f5ff;\n --exp-builder-blue200: #ceecff;\n --exp-builder-blue300: #98cbff;\n --exp-builder-blue400: #40a0ff;\n --exp-builder-blue500: #036fe3;\n --exp-builder-blue600: #0059c8;\n --exp-builder-blue700: #0041ab;\n --exp-builder-blue800: #003298;\n --exp-builder-blue900: #002a8e;\n --exp-builder-gray100: #f7f9fa;\n --exp-builder-gray200: #e7ebee;\n --exp-builder-gray300: #cfd9e0;\n --exp-builder-gray400: #aec1cc;\n --exp-builder-gray500: #67728a;\n --exp-builder-gray600: #5a657c;\n --exp-builder-gray700: #414d63;\n --exp-builder-gray800: #1b273a;\n --exp-builder-gray900: #111b2b;\n --exp-builder-purple600: #6c3ecf;\n --exp-builder-red200: #ffe0e0;\n --exp-builder-red800: #7f0010;\n --exp-builder-color-white: #ffffff;\n --exp-builder-glow-primary: 0px 0px 0px 3px #e8f5ff;\n\n /* RGB colors for applying opacity */\n --exp-builder-blue100-rgb: 232, 245, 255;\n --exp-builder-blue300-rgb: 152, 203, 255;\n\n /* Spacing tokens from Forma 36: https://f36.contentful.com/tokens/spacing */\n --exp-builder-spacing-s: 0.75rem;\n --exp-builder-spacing-2xs: 0.25rem;\n\n /* Typography tokens from Forma 36: https://f36.contentful.com/tokens/typography */\n --exp-builder-font-size-l: 1rem;\n --exp-builder-font-size-m: 0.875rem;\n --exp-builder-font-stack-primary: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,\n sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;\n --exp-builder-line-height-condensed: 1.25;\n}\n";
|
|
15
|
+
styleInject(css_248z$8);
|
|
16
16
|
|
|
17
17
|
const INCOMING_EVENTS$1 = {
|
|
18
18
|
RequestEditorMode: 'requestEditorMode',
|
|
@@ -70,11 +70,13 @@ const CONTENTFUL_COMPONENTS$1 = {
|
|
|
70
70
|
},
|
|
71
71
|
};
|
|
72
72
|
const EMPTY_CONTAINER_HEIGHT$1 = '80px';
|
|
73
|
+
const DEFAULT_IMAGE_WIDTH = '500px';
|
|
73
74
|
var PostMessageMethods$2;
|
|
74
75
|
(function (PostMessageMethods) {
|
|
75
76
|
PostMessageMethods["REQUEST_ENTITIES"] = "REQUEST_ENTITIES";
|
|
76
77
|
PostMessageMethods["REQUESTED_ENTITIES"] = "REQUESTED_ENTITIES";
|
|
77
78
|
})(PostMessageMethods$2 || (PostMessageMethods$2 = {}));
|
|
79
|
+
const SUPPORTED_IMAGE_FORMATS = ['jpg', 'png', 'webp', 'gif', 'avif'];
|
|
78
80
|
|
|
79
81
|
const structureComponents = new Set([
|
|
80
82
|
CONTENTFUL_COMPONENTS$1.section.id,
|
|
@@ -225,24 +227,18 @@ const transformAlignment = (cfHorizontalAlignment, cfVerticalAlignment, cfFlexDi
|
|
|
225
227
|
? `safe ${cfHorizontalAlignment}`
|
|
226
228
|
: cfHorizontalAlignment,
|
|
227
229
|
};
|
|
228
|
-
const transformBackgroundImage = (cfBackgroundImageUrl,
|
|
229
|
-
const matchBackgroundSize = (
|
|
230
|
-
if ('fill' ===
|
|
230
|
+
const transformBackgroundImage = (cfBackgroundImageUrl, cfBackgroundImageOptions) => {
|
|
231
|
+
const matchBackgroundSize = (scaling) => {
|
|
232
|
+
if ('fill' === scaling)
|
|
231
233
|
return 'cover';
|
|
232
|
-
if ('fit' ===
|
|
234
|
+
if ('fit' === scaling)
|
|
233
235
|
return 'contain';
|
|
234
|
-
return undefined;
|
|
235
236
|
};
|
|
236
|
-
const matchBackgroundPosition = (
|
|
237
|
-
if (!
|
|
238
|
-
return
|
|
239
|
-
}
|
|
240
|
-
if ('string' !== typeof cfBackgroundImageAlignment) {
|
|
241
|
-
return undefined;
|
|
237
|
+
const matchBackgroundPosition = (alignment) => {
|
|
238
|
+
if (!alignment || 'string' !== typeof alignment) {
|
|
239
|
+
return;
|
|
242
240
|
}
|
|
243
|
-
let [horizontalAlignment, verticalAlignment] =
|
|
244
|
-
.trim()
|
|
245
|
-
.split(/\s+/, 2);
|
|
241
|
+
let [horizontalAlignment, verticalAlignment] = alignment.trim().split(/\s+/, 2);
|
|
246
242
|
// Special case for handling single values
|
|
247
243
|
// for backwards compatibility with single values 'right','left', 'center', 'top','bottom'
|
|
248
244
|
if (horizontalAlignment && !verticalAlignment) {
|
|
@@ -278,50 +274,29 @@ const transformBackgroundImage = (cfBackgroundImageUrl, cfBackgroundImageScaling
|
|
|
278
274
|
return `${horizontalAlignment} ${verticalAlignment}`;
|
|
279
275
|
};
|
|
280
276
|
if (!cfBackgroundImageUrl) {
|
|
281
|
-
return
|
|
277
|
+
return;
|
|
282
278
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
backgroundSize: matchBackgroundSize(cfBackgroundImageScaling),
|
|
288
|
-
};
|
|
289
|
-
};
|
|
290
|
-
const transformContentValue = (value, variableDefinition) => {
|
|
291
|
-
if (variableDefinition.type === 'RichText') {
|
|
292
|
-
return transformRichText(value);
|
|
279
|
+
let backgroundImage;
|
|
280
|
+
let backgroundImageSet;
|
|
281
|
+
if (typeof cfBackgroundImageUrl === 'string') {
|
|
282
|
+
backgroundImage = `url(${cfBackgroundImageUrl})`;
|
|
293
283
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
return {
|
|
299
|
-
data: {},
|
|
300
|
-
content: [
|
|
301
|
-
{
|
|
302
|
-
nodeType: BLOCKS.PARAGRAPH,
|
|
303
|
-
data: {},
|
|
304
|
-
content: [
|
|
305
|
-
{
|
|
306
|
-
data: {},
|
|
307
|
-
nodeType: 'text',
|
|
308
|
-
value: value,
|
|
309
|
-
marks: [],
|
|
310
|
-
},
|
|
311
|
-
],
|
|
312
|
-
},
|
|
313
|
-
],
|
|
314
|
-
nodeType: BLOCKS.DOCUMENT,
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
if (typeof value === 'object' && value.nodeType === BLOCKS.DOCUMENT) {
|
|
318
|
-
return value;
|
|
284
|
+
else {
|
|
285
|
+
const imgSet = cfBackgroundImageUrl.srcSet?.join(',');
|
|
286
|
+
backgroundImage = `url(${cfBackgroundImageUrl.url})`;
|
|
287
|
+
backgroundImageSet = `image-set(${imgSet})`;
|
|
319
288
|
}
|
|
320
|
-
return
|
|
289
|
+
return {
|
|
290
|
+
backgroundImage,
|
|
291
|
+
backgroundImage2: backgroundImageSet,
|
|
292
|
+
backgroundRepeat: cfBackgroundImageOptions?.scaling === 'tile' ? 'repeat' : 'no-repeat',
|
|
293
|
+
backgroundPosition: matchBackgroundPosition(cfBackgroundImageOptions?.alignment),
|
|
294
|
+
backgroundSize: matchBackgroundSize(cfBackgroundImageOptions?.scaling),
|
|
295
|
+
};
|
|
321
296
|
};
|
|
322
297
|
const transformWidthSizing = ({ value, cfMargin, }) => {
|
|
323
298
|
if (!value || !cfMargin)
|
|
324
|
-
return
|
|
299
|
+
return;
|
|
325
300
|
const transformedValue = transformFill(value);
|
|
326
301
|
const marginValues = cfMargin.split(' ');
|
|
327
302
|
const rightMargin = marginValues[1] || '0px';
|
|
@@ -339,7 +314,12 @@ const transformWidthSizing = ({ value, cfMargin, }) => {
|
|
|
339
314
|
return transformedValue;
|
|
340
315
|
};
|
|
341
316
|
|
|
342
|
-
const toCSSAttribute = (key) =>
|
|
317
|
+
const toCSSAttribute = (key) => {
|
|
318
|
+
let val = key.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase());
|
|
319
|
+
// Remove the number from the end of the key to allow for overrides on style properties
|
|
320
|
+
val = val.replace(/\d+$/, '');
|
|
321
|
+
return val;
|
|
322
|
+
};
|
|
343
323
|
const buildStyleTag = ({ styles, nodeId }) => {
|
|
344
324
|
const stylesStr = Object.entries(styles)
|
|
345
325
|
.filter(([, value]) => value !== undefined)
|
|
@@ -349,21 +329,22 @@ const buildStyleTag = ({ styles, nodeId }) => {
|
|
|
349
329
|
const styleRule = `.${className}{ ${stylesStr} }`;
|
|
350
330
|
return [className, styleRule];
|
|
351
331
|
};
|
|
352
|
-
const buildCfStyles = ({ cfHorizontalAlignment, cfVerticalAlignment, cfFlexDirection, cfFlexWrap, cfMargin, cfPadding, cfBackgroundColor, cfWidth, cfHeight, cfMaxWidth, cfBorder, cfGap, cfBackgroundImageUrl,
|
|
332
|
+
const buildCfStyles = ({ cfHorizontalAlignment, cfVerticalAlignment, cfFlexDirection, cfFlexWrap, cfMargin, cfPadding, cfBackgroundColor, cfWidth, cfHeight, cfMaxWidth, cfBorder, cfBorderRadius, cfGap, cfBackgroundImageUrl, cfBackgroundImageOptions, cfFontSize, cfFontWeight, cfImageOptions, cfLineHeight, cfLetterSpacing, cfTextColor, cfTextAlign, cfTextTransform, cfTextBold, cfTextItalic, cfTextUnderline, cfColumnSpan, }) => {
|
|
353
333
|
return {
|
|
354
334
|
margin: cfMargin,
|
|
355
335
|
padding: cfPadding,
|
|
356
336
|
backgroundColor: cfBackgroundColor,
|
|
357
|
-
width: transformWidthSizing({ value: cfWidth, cfMargin }),
|
|
358
|
-
height: transformFill(cfHeight),
|
|
337
|
+
width: transformWidthSizing({ value: cfWidth || cfImageOptions?.width, cfMargin }),
|
|
338
|
+
height: transformFill(cfHeight || cfImageOptions?.height),
|
|
359
339
|
maxWidth: cfMaxWidth,
|
|
360
340
|
...transformGridColumn(cfColumnSpan),
|
|
361
341
|
...transformBorderStyle(cfBorder),
|
|
342
|
+
borderRadius: cfBorderRadius,
|
|
362
343
|
gap: cfGap,
|
|
363
344
|
...transformAlignment(cfHorizontalAlignment, cfVerticalAlignment, cfFlexDirection),
|
|
364
345
|
flexDirection: cfFlexDirection,
|
|
365
346
|
flexWrap: cfFlexWrap,
|
|
366
|
-
...transformBackgroundImage(cfBackgroundImageUrl,
|
|
347
|
+
...transformBackgroundImage(cfBackgroundImageUrl, cfBackgroundImageOptions),
|
|
367
348
|
fontSize: cfFontSize,
|
|
368
349
|
fontWeight: cfTextBold ? 'bold' : cfFontWeight,
|
|
369
350
|
fontStyle: cfTextItalic ? 'italic' : 'normal',
|
|
@@ -374,10 +355,12 @@ const buildCfStyles = ({ cfHorizontalAlignment, cfVerticalAlignment, cfFlexDirec
|
|
|
374
355
|
textTransform: cfTextTransform,
|
|
375
356
|
textDecoration: cfTextUnderline ? 'underline' : 'none',
|
|
376
357
|
boxSizing: 'border-box',
|
|
358
|
+
objectFit: cfImageOptions?.objectFit,
|
|
359
|
+
objectPosition: cfImageOptions?.objectPosition,
|
|
377
360
|
};
|
|
378
361
|
};
|
|
379
362
|
/**
|
|
380
|
-
* Container/section default
|
|
363
|
+
* Container/section default behavior:
|
|
381
364
|
* Default height => height: EMPTY_CONTAINER_HEIGHT (120px)
|
|
382
365
|
* If a container component has children => height: 'fit-content'
|
|
383
366
|
*/
|
|
@@ -391,6 +374,206 @@ const calculateNodeDefaultHeight = ({ blockId, children, value, }) => {
|
|
|
391
374
|
return EMPTY_CONTAINER_HEIGHT$1;
|
|
392
375
|
};
|
|
393
376
|
|
|
377
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
378
|
+
function get(obj, path) {
|
|
379
|
+
if (!path.length) {
|
|
380
|
+
return obj;
|
|
381
|
+
}
|
|
382
|
+
try {
|
|
383
|
+
const [currentPath, ...nextPath] = path;
|
|
384
|
+
return get(obj[currentPath], nextPath);
|
|
385
|
+
}
|
|
386
|
+
catch (err) {
|
|
387
|
+
return undefined;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const getBoundValue = (entryOrAsset, path) => {
|
|
392
|
+
const value = get(entryOrAsset, path.split('/').slice(2, -1));
|
|
393
|
+
return value && typeof value == 'object' && value.url
|
|
394
|
+
? value.url
|
|
395
|
+
: value;
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
const transformRichText = (entryOrAsset, path) => {
|
|
399
|
+
const value = getBoundValue(entryOrAsset, path);
|
|
400
|
+
if (typeof value === 'string') {
|
|
401
|
+
return {
|
|
402
|
+
data: {},
|
|
403
|
+
content: [
|
|
404
|
+
{
|
|
405
|
+
nodeType: BLOCKS.PARAGRAPH,
|
|
406
|
+
data: {},
|
|
407
|
+
content: [
|
|
408
|
+
{
|
|
409
|
+
data: {},
|
|
410
|
+
nodeType: 'text',
|
|
411
|
+
value: value,
|
|
412
|
+
marks: [],
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
},
|
|
416
|
+
],
|
|
417
|
+
nodeType: BLOCKS.DOCUMENT,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
if (typeof value === 'object' && value.nodeType === BLOCKS.DOCUMENT) {
|
|
421
|
+
return value;
|
|
422
|
+
}
|
|
423
|
+
return undefined;
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
function getOptimizedImageUrl(url, width, quality, format) {
|
|
427
|
+
const params = new URLSearchParams();
|
|
428
|
+
if (width) {
|
|
429
|
+
params.append('w', width.toString());
|
|
430
|
+
}
|
|
431
|
+
if (quality && quality > 0 && quality < 100) {
|
|
432
|
+
params.append('q', quality.toString());
|
|
433
|
+
}
|
|
434
|
+
if (format) {
|
|
435
|
+
params.append('fm', format);
|
|
436
|
+
}
|
|
437
|
+
const queryString = params.toString();
|
|
438
|
+
return `${url}${queryString ? '?' + queryString : ''}`;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const MAX_WIDTH_ALLOWED$1 = 2000;
|
|
442
|
+
const getOptimizedBackgroundImageAsset = (file, widthStyle, quality = 100, format) => {
|
|
443
|
+
if (!validateParams(file, quality, format)) ;
|
|
444
|
+
const url = file.url;
|
|
445
|
+
const { width1x, width2x } = getWidths(widthStyle, file);
|
|
446
|
+
const imageUrl1x = getOptimizedImageUrl(url, width1x, quality, format);
|
|
447
|
+
const imageUrl2x = getOptimizedImageUrl(url, width2x, quality, format);
|
|
448
|
+
const srcSet = [`url(${imageUrl1x}) 1x`, `url(${imageUrl2x}) 2x`];
|
|
449
|
+
const returnedUrlImageUrl = getOptimizedImageUrl(url, width2x, quality, format);
|
|
450
|
+
const optimizedBackgroundImageAsset = {
|
|
451
|
+
url: returnedUrlImageUrl,
|
|
452
|
+
srcSet,
|
|
453
|
+
file,
|
|
454
|
+
};
|
|
455
|
+
return optimizedBackgroundImageAsset;
|
|
456
|
+
function validateParams(file, quality, format) {
|
|
457
|
+
if (!file.details.image) {
|
|
458
|
+
throw Error('No image in file asset to transform');
|
|
459
|
+
}
|
|
460
|
+
if (quality < 0 || quality > 100) {
|
|
461
|
+
throw Error('Quality must be between 0 and 100');
|
|
462
|
+
}
|
|
463
|
+
if (format && !SUPPORTED_IMAGE_FORMATS.includes(format)) {
|
|
464
|
+
throw Error(`Format must be one of ${SUPPORTED_IMAGE_FORMATS.join(', ')}`);
|
|
465
|
+
}
|
|
466
|
+
return true;
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
function getWidths(widthStyle, file) {
|
|
470
|
+
let width1x = 0;
|
|
471
|
+
let width2x = 0;
|
|
472
|
+
const intrinsicImageWidth = file.details.image.width;
|
|
473
|
+
if (widthStyle.endsWith('px')) {
|
|
474
|
+
width1x = Math.min(Number(widthStyle.replace('px', '')), intrinsicImageWidth);
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
width1x = Math.min(MAX_WIDTH_ALLOWED$1, intrinsicImageWidth);
|
|
478
|
+
}
|
|
479
|
+
width2x = Math.min(width1x * 2, intrinsicImageWidth);
|
|
480
|
+
return { width1x, width2x };
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const MAX_WIDTH_ALLOWED = 4000;
|
|
484
|
+
const getOptimizedImageAsset = (file, sizes, quality = 100, format) => {
|
|
485
|
+
if (!validateParams(file, quality, format)) ;
|
|
486
|
+
const url = file.url;
|
|
487
|
+
const maxWidth = Math.min(file.details.image.width, MAX_WIDTH_ALLOWED);
|
|
488
|
+
const numOfParts = Math.max(2, Math.ceil(maxWidth / 500));
|
|
489
|
+
const widthParts = Array.from({ length: numOfParts }, (_, index) => Math.ceil((index + 1) * (maxWidth / numOfParts)));
|
|
490
|
+
const srcSet = sizes
|
|
491
|
+
? widthParts.map((width) => `${getOptimizedImageUrl(url, width, quality, format)} ${width}w`)
|
|
492
|
+
: [];
|
|
493
|
+
const intrinsicImageWidth = file.details.image.width;
|
|
494
|
+
if (intrinsicImageWidth > MAX_WIDTH_ALLOWED) {
|
|
495
|
+
srcSet.push(`${getOptimizedImageUrl(url, undefined, quality, format)} ${intrinsicImageWidth}w`);
|
|
496
|
+
}
|
|
497
|
+
const returnedUrl = getOptimizedImageUrl(url, file.details.image.width > 2000 ? 2000 : undefined, quality, format);
|
|
498
|
+
const optimizedImageAsset = {
|
|
499
|
+
url: returnedUrl,
|
|
500
|
+
srcSet,
|
|
501
|
+
sizes,
|
|
502
|
+
file,
|
|
503
|
+
};
|
|
504
|
+
return optimizedImageAsset;
|
|
505
|
+
function validateParams(file, quality, format) {
|
|
506
|
+
if (!file.details.image) {
|
|
507
|
+
throw Error('No image in file asset to transform');
|
|
508
|
+
}
|
|
509
|
+
if (quality < 0 || quality > 100) {
|
|
510
|
+
throw Error('Quality must be between 0 and 100');
|
|
511
|
+
}
|
|
512
|
+
if (format && !SUPPORTED_IMAGE_FORMATS.includes(format)) {
|
|
513
|
+
throw Error(`Format must be one of ${SUPPORTED_IMAGE_FORMATS.join(', ')}`);
|
|
514
|
+
}
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
const transformMedia = (asset, variables, resolveDesignValue, variableName, path) => {
|
|
520
|
+
let value;
|
|
521
|
+
//TODO: this will be better served by injectable type transformers instead of if statement
|
|
522
|
+
if (variableName === 'cfImageAsset') {
|
|
523
|
+
const optionsVariableName = 'cfImageOptions';
|
|
524
|
+
const options = resolveDesignValue(variables[optionsVariableName]?.type === 'DesignValue'
|
|
525
|
+
? variables[optionsVariableName].valuesByBreakpoint
|
|
526
|
+
: {}, optionsVariableName);
|
|
527
|
+
if (!options) {
|
|
528
|
+
console.error(`Error transforming image asset: Required variable [${optionsVariableName}] missing from component definition`);
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
try {
|
|
532
|
+
value = getOptimizedImageAsset(asset.fields.file, options.targetSize, Number(options.quality), options.format);
|
|
533
|
+
return value;
|
|
534
|
+
}
|
|
535
|
+
catch (error) {
|
|
536
|
+
console.error('Error transforming image asset', error);
|
|
537
|
+
}
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
if (variableName === 'cfBackgroundImageUrl') {
|
|
541
|
+
const width = resolveDesignValue(variables['cfWidth']?.type === 'DesignValue' ? variables['cfWidth'].valuesByBreakpoint : {}, 'cfWidth');
|
|
542
|
+
const optionsVariableName = 'cfBackgroundImageOptions';
|
|
543
|
+
const options = resolveDesignValue(variables[optionsVariableName]?.type === 'DesignValue'
|
|
544
|
+
? variables[optionsVariableName].valuesByBreakpoint
|
|
545
|
+
: {}, optionsVariableName);
|
|
546
|
+
if (!options) {
|
|
547
|
+
console.error(`Error transforming image asset: Required variable [${optionsVariableName}] missing from component definition`);
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
try {
|
|
551
|
+
value = getOptimizedBackgroundImageAsset(asset.fields.file, width, Number(options.quality), options.format);
|
|
552
|
+
return value;
|
|
553
|
+
}
|
|
554
|
+
catch (error) {
|
|
555
|
+
console.error('Error transforming image asset', error);
|
|
556
|
+
}
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
// return getBoundValue(asset, entityStore, binding, path);
|
|
560
|
+
return getBoundValue(asset, path);
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
const transformBoundContentValue = (variables, entityStore, binding, resolveDesignValue, variableName, variableDefinition, path) => {
|
|
564
|
+
const entityOrAsset = entityStore.getEntryOrAsset(binding, path);
|
|
565
|
+
if (!entityOrAsset)
|
|
566
|
+
return;
|
|
567
|
+
switch (variableDefinition.type) {
|
|
568
|
+
case 'Media':
|
|
569
|
+
return transformMedia(entityOrAsset, variables, resolveDesignValue, variableName, path);
|
|
570
|
+
case 'RichText':
|
|
571
|
+
return transformRichText(entityOrAsset, path);
|
|
572
|
+
default:
|
|
573
|
+
return getBoundValue(entityOrAsset, path);
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
|
|
394
577
|
const getDataFromTree = (tree) => {
|
|
395
578
|
let dataSource = {};
|
|
396
579
|
let unboundValues = {};
|
|
@@ -522,48 +705,19 @@ const builtInStyles = {
|
|
|
522
705
|
description: 'The border of the section',
|
|
523
706
|
defaultValue: '0px solid rgba(0, 0, 0, 0)',
|
|
524
707
|
},
|
|
525
|
-
|
|
526
|
-
displayName: '
|
|
708
|
+
cfBorderRadius: {
|
|
709
|
+
displayName: 'Border Radius',
|
|
527
710
|
type: 'Text',
|
|
528
711
|
group: 'style',
|
|
529
|
-
description: 'The
|
|
712
|
+
description: 'The border radius of the section',
|
|
530
713
|
defaultValue: '0px',
|
|
531
714
|
},
|
|
532
|
-
|
|
533
|
-
displayName: '
|
|
534
|
-
type: 'Text',
|
|
535
|
-
defaultValue: '',
|
|
536
|
-
description: 'Background image for section or container',
|
|
537
|
-
},
|
|
538
|
-
cfBackgroundImageScaling: {
|
|
539
|
-
displayName: 'Image scaling',
|
|
540
|
-
type: 'Text',
|
|
541
|
-
group: 'style',
|
|
542
|
-
description: 'Adjust background image to fit, fill or tile the container',
|
|
543
|
-
defaultValue: 'fit',
|
|
544
|
-
validations: {
|
|
545
|
-
in: [
|
|
546
|
-
{
|
|
547
|
-
value: 'fill',
|
|
548
|
-
displayName: 'Fill',
|
|
549
|
-
},
|
|
550
|
-
{
|
|
551
|
-
value: 'fit',
|
|
552
|
-
displayName: 'Fit',
|
|
553
|
-
},
|
|
554
|
-
{
|
|
555
|
-
value: 'tile',
|
|
556
|
-
displayName: 'Tile',
|
|
557
|
-
},
|
|
558
|
-
],
|
|
559
|
-
},
|
|
560
|
-
},
|
|
561
|
-
cfBackgroundImageAlignment: {
|
|
562
|
-
displayName: 'Image alignment',
|
|
715
|
+
cfGap: {
|
|
716
|
+
displayName: 'Gap',
|
|
563
717
|
type: 'Text',
|
|
564
718
|
group: 'style',
|
|
565
|
-
description: '
|
|
566
|
-
defaultValue: '
|
|
719
|
+
description: 'The spacing between the elements of the section',
|
|
720
|
+
defaultValue: '0px',
|
|
567
721
|
},
|
|
568
722
|
cfHyperlink: {
|
|
569
723
|
displayName: 'Hyperlink',
|
|
@@ -612,6 +766,40 @@ const optionalBuiltInStyles = {
|
|
|
612
766
|
description: 'The font weight of the element',
|
|
613
767
|
defaultValue: '400',
|
|
614
768
|
},
|
|
769
|
+
cfImageAsset: {
|
|
770
|
+
displayName: 'Image',
|
|
771
|
+
type: 'Media',
|
|
772
|
+
description: 'Image to display',
|
|
773
|
+
},
|
|
774
|
+
cfImageOptions: {
|
|
775
|
+
displayName: 'Image options',
|
|
776
|
+
type: 'Object',
|
|
777
|
+
group: 'style',
|
|
778
|
+
defaultValue: {
|
|
779
|
+
width: DEFAULT_IMAGE_WIDTH,
|
|
780
|
+
height: '100%',
|
|
781
|
+
objectFit: 'none',
|
|
782
|
+
objectPosition: 'center center',
|
|
783
|
+
quality: '100',
|
|
784
|
+
targetSize: DEFAULT_IMAGE_WIDTH,
|
|
785
|
+
},
|
|
786
|
+
},
|
|
787
|
+
cfBackgroundImageUrl: {
|
|
788
|
+
displayName: 'Background image',
|
|
789
|
+
type: 'Media',
|
|
790
|
+
description: 'Background image for component',
|
|
791
|
+
},
|
|
792
|
+
cfBackgroundImageOptions: {
|
|
793
|
+
displayName: 'Background image options',
|
|
794
|
+
type: 'Object',
|
|
795
|
+
group: 'style',
|
|
796
|
+
defaultValue: {
|
|
797
|
+
scaling: 'fill',
|
|
798
|
+
alignment: 'left top',
|
|
799
|
+
quality: '100',
|
|
800
|
+
targetSize: '2000px',
|
|
801
|
+
},
|
|
802
|
+
},
|
|
615
803
|
cfLineHeight: {
|
|
616
804
|
displayName: 'Line Height',
|
|
617
805
|
type: 'Text',
|
|
@@ -813,6 +1001,7 @@ const builtInStylesWithDesignTokens = [
|
|
|
813
1001
|
'cfHeight',
|
|
814
1002
|
'cfBackgroundColor',
|
|
815
1003
|
'cfBorder',
|
|
1004
|
+
'cfBorderRadius',
|
|
816
1005
|
'cfFontSize',
|
|
817
1006
|
'cfLineHeight',
|
|
818
1007
|
'cfLetterSpacing',
|
|
@@ -994,29 +1183,9 @@ const sendMessage = (eventType, data) => {
|
|
|
994
1183
|
}, '*');
|
|
995
1184
|
};
|
|
996
1185
|
|
|
997
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
998
|
-
function get(obj, path) {
|
|
999
|
-
if (!path.length) {
|
|
1000
|
-
return obj;
|
|
1001
|
-
}
|
|
1002
|
-
try {
|
|
1003
|
-
const [currentPath, ...nextPath] = path;
|
|
1004
|
-
return get(obj[currentPath], nextPath);
|
|
1005
|
-
}
|
|
1006
|
-
catch (err) {
|
|
1007
|
-
return undefined;
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
function transformAssetFileToUrl(fieldValue) {
|
|
1012
|
-
return fieldValue && typeof fieldValue == 'object' && fieldValue.url
|
|
1013
|
-
? fieldValue.url
|
|
1014
|
-
: fieldValue;
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
1186
|
/**
|
|
1018
1187
|
* Base Store for entities
|
|
1019
|
-
* Can be
|
|
1188
|
+
* Can be extended for the different loading behaviours (editor, production, ..)
|
|
1020
1189
|
*/
|
|
1021
1190
|
class EntityStoreBase {
|
|
1022
1191
|
constructor({ entities, locale }) {
|
|
@@ -1033,68 +1202,26 @@ class EntityStoreBase {
|
|
|
1033
1202
|
updateEntity(entity) {
|
|
1034
1203
|
this.addEntity(entity);
|
|
1035
1204
|
}
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
resolvedFieldset.push([entityToResolveFieldsFrom, field, _localeQualifier]);
|
|
1049
|
-
break;
|
|
1050
|
-
}
|
|
1051
|
-
const fieldValue = get(entityToResolveFieldsFrom, ['fields', field]);
|
|
1052
|
-
if (undefined === fieldValue) {
|
|
1053
|
-
return {
|
|
1054
|
-
resolvedFieldset,
|
|
1055
|
-
isFullyResolved: false,
|
|
1056
|
-
reason: `Cannot resolve field Link<${entityToResolveFieldsFrom.sys.type}>(sys.id=${entityToResolveFieldsFrom.sys.id}).fields[${field}] as field value is not defined`,
|
|
1057
|
-
};
|
|
1058
|
-
}
|
|
1059
|
-
else if (isLink(fieldValue)) {
|
|
1060
|
-
const entity = this.getEntityFromLink(fieldValue);
|
|
1061
|
-
if (entity === undefined) {
|
|
1062
|
-
throw new Error(`Logic Error: Broken Precondition [by the time resolution of deep path happens all referents should be in EntityStore]: Cannot resolve field ${field} of a fieldset row [${JSON.stringify(row)}] as linked entity not found in the EntityStore. ${JSON.stringify({
|
|
1063
|
-
link: fieldValue,
|
|
1064
|
-
})}`);
|
|
1065
|
-
}
|
|
1066
|
-
resolvedFieldset.push([entityToResolveFieldsFrom, field, _localeQualifier]);
|
|
1067
|
-
entityToResolveFieldsFrom = entity; // we move up
|
|
1068
|
-
}
|
|
1069
|
-
else {
|
|
1070
|
-
// TODO: Eg. when someone changed the schema and the field is not a link anymore, what should we return then?
|
|
1071
|
-
throw new Error(`LogicError: Invalid value of a field we consider a reference field. Cannot resolve field ${field} of a fieldset as it is not a link, neither undefined.`);
|
|
1072
|
-
}
|
|
1205
|
+
getEntryOrAsset(linkOrEntryOrAsset, path) {
|
|
1206
|
+
if (isDeepPath(path)) {
|
|
1207
|
+
return this.getDeepEntry(linkOrEntryOrAsset, path);
|
|
1208
|
+
}
|
|
1209
|
+
let entity;
|
|
1210
|
+
if (isLink(linkOrEntryOrAsset)) {
|
|
1211
|
+
const resolvedEntity = linkOrEntryOrAsset.sys.linkType === 'Entry'
|
|
1212
|
+
? this.entryMap.get(linkOrEntryOrAsset.sys.id)
|
|
1213
|
+
: this.assetMap.get(linkOrEntryOrAsset.sys.id);
|
|
1214
|
+
if (!resolvedEntity || resolvedEntity.sys.type !== linkOrEntryOrAsset.sys.linkType) {
|
|
1215
|
+
console.warn(`Experience references unresolved entity: ${JSON.stringify(linkOrEntryOrAsset)}`);
|
|
1216
|
+
return;
|
|
1073
1217
|
}
|
|
1074
|
-
|
|
1075
|
-
resolvedFieldset,
|
|
1076
|
-
isFullyResolved: true,
|
|
1077
|
-
};
|
|
1078
|
-
};
|
|
1079
|
-
const headEntity = isLink(headLinkOrEntity)
|
|
1080
|
-
? this.getEntityFromLink(headLinkOrEntity)
|
|
1081
|
-
: headLinkOrEntity;
|
|
1082
|
-
if (undefined === headEntity) {
|
|
1083
|
-
return;
|
|
1218
|
+
entity = resolvedEntity;
|
|
1084
1219
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
// in case we can't follow till the end, we should signal that there was null-reference in the path
|
|
1089
|
-
const { resolvedFieldset, isFullyResolved, reason } = resolveFieldset(unresolvedFieldset, headEntity);
|
|
1090
|
-
if (!isFullyResolved) {
|
|
1091
|
-
reason &&
|
|
1092
|
-
console.debug(`[experiences-sdk-react::EntityStoreBased::getValueDeep()] Deep path wasn't resolved till leaf node, falling back to undefined, because: ${reason}`);
|
|
1093
|
-
return undefined;
|
|
1220
|
+
else {
|
|
1221
|
+
// We already have the complete entity in preview & delivery (resolved by the CMA client)
|
|
1222
|
+
entity = linkOrEntryOrAsset;
|
|
1094
1223
|
}
|
|
1095
|
-
|
|
1096
|
-
const fieldValue = get(leafEntity, ['fields', field]); // is allowed to be undefined (when non-required field not set; or even when field does NOT exist on the type)
|
|
1097
|
-
return transformAssetFileToUrl(fieldValue);
|
|
1224
|
+
return entity;
|
|
1098
1225
|
}
|
|
1099
1226
|
/**
|
|
1100
1227
|
* @deprecated in the base class this should be simply an abstract method
|
|
@@ -1151,7 +1278,7 @@ class EntityStoreBase {
|
|
|
1151
1278
|
if (missing.length) {
|
|
1152
1279
|
// TODO: move to `debug` utils once it is extracted
|
|
1153
1280
|
console.warn(`Asset "${id}" is not in the store`);
|
|
1154
|
-
return
|
|
1281
|
+
return;
|
|
1155
1282
|
}
|
|
1156
1283
|
return resolved[0];
|
|
1157
1284
|
}
|
|
@@ -1167,7 +1294,7 @@ class EntityStoreBase {
|
|
|
1167
1294
|
if (missing.length) {
|
|
1168
1295
|
// TODO: move to `debug` utils once it is extracted
|
|
1169
1296
|
console.warn(`Entry "${id}" is not in the store`);
|
|
1170
|
-
return
|
|
1297
|
+
return;
|
|
1171
1298
|
}
|
|
1172
1299
|
return resolved[0];
|
|
1173
1300
|
}
|
|
@@ -1178,6 +1305,70 @@ class EntityStoreBase {
|
|
|
1178
1305
|
}
|
|
1179
1306
|
return resolved;
|
|
1180
1307
|
}
|
|
1308
|
+
getDeepEntry(linkOrEntryOrAsset, path) {
|
|
1309
|
+
const resolveFieldset = (unresolvedFieldset, headEntry) => {
|
|
1310
|
+
const resolvedFieldset = [];
|
|
1311
|
+
let entityToResolveFieldsFrom = headEntry;
|
|
1312
|
+
for (let i = 0; i < unresolvedFieldset.length; i++) {
|
|
1313
|
+
const isLeaf = i === unresolvedFieldset.length - 1; // with last row, we are not expecting a link, but a value
|
|
1314
|
+
const row = unresolvedFieldset[i];
|
|
1315
|
+
const [, field, _localeQualifier] = row;
|
|
1316
|
+
if (!entityToResolveFieldsFrom) {
|
|
1317
|
+
throw new Error(`Logic Error: Cannot resolve field ${field} of a fieldset as there is no entity to resolve it from.`);
|
|
1318
|
+
}
|
|
1319
|
+
if (isLeaf) {
|
|
1320
|
+
resolvedFieldset.push([entityToResolveFieldsFrom, field, _localeQualifier]);
|
|
1321
|
+
break;
|
|
1322
|
+
}
|
|
1323
|
+
const fieldValue = get(entityToResolveFieldsFrom, ['fields', field]);
|
|
1324
|
+
if (undefined === fieldValue) {
|
|
1325
|
+
return {
|
|
1326
|
+
resolvedFieldset,
|
|
1327
|
+
isFullyResolved: false,
|
|
1328
|
+
reason: `Cannot resolve field Link<${entityToResolveFieldsFrom.sys.type}>(sys.id=${entityToResolveFieldsFrom.sys.id}).fields[${field}] as field value is not defined`,
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1331
|
+
else if (isLink(fieldValue)) {
|
|
1332
|
+
const entity = this.getEntityFromLink(fieldValue);
|
|
1333
|
+
if (entity === undefined) {
|
|
1334
|
+
return {
|
|
1335
|
+
resolvedFieldset,
|
|
1336
|
+
isFullyResolved: false,
|
|
1337
|
+
reason: `Field reference Link (sys.id=${fieldValue.sys.id}) not found in the EntityStore, waiting...`,
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1340
|
+
resolvedFieldset.push([entityToResolveFieldsFrom, field, _localeQualifier]);
|
|
1341
|
+
entityToResolveFieldsFrom = entity; // we move up
|
|
1342
|
+
}
|
|
1343
|
+
else {
|
|
1344
|
+
// TODO: Eg. when someone changed the schema and the field is not a link anymore, what should we return then?
|
|
1345
|
+
throw new Error(`LogicError: Invalid value of a field we consider a reference field. Cannot resolve field ${field} of a fieldset as it is not a link, neither undefined.`);
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
return {
|
|
1349
|
+
resolvedFieldset,
|
|
1350
|
+
isFullyResolved: true,
|
|
1351
|
+
};
|
|
1352
|
+
};
|
|
1353
|
+
const headEntity = isLink(linkOrEntryOrAsset)
|
|
1354
|
+
? this.getEntityFromLink(linkOrEntryOrAsset)
|
|
1355
|
+
: linkOrEntryOrAsset;
|
|
1356
|
+
if (undefined === headEntity) {
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1359
|
+
const unresolvedFieldset = parseDataSourcePathIntoFieldset(path);
|
|
1360
|
+
// The purpose here is to take this intermediate representation of the deep-path
|
|
1361
|
+
// and to follow the links to the leaf-entity and field
|
|
1362
|
+
// in case we can't follow till the end, we should signal that there was null-reference in the path
|
|
1363
|
+
const { resolvedFieldset, isFullyResolved, reason } = resolveFieldset(unresolvedFieldset, headEntity);
|
|
1364
|
+
if (!isFullyResolved) {
|
|
1365
|
+
reason &&
|
|
1366
|
+
console.debug(`[exp-builder.sdk::EntityStoreBased::getValueDeep()] Deep path wasn't resolved till leaf node, falling back to undefined, because: ${reason}`);
|
|
1367
|
+
return;
|
|
1368
|
+
}
|
|
1369
|
+
const [leafEntity] = resolvedFieldset[resolvedFieldset.length - 1];
|
|
1370
|
+
return leafEntity;
|
|
1371
|
+
}
|
|
1181
1372
|
isAsset(entity) {
|
|
1182
1373
|
return entity.sys.type === 'Asset';
|
|
1183
1374
|
}
|
|
@@ -1356,11 +1547,16 @@ class EditorModeEntityStore extends EditorEntityStore {
|
|
|
1356
1547
|
const { missing: missingAssetIds } = this.getEntitiesFromMap('Asset', uniqueAssetIds);
|
|
1357
1548
|
return { missingEntryIds, missingAssetIds };
|
|
1358
1549
|
}
|
|
1359
|
-
getValue(
|
|
1360
|
-
|
|
1550
|
+
getValue(entityLinkOrEntity, path) {
|
|
1551
|
+
const entity = this.getEntryOrAsset(entityLinkOrEntity, path.join('/'));
|
|
1552
|
+
if (!entity) {
|
|
1361
1553
|
return;
|
|
1362
|
-
|
|
1363
|
-
|
|
1554
|
+
}
|
|
1555
|
+
const fieldValue = get(entity, path);
|
|
1556
|
+
// walk around to render asset files
|
|
1557
|
+
return fieldValue && typeof fieldValue == 'object' && fieldValue.url
|
|
1558
|
+
? fieldValue.url
|
|
1559
|
+
: fieldValue;
|
|
1364
1560
|
}
|
|
1365
1561
|
}
|
|
1366
1562
|
|
|
@@ -1442,9 +1638,9 @@ function gatherDeepReferencesFromTree(startingNode, dataSource) {
|
|
|
1442
1638
|
return deepReferences;
|
|
1443
1639
|
}
|
|
1444
1640
|
|
|
1445
|
-
var css_248z$
|
|
1641
|
+
var css_248z$7 = ".styles-module_DraggableComponent__m5-dA {\n pointer-events: all;\n position: relative;\n transition: outline 0.2s;\n cursor: grab;\n box-sizing: border-box;\n display: flex;\n}\n\n.styles-module_DraggableComponent__m5-dA:before {\n content: '';\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n outline-offset: -2px;\n outline: 2px solid transparent;\n z-index: 1;\n pointer-events: none;\n}\n\n.styles-module_DraggableClone__X8zTA:before {\n outline: 2px solid var(--exp-builder-blue500);\n}\n\n.styles-module_DraggableClone__X8zTA,\n.styles-module_DraggableClone__X8zTA * {\n pointer-events: none !important;\n}\n\n.styles-module_DraggableComponent__m5-dA:not(.styles-module_userIsDragging__lqbjG) :not(.styles-module_DraggableComponent__m5-dA) {\n pointer-events: none;\n}\n\n.styles-module_isDragging__WHjPU {\n overflow: hidden;\n}\n\n.styles-module_isSelected__BzICQ:before {\n outline: 2px solid transparent !important;\n}\n\n.styles-module_overlay__r4th9 {\n position: absolute;\n display: flex;\n align-items: center;\n min-width: max-content;\n height: 24px;\n z-index: 1;\n font-family: var(--exp-builder-font-stack-primary);\n font-size: 14px;\n font-weight: 500;\n background-color: var(--exp-builder-gray500);\n color: var(--exp-builder-color-white);\n border-radius: 0 0 2px 0;\n padding: 4px 12px 4px 12px;\n transition: opacity 0.2s;\n opacity: 0;\n text-wrap: nowrap;\n}\n\n.styles-module_overlayContainer__eiX-5 {\n opacity: 0;\n}\n\n.styles-module_overlayAssembly__tOzZU {\n background-color: var(--exp-builder-purple600);\n}\n\n.styles-module_userIsDragging__lqbjG > .styles-module_overlay__r4th9,\n.styles-module_userIsDragging__lqbjG > .styles-module_overlayContainer__eiX-5 {\n opacity: 0 !important;\n}\n\n.styles-module_userIsDragging__lqbjG:before {\n outline: 2px solid transparent !important;\n}\n\n.styles-module_DraggableComponent__m5-dA:hover:not(:has(div[data-rfd-draggable-id]:hover)) > .styles-module_overlay__r4th9 {\n opacity: 1;\n}\n\n.styles-module_DraggableComponent__m5-dA:hover:before,\n.styles-module_DraggableComponent__m5-dA:hover div[data-rfd-draggable-id]:before {\n outline: 2px dashed var(--exp-builder-gray500);\n}\n\n.styles-module_DraggableComponent__m5-dA:hover:not(:has(div[data-rfd-draggable-id]:hover)):before {\n outline: 2px solid var(--exp-builder-gray500);\n}\n\n.styles-module_isAssemblyBlock__Y3Avk:hover:before,\n.styles-module_isAssemblyBlock__Y3Avk:hover div[data-rfd-draggable-id]:before,\n.styles-module_DraggableComponent__m5-dA:hover div[data-rfd-draggable-id][data-cf-node-block-type^='assembly']:before {\n outline: 2px dashed var(--exp-builder-purple600);\n}\n\n.styles-module_isAssemblyBlock__Y3Avk:hover:not(:has(div[data-rfd-draggable-id]:hover)):before {\n outline: 2px solid var(--exp-builder-purple600);\n}\n";
|
|
1446
1642
|
var styles$3 = {"DraggableComponent":"styles-module_DraggableComponent__m5-dA","DraggableClone":"styles-module_DraggableClone__X8zTA","userIsDragging":"styles-module_userIsDragging__lqbjG","isDragging":"styles-module_isDragging__WHjPU","isSelected":"styles-module_isSelected__BzICQ","overlay":"styles-module_overlay__r4th9","overlayContainer":"styles-module_overlayContainer__eiX-5","overlayAssembly":"styles-module_overlayAssembly__tOzZU","isAssemblyBlock":"styles-module_isAssemblyBlock__Y3Avk"};
|
|
1447
|
-
styleInject(css_248z$
|
|
1643
|
+
styleInject(css_248z$7);
|
|
1448
1644
|
|
|
1449
1645
|
const SCROLL_STATES = {
|
|
1450
1646
|
Start: 'scrollStart',
|
|
@@ -1547,13 +1743,15 @@ const CF_STYLE_ATTRIBUTES = [
|
|
|
1547
1743
|
'cfWidth',
|
|
1548
1744
|
'cfMaxWidth',
|
|
1549
1745
|
'cfHeight',
|
|
1746
|
+
'cfImageAsset',
|
|
1747
|
+
'cfImageOptions',
|
|
1748
|
+
'cfBackgroundImageUrl',
|
|
1749
|
+
'cfBackgroundImageOptions',
|
|
1550
1750
|
'cfFlexDirection',
|
|
1551
1751
|
'cfFlexWrap',
|
|
1552
1752
|
'cfBorder',
|
|
1753
|
+
'cfBorderRadius',
|
|
1553
1754
|
'cfGap',
|
|
1554
|
-
'cfBackgroundImageUrl',
|
|
1555
|
-
'cfBackgroundImageScaling',
|
|
1556
|
-
'cfBackgroundImageAlignment',
|
|
1557
1755
|
'cfFontSize',
|
|
1558
1756
|
'cfFontWeight',
|
|
1559
1757
|
'cfLineHeight',
|
|
@@ -1568,6 +1766,8 @@ const CF_STYLE_ATTRIBUTES = [
|
|
|
1568
1766
|
// we need to keep those in this constant array
|
|
1569
1767
|
// so that omit() in <VisualEditorBlock> and <CompositionBlock>
|
|
1570
1768
|
// can filter them out and not pass as props
|
|
1769
|
+
'cfBackgroundImageScaling',
|
|
1770
|
+
'cfBackgroundImageAlignment',
|
|
1571
1771
|
'cfBackgroundImageAlignmentVertical',
|
|
1572
1772
|
'cfBackgroundImageAlignmentHorizontal',
|
|
1573
1773
|
];
|
|
@@ -2161,48 +2361,25 @@ const useComponentProps = ({ node, areEntitiesFetched, resolveDesignValue, rende
|
|
|
2161
2361
|
};
|
|
2162
2362
|
}
|
|
2163
2363
|
else if (variableMapping.type === 'BoundValue') {
|
|
2164
|
-
|
|
2165
|
-
console.debug(`[experiences-sdk-react::useComponentProps] Idle-cycle: as entities are not fetched(areEntitiesFetched=${areEntitiesFetched}), we cannot resolve bound values for ${variableName} so we just resolve them to default values.`);
|
|
2166
|
-
// Just forcing default value (if we're in idle-cycle, entities are missing)
|
|
2167
|
-
return {
|
|
2168
|
-
...acc,
|
|
2169
|
-
[variableName]: transformContentValue(variableDefinition.defaultValue, variableDefinition),
|
|
2170
|
-
};
|
|
2171
|
-
}
|
|
2172
|
-
if (isDeepPath(variableMapping.path)) {
|
|
2173
|
-
const [, uuid] = variableMapping.path.split('/');
|
|
2174
|
-
const link = dataSource[uuid];
|
|
2175
|
-
const boundValue = entityStore?.getValueDeep(link, variableMapping.path);
|
|
2176
|
-
const value = boundValue || variableDefinition.defaultValue;
|
|
2177
|
-
return {
|
|
2178
|
-
...acc,
|
|
2179
|
-
[variableName]: transformContentValue(value, variableDefinition),
|
|
2180
|
-
};
|
|
2181
|
-
}
|
|
2182
|
-
// // take value from the datasource for both bound and unbound value types
|
|
2183
|
-
const [, uuid, ...path] = variableMapping.path.split('/');
|
|
2364
|
+
const [, uuid, path] = variableMapping.path.split('/');
|
|
2184
2365
|
const binding = dataSource[uuid];
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
: undefined;
|
|
2366
|
+
const variableDefinition = definition.variables[variableName];
|
|
2367
|
+
let boundValue = transformBoundContentValue(node.data.props, entityStore, binding, resolveDesignValue, variableName, variableDefinition, variableMapping.path);
|
|
2188
2368
|
// In some cases, there may be an asset linked in the path, so we need to consider this scenario:
|
|
2189
2369
|
// If no 'boundValue' is found, we also attempt to extract the value associated with the second-to-last item in the path.
|
|
2190
2370
|
// If successful, it means we have identified the linked asset.
|
|
2191
2371
|
if (!boundValue) {
|
|
2192
2372
|
const maybeBoundAsset = areEntitiesFetched
|
|
2193
|
-
? entityStore.getValue(binding, path.slice(0, -2))
|
|
2373
|
+
? entityStore.getValue(binding, path.split('/').slice(0, -2))
|
|
2194
2374
|
: undefined;
|
|
2195
2375
|
if (isLinkToAsset(maybeBoundAsset)) {
|
|
2196
2376
|
boundValue = maybeBoundAsset;
|
|
2197
2377
|
}
|
|
2198
2378
|
}
|
|
2199
|
-
if (typeof boundValue === 'object' && boundValue.sys?.linkType === 'Asset') {
|
|
2200
|
-
boundValue = entityStore?.getValue(boundValue, ['fields', 'file']);
|
|
2201
|
-
}
|
|
2202
2379
|
const value = boundValue || variableDefinition.defaultValue;
|
|
2203
2380
|
return {
|
|
2204
2381
|
...acc,
|
|
2205
|
-
[variableName]:
|
|
2382
|
+
[variableName]: value,
|
|
2206
2383
|
};
|
|
2207
2384
|
}
|
|
2208
2385
|
else {
|
|
@@ -2275,12 +2452,15 @@ const useComponentProps = ({ node, areEntitiesFetched, resolveDesignValue, rende
|
|
|
2275
2452
|
'data-cf-node-block-id': node.data.blockId,
|
|
2276
2453
|
'data-cf-node-block-type': node.type,
|
|
2277
2454
|
};
|
|
2455
|
+
//List explicit style props that will end up being passed to the component
|
|
2456
|
+
const stylesToKeep = ['cfImageAsset'];
|
|
2457
|
+
const stylesToRemove = CF_STYLE_ATTRIBUTES.filter((style) => !stylesToKeep.includes(style));
|
|
2278
2458
|
const componentProps = {
|
|
2279
2459
|
className: componentClass,
|
|
2280
2460
|
editorMode: true,
|
|
2281
2461
|
node,
|
|
2282
2462
|
renderDropzone,
|
|
2283
|
-
...omit(props,
|
|
2463
|
+
...omit(props, stylesToRemove, ['cfHyperlink', 'cfOpenInNewTab']),
|
|
2284
2464
|
...(definition.children ? { children: renderDropzone(node) } : {}),
|
|
2285
2465
|
};
|
|
2286
2466
|
return { componentProps, wrapperProps };
|
|
@@ -2302,13 +2482,16 @@ var PostMessageMethods;
|
|
|
2302
2482
|
PostMessageMethods["REQUESTED_ENTITIES"] = "REQUESTED_ENTITIES";
|
|
2303
2483
|
})(PostMessageMethods || (PostMessageMethods = {}));
|
|
2304
2484
|
|
|
2305
|
-
var css_248z$
|
|
2485
|
+
var css_248z$5 = ".cf-heading {\n white-space: pre-line;\n}\n";
|
|
2486
|
+
styleInject(css_248z$5);
|
|
2487
|
+
|
|
2488
|
+
var css_248z$4 = ".cf-richtext {\n white-space: pre-line;\n}\n";
|
|
2306
2489
|
styleInject(css_248z$4);
|
|
2307
2490
|
|
|
2308
|
-
var css_248z$3 = ".cf-
|
|
2491
|
+
var css_248z$3 = ".cf-text {\n white-space: pre-line;\n}\n";
|
|
2309
2492
|
styleInject(css_248z$3);
|
|
2310
2493
|
|
|
2311
|
-
var css_248z$2$1 = ".cf-
|
|
2494
|
+
var css_248z$2$1 = ".cf-no-image {\n position: relative;\n}\n\n.cf-no-image img {\n background-color: var(--cf-color-gray100);\n outline-offset: -2px;\n outline: 2px solid rgba(var(--cf-color-gray400-rgb), 0.5);\n}\n\n[data-ctfl-draggable-id] .cf-no-image {\n width: 100%;\n height: 100%;\n}\n\n[data-ctfl-draggable-id] .cf-no-image img {\n width: 100%;\n}\n\n.cf-no-image svg {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n height: var(--cf-text-3xl);\n width: var(--cf-text-3xl);\n max-height: 100%;\n max-width: 100%;\n}\n\n.cf-no-image svg path {\n fill: var(--cf-color-gray400);\n}\n";
|
|
2312
2495
|
styleInject(css_248z$2$1);
|
|
2313
2496
|
|
|
2314
2497
|
var css_248z$1$1 = ".contentful-container {\n position: relative;\n display: flex;\n box-sizing: border-box;\n pointer-events: all;\n}\n\n.contentful-container::-webkit-scrollbar {\n display: none; /* Safari and Chrome */\n}\n\n.cf-single-column-wrapper {\n position: relative;\n}\n\n.cf-container-wrapper {\n position: relative;\n width: 100%;\n}\n\n.cf-container-label {\n position: absolute;\n pointer-events: none;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n overflow-x: clip;\n font-family: var(--exp-builder-font-stack-primary);\n font-size: 12px;\n color: var(--exp-builder-gray400);\n z-index: 10;\n}\n\n/* used by ContentfulSectionAsHyperlink.tsx */\n\n.contentful-container-link,\n.contentful-container-link:active,\n.contentful-container-link:visited,\n.contentful-container-link:hover,\n.contentful-container-link:read-write,\n.contentful-container-link:focus-visible {\n color: inherit;\n text-decoration: unset;\n outline: unset;\n}\n";
|
|
@@ -2336,8 +2519,8 @@ const Flex = forwardRef(({ id, children, onMouseEnter, onMouseUp, onMouseLeave,
|
|
|
2336
2519
|
});
|
|
2337
2520
|
Flex.displayName = 'Flex';
|
|
2338
2521
|
|
|
2339
|
-
var css_248z$
|
|
2340
|
-
styleInject(css_248z$
|
|
2522
|
+
var css_248z$6 = ".Columns {\n display: flex;\n gap: 24px;\n grid-template-columns: repeat(12, 1fr);\n flex-direction: column;\n min-height: 0; /* NEW */\n min-width: 0; /* NEW; needed for Firefox */\n}\n\n@media (min-width: 768px) {\n .Columns {\n display: grid;\n }\n}\n\n.cf-single-column-wrapper {\n position: relative;\n}\n\n.cf-single-column {\n pointer-events: all;\n}\n\n.cf-single-column-label {\n pointer-events: none;\n position: absolute;\n z-index: -1;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n font-family: var(--exp-builder-font-stack-primary);\n font-size: 12px;\n color: var(--exp-builder-gray400);\n z-index: 100;\n}\n";
|
|
2523
|
+
styleInject(css_248z$6);
|
|
2341
2524
|
|
|
2342
2525
|
const ColumnWrapper = forwardRef((props, ref) => {
|
|
2343
2526
|
return (React.createElement("div", { ref: ref, ...props, style: {
|
|
@@ -2560,7 +2743,7 @@ const DraggableChildComponent = (props) => {
|
|
|
2560
2743
|
})));
|
|
2561
2744
|
};
|
|
2562
2745
|
|
|
2563
|
-
var css_248z$2 = ".styles-module_container__te-1H {\n margin-left: auto;\n margin-right: auto;\n position: relative;\n height: 100%;\n width: 100%;\n background-color: transparent;\n transition: background-color 0.2s;\n pointer-events: all !important;\n}\n\n.styles-module_container__te-1H:not(.styles-module_isRoot__5cn-i):before {\n content: '';\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n outline-offset: -1px;\n outline: 2px solid transparent;\n z-index: 1;\n transition: outline 0.2s;\n pointer-events: none;\n}\n\n.styles-module_isRoot__5cn-i,\n.styles-module_isEmptyCanvas__0XHZR {\n flex: 1;\n}\n\n.styles-module_isEmptyZone__zVpnZ {\n min-height: 80px;\n}\n\n.styles-module_isDragging__Gm8v5:not(.styles-module_isRoot__5cn-i):before {\n outline: 2px dashed var(--exp-builder-gray300);\n}\n\n.styles-module_isDestination__5sCQx:not(.styles-module_isRoot__5cn-i):before {\n transition:\n outline 0.2s,\n background-color 0.2s;\n outline: 2px dashed var(--exp-builder-blue400);\n background-color: rgba(var(--exp-builder-blue100-rgb), 0.5);\n z-index: 2;\n}\n\n.styles-module_hitbox__YQ-1Z {\n position: fixed;\n pointer-events: all !important;\n}\n";
|
|
2746
|
+
var css_248z$2 = ".styles-module_container__te-1H {\n margin-left: auto;\n margin-right: auto;\n position: relative;\n height: 100%;\n width: 100%;\n background-color: transparent;\n transition: background-color 0.2s;\n pointer-events: all !important;\n}\n\n.styles-module_container__te-1H:not(.styles-module_isRoot__5cn-i):before {\n content: '';\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n outline-offset: -1px;\n outline: 2px solid transparent;\n z-index: 1;\n transition: outline 0.2s;\n pointer-events: none;\n}\n\n.styles-module_isRoot__5cn-i,\n.styles-module_isEmptyCanvas__0XHZR {\n flex: 1;\n}\n\n.styles-module_isEmptyZone__zVpnZ {\n min-height: 80px;\n}\n\n.styles-module_isDragging__Gm8v5:not(.styles-module_isRoot__5cn-i):before {\n outline: 2px dashed var(--exp-builder-gray300);\n}\n\n.styles-module_isDestination__5sCQx:not(.styles-module_isRoot__5cn-i):before {\n transition:\n outline 0.2s,\n background-color 0.2s;\n outline: 2px dashed var(--exp-builder-blue400);\n background-color: rgba(var(--exp-builder-blue100-rgb), 0.5);\n z-index: 2;\n}\n\n.styles-module_hitbox__YQ-1Z {\n position: fixed;\n pointer-events: all !important;\n}\n\n.styles-module_hitbox__YQ-1Z {\n position: fixed;\n pointer-events: all !important;\n}\n";
|
|
2564
2747
|
var styles$2 = {"container":"styles-module_container__te-1H","isRoot":"styles-module_isRoot__5cn-i","isEmptyCanvas":"styles-module_isEmptyCanvas__0XHZR","isEmptyZone":"styles-module_isEmptyZone__zVpnZ","isDragging":"styles-module_isDragging__Gm8v5","isDestination":"styles-module_isDestination__5sCQx","hitbox":"styles-module_hitbox__YQ-1Z"};
|
|
2565
2748
|
styleInject(css_248z$2);
|
|
2566
2749
|
|