@builder.io/sdk-react 0.2.0 → 0.2.2
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/CHANGELOG.md +13 -1
- package/dist/react/blocks/symbol/symbol.js +2 -1
- package/dist/react/components/render-block/block-styles.js +3 -0
- package/dist/react/components/render-block/render-block.helpers.js +16 -1
- package/dist/react/components/render-block/render-block.js +36 -55
- package/dist/react/components/render-content/render-content.js +8 -7
- package/dist/react/components/render-content-variants/helpers.js +98 -0
- package/dist/react/components/render-content-variants/render-content-variants.js +45 -0
- package/dist/react/components/render-inlined-styles.js +3 -3
- package/dist/react/functions/get-block-properties.js +4 -1
- package/dist/react/functions/get-content/index.js +22 -15
- package/dist/react/functions/track/index.js +2 -1
- package/dist/react/helpers/logger.js +7 -0
- package/dist/rsc/blocks/symbol/symbol.js +2 -1
- package/dist/rsc/components/render-block/block-styles.js +3 -0
- package/dist/rsc/components/render-block/render-block.helpers.js +16 -1
- package/dist/rsc/components/render-block/render-block.js +32 -51
- package/dist/rsc/components/render-content/render-content.js +1 -0
- package/dist/rsc/components/render-content-variants/helpers.js +99 -0
- package/dist/rsc/components/render-content-variants/render-content-variants.js +45 -0
- package/dist/rsc/components/render-inlined-styles.js +3 -3
- package/dist/rsc/functions/get-block-properties.js +4 -1
- package/dist/rsc/functions/get-content/index.js +22 -15
- package/dist/rsc/functions/track/index.js +2 -1
- package/dist/rsc/helpers/logger.js +7 -0
- package/package.json +1 -1
- package/packages/react/src/blocks/symbol/symbol.jsx +2 -1
- package/packages/react/src/components/render-block/block-styles.jsx +3 -0
- package/packages/react/src/components/render-block/render-block.helpers.js +16 -0
- package/packages/react/src/components/render-block/render-block.jsx +42 -61
- package/packages/react/src/components/render-content/render-content.jsx +11 -8
- package/packages/react/src/components/render-inlined-styles.jsx +4 -4
- package/packages/react/src/functions/get-block-properties.js +4 -1
- package/packages/react/src/functions/get-content/index.js +21 -15
- package/packages/react/src/functions/track/index.js +2 -1
- package/packages/react/src/helpers/logger.js +9 -0
- package/packages/rsc/src/blocks/symbol/symbol.jsx +2 -4
- package/packages/rsc/src/components/render-block/block-styles.jsx +3 -0
- package/packages/rsc/src/components/render-block/render-block.helpers.js +16 -0
- package/packages/rsc/src/components/render-block/render-block.jsx +32 -53
- package/packages/rsc/src/components/render-content/render-content.jsx +1 -0
- package/packages/rsc/src/components/render-inlined-styles.jsx +3 -3
- package/packages/rsc/src/functions/get-block-properties.js +4 -1
- package/packages/rsc/src/functions/get-content/index.js +21 -15
- package/packages/rsc/src/functions/track/index.js +2 -1
- package/packages/rsc/src/helpers/logger.js +9 -0
- package/packages/react/src/functions/get-block-tag.js +0 -6
- package/packages/rsc/src/functions/get-block-tag.js +0 -6
- package/src/blocks/BaseText.jsx +0 -9
- package/src/blocks/button/button.jsx +0 -27
- package/src/blocks/button/component-info.js +0 -41
- package/src/blocks/columns/columns.jsx +0 -172
- package/src/blocks/columns/component-info.js +0 -242
- package/src/blocks/custom-code/component-info.js +0 -31
- package/src/blocks/custom-code/custom-code.jsx +0 -64
- package/src/blocks/embed/component-info.js +0 -44
- package/src/blocks/embed/embed.jsx +0 -49
- package/src/blocks/embed/helpers.js +0 -9
- package/src/blocks/form/component-info.js +0 -262
- package/src/blocks/form/form.jsx +0 -253
- package/src/blocks/fragment/component-info.js +0 -11
- package/src/blocks/fragment/fragment.jsx +0 -5
- package/src/blocks/image/component-info.js +0 -151
- package/src/blocks/image/image.helpers.js +0 -48
- package/src/blocks/image/image.jsx +0 -122
- package/src/blocks/img/component-info.js +0 -20
- package/src/blocks/img/img.jsx +0 -17
- package/src/blocks/input/component-info.js +0 -74
- package/src/blocks/input/input.jsx +0 -19
- package/src/blocks/raw-text/component-info.js +0 -16
- package/src/blocks/raw-text/raw-text.jsx +0 -10
- package/src/blocks/section/component-info.js +0 -49
- package/src/blocks/section/section.jsx +0 -27
- package/src/blocks/select/component-info.js +0 -59
- package/src/blocks/select/select.jsx +0 -20
- package/src/blocks/submit-button/component-info.js +0 -28
- package/src/blocks/submit-button/submit-button.jsx +0 -9
- package/src/blocks/symbol/component-info.js +0 -43
- package/src/blocks/symbol/symbol.jsx +0 -84
- package/src/blocks/text/component-info.js +0 -24
- package/src/blocks/text/text.jsx +0 -10
- package/src/blocks/textarea/component-info.js +0 -47
- package/src/blocks/textarea/textarea.jsx +0 -13
- package/src/blocks/util.js +0 -8
- package/src/blocks/video/component-info.js +0 -106
- package/src/blocks/video/video.jsx +0 -58
- package/src/components/render-block/block-styles.jsx +0 -69
- package/src/components/render-block/render-block.helpers.js +0 -23
- package/src/components/render-block/render-block.jsx +0 -252
- package/src/components/render-block/render-component-with-context.jsx +0 -38
- package/src/components/render-block/render-component.jsx +0 -33
- package/src/components/render-block/render-repeated-block.jsx +0 -33
- package/src/components/render-block/types.js +0 -0
- package/src/components/render-blocks.jsx +0 -89
- package/src/components/render-content/builder-editing.jsx +0 -5
- package/src/components/render-content/components/render-styles.jsx +0 -64
- package/src/components/render-content/index.js +0 -4
- package/src/components/render-content/render-content.jsx +0 -370
- package/src/components/render-inlined-styles.jsx +0 -28
- package/src/constants/builder-registered-components.js +0 -54
- package/src/constants/device-sizes.js +0 -48
- package/src/constants/target.js +0 -4
- package/src/context/builder.context.js +0 -12
- package/src/context/types.js +0 -0
- package/src/functions/camel-to-kebab-case.js +0 -4
- package/src/functions/evaluate.js +0 -29
- package/src/functions/event-handler-name.js +0 -7
- package/src/functions/extract-text-styles.js +0 -22
- package/src/functions/fast-clone.js +0 -4
- package/src/functions/get-block-actions-handler.js +0 -11
- package/src/functions/get-block-actions.js +0 -18
- package/src/functions/get-block-component-options.js +0 -28
- package/src/functions/get-block-properties.js +0 -50
- package/src/functions/get-block-tag.js +0 -6
- package/src/functions/get-builder-search-params/fn.test.js +0 -13
- package/src/functions/get-builder-search-params/index.js +0 -38
- package/src/functions/get-content/ab-testing.js +0 -99
- package/src/functions/get-content/generate-content-url.js +0 -55
- package/src/functions/get-content/generate-content-url.test.js +0 -31
- package/src/functions/get-content/index.js +0 -65
- package/src/functions/get-content/types.js +0 -0
- package/src/functions/get-fetch.js +0 -14
- package/src/functions/get-global-this.js +0 -18
- package/src/functions/get-processed-block.js +0 -59
- package/src/functions/get-processed-block.test.js +0 -32
- package/src/functions/get-react-native-block-styles.js +0 -33
- package/src/functions/if-target.js +0 -15
- package/src/functions/is-browser.js +0 -6
- package/src/functions/is-editing.js +0 -7
- package/src/functions/is-iframe.js +0 -7
- package/src/functions/is-previewing.js +0 -14
- package/src/functions/on-change.js +0 -27
- package/src/functions/on-change.test.js +0 -19
- package/src/functions/register-component.js +0 -68
- package/src/functions/register.js +0 -29
- package/src/functions/sanitize-react-native-block-styles.js +0 -66
- package/src/functions/set-editor-settings.js +0 -15
- package/src/functions/set.js +0 -11
- package/src/functions/set.test.js +0 -16
- package/src/functions/track.js +0 -124
- package/src/functions/transform-block-properties.js +0 -6
- package/src/functions/transform-block.js +0 -6
- package/src/helpers/ab-tests.js +0 -16
- package/src/helpers/cookie.js +0 -81
- package/src/helpers/css.js +0 -34
- package/src/helpers/flatten.js +0 -34
- package/src/helpers/localStorage.js +0 -35
- package/src/helpers/nullable.js +0 -4
- package/src/helpers/sessionId.js +0 -52
- package/src/helpers/time.js +0 -5
- package/src/helpers/url.js +0 -13
- package/src/helpers/url.test.js +0 -21
- package/src/helpers/uuid.js +0 -13
- package/src/helpers/visitorId.js +0 -34
- package/src/index-helpers/blocks-exports.js +0 -22
- package/src/index-helpers/top-of-file.js +0 -4
- package/src/index.js +0 -14
- package/src/scripts/init-editing.js +0 -93
- package/src/types/builder-block.js +0 -0
- package/src/types/builder-content.js +0 -0
- package/src/types/can-track.js +0 -0
- package/src/types/components.js +0 -0
- package/src/types/deep-partial.js +0 -0
- package/src/types/element.js +0 -0
- package/src/types/targets.js +0 -0
- package/src/types/typescript.js +0 -0
|
@@ -2,16 +2,14 @@ import * as React from "react";
|
|
|
2
2
|
import { getBlockActions } from "../../functions/get-block-actions.js";
|
|
3
3
|
import { getBlockComponentOptions } from "../../functions/get-block-component-options.js";
|
|
4
4
|
import { getBlockProperties } from "../../functions/get-block-properties.js";
|
|
5
|
-
import { getBlockTag } from "../../functions/get-block-tag.js";
|
|
6
5
|
import { getProcessedBlock } from "../../functions/get-processed-block.js";
|
|
7
6
|
import BlockStyles from "./block-styles";
|
|
8
|
-
import { getComponent, getRepeatItemData, isEmptyHtmlElement, } from "./render-block.helpers.js";
|
|
7
|
+
import { getComponent, getProxyState, getRepeatItemData, isEmptyHtmlElement, } from "./render-block.helpers.js";
|
|
9
8
|
import RenderRepeatedBlock from "./render-repeated-block";
|
|
10
9
|
import { TARGET } from "../../constants/target.js";
|
|
11
10
|
import { extractTextStyles } from "../../functions/extract-text-styles.js";
|
|
12
11
|
import RenderComponent from "./render-component";
|
|
13
12
|
import { getReactNativeBlockStyles } from "../../functions/get-react-native-block-styles.js";
|
|
14
|
-
import { checkIsDefined } from "../../helpers/nullable.js";
|
|
15
13
|
function RenderBlock(props) {
|
|
16
14
|
const _context = { ...props["_context"] };
|
|
17
15
|
const state = {
|
|
@@ -19,9 +17,10 @@ function RenderBlock(props) {
|
|
|
19
17
|
block: props.block,
|
|
20
18
|
context: props.context,
|
|
21
19
|
}),
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
repeatItemData: getRepeatItemData({
|
|
21
|
+
block: props.block,
|
|
22
|
+
context: props.context,
|
|
23
|
+
}),
|
|
25
24
|
get useBlock() {
|
|
26
25
|
return state.repeatItemData
|
|
27
26
|
? props.block
|
|
@@ -32,35 +31,21 @@ function RenderBlock(props) {
|
|
|
32
31
|
shouldEvaluateBindings: true,
|
|
33
32
|
});
|
|
34
33
|
},
|
|
34
|
+
tag: props.block.tagName || "div",
|
|
35
35
|
get canShowBlock() {
|
|
36
|
-
if (
|
|
36
|
+
if ("hide" in state.useBlock) {
|
|
37
37
|
return !state.useBlock.hide;
|
|
38
38
|
}
|
|
39
|
-
if (
|
|
39
|
+
if ("show" in state.useBlock) {
|
|
40
40
|
return state.useBlock.show;
|
|
41
41
|
}
|
|
42
42
|
return true;
|
|
43
43
|
},
|
|
44
|
-
|
|
45
|
-
if (typeof Proxy === "undefined") {
|
|
46
|
-
console.error("no Proxy available in this environment, cannot proxy state.");
|
|
47
|
-
return props.context.state;
|
|
48
|
-
}
|
|
49
|
-
const useState = new Proxy(props.context.state, {
|
|
50
|
-
set: (obj, prop, value) => {
|
|
51
|
-
// set the value on the state object, so that the event handler instantly gets the update.
|
|
52
|
-
obj[prop] = value;
|
|
53
|
-
// set the value in the context, so that the rest of the app gets the update.
|
|
54
|
-
props.context.setState?.(obj);
|
|
55
|
-
return true;
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
return useState;
|
|
59
|
-
},
|
|
44
|
+
proxyState: getProxyState(props.context),
|
|
60
45
|
get actions() {
|
|
61
46
|
return getBlockActions({
|
|
62
47
|
block: state.useBlock,
|
|
63
|
-
state: state.proxyState,
|
|
48
|
+
state: TARGET === "qwik" ? props.context.state : state.proxyState,
|
|
64
49
|
context: props.context.context,
|
|
65
50
|
});
|
|
66
51
|
},
|
|
@@ -79,28 +64,6 @@ function RenderBlock(props) {
|
|
|
79
64
|
: {}),
|
|
80
65
|
};
|
|
81
66
|
},
|
|
82
|
-
get renderComponentProps() {
|
|
83
|
-
return {
|
|
84
|
-
blockChildren: state.useBlock.children ?? [],
|
|
85
|
-
componentRef: state.component?.component,
|
|
86
|
-
componentOptions: {
|
|
87
|
-
...getBlockComponentOptions(state.useBlock),
|
|
88
|
-
/**
|
|
89
|
-
* These attributes are passed to the wrapper element when there is one. If `noWrap` is set to true, then
|
|
90
|
-
* they are provided to the component itself directly.
|
|
91
|
-
*/
|
|
92
|
-
...(!state.component?.noWrap
|
|
93
|
-
? {}
|
|
94
|
-
: {
|
|
95
|
-
attributes: {
|
|
96
|
-
...state.attributes,
|
|
97
|
-
...state.actions,
|
|
98
|
-
},
|
|
99
|
-
}),
|
|
100
|
-
},
|
|
101
|
-
context: state.childrenContext,
|
|
102
|
-
};
|
|
103
|
-
},
|
|
104
67
|
get childrenWithoutParentComponent() {
|
|
105
68
|
/**
|
|
106
69
|
* When there is no `componentRef`, there might still be children that need to be rendered. In this case,
|
|
@@ -113,10 +76,6 @@ function RenderBlock(props) {
|
|
|
113
76
|
? state.useBlock.children ?? []
|
|
114
77
|
: [];
|
|
115
78
|
},
|
|
116
|
-
repeatItemData: getRepeatItemData({
|
|
117
|
-
block: props.block,
|
|
118
|
-
context: props.context,
|
|
119
|
-
}),
|
|
120
79
|
get childrenContext() {
|
|
121
80
|
const getInheritedTextStyles = () => {
|
|
122
81
|
if (TARGET !== "reactNative") {
|
|
@@ -139,6 +98,28 @@ function RenderBlock(props) {
|
|
|
139
98
|
inheritedStyles: getInheritedTextStyles(),
|
|
140
99
|
};
|
|
141
100
|
},
|
|
101
|
+
get renderComponentProps() {
|
|
102
|
+
return {
|
|
103
|
+
blockChildren: state.useBlock.children ?? [],
|
|
104
|
+
componentRef: state.component?.component,
|
|
105
|
+
componentOptions: {
|
|
106
|
+
...getBlockComponentOptions(state.useBlock),
|
|
107
|
+
/**
|
|
108
|
+
* These attributes are passed to the wrapper element when there is one. If `noWrap` is set to true, then
|
|
109
|
+
* they are provided to the component itself directly.
|
|
110
|
+
*/
|
|
111
|
+
...(!state.component?.noWrap
|
|
112
|
+
? {}
|
|
113
|
+
: {
|
|
114
|
+
attributes: {
|
|
115
|
+
...state.attributes,
|
|
116
|
+
...state.actions,
|
|
117
|
+
},
|
|
118
|
+
}),
|
|
119
|
+
},
|
|
120
|
+
context: state.childrenContext,
|
|
121
|
+
};
|
|
122
|
+
},
|
|
142
123
|
};
|
|
143
124
|
const TagRef = state.tag;
|
|
144
125
|
return (React.createElement(React.Fragment, null, state.canShowBlock ? (React.createElement(React.Fragment, null, !state.component?.noWrap ? (React.createElement(React.Fragment, null,
|
|
@@ -16,6 +16,7 @@ import { checkIsDefined } from "../../helpers/nullable.js";
|
|
|
16
16
|
import { getInteractionPropertiesForEvent } from "../../functions/track/interaction.js";
|
|
17
17
|
import { getContentInitialValue, getContextStateInitialValue, } from "./render-content.helpers.js";
|
|
18
18
|
import { TARGET } from "../../constants/target.js";
|
|
19
|
+
import { logger } from "../../helpers/logger.js";
|
|
19
20
|
function RenderContent(props) {
|
|
20
21
|
const _context = { ...props["_context"] };
|
|
21
22
|
const state = {
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
const variantScriptFn = function main(contentId, variants) {
|
|
2
|
+
console.log("Running variant script", JSON.stringify({ contentId, variants }));
|
|
3
|
+
if (!navigator.cookieEnabled) {
|
|
4
|
+
console.log("Cookies are disabled, skipping variant script");
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const templateSelectorById = (id) => `template[data-template-variant-id="${id}"]`;
|
|
8
|
+
function removeTemplates() {
|
|
9
|
+
console.log("Removing variants");
|
|
10
|
+
variants.forEach((template) => {
|
|
11
|
+
const el2 = document.querySelector(templateSelectorById(template.id));
|
|
12
|
+
if (el2) {
|
|
13
|
+
console.log("Removing variant", template.id);
|
|
14
|
+
el2.remove();
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
const el = document.getElementById(`variants-script-${contentId}`);
|
|
18
|
+
if (el) {
|
|
19
|
+
console.log("Removing variant script");
|
|
20
|
+
el.remove();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (typeof document.createElement("template").content === "undefined") {
|
|
24
|
+
console.log("Template polyfill not found, skipping variant script");
|
|
25
|
+
removeTemplates();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
function setCookie(name, value, days) {
|
|
29
|
+
let expires = "";
|
|
30
|
+
if (days) {
|
|
31
|
+
const date = new Date();
|
|
32
|
+
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1e3);
|
|
33
|
+
expires = "; expires=" + date.toUTCString();
|
|
34
|
+
}
|
|
35
|
+
document.cookie = name + "=" + (value || "") + expires + "; path=/; Secure; SameSite=None";
|
|
36
|
+
}
|
|
37
|
+
function getCookie(name) {
|
|
38
|
+
const nameEQ = name + "=";
|
|
39
|
+
const ca = document.cookie.split(";");
|
|
40
|
+
for (let i = 0; i < ca.length; i++) {
|
|
41
|
+
let c = ca[i];
|
|
42
|
+
while (c.charAt(0) == " ")
|
|
43
|
+
c = c.substring(1, c.length);
|
|
44
|
+
if (c.indexOf(nameEQ) == 0)
|
|
45
|
+
return c.substring(nameEQ.length, c.length);
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
function getAndSetVariantId() {
|
|
50
|
+
const cookieName = `builder.tests.${contentId}`;
|
|
51
|
+
const variantInCookie = getCookie(cookieName);
|
|
52
|
+
const availableIDs = variants.map((vr) => vr.id).concat(contentId);
|
|
53
|
+
if (variantInCookie && availableIDs.indexOf(variantInCookie) > -1) {
|
|
54
|
+
return variantInCookie;
|
|
55
|
+
}
|
|
56
|
+
let n = 0;
|
|
57
|
+
const random = Math.random();
|
|
58
|
+
for (let i = 0; i < variants.length; i++) {
|
|
59
|
+
const variant = variants[i];
|
|
60
|
+
const testRatio = variant.testRatio;
|
|
61
|
+
n += testRatio;
|
|
62
|
+
if (random < n) {
|
|
63
|
+
setCookie(cookieName, variant.id);
|
|
64
|
+
return variant.id;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
setCookie(cookieName, contentId);
|
|
68
|
+
return contentId;
|
|
69
|
+
}
|
|
70
|
+
const variantId = getAndSetVariantId();
|
|
71
|
+
if (variantId !== contentId) {
|
|
72
|
+
console.log("Variant found", variantId);
|
|
73
|
+
const winningTemplate = document.querySelector(templateSelectorById(variantId));
|
|
74
|
+
console.log("winningTemplate", winningTemplate);
|
|
75
|
+
if (!winningTemplate) {
|
|
76
|
+
console.log("No template found for variant", variantId);
|
|
77
|
+
console.log("selector: ", templateSelectorById(variantId));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const templatesParent = winningTemplate.parentNode;
|
|
81
|
+
if (templatesParent) {
|
|
82
|
+
const defaultContent = templatesParent.querySelector(`div[builder-content-id="${contentId}"]`);
|
|
83
|
+
templatesParent.replaceChild(winningTemplate.content.firstElementChild, defaultContent);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else if (variants.length > 0) {
|
|
87
|
+
console.log("No variant found, removing all variants");
|
|
88
|
+
}
|
|
89
|
+
removeTemplates();
|
|
90
|
+
console.log("Variant script complete");
|
|
91
|
+
};
|
|
92
|
+
const getVariantsScriptString = (variants, contentId) => {
|
|
93
|
+
const fnStr = variantScriptFn.toString().replace(/\s+/g, " ");
|
|
94
|
+
return `
|
|
95
|
+
${fnStr}
|
|
96
|
+
main("${contentId}", ${JSON.stringify(variants)})
|
|
97
|
+
`;
|
|
98
|
+
};
|
|
99
|
+
export { getVariantsScriptString };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { isBrowser } from "../../functions/is-browser";
|
|
4
|
+
import { getVariantsScriptString } from "./helpers";
|
|
5
|
+
import RenderContent from "../render-content/render-content";
|
|
6
|
+
import { checkIsDefined } from "../../helpers/nullable";
|
|
7
|
+
import { handleABTestingSync } from "../../helpers/ab-tests";
|
|
8
|
+
import { TARGET } from "../../constants/target";
|
|
9
|
+
function RenderContentVariants(props) {
|
|
10
|
+
const _context = { ...props["_context"] };
|
|
11
|
+
const state = {
|
|
12
|
+
variantScriptStr: getVariantsScriptString(Object.values(props.content?.variations || {}).map((value) => ({
|
|
13
|
+
id: value.id,
|
|
14
|
+
testRatio: value.testRatio,
|
|
15
|
+
})), props.content?.id || ""),
|
|
16
|
+
contentToUse: ((isBrowser() && props.canTrack) || !isBrowser()) &&
|
|
17
|
+
Object.keys(props.content?.variations || {}).length > 0
|
|
18
|
+
? undefined
|
|
19
|
+
: handleABTestingSync({
|
|
20
|
+
item: props.content,
|
|
21
|
+
canTrack: checkIsDefined(props.canTrack) ? props.canTrack : true,
|
|
22
|
+
}),
|
|
23
|
+
shouldRenderVariants: ((isBrowser() && props.canTrack) || !isBrowser()) &&
|
|
24
|
+
Object.keys(props.content?.variations || {}).length > 0,
|
|
25
|
+
variants: null,
|
|
26
|
+
};
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (TARGET === "svelte" && state.shouldRenderVariants) {
|
|
29
|
+
// get first template in loop
|
|
30
|
+
const templates = document.querySelectorAll(`template[data-template-variant-id="${state.variants[0]?.id}"]`);
|
|
31
|
+
const lastTemplate = templates[templates.length - 1];
|
|
32
|
+
// create and append script as sibling of template
|
|
33
|
+
const script = document.createElement("script");
|
|
34
|
+
script.id = `variants-script-${props.content?.id}`;
|
|
35
|
+
script.innerHTML = state.variantScriptStr;
|
|
36
|
+
lastTemplate?.parentNode?.append(script, lastTemplate);
|
|
37
|
+
}
|
|
38
|
+
}, []);
|
|
39
|
+
return (React.createElement(React.Fragment, null, state.shouldRenderVariants ? (React.createElement(React.Fragment, null,
|
|
40
|
+
Object.values(props.content.variations)?.map((variant) => (React.createElement("template", { key: variant?.id, "data-template-variant-id": variant?.id },
|
|
41
|
+
React.createElement(RenderContent, { content: variant, apiKey: props.apiKey, apiVersion: props.apiVersion, canTrack: props.canTrack, customComponents: props.customComponents, _context: _context })))),
|
|
42
|
+
React.createElement("script", { id: `variants-script-${props.content?.id}`, dangerouslySetInnerHTML: { __html: state.variantScriptStr } }),
|
|
43
|
+
React.createElement(RenderContent, { content: state.contentToUse, apiKey: props.apiKey, apiVersion: props.apiVersion, canTrack: props.canTrack, customComponents: props.customComponents, _context: _context }))) : (React.createElement(RenderContent, { content: state.contentToUse, apiKey: props.apiKey, apiVersion: props.apiVersion, canTrack: props.canTrack, customComponents: props.customComponents, _context: _context }))));
|
|
44
|
+
}
|
|
45
|
+
export default RenderContentVariants;
|
|
@@ -3,14 +3,14 @@ import { TARGET } from "../constants/target.js";
|
|
|
3
3
|
function RenderInlinedStyles(props) {
|
|
4
4
|
const _context = { ...props["_context"] };
|
|
5
5
|
const state = {
|
|
6
|
-
get injectedStyleScript() {
|
|
7
|
-
return `<${state.tag}>${props.styles}</${state.tag}>`;
|
|
8
|
-
},
|
|
9
6
|
get tag() {
|
|
10
7
|
// NOTE: we have to obfusctate the name of the tag due to a limitation in the svelte-preprocessor plugin.
|
|
11
8
|
// https://github.com/sveltejs/vite-plugin-svelte/issues/315#issuecomment-1109000027
|
|
12
9
|
return "sty" + "le";
|
|
13
10
|
},
|
|
11
|
+
get injectedStyleScript() {
|
|
12
|
+
return `<${state.tag}>${props.styles}</${state.tag}>`;
|
|
13
|
+
},
|
|
14
14
|
};
|
|
15
15
|
const TagRef = state.tag;
|
|
16
16
|
return (React.createElement(React.Fragment, null, TARGET === "svelte" || TARGET === "qwik" ? (React.createElement(React.Fragment, null,
|
|
@@ -20,9 +20,12 @@ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
|
20
20
|
import { TARGET } from "../constants/target.js";
|
|
21
21
|
import { convertStyleMapToCSSArray } from "../helpers/css.js";
|
|
22
22
|
import { transformBlockProperties } from "./transform-block-properties.js";
|
|
23
|
+
const extractRelevantRootBlockProperties = (block) => {
|
|
24
|
+
return { href: block.href };
|
|
25
|
+
};
|
|
23
26
|
function getBlockProperties(block) {
|
|
24
27
|
var _a;
|
|
25
|
-
const properties = __spreadProps(__spreadValues({}, block.properties), {
|
|
28
|
+
const properties = __spreadProps(__spreadValues(__spreadValues({}, extractRelevantRootBlockProperties(block)), block.properties), {
|
|
26
29
|
"builder-id": block.id,
|
|
27
30
|
style: getStyleAttribute(block.style),
|
|
28
31
|
class: [block.id, "builder-block", block.class, (_a = block.properties) == null ? void 0 : _a.class].filter(Boolean).join(" ")
|
|
@@ -39,13 +39,14 @@ var __async = (__this, __arguments, generator) => {
|
|
|
39
39
|
step((generator = generator.apply(__this, __arguments)).next());
|
|
40
40
|
});
|
|
41
41
|
};
|
|
42
|
+
import { logger } from "../../helpers/logger.js";
|
|
42
43
|
import { fetch } from "../get-fetch.js";
|
|
43
44
|
import { handleABTesting } from "./ab-testing.js";
|
|
44
45
|
import { generateContentUrl } from "./generate-content-url.js";
|
|
45
46
|
function getContent(options) {
|
|
46
47
|
return __async(this, null, function* () {
|
|
47
48
|
const allContent = yield getAllContent(__spreadProps(__spreadValues({}, options), { limit: 1 }));
|
|
48
|
-
if ("results" in allContent) {
|
|
49
|
+
if (allContent && "results" in allContent) {
|
|
49
50
|
return (allContent == null ? void 0 : allContent.results[0]) || null;
|
|
50
51
|
}
|
|
51
52
|
return null;
|
|
@@ -53,25 +54,31 @@ function getContent(options) {
|
|
|
53
54
|
}
|
|
54
55
|
function getAllContent(options) {
|
|
55
56
|
return __async(this, null, function* () {
|
|
56
|
-
const url = generateContentUrl(options);
|
|
57
|
-
const res = yield fetch(url.href);
|
|
58
|
-
const content = yield res.json();
|
|
59
|
-
if ("status" in content && !("results" in content)) {
|
|
60
|
-
console.error("[Builder.io]: Error fetching data. ", content, options);
|
|
61
|
-
return content;
|
|
62
|
-
}
|
|
63
|
-
const canTrack = options.canTrack !== false;
|
|
64
57
|
try {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
58
|
+
const url = generateContentUrl(options);
|
|
59
|
+
const res = yield fetch(url.href);
|
|
60
|
+
const content = yield res.json();
|
|
61
|
+
if ("status" in content && !("results" in content)) {
|
|
62
|
+
logger.error("Error fetching data. ", content, options);
|
|
63
|
+
return content;
|
|
64
|
+
}
|
|
65
|
+
const canTrack = options.canTrack !== false;
|
|
66
|
+
try {
|
|
67
|
+
if (canTrack && Array.isArray(content.results)) {
|
|
68
|
+
for (const item of content.results) {
|
|
69
|
+
yield handleABTesting({ item, canTrack });
|
|
70
|
+
}
|
|
68
71
|
}
|
|
69
72
|
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
logger.error("Could not setup A/B testing. ", e);
|
|
75
|
+
}
|
|
76
|
+
return content;
|
|
70
77
|
}
|
|
71
|
-
catch (
|
|
72
|
-
|
|
78
|
+
catch (error) {
|
|
79
|
+
logger.error("Error fetching data. ", error);
|
|
80
|
+
return null;
|
|
73
81
|
}
|
|
74
|
-
return content;
|
|
75
82
|
});
|
|
76
83
|
}
|
|
77
84
|
export { getAllContent, getContent };
|
|
@@ -52,6 +52,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
52
52
|
});
|
|
53
53
|
};
|
|
54
54
|
import { TARGET } from "../../constants/target.js";
|
|
55
|
+
import { logger } from "../../helpers/logger.js";
|
|
55
56
|
import { getSessionId } from "../../helpers/sessionId.js";
|
|
56
57
|
import { getVisitorId } from "../../helpers/visitorId.js";
|
|
57
58
|
import { isBrowser } from "../is-browser.js";
|
|
@@ -90,7 +91,7 @@ const createEvent = (_a) => __async(void 0, null, function* () {
|
|
|
90
91
|
function _track(eventProps) {
|
|
91
92
|
return __async(this, null, function* () {
|
|
92
93
|
if (!eventProps.apiKey) {
|
|
93
|
-
|
|
94
|
+
logger.error("Missing API key for track call. Please provide your API key.");
|
|
94
95
|
return;
|
|
95
96
|
}
|
|
96
97
|
if (!eventProps.canTrack) {
|
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@ import RenderContent from "../../components/render-content/render-content";
|
|
|
4
4
|
import BuilderContext from "../../context/builder.context.js";
|
|
5
5
|
import { getContent } from "../../functions/get-content/index.js";
|
|
6
6
|
import { TARGET } from "../../constants/target";
|
|
7
|
+
import { logger } from "../../helpers/logger";
|
|
7
8
|
|
|
8
9
|
function Symbol(props) {
|
|
9
10
|
const [className, setClassName] = useState(() =>
|
|
@@ -53,7 +54,7 @@ function Symbol(props) {
|
|
|
53
54
|
}
|
|
54
55
|
})
|
|
55
56
|
.catch((err) => {
|
|
56
|
-
|
|
57
|
+
logger.error("Could not fetch symbol content: ", err);
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
}
|
|
@@ -40,6 +40,9 @@ function BlockStyles(props) {
|
|
|
40
40
|
const mediumStyles = styles?.medium;
|
|
41
41
|
const smallStyles = styles?.small;
|
|
42
42
|
const className = useBlock().id;
|
|
43
|
+
if (!className) {
|
|
44
|
+
return "";
|
|
45
|
+
}
|
|
43
46
|
const largeStylesClass = largeStyles
|
|
44
47
|
? createCssClass({
|
|
45
48
|
className,
|
|
@@ -106,8 +106,24 @@ const getRepeatItemData = ({
|
|
|
106
106
|
}));
|
|
107
107
|
return repeatArray;
|
|
108
108
|
};
|
|
109
|
+
const getProxyState = (context) => {
|
|
110
|
+
if (typeof Proxy === "undefined") {
|
|
111
|
+
console.error("no Proxy available in this environment, cannot proxy state.");
|
|
112
|
+
return context.state;
|
|
113
|
+
}
|
|
114
|
+
const useState = new Proxy(context.state, {
|
|
115
|
+
set: (obj, prop, value) => {
|
|
116
|
+
var _a;
|
|
117
|
+
obj[prop] = value;
|
|
118
|
+
(_a = context.setState) == null ? void 0 : _a.call(context, obj);
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
return useState;
|
|
123
|
+
};
|
|
109
124
|
export {
|
|
110
125
|
getComponent,
|
|
126
|
+
getProxyState,
|
|
111
127
|
getRepeatItemData,
|
|
112
128
|
isEmptyHtmlElement
|
|
113
129
|
};
|
|
@@ -3,11 +3,11 @@ import { useState } from "react";
|
|
|
3
3
|
import { getBlockActions } from "../../functions/get-block-actions.js";
|
|
4
4
|
import { getBlockComponentOptions } from "../../functions/get-block-component-options.js";
|
|
5
5
|
import { getBlockProperties } from "../../functions/get-block-properties.js";
|
|
6
|
-
import { getBlockTag } from "../../functions/get-block-tag.js";
|
|
7
6
|
import { getProcessedBlock } from "../../functions/get-processed-block.js";
|
|
8
7
|
import BlockStyles from "./block-styles";
|
|
9
8
|
import {
|
|
10
9
|
getComponent,
|
|
10
|
+
getProxyState,
|
|
11
11
|
getRepeatItemData,
|
|
12
12
|
isEmptyHtmlElement,
|
|
13
13
|
} from "./render-block.helpers.js";
|
|
@@ -16,7 +16,6 @@ import { TARGET } from "../../constants/target.js";
|
|
|
16
16
|
import { extractTextStyles } from "../../functions/extract-text-styles.js";
|
|
17
17
|
import RenderComponent from "./render-component";
|
|
18
18
|
import { getReactNativeBlockStyles } from "../../functions/get-react-native-block-styles.js";
|
|
19
|
-
import { checkIsDefined } from "../../helpers/nullable.js";
|
|
20
19
|
|
|
21
20
|
function RenderBlock(props) {
|
|
22
21
|
const [component, setComponent] = useState(() =>
|
|
@@ -26,9 +25,12 @@ function RenderBlock(props) {
|
|
|
26
25
|
})
|
|
27
26
|
);
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const [repeatItemData, setRepeatItemData] = useState(() =>
|
|
29
|
+
getRepeatItemData({
|
|
30
|
+
block: props.block,
|
|
31
|
+
context: props.context,
|
|
32
|
+
})
|
|
33
|
+
);
|
|
32
34
|
|
|
33
35
|
function useBlock() {
|
|
34
36
|
return repeatItemData
|
|
@@ -41,40 +43,26 @@ function RenderBlock(props) {
|
|
|
41
43
|
});
|
|
42
44
|
}
|
|
43
45
|
|
|
46
|
+
const [tag, setTag] = useState(() => props.block.tagName || "div");
|
|
47
|
+
|
|
44
48
|
function canShowBlock() {
|
|
45
|
-
if (
|
|
49
|
+
if ("hide" in useBlock()) {
|
|
46
50
|
return !useBlock().hide;
|
|
47
51
|
}
|
|
48
|
-
if (
|
|
52
|
+
if ("show" in useBlock()) {
|
|
49
53
|
return useBlock().show;
|
|
50
54
|
}
|
|
51
55
|
return true;
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"no Proxy available in this environment, cannot proxy state."
|
|
58
|
-
);
|
|
59
|
-
return props.context.state;
|
|
60
|
-
}
|
|
61
|
-
const useState = new Proxy(props.context.state, {
|
|
62
|
-
set: (obj, prop, value) => {
|
|
63
|
-
// set the value on the state object, so that the event handler instantly gets the update.
|
|
64
|
-
obj[prop] = value;
|
|
65
|
-
|
|
66
|
-
// set the value in the context, so that the rest of the app gets the update.
|
|
67
|
-
props.context.setState?.(obj);
|
|
68
|
-
return true;
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
return useState;
|
|
72
|
-
}
|
|
58
|
+
const [proxyState, setProxyState] = useState(() =>
|
|
59
|
+
getProxyState(props.context)
|
|
60
|
+
);
|
|
73
61
|
|
|
74
62
|
function actions() {
|
|
75
63
|
return getBlockActions({
|
|
76
64
|
block: useBlock(),
|
|
77
|
-
state: proxyState
|
|
65
|
+
state: TARGET === "qwik" ? props.context.state : proxyState,
|
|
78
66
|
context: props.context.context,
|
|
79
67
|
});
|
|
80
68
|
}
|
|
@@ -95,29 +83,6 @@ function RenderBlock(props) {
|
|
|
95
83
|
};
|
|
96
84
|
}
|
|
97
85
|
|
|
98
|
-
function renderComponentProps() {
|
|
99
|
-
return {
|
|
100
|
-
blockChildren: useBlock().children ?? [],
|
|
101
|
-
componentRef: component?.component,
|
|
102
|
-
componentOptions: {
|
|
103
|
-
...getBlockComponentOptions(useBlock()),
|
|
104
|
-
/**
|
|
105
|
-
* These attributes are passed to the wrapper element when there is one. If `noWrap` is set to true, then
|
|
106
|
-
* they are provided to the component itself directly.
|
|
107
|
-
*/
|
|
108
|
-
...(!component?.noWrap
|
|
109
|
-
? {}
|
|
110
|
-
: {
|
|
111
|
-
attributes: {
|
|
112
|
-
...attributes(),
|
|
113
|
-
...actions(),
|
|
114
|
-
},
|
|
115
|
-
}),
|
|
116
|
-
},
|
|
117
|
-
context: childrenContext(),
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
86
|
function childrenWithoutParentComponent() {
|
|
122
87
|
/**
|
|
123
88
|
* When there is no `componentRef`, there might still be children that need to be rendered. In this case,
|
|
@@ -130,13 +95,6 @@ function RenderBlock(props) {
|
|
|
130
95
|
return shouldRenderChildrenOutsideRef ? useBlock().children ?? [] : [];
|
|
131
96
|
}
|
|
132
97
|
|
|
133
|
-
const [repeatItemData, setRepeatItemData] = useState(() =>
|
|
134
|
-
getRepeatItemData({
|
|
135
|
-
block: props.block,
|
|
136
|
-
context: props.context,
|
|
137
|
-
})
|
|
138
|
-
);
|
|
139
|
-
|
|
140
98
|
function childrenContext() {
|
|
141
99
|
const getInheritedTextStyles = () => {
|
|
142
100
|
if (TARGET !== "reactNative") {
|
|
@@ -162,7 +120,30 @@ function RenderBlock(props) {
|
|
|
162
120
|
};
|
|
163
121
|
}
|
|
164
122
|
|
|
165
|
-
|
|
123
|
+
function renderComponentProps() {
|
|
124
|
+
return {
|
|
125
|
+
blockChildren: useBlock().children ?? [],
|
|
126
|
+
componentRef: component?.component,
|
|
127
|
+
componentOptions: {
|
|
128
|
+
...getBlockComponentOptions(useBlock()),
|
|
129
|
+
/**
|
|
130
|
+
* These attributes are passed to the wrapper element when there is one. If `noWrap` is set to true, then
|
|
131
|
+
* they are provided to the component itself directly.
|
|
132
|
+
*/
|
|
133
|
+
...(!component?.noWrap
|
|
134
|
+
? {}
|
|
135
|
+
: {
|
|
136
|
+
attributes: {
|
|
137
|
+
...attributes(),
|
|
138
|
+
...actions(),
|
|
139
|
+
},
|
|
140
|
+
}),
|
|
141
|
+
},
|
|
142
|
+
context: childrenContext(),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const TagRef = tag;
|
|
166
147
|
|
|
167
148
|
return (
|
|
168
149
|
<>
|
|
@@ -170,12 +151,12 @@ function RenderBlock(props) {
|
|
|
170
151
|
<>
|
|
171
152
|
{!component?.noWrap ? (
|
|
172
153
|
<>
|
|
173
|
-
{isEmptyHtmlElement(tag
|
|
154
|
+
{isEmptyHtmlElement(tag) ? (
|
|
174
155
|
<>
|
|
175
156
|
<TagRef {...attributes()} {...actions()} />
|
|
176
157
|
</>
|
|
177
158
|
) : null}
|
|
178
|
-
{!isEmptyHtmlElement(tag
|
|
159
|
+
{!isEmptyHtmlElement(tag) && repeatItemData ? (
|
|
179
160
|
<>
|
|
180
161
|
{repeatItemData?.map((data, index) => (
|
|
181
162
|
<RenderRepeatedBlock
|
|
@@ -186,7 +167,7 @@ function RenderBlock(props) {
|
|
|
186
167
|
))}
|
|
187
168
|
</>
|
|
188
169
|
) : null}
|
|
189
|
-
{!isEmptyHtmlElement(tag
|
|
170
|
+
{!isEmptyHtmlElement(tag) && !repeatItemData ? (
|
|
190
171
|
<>
|
|
191
172
|
<TagRef {...attributes()} {...actions()}>
|
|
192
173
|
<RenderComponent {...renderComponentProps()} />
|