@contentful/experiences-visual-editor-react 0.0.1-alpha.9 → 0.0.1-beta.1
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 +66 -74
- package/dist/index.js.map +1 -1
- package/dist/renderApp.js +15013 -15021
- package/dist/renderApp.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -2,10 +2,10 @@ import styleInject from 'style-inject';
|
|
|
2
2
|
import React, { useRef, useMemo, useEffect, useState, forwardRef, useCallback } from 'react';
|
|
3
3
|
import md5 from 'md5';
|
|
4
4
|
import { BLOCKS } from '@contentful/rich-text-types';
|
|
5
|
+
import { isEqual, get as get$1, omit } from 'lodash-es';
|
|
5
6
|
import { Draggable, Droppable, DragDropContext } from '@hello-pangea/dnd';
|
|
6
7
|
import classNames from 'classnames';
|
|
7
8
|
import { create } from 'zustand';
|
|
8
|
-
import { isEqual, get as get$1, omit } from 'lodash-es';
|
|
9
9
|
import '@contentful/rich-text-react-renderer';
|
|
10
10
|
import { produce } from 'immer';
|
|
11
11
|
import { createPortal } from 'react-dom';
|
|
@@ -49,23 +49,23 @@ const CONTENTFUL_COMPONENTS$1 = {
|
|
|
49
49
|
name: 'Column',
|
|
50
50
|
},
|
|
51
51
|
button: {
|
|
52
|
-
id: 'button',
|
|
52
|
+
id: 'contentful-button',
|
|
53
53
|
name: 'Button',
|
|
54
54
|
},
|
|
55
55
|
heading: {
|
|
56
|
-
id: 'heading',
|
|
56
|
+
id: 'contentful-heading',
|
|
57
57
|
name: 'Heading',
|
|
58
58
|
},
|
|
59
59
|
image: {
|
|
60
|
-
id: 'image',
|
|
60
|
+
id: 'contentful-image',
|
|
61
61
|
name: 'Image',
|
|
62
62
|
},
|
|
63
63
|
richText: {
|
|
64
|
-
id: 'richText',
|
|
64
|
+
id: 'contentful-richText',
|
|
65
65
|
name: 'Rich Text',
|
|
66
66
|
},
|
|
67
67
|
text: {
|
|
68
|
-
id: 'text',
|
|
68
|
+
id: 'contentful-text',
|
|
69
69
|
name: 'Text',
|
|
70
70
|
},
|
|
71
71
|
};
|
|
@@ -424,6 +424,9 @@ const transformRichText = (entryOrAsset, path) => {
|
|
|
424
424
|
};
|
|
425
425
|
|
|
426
426
|
function getOptimizedImageUrl(url, width, quality, format) {
|
|
427
|
+
if (url.startsWith('//')) {
|
|
428
|
+
url = 'https:' + url;
|
|
429
|
+
}
|
|
427
430
|
const params = new URLSearchParams();
|
|
428
431
|
if (width) {
|
|
429
432
|
params.append('w', width.toString());
|
|
@@ -438,63 +441,67 @@ function getOptimizedImageUrl(url, width, quality, format) {
|
|
|
438
441
|
return `${url}${queryString ? '?' + queryString : ''}`;
|
|
439
442
|
}
|
|
440
443
|
|
|
444
|
+
function validateParams(file, quality, format) {
|
|
445
|
+
if (!file.details.image) {
|
|
446
|
+
throw Error('No image in file asset to transform');
|
|
447
|
+
}
|
|
448
|
+
if (quality < 0 || quality > 100) {
|
|
449
|
+
throw Error('Quality must be between 0 and 100');
|
|
450
|
+
}
|
|
451
|
+
if (format && !SUPPORTED_IMAGE_FORMATS.includes(format)) {
|
|
452
|
+
throw Error(`Format must be one of ${SUPPORTED_IMAGE_FORMATS.join(', ')}`);
|
|
453
|
+
}
|
|
454
|
+
return true;
|
|
455
|
+
}
|
|
456
|
+
|
|
441
457
|
const MAX_WIDTH_ALLOWED$1 = 2000;
|
|
442
|
-
const getOptimizedBackgroundImageAsset = (file, widthStyle, quality = 100, format) => {
|
|
443
|
-
|
|
458
|
+
const getOptimizedBackgroundImageAsset = (file, widthStyle, quality = '100%', format) => {
|
|
459
|
+
const qualityNumber = Number(quality.replace('%', ''));
|
|
460
|
+
if (!validateParams(file, qualityNumber, format)) ;
|
|
461
|
+
if (!validateParams(file, qualityNumber, format)) ;
|
|
444
462
|
const url = file.url;
|
|
445
463
|
const { width1x, width2x } = getWidths(widthStyle, file);
|
|
446
|
-
const imageUrl1x = getOptimizedImageUrl(url, width1x,
|
|
447
|
-
const imageUrl2x = getOptimizedImageUrl(url, width2x,
|
|
464
|
+
const imageUrl1x = getOptimizedImageUrl(url, width1x, qualityNumber, format);
|
|
465
|
+
const imageUrl2x = getOptimizedImageUrl(url, width2x, qualityNumber, format);
|
|
448
466
|
const srcSet = [`url(${imageUrl1x}) 1x`, `url(${imageUrl2x}) 2x`];
|
|
449
|
-
const
|
|
467
|
+
const returnedUrl = getOptimizedImageUrl(url, width2x, qualityNumber, format);
|
|
450
468
|
const optimizedBackgroundImageAsset = {
|
|
451
|
-
url:
|
|
469
|
+
url: returnedUrl,
|
|
452
470
|
srcSet,
|
|
453
471
|
file,
|
|
454
472
|
};
|
|
455
473
|
return optimizedBackgroundImageAsset;
|
|
456
|
-
function
|
|
457
|
-
|
|
458
|
-
|
|
474
|
+
function getWidths(widthStyle, file) {
|
|
475
|
+
let width1x = 0;
|
|
476
|
+
let width2x = 0;
|
|
477
|
+
const intrinsicImageWidth = file.details.image.width;
|
|
478
|
+
if (widthStyle.endsWith('px')) {
|
|
479
|
+
width1x = Math.min(Number(widthStyle.replace('px', '')), intrinsicImageWidth);
|
|
459
480
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
-
if (format && !SUPPORTED_IMAGE_FORMATS.includes(format)) {
|
|
464
|
-
throw Error(`Format must be one of ${SUPPORTED_IMAGE_FORMATS.join(', ')}`);
|
|
481
|
+
else {
|
|
482
|
+
width1x = Math.min(MAX_WIDTH_ALLOWED$1, intrinsicImageWidth);
|
|
465
483
|
}
|
|
466
|
-
|
|
484
|
+
width2x = Math.min(width1x * 2, intrinsicImageWidth);
|
|
485
|
+
return { width1x, width2x };
|
|
467
486
|
}
|
|
468
487
|
};
|
|
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
488
|
|
|
483
489
|
const MAX_WIDTH_ALLOWED = 4000;
|
|
484
|
-
const getOptimizedImageAsset = (file, sizes, quality = 100, format) => {
|
|
485
|
-
|
|
490
|
+
const getOptimizedImageAsset = (file, sizes, quality = '100%', format) => {
|
|
491
|
+
const qualityNumber = Number(quality.replace('%', ''));
|
|
492
|
+
if (!validateParams(file, qualityNumber, format)) ;
|
|
486
493
|
const url = file.url;
|
|
487
494
|
const maxWidth = Math.min(file.details.image.width, MAX_WIDTH_ALLOWED);
|
|
488
495
|
const numOfParts = Math.max(2, Math.ceil(maxWidth / 500));
|
|
489
496
|
const widthParts = Array.from({ length: numOfParts }, (_, index) => Math.ceil((index + 1) * (maxWidth / numOfParts)));
|
|
490
497
|
const srcSet = sizes
|
|
491
|
-
? widthParts.map((width) => `${getOptimizedImageUrl(url, width,
|
|
498
|
+
? widthParts.map((width) => `${getOptimizedImageUrl(url, width, qualityNumber, format)} ${width}w`)
|
|
492
499
|
: [];
|
|
493
500
|
const intrinsicImageWidth = file.details.image.width;
|
|
494
501
|
if (intrinsicImageWidth > MAX_WIDTH_ALLOWED) {
|
|
495
|
-
srcSet.push(`${getOptimizedImageUrl(url, undefined,
|
|
502
|
+
srcSet.push(`${getOptimizedImageUrl(url, undefined, qualityNumber, format)} ${intrinsicImageWidth}w`);
|
|
496
503
|
}
|
|
497
|
-
const returnedUrl = getOptimizedImageUrl(url, file.details.image.width > 2000 ? 2000 : undefined,
|
|
504
|
+
const returnedUrl = getOptimizedImageUrl(url, file.details.image.width > 2000 ? 2000 : undefined, qualityNumber, format);
|
|
498
505
|
const optimizedImageAsset = {
|
|
499
506
|
url: returnedUrl,
|
|
500
507
|
srcSet,
|
|
@@ -502,18 +509,6 @@ const getOptimizedImageAsset = (file, sizes, quality = 100, format) => {
|
|
|
502
509
|
file,
|
|
503
510
|
};
|
|
504
511
|
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
512
|
};
|
|
518
513
|
|
|
519
514
|
const transformMedia = (asset, variables, resolveDesignValue, variableName, path) => {
|
|
@@ -529,7 +524,7 @@ const transformMedia = (asset, variables, resolveDesignValue, variableName, path
|
|
|
529
524
|
return;
|
|
530
525
|
}
|
|
531
526
|
try {
|
|
532
|
-
value = getOptimizedImageAsset(asset.fields.file, options.targetSize,
|
|
527
|
+
value = getOptimizedImageAsset(asset.fields.file, options.targetSize, options.quality, options.format);
|
|
533
528
|
return value;
|
|
534
529
|
}
|
|
535
530
|
catch (error) {
|
|
@@ -548,7 +543,7 @@ const transformMedia = (asset, variables, resolveDesignValue, variableName, path
|
|
|
548
543
|
return;
|
|
549
544
|
}
|
|
550
545
|
try {
|
|
551
|
-
value = getOptimizedBackgroundImageAsset(asset.fields.file, width,
|
|
546
|
+
value = getOptimizedBackgroundImageAsset(asset.fields.file, width, options.quality, options.format);
|
|
552
547
|
return value;
|
|
553
548
|
}
|
|
554
549
|
catch (error) {
|
|
@@ -595,6 +590,7 @@ const getDataFromTree = (tree) => {
|
|
|
595
590
|
};
|
|
596
591
|
};
|
|
597
592
|
|
|
593
|
+
// These styles get added to every component, user custom or contentful provided
|
|
598
594
|
const builtInStyles = {
|
|
599
595
|
cfVerticalAlignment: {
|
|
600
596
|
validations: {
|
|
@@ -705,13 +701,6 @@ const builtInStyles = {
|
|
|
705
701
|
description: 'The border of the section',
|
|
706
702
|
defaultValue: '0px solid rgba(0, 0, 0, 0)',
|
|
707
703
|
},
|
|
708
|
-
cfBorderRadius: {
|
|
709
|
-
displayName: 'Border Radius',
|
|
710
|
-
type: 'Text',
|
|
711
|
-
group: 'style',
|
|
712
|
-
description: 'The border radius of the section',
|
|
713
|
-
defaultValue: '0px',
|
|
714
|
-
},
|
|
715
704
|
cfGap: {
|
|
716
705
|
displayName: 'Gap',
|
|
717
706
|
type: 'Text',
|
|
@@ -778,9 +767,6 @@ const optionalBuiltInStyles = {
|
|
|
778
767
|
defaultValue: {
|
|
779
768
|
width: DEFAULT_IMAGE_WIDTH,
|
|
780
769
|
height: '100%',
|
|
781
|
-
objectFit: 'none',
|
|
782
|
-
objectPosition: 'center center',
|
|
783
|
-
quality: '100',
|
|
784
770
|
targetSize: DEFAULT_IMAGE_WIDTH,
|
|
785
771
|
},
|
|
786
772
|
},
|
|
@@ -796,10 +782,16 @@ const optionalBuiltInStyles = {
|
|
|
796
782
|
defaultValue: {
|
|
797
783
|
scaling: 'fill',
|
|
798
784
|
alignment: 'left top',
|
|
799
|
-
quality: '100',
|
|
800
785
|
targetSize: '2000px',
|
|
801
786
|
},
|
|
802
787
|
},
|
|
788
|
+
cfBorderRadius: {
|
|
789
|
+
displayName: 'Border Radius',
|
|
790
|
+
type: 'Text',
|
|
791
|
+
group: 'style',
|
|
792
|
+
description: 'The border radius of the section',
|
|
793
|
+
defaultValue: '0px',
|
|
794
|
+
},
|
|
803
795
|
cfLineHeight: {
|
|
804
796
|
displayName: 'Line Height',
|
|
805
797
|
type: 'Text',
|
|
@@ -1710,23 +1702,23 @@ const CONTENTFUL_COMPONENTS = {
|
|
|
1710
1702
|
name: 'Column',
|
|
1711
1703
|
},
|
|
1712
1704
|
button: {
|
|
1713
|
-
id: 'button',
|
|
1705
|
+
id: 'contentful-button',
|
|
1714
1706
|
name: 'Button',
|
|
1715
1707
|
},
|
|
1716
1708
|
heading: {
|
|
1717
|
-
id: 'heading',
|
|
1709
|
+
id: 'contentful-heading',
|
|
1718
1710
|
name: 'Heading',
|
|
1719
1711
|
},
|
|
1720
1712
|
image: {
|
|
1721
|
-
id: 'image',
|
|
1713
|
+
id: 'contentful-image',
|
|
1722
1714
|
name: 'Image',
|
|
1723
1715
|
},
|
|
1724
1716
|
richText: {
|
|
1725
|
-
id: 'richText',
|
|
1717
|
+
id: 'contentful-richText',
|
|
1726
1718
|
name: 'Rich Text',
|
|
1727
1719
|
},
|
|
1728
1720
|
text: {
|
|
1729
|
-
id: 'text',
|
|
1721
|
+
id: 'contentful-text',
|
|
1730
1722
|
name: 'Text',
|
|
1731
1723
|
},
|
|
1732
1724
|
};
|
|
@@ -2491,7 +2483,7 @@ styleInject(css_248z$4);
|
|
|
2491
2483
|
var css_248z$3 = ".cf-text {\n white-space: pre-line;\n}\n";
|
|
2492
2484
|
styleInject(css_248z$3);
|
|
2493
2485
|
|
|
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";
|
|
2486
|
+
var css_248z$2$1 = "@import url(https://fonts.googleapis.com/css2?family=Archivo:ital,wght@0,400;0,500;0,600;1,400;1,600&display=swap);\n\n:root {\n /* All sizing comments based of 16px base body font size */\n\n /* color */\n --cf-color-white: #fff;\n --cf-color-black: #000;\n --cf-color-gray100: #f7f9fa;\n --cf-color-gray400: #aec1cc;\n --cf-color-gray400-rgb: 174, 193, 204;\n\n /* spacing */\n --cf-spacing-0: 0rem; /* 0px */\n --cf-spacing-1: 0.125rem; /* 2px */\n --cf-spacing-2: 0.25rem; /* 4px */\n --cf-spacing-3: 0.375rem; /* 6px */\n --cf-spacing-4: 0.5rem; /* 8px */\n --cf-spacing-5: 0.625rem; /* 10px */\n --cf-spacing-6: 0.75rem; /* 12px */\n --cf-spacing-7: 0.875rem; /* 14px */\n --cf-spacing-8: 1rem; /* 16px */\n --cf-spacing-9: 1.25rem; /* 20px */\n --cf-spacing-10: 1.5rem; /* 24px */\n --cf-spacing-11: 1.75rem; /* 28px */\n --cf-spacing-12: 2rem; /* 32px */\n --cf-spacing-13: 2.25rem; /* 36px */\n\n /* font-size */\n --cf-text-xs: 0.75rem; /* 12px */\n --cf-text-sm: 0.875rem; /* 14px */\n --cf-text-base: 1rem; /* 16px */\n --cf-text-lg: 1.125rem; /* 18px */\n --cf-text-xl: 1.25rem; /* 20px */\n --cf-text-2xl: 1.5rem; /* 24px */\n --cf-text-3xl: 2rem; /* 32px */\n --cf-text-4xl: 2.75rem; /* 44px */\n\n /* font-weight */\n --cf-font-light: 300;\n --cf-font-normal: 400;\n --cf-font-medium: 500;\n --cf-font-semibold: 600;\n --cf-font-bold: 700;\n --cf-font-extra-bold: 800;\n --cf-font-black: 900;\n\n /* border-radius */\n --cf-border-radius-none: 0px; /* none */\n --cf-border-radius-sm: 0.125rem; /* 2px */\n --cf-border-radius: 0.25rem; /* 4px */\n --cf-border-radius-md: 0.375rem; /* 6px */\n --cf-border-radius-lg: 0.5rem; /* 8px */\n --cf-border-radius-xl: 0.75rem; /* 12px */\n --cf-border-radius-2xl: 1rem; /* 16px */\n --cf-border-radius-3xl: 1.5rem; /* 24px */\n --cf-border-radius-full: 9999px; /* full */\n\n /* font-family */\n --cf-font-family-sans: Archivo, Helvetica, Arial, sans-serif;\n --cf-font-family-serif: Georgia, Cambria, Times New Roman, Times, serif;\n\n /* max widths */\n --cf-max-width-full: 100%;\n\n /* component specific colors */\n --cf-button-bg: var(--cf-color-black);\n --cf-button-color: var(--cf-color-white);\n --cf-text-color: var(--cf-color-black);\n}\n\n.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";
|
|
2495
2487
|
styleInject(css_248z$2$1);
|
|
2496
2488
|
|
|
2497
2489
|
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";
|
|
@@ -2672,15 +2664,15 @@ const useComponent = ({ node: rawNode, resolveDesignValue, renderDropzone, userI
|
|
|
2672
2664
|
return rawNode;
|
|
2673
2665
|
}, [areEntitiesFetched, rawNode, entityStore]);
|
|
2674
2666
|
const componentRegistration = useMemo(() => {
|
|
2675
|
-
|
|
2667
|
+
let registration = componentRegistry.get(node.data.blockId);
|
|
2676
2668
|
if (node.type === ASSEMBLY_NODE_TYPE && !registration) {
|
|
2677
|
-
|
|
2669
|
+
registration = createAssemblyRegistration({
|
|
2678
2670
|
definitionId: node.data.blockId,
|
|
2679
2671
|
component: Assembly,
|
|
2680
2672
|
});
|
|
2681
2673
|
}
|
|
2682
|
-
|
|
2683
|
-
|
|
2674
|
+
if (!registration) {
|
|
2675
|
+
throw Error(`Component registration not found for component with id: "${node.data.blockId}". The component might of been removed. To proceed, remove the component manually from the layers tab.`);
|
|
2684
2676
|
}
|
|
2685
2677
|
return registration;
|
|
2686
2678
|
}, [node]);
|