@builder.io/sdk-react 0.2.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -3
- package/dist/sdk/blocks/BaseText.js +1 -1
- package/dist/sdk/blocks/button/button.js +1 -1
- package/dist/sdk/blocks/columns/columns.js +6 -6
- package/dist/sdk/blocks/custom-code/custom-code.js +1 -1
- package/dist/sdk/blocks/embed/embed.js +1 -1
- package/dist/sdk/blocks/fragment/fragment.js +1 -1
- package/dist/sdk/blocks/image/image.js +1 -1
- package/dist/sdk/blocks/img/img.js +1 -1
- package/dist/sdk/blocks/input/input.js +1 -1
- package/dist/sdk/blocks/raw-text/raw-text.js +1 -1
- package/dist/sdk/blocks/section/section.js +1 -1
- package/dist/sdk/blocks/select/select.js +1 -1
- package/dist/sdk/blocks/submit-button/submit-button.js +1 -1
- package/dist/sdk/blocks/symbol/symbol.js +2 -2
- package/dist/sdk/blocks/text/text.js +1 -1
- package/dist/sdk/blocks/textarea/textarea.js +1 -1
- package/dist/sdk/blocks/video/video.js +1 -1
- package/dist/sdk/components/render-block/block-styles.js +4 -2
- package/dist/sdk/components/render-block/render-block.helpers.d.ts +0 -1
- package/dist/sdk/components/render-block/render-block.helpers.js +8 -20
- package/dist/sdk/components/render-block/render-block.js +25 -20
- package/dist/sdk/components/render-block/render-component.js +2 -3
- package/dist/sdk/components/render-block/render-repeated-block.js +4 -3
- package/dist/sdk/components/render-blocks.js +1 -1
- package/dist/sdk/components/render-content/builder-editing.js +1 -1
- package/dist/sdk/components/render-content/components/render-styles.js +2 -2
- package/dist/sdk/components/render-content/render-content.js +45 -11
- package/dist/sdk/components/render-content/render-content.types.d.ts +11 -2
- package/dist/sdk/components/render-content/wrap-component-ref.d.ts +6 -0
- package/dist/sdk/components/render-content/wrap-component-ref.js +6 -0
- package/dist/sdk/components/render-content-variants/helpers.d.ts +17 -0
- package/dist/sdk/components/render-content-variants/helpers.js +182 -0
- package/dist/sdk/components/render-content-variants/render-content-variants.d.ts +5 -0
- package/dist/sdk/components/render-content-variants/render-content-variants.js +37 -0
- package/dist/sdk/components/render-inlined-styles.d.ts +1 -0
- package/dist/sdk/components/render-inlined-styles.js +2 -13
- package/dist/sdk/constants/sdk-version.d.ts +1 -0
- package/dist/sdk/constants/sdk-version.js +1 -0
- package/dist/sdk/context/builder.context.js +3 -2
- package/dist/sdk/context/types.d.ts +17 -2
- package/dist/sdk/functions/evaluate.d.ts +4 -3
- package/dist/sdk/functions/evaluate.js +23 -2
- package/dist/sdk/functions/evaluate.test.d.ts +1 -0
- package/dist/sdk/functions/evaluate.test.js +17 -0
- package/dist/sdk/functions/get-block-actions-handler.d.ts +1 -1
- package/dist/sdk/functions/get-block-actions-handler.js +3 -1
- package/dist/sdk/functions/get-block-actions.d.ts +1 -1
- package/dist/sdk/functions/get-content/generate-content-url.js +2 -2
- package/dist/sdk/functions/get-content/generate-content-url.test.js +15 -0
- package/dist/sdk/functions/get-content/index.d.ts +7 -2
- package/dist/sdk/functions/get-content/index.js +43 -20
- package/dist/sdk/functions/get-content/types.d.ts +6 -0
- package/dist/sdk/functions/get-processed-block.d.ts +2 -2
- package/dist/sdk/functions/get-processed-block.js +16 -4
- package/dist/sdk/functions/get-processed-block.test.js +3 -1
- package/dist/sdk/helpers/ab-tests.d.ts +8 -7
- package/dist/sdk/helpers/ab-tests.js +103 -4
- package/dist/sdk/helpers/canTrack.d.ts +1 -0
- package/dist/sdk/helpers/canTrack.js +2 -0
- package/dist/sdk/helpers/cookie.d.ts +7 -3
- package/dist/sdk/helpers/cookie.js +9 -6
- package/dist/sdk/helpers/logger.d.ts +1 -0
- package/dist/sdk/helpers/logger.js +1 -0
- package/dist/sdk/index-helpers/blocks-exports.d.ts +1 -1
- package/dist/sdk/index-helpers/blocks-exports.js +1 -1
- package/dist/sdk/index.d.ts +8 -7
- package/dist/sdk/index.js +6 -7
- package/dist/sdk/scripts/init-editing.d.ts +1 -0
- package/dist/sdk/scripts/init-editing.js +2 -0
- package/dist/sdk/types/builder-content.d.ts +1 -3
- package/package.json +2 -5
package/README.md
CHANGED
|
@@ -1,6 +1,72 @@
|
|
|
1
1
|
# Builder.io React SDK v2 (BETA)
|
|
2
2
|
|
|
3
|
-
This is the React v2 SDK.
|
|
3
|
+
This is the React v2 SDK, `@builder.io/sdk-react`.
|
|
4
|
+
|
|
5
|
+
NOTE: it is still in Beta. For the stable React v1 SDK [go here](../../../react/), i.e. `builder.io/react`.
|
|
6
|
+
|
|
7
|
+
## API Reference
|
|
8
|
+
|
|
9
|
+
To use the SDK, you need to:
|
|
10
|
+
|
|
11
|
+
- fetch the builder data using `getContent`: you can see how to use it here https://www.builder.io/c/docs/content-api, and how it differs from the React V1 SDK's `builder.get()` function.
|
|
12
|
+
|
|
13
|
+
NOTE: if you are using the SDK in next v13's app directory, you will have to import `getContent` from @builder.io/sdk-react/server`. this is a special import that guarantees you don't import any client components with your data fetching.
|
|
14
|
+
|
|
15
|
+
- pass that data to the `RenderContent` component, along with the following properties:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
type RenderContentProps = {
|
|
19
|
+
content?: Nullable<BuilderContent>;
|
|
20
|
+
model?: string;
|
|
21
|
+
data?: { [key: string]: any };
|
|
22
|
+
context?: BuilderRenderContext;
|
|
23
|
+
apiKey: string;
|
|
24
|
+
apiVersion?: ApiVersion;
|
|
25
|
+
customComponents?: RegisteredComponent[];
|
|
26
|
+
canTrack?: boolean;
|
|
27
|
+
locale?: string;
|
|
28
|
+
includeRefs?: boolean;
|
|
29
|
+
};
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Here is a simplified example showing how you would use both:
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import { RenderContent, getContent, isPreviewing } from '@builder.io/sdk-react';
|
|
36
|
+
import { useEffect, useState } from 'react';
|
|
37
|
+
|
|
38
|
+
const BUILDER_PUBLIC_API_KEY = 'YOUR API KEY';
|
|
39
|
+
|
|
40
|
+
function App() {
|
|
41
|
+
const [content, setContent] = useState(undefined);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
getContent({
|
|
45
|
+
model: 'page',
|
|
46
|
+
apiKey: BUILDER_PUBLIC_API_KEY,
|
|
47
|
+
userAttributes: {
|
|
48
|
+
urlPath: window.location.pathname || '/',
|
|
49
|
+
},
|
|
50
|
+
}).then((content) => {
|
|
51
|
+
setContent(content);
|
|
52
|
+
});
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
55
|
+
const shouldRenderBuilderContent = content || isPreviewing();
|
|
56
|
+
|
|
57
|
+
return shouldRenderBuilderContent ? (
|
|
58
|
+
<RenderContent
|
|
59
|
+
content={content}
|
|
60
|
+
model="page"
|
|
61
|
+
apiKey={BUILDER_PUBLIC_API_KEY}
|
|
62
|
+
/>
|
|
63
|
+
) : (
|
|
64
|
+
<div>Content Not Found</div>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Look at the [examples](#examples) for more information.
|
|
4
70
|
|
|
5
71
|
## Mitosis
|
|
6
72
|
|
|
@@ -13,10 +79,13 @@ To check the status of the SDK, look at [these tables](../../README.md#feature-i
|
|
|
13
79
|
## Getting Started
|
|
14
80
|
|
|
15
81
|
```
|
|
16
|
-
npm install @builder.io/sdk-react
|
|
82
|
+
npm install @builder.io/sdk-react
|
|
17
83
|
```
|
|
18
84
|
|
|
19
|
-
|
|
85
|
+
## Examples
|
|
86
|
+
|
|
87
|
+
- [React](../../../../examples/react-v2/)
|
|
88
|
+
- [Next.js + app dir](../../../../examples/next-app-directory)
|
|
20
89
|
|
|
21
90
|
## Fetch
|
|
22
91
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { useState, useContext } from "react";
|
|
4
4
|
import RenderBlocks from "../../components/render-blocks";
|
|
@@ -50,7 +50,7 @@ function Columns(props) {
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
const width = getColumnCssWidth(index);
|
|
53
|
-
const gutterPixels = `${
|
|
53
|
+
const gutterPixels = `${gutter}px`;
|
|
54
54
|
const mobileWidth = "100%";
|
|
55
55
|
const mobileMarginLeft = 0;
|
|
56
56
|
return {
|
|
@@ -108,17 +108,17 @@ function Columns(props) {
|
|
|
108
108
|
const builderContext = useContext(BuilderContext);
|
|
109
109
|
return (React.createElement(React.Fragment, null,
|
|
110
110
|
React.createElement("div", { className: `builder-columns ${props.builderBlock.id}-breakpoints` +
|
|
111
|
-
" div-
|
|
111
|
+
" div-08005e06", style: columnsCssVars() },
|
|
112
112
|
TARGET !== "reactNative" ? (React.createElement(React.Fragment, null,
|
|
113
113
|
React.createElement(RenderInlinedStyles, { styles: columnsStyles() }))) : null,
|
|
114
|
-
props.columns?.map((column, index) => (React.createElement("div", { className: "builder-column div-
|
|
114
|
+
props.columns?.map((column, index) => (React.createElement("div", { className: "builder-column div-08005e06-2", style: columnCssVars(index), key: index },
|
|
115
115
|
React.createElement(RenderBlocks, { blocks: column.blocks, path: `component.options.columns.${index}.blocks`, parent: props.builderBlock.id, styleProp: {
|
|
116
116
|
flexGrow: "1",
|
|
117
117
|
} }))))),
|
|
118
|
-
React.createElement("style", null, `.div-
|
|
118
|
+
React.createElement("style", null, `.div-08005e06 {
|
|
119
119
|
display: flex;
|
|
120
120
|
line-height: normal;
|
|
121
|
-
}.div-
|
|
121
|
+
}.div-08005e06-2 {
|
|
122
122
|
display: flex;
|
|
123
123
|
flex-direction: column;
|
|
124
124
|
align-items: stretch;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { useState, useContext, useEffect } from "react";
|
|
4
4
|
import RenderContent from "../../components/render-content/render-content";
|
|
@@ -62,7 +62,7 @@ function Symbol(props) {
|
|
|
62
62
|
return (React.createElement("div", { ...props.attributes, className: className },
|
|
63
63
|
React.createElement(RenderContent, { apiVersion: builderContext.apiVersion, apiKey: builderContext.apiKey, context: builderContext.context, customComponents: Object.values(builderContext.registeredComponents), data: {
|
|
64
64
|
...props.symbol?.data,
|
|
65
|
-
...builderContext.
|
|
65
|
+
...builderContext.localState,
|
|
66
66
|
...contentToUse?.data?.state,
|
|
67
67
|
}, model: props.symbol?.model, content: contentToUse })));
|
|
68
68
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { getMaxWidthQueryForSize, getSizesForBreakpoints, } from "../../constants/device-sizes.js";
|
|
4
4
|
import { TARGET } from "../../constants/target.js";
|
|
@@ -10,7 +10,9 @@ function BlockStyles(props) {
|
|
|
10
10
|
function useBlock() {
|
|
11
11
|
return getProcessedBlock({
|
|
12
12
|
block: props.block,
|
|
13
|
-
|
|
13
|
+
localState: props.context.localState,
|
|
14
|
+
rootState: props.context.rootState,
|
|
15
|
+
rootSetState: props.context.rootSetState,
|
|
14
16
|
context: props.context.context,
|
|
15
17
|
shouldEvaluateBindings: true,
|
|
16
18
|
});
|
|
@@ -27,7 +27,9 @@ export const isEmptyHtmlElement = (tagName) => {
|
|
|
27
27
|
export const getComponent = ({ block, context, }) => {
|
|
28
28
|
const componentName = getProcessedBlock({
|
|
29
29
|
block,
|
|
30
|
-
|
|
30
|
+
localState: context.localState,
|
|
31
|
+
rootState: context.rootState,
|
|
32
|
+
rootSetState: context.rootSetState,
|
|
31
33
|
context: context.context,
|
|
32
34
|
shouldEvaluateBindings: false,
|
|
33
35
|
}).component?.name;
|
|
@@ -57,7 +59,9 @@ export const getRepeatItemData = ({ block, context, }) => {
|
|
|
57
59
|
}
|
|
58
60
|
const itemsArray = evaluate({
|
|
59
61
|
code: repeat.collection,
|
|
60
|
-
|
|
62
|
+
localState: context.localState,
|
|
63
|
+
rootState: context.rootState,
|
|
64
|
+
rootSetState: context.rootSetState,
|
|
61
65
|
context: context.context,
|
|
62
66
|
});
|
|
63
67
|
if (!Array.isArray(itemsArray)) {
|
|
@@ -68,8 +72,8 @@ export const getRepeatItemData = ({ block, context, }) => {
|
|
|
68
72
|
const repeatArray = itemsArray.map((item, index) => ({
|
|
69
73
|
context: {
|
|
70
74
|
...context,
|
|
71
|
-
|
|
72
|
-
...context.
|
|
75
|
+
localState: {
|
|
76
|
+
...context.localState,
|
|
73
77
|
$index: index,
|
|
74
78
|
$item: item,
|
|
75
79
|
[itemNameToUse]: item,
|
|
@@ -80,19 +84,3 @@ export const getRepeatItemData = ({ block, context, }) => {
|
|
|
80
84
|
}));
|
|
81
85
|
return repeatArray;
|
|
82
86
|
};
|
|
83
|
-
export const getProxyState = (context) => {
|
|
84
|
-
if (typeof Proxy === 'undefined') {
|
|
85
|
-
console.error('no Proxy available in this environment, cannot proxy state.');
|
|
86
|
-
return context.state;
|
|
87
|
-
}
|
|
88
|
-
const useState = new Proxy(context.state, {
|
|
89
|
-
set: (obj, prop, value) => {
|
|
90
|
-
// set the value on the state object, so that the event handler instantly gets the update.
|
|
91
|
-
obj[prop] = value;
|
|
92
|
-
// set the value in the context, so that the rest of the app gets the update.
|
|
93
|
-
context.setState?.(obj);
|
|
94
|
-
return true;
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
return useState;
|
|
98
|
-
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { getBlockActions } from "../../functions/get-block-actions.js";
|
|
@@ -6,7 +6,7 @@ import { getBlockComponentOptions } from "../../functions/get-block-component-op
|
|
|
6
6
|
import { getBlockProperties } from "../../functions/get-block-properties.js";
|
|
7
7
|
import { getProcessedBlock } from "../../functions/get-processed-block.js";
|
|
8
8
|
import BlockStyles from "./block-styles";
|
|
9
|
-
import { getComponent,
|
|
9
|
+
import { getComponent, getRepeatItemData, isEmptyHtmlElement, } from "./render-block.helpers.js";
|
|
10
10
|
import RenderRepeatedBlock from "./render-repeated-block";
|
|
11
11
|
import { TARGET } from "../../constants/target.js";
|
|
12
12
|
import { extractTextStyles } from "../../functions/extract-text-styles.js";
|
|
@@ -17,21 +17,25 @@ function RenderBlock(props) {
|
|
|
17
17
|
block: props.block,
|
|
18
18
|
context: props.context,
|
|
19
19
|
}));
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
function repeatItem() {
|
|
21
|
+
return getRepeatItemData({
|
|
22
|
+
block: props.block,
|
|
23
|
+
context: props.context,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
24
26
|
function useBlock() {
|
|
25
|
-
return
|
|
27
|
+
return repeatItem()
|
|
26
28
|
? props.block
|
|
27
29
|
: getProcessedBlock({
|
|
28
30
|
block: props.block,
|
|
29
|
-
|
|
31
|
+
localState: props.context.localState,
|
|
32
|
+
rootState: props.context.rootState,
|
|
33
|
+
rootSetState: props.context.rootSetState,
|
|
30
34
|
context: props.context.context,
|
|
31
35
|
shouldEvaluateBindings: true,
|
|
32
36
|
});
|
|
33
37
|
}
|
|
34
|
-
const [
|
|
38
|
+
const [Tag, setTag] = useState(() => props.block.tagName || "div");
|
|
35
39
|
function canShowBlock() {
|
|
36
40
|
if ("hide" in useBlock()) {
|
|
37
41
|
return !useBlock().hide;
|
|
@@ -41,11 +45,12 @@ function RenderBlock(props) {
|
|
|
41
45
|
}
|
|
42
46
|
return true;
|
|
43
47
|
}
|
|
44
|
-
const [proxyState, setProxyState] = useState(() => getProxyState(props.context));
|
|
45
48
|
function actions() {
|
|
46
49
|
return getBlockActions({
|
|
47
50
|
block: useBlock(),
|
|
48
|
-
|
|
51
|
+
rootState: props.context.rootState,
|
|
52
|
+
rootSetState: props.context.rootSetState,
|
|
53
|
+
localState: props.context.localState,
|
|
49
54
|
context: props.context.context,
|
|
50
55
|
});
|
|
51
56
|
}
|
|
@@ -71,7 +76,7 @@ function RenderBlock(props) {
|
|
|
71
76
|
* NOTE: We make sure not to render this if `repeatItemData` is non-null, because that means we are rendering an array of
|
|
72
77
|
* blocks, and the children will be repeated within those blocks.
|
|
73
78
|
*/
|
|
74
|
-
const shouldRenderChildrenOutsideRef = !component?.component && !
|
|
79
|
+
const shouldRenderChildrenOutsideRef = !component?.component && !repeatItem();
|
|
75
80
|
return shouldRenderChildrenOutsideRef ? useBlock().children ?? [] : [];
|
|
76
81
|
}
|
|
77
82
|
function childrenContext() {
|
|
@@ -88,10 +93,11 @@ function RenderBlock(props) {
|
|
|
88
93
|
return {
|
|
89
94
|
apiKey: props.context.apiKey,
|
|
90
95
|
apiVersion: props.context.apiVersion,
|
|
91
|
-
|
|
96
|
+
localState: props.context.localState,
|
|
97
|
+
rootState: props.context.rootState,
|
|
98
|
+
rootSetState: props.context.rootSetState,
|
|
92
99
|
content: props.context.content,
|
|
93
100
|
context: props.context.context,
|
|
94
|
-
setState: props.context.setState,
|
|
95
101
|
registeredComponents: props.context.registeredComponents,
|
|
96
102
|
inheritedStyles: getInheritedTextStyles(),
|
|
97
103
|
};
|
|
@@ -118,13 +124,12 @@ function RenderBlock(props) {
|
|
|
118
124
|
context: childrenContext(),
|
|
119
125
|
};
|
|
120
126
|
}
|
|
121
|
-
const TagRef = tag;
|
|
122
127
|
return (React.createElement(React.Fragment, null, canShowBlock() ? (React.createElement(React.Fragment, null, !component?.noWrap ? (React.createElement(React.Fragment, null,
|
|
123
|
-
isEmptyHtmlElement(
|
|
124
|
-
React.createElement(
|
|
125
|
-
!isEmptyHtmlElement(
|
|
126
|
-
!isEmptyHtmlElement(
|
|
127
|
-
React.createElement(
|
|
128
|
+
isEmptyHtmlElement(Tag) ? (React.createElement(React.Fragment, null,
|
|
129
|
+
React.createElement(Tag, { ...attributes(), ...actions() }))) : null,
|
|
130
|
+
!isEmptyHtmlElement(Tag) && repeatItem() ? (React.createElement(React.Fragment, null, repeatItem()?.map((data, index) => (React.createElement(RenderRepeatedBlock, { key: index, repeatContext: data.context, block: data.block }))))) : null,
|
|
131
|
+
!isEmptyHtmlElement(Tag) && !repeatItem() ? (React.createElement(React.Fragment, null,
|
|
132
|
+
React.createElement(Tag, { ...attributes(), ...actions() },
|
|
128
133
|
React.createElement(RenderComponent, { ...renderComponentProps() }),
|
|
129
134
|
childrenWithoutParentComponent()?.map((child) => (React.createElement(RenderBlock, { key: "render-block-" + child.id, block: child, context: childrenContext() }))),
|
|
130
135
|
childrenWithoutParentComponent()?.map((child) => (React.createElement(BlockStyles, { key: "block-style-" + child.id, block: child, context: childrenContext() })))))) : null)) : (React.createElement(React.Fragment, null,
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import BlockStyles from "./block-styles";
|
|
4
4
|
import RenderBlock from "./render-block";
|
|
5
5
|
function RenderComponent(props) {
|
|
6
|
-
const ComponentRefRef = props.componentRef;
|
|
7
6
|
return (React.createElement(React.Fragment, null, props.componentRef ? (React.createElement(React.Fragment, null,
|
|
8
|
-
React.createElement(
|
|
7
|
+
React.createElement(props.componentRef, { ...props.componentOptions },
|
|
9
8
|
props.blockChildren?.map((child) => (React.createElement(RenderBlock, { key: "render-block-" + child.id, block: child, context: props.context }))),
|
|
10
9
|
props.blockChildren?.map((child) => (React.createElement(BlockStyles, { key: "block-style-" + child.id, block: child, context: props.context })))))) : null));
|
|
11
10
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
/**
|
|
4
4
|
* We can't make this a generic `ProvideContext` function because Vue 2 won't support root slots, e.g.
|
|
@@ -14,8 +14,9 @@ import RenderBlock from "./render-block";
|
|
|
14
14
|
function RenderRepeatedBlock(props) {
|
|
15
15
|
return (React.createElement(BuilderContext.Provider, { value: {
|
|
16
16
|
content: props.repeatContext.content,
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
localState: props.repeatContext.localState,
|
|
18
|
+
rootState: props.repeatContext.rootState,
|
|
19
|
+
rootSetState: props.repeatContext.rootSetState,
|
|
19
20
|
context: props.repeatContext.context,
|
|
20
21
|
apiKey: props.repeatContext.apiKey,
|
|
21
22
|
registeredComponents: props.repeatContext.registeredComponents,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import RenderInlinedStyles from "../../render-inlined-styles";
|
|
@@ -26,7 +26,7 @@ ${getFontCss({
|
|
|
26
26
|
text-align: inherit;
|
|
27
27
|
font-family: inherit;
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
`.trim());
|
|
30
30
|
return React.createElement(RenderInlinedStyles, { styles: injectedStyles });
|
|
31
31
|
}
|
|
32
32
|
export default RenderContentStyles;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { useState, useRef, useEffect } from "react";
|
|
4
4
|
import { getDefaultRegisteredComponents } from "../../constants/builder-registered-components.js";
|
|
@@ -19,6 +19,8 @@ import { getInteractionPropertiesForEvent } from "../../functions/track/interact
|
|
|
19
19
|
import { getContentInitialValue, getContextStateInitialValue, } from "./render-content.helpers.js";
|
|
20
20
|
import { TARGET } from "../../constants/target.js";
|
|
21
21
|
import { logger } from "../../helpers/logger.js";
|
|
22
|
+
import { getRenderContentScriptString } from "../render-content-variants/helpers.js";
|
|
23
|
+
import { wrapComponentRef } from "./wrap-component-ref.js";
|
|
22
24
|
function RenderContent(props) {
|
|
23
25
|
const elementRef = useRef(null);
|
|
24
26
|
const [forceReRenderCount, setForceReRenderCount] = useState(() => 0);
|
|
@@ -58,8 +60,8 @@ function RenderContent(props) {
|
|
|
58
60
|
data: props.data,
|
|
59
61
|
locale: props.locale,
|
|
60
62
|
}));
|
|
61
|
-
function
|
|
62
|
-
setContentState(
|
|
63
|
+
function contentSetState(newRootState) {
|
|
64
|
+
setContentState(newRootState);
|
|
63
65
|
}
|
|
64
66
|
const [allRegisteredComponents, setAllRegisteredComponents] = useState(() => [
|
|
65
67
|
...getDefaultRegisteredComponents(),
|
|
@@ -70,9 +72,12 @@ function RenderContent(props) {
|
|
|
70
72
|
// which is the new standard way of providing custom components, and must therefore take precedence.
|
|
71
73
|
...components,
|
|
72
74
|
...(props.customComponents || []),
|
|
73
|
-
].reduce((acc, curr) => ({
|
|
75
|
+
].reduce((acc, { component, ...curr }) => ({
|
|
74
76
|
...acc,
|
|
75
|
-
[curr.name]:
|
|
77
|
+
[curr.name]: {
|
|
78
|
+
component: TARGET === "vue3" ? wrapComponentRef(component) : component,
|
|
79
|
+
...curr,
|
|
80
|
+
},
|
|
76
81
|
}), {}));
|
|
77
82
|
function processMessage(event) {
|
|
78
83
|
const { data } = event;
|
|
@@ -117,7 +122,9 @@ function RenderContent(props) {
|
|
|
117
122
|
evaluate({
|
|
118
123
|
code: jsCode,
|
|
119
124
|
context: props.context || {},
|
|
120
|
-
|
|
125
|
+
localState: undefined,
|
|
126
|
+
rootState: contentState,
|
|
127
|
+
rootSetState: contentSetState,
|
|
121
128
|
});
|
|
122
129
|
}
|
|
123
130
|
}
|
|
@@ -145,7 +152,9 @@ function RenderContent(props) {
|
|
|
145
152
|
return expression.replace(/{{([^}]+)}}/g, (_match, group) => evaluate({
|
|
146
153
|
code: group,
|
|
147
154
|
context: props.context || {},
|
|
148
|
-
|
|
155
|
+
localState: undefined,
|
|
156
|
+
rootState: contentState,
|
|
157
|
+
rootSetState: contentSetState,
|
|
149
158
|
}));
|
|
150
159
|
}
|
|
151
160
|
function handleRequest({ url, key }) {
|
|
@@ -156,7 +165,7 @@ function RenderContent(props) {
|
|
|
156
165
|
...contentState,
|
|
157
166
|
[key]: json,
|
|
158
167
|
};
|
|
159
|
-
|
|
168
|
+
contentSetState(newState);
|
|
160
169
|
})
|
|
161
170
|
.catch((err) => {
|
|
162
171
|
console.error("error fetching dynamic data", url, err);
|
|
@@ -186,6 +195,11 @@ function RenderContent(props) {
|
|
|
186
195
|
}));
|
|
187
196
|
}
|
|
188
197
|
}
|
|
198
|
+
const [scriptStr, setScriptStr] = useState(() => getRenderContentScriptString({
|
|
199
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
|
|
200
|
+
contentId: props.content?.id,
|
|
201
|
+
parentContentId: props.parentContentId,
|
|
202
|
+
}));
|
|
189
203
|
useEffect(() => {
|
|
190
204
|
if (!props.apiKey) {
|
|
191
205
|
logger.error("No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop.");
|
|
@@ -205,6 +219,11 @@ function RenderContent(props) {
|
|
|
205
219
|
includeRefs: props.includeRefs,
|
|
206
220
|
}
|
|
207
221
|
: {}),
|
|
222
|
+
...(props.enrich
|
|
223
|
+
? {
|
|
224
|
+
enrich: props.enrich,
|
|
225
|
+
}
|
|
226
|
+
: {}),
|
|
208
227
|
});
|
|
209
228
|
Object.values(allRegisteredComponents).forEach((registeredComponent) => {
|
|
210
229
|
const message = createRegisterComponentMessage(registeredComponent);
|
|
@@ -280,15 +299,30 @@ function RenderContent(props) {
|
|
|
280
299
|
}, []);
|
|
281
300
|
return (React.createElement(builderContext.Provider, { value: {
|
|
282
301
|
content: useContent,
|
|
283
|
-
|
|
284
|
-
|
|
302
|
+
localState: undefined,
|
|
303
|
+
rootState: contentState,
|
|
304
|
+
rootSetState: TARGET === "qwik" ? undefined : contentSetState,
|
|
285
305
|
context: props.context || {},
|
|
286
306
|
apiKey: props.apiKey,
|
|
287
307
|
apiVersion: props.apiVersion,
|
|
288
308
|
registeredComponents: allRegisteredComponents,
|
|
289
309
|
inheritedStyles: {},
|
|
290
310
|
} }, useContent ? (React.createElement(React.Fragment, null,
|
|
291
|
-
React.createElement("div", { ref: elementRef, onClick: (event) => onClick(event), "builder-content-id": useContent?.id, "builder-model": props.model
|
|
311
|
+
React.createElement("div", { ref: elementRef, onClick: (event) => onClick(event), "builder-content-id": useContent?.id, "builder-model": props.model, ...(TARGET === "reactNative"
|
|
312
|
+
? {
|
|
313
|
+
dataSet: {
|
|
314
|
+
// currently, we can't set the actual ID here. // we don't need it right now, we just need to identify content divs for testing.
|
|
315
|
+
"builder-content-id": "",
|
|
316
|
+
},
|
|
317
|
+
}
|
|
318
|
+
: {}), ...(props.hideContent
|
|
319
|
+
? {
|
|
320
|
+
hidden: true,
|
|
321
|
+
"aria-hidden": true,
|
|
322
|
+
}
|
|
323
|
+
: {}), className: props.classNameProp },
|
|
324
|
+
props.isSsrAbTest ? (React.createElement(React.Fragment, null,
|
|
325
|
+
React.createElement("script", { dangerouslySetInnerHTML: { __html: scriptStr } }))) : null,
|
|
292
326
|
TARGET !== "reactNative" ? (React.createElement(React.Fragment, null,
|
|
293
327
|
React.createElement(RenderContentStyles, { contentId: useContent?.id, cssCode: useContent?.data?.cssCode, customFonts: useContent?.data?.customFonts }))) : null,
|
|
294
328
|
React.createElement(RenderBlocks, { blocks: useContent?.data?.blocks, key: forceReRenderCount })))) : null));
|
|
@@ -2,7 +2,7 @@ import type { BuilderRenderContext, RegisteredComponent, BuilderRenderState } fr
|
|
|
2
2
|
import type { BuilderContent } from '../../types/builder-content';
|
|
3
3
|
import type { Nullable } from '../../types/typescript';
|
|
4
4
|
import type { ApiVersion } from '../../types/api-version';
|
|
5
|
-
export
|
|
5
|
+
export interface RenderContentProps {
|
|
6
6
|
content?: Nullable<BuilderContent>;
|
|
7
7
|
model?: string;
|
|
8
8
|
data?: {
|
|
@@ -14,8 +14,17 @@ export type RenderContentProps = {
|
|
|
14
14
|
customComponents?: RegisteredComponent[];
|
|
15
15
|
canTrack?: boolean;
|
|
16
16
|
locale?: string;
|
|
17
|
+
/** @deprecated use `enrich` instead **/
|
|
17
18
|
includeRefs?: boolean;
|
|
18
|
-
|
|
19
|
+
enrich?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* TO-DO: improve qwik generator to not remap this name for non-HTML tags, then name it `className`
|
|
22
|
+
*/
|
|
23
|
+
classNameProp?: string;
|
|
24
|
+
hideContent?: boolean;
|
|
25
|
+
parentContentId?: string;
|
|
26
|
+
isSsrAbTest?: boolean;
|
|
27
|
+
}
|
|
19
28
|
export interface BuilderComponentStateChange {
|
|
20
29
|
state: BuilderRenderState;
|
|
21
30
|
ref: {
|