@builder.io/sdk-react 0.2.3-4 → 0.3.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/README.md +72 -3
- package/dist/sdk/blocks/columns/columns.js +5 -5
- package/dist/sdk/blocks/image/image.js +8 -7
- package/dist/sdk/blocks/symbol/symbol.js +3 -2
- package/dist/sdk/blocks/video/video.js +4 -1
- package/dist/sdk/components/render-block/block-styles.js +3 -1
- 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 +24 -15
- package/dist/sdk/components/render-block/render-repeated-block.js +3 -2
- package/dist/sdk/components/render-content/render-content.js +31 -12
- package/dist/sdk/components/render-content-variants/helpers.d.ts +12 -0
- package/dist/sdk/components/render-content-variants/helpers.js +154 -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 +29 -0
- package/dist/sdk/components/render-inlined-styles.js +2 -2
- 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-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/canTrack.d.ts +1 -0
- package/dist/sdk/helpers/canTrack.js +2 -0
- package/dist/sdk/index.d.ts +1 -0
- package/dist/sdk/scripts/init-editing.js +2 -0
- package/package.json +5 -5
- package/CHANGELOG.md +0 -25
- package/packages/react/src/blocks/BaseText.tsx +0 -19
- package/packages/react/src/blocks/button/button.tsx +0 -45
- package/packages/react/src/blocks/button/component-info.ts +0 -42
- package/packages/react/src/blocks/columns/columns.tsx +0 -211
- package/packages/react/src/blocks/columns/component-info.ts +0 -254
- package/packages/react/src/blocks/custom-code/component-info.ts +0 -31
- package/packages/react/src/blocks/custom-code/custom-code.tsx +0 -76
- package/packages/react/src/blocks/embed/component-info.ts +0 -55
- package/packages/react/src/blocks/embed/embed.tsx +0 -59
- package/packages/react/src/blocks/embed/helpers.ts +0 -8
- package/packages/react/src/blocks/form/component-info.ts +0 -282
- package/packages/react/src/blocks/form/form.tsx +0 -320
- package/packages/react/src/blocks/fragment/component-info.ts +0 -10
- package/packages/react/src/blocks/fragment/fragment.tsx +0 -14
- package/packages/react/src/blocks/image/component-info.ts +0 -172
- package/packages/react/src/blocks/image/image.helpers.ts +0 -75
- package/packages/react/src/blocks/image/image.tsx +0 -144
- package/packages/react/src/blocks/img/component-info.ts +0 -21
- package/packages/react/src/blocks/img/img.tsx +0 -40
- package/packages/react/src/blocks/input/component-info.ts +0 -78
- package/packages/react/src/blocks/input/input.tsx +0 -33
- package/packages/react/src/blocks/raw-text/component-info.ts +0 -15
- package/packages/react/src/blocks/raw-text/raw-text.tsx +0 -18
- package/packages/react/src/blocks/section/component-info.ts +0 -50
- package/packages/react/src/blocks/section/section.tsx +0 -33
- package/packages/react/src/blocks/select/component-info.ts +0 -61
- package/packages/react/src/blocks/select/select.tsx +0 -35
- package/packages/react/src/blocks/submit-button/component-info.ts +0 -32
- package/packages/react/src/blocks/submit-button/submit-button.tsx +0 -17
- package/packages/react/src/blocks/symbol/component-info.ts +0 -43
- package/packages/react/src/blocks/symbol/symbol.tsx +0 -111
- package/packages/react/src/blocks/text/component-info.ts +0 -24
- package/packages/react/src/blocks/text/text.tsx +0 -20
- package/packages/react/src/blocks/textarea/component-info.ts +0 -48
- package/packages/react/src/blocks/textarea/textarea.tsx +0 -24
- package/packages/react/src/blocks/util.ts +0 -18
- package/packages/react/src/blocks/video/component-info.ts +0 -109
- package/packages/react/src/blocks/video/video.tsx +0 -84
- package/packages/react/src/components/render-block/block-styles.tsx +0 -98
- package/packages/react/src/components/render-block/render-block.helpers.ts +0 -138
- package/packages/react/src/components/render-block/render-block.tsx +0 -216
- package/packages/react/src/components/render-block/render-component.tsx +0 -52
- package/packages/react/src/components/render-block/render-repeated-block.tsx +0 -43
- package/packages/react/src/components/render-block/types.ts +0 -7
- package/packages/react/src/components/render-blocks.tsx +0 -97
- package/packages/react/src/components/render-content/builder-editing.tsx +0 -8
- package/packages/react/src/components/render-content/components/render-styles.helpers.ts +0 -79
- package/packages/react/src/components/render-content/components/render-styles.tsx +0 -45
- package/packages/react/src/components/render-content/index.ts +0 -1
- package/packages/react/src/components/render-content/render-content.helpers.ts +0 -48
- package/packages/react/src/components/render-content/render-content.tsx +0 -410
- package/packages/react/src/components/render-content/render-content.types.ts +0 -33
- package/packages/react/src/components/render-inlined-styles.tsx +0 -36
- package/packages/react/src/constants/builder-registered-components.ts +0 -42
- package/packages/react/src/constants/device-sizes.ts +0 -65
- package/packages/react/src/constants/target.ts +0 -2
- package/packages/react/src/context/builder.context.ts +0 -12
- package/packages/react/src/context/types.ts +0 -26
- package/packages/react/src/functions/camel-to-kebab-case.ts +0 -2
- package/packages/react/src/functions/evaluate.ts +0 -57
- package/packages/react/src/functions/event-handler-name.ts +0 -6
- package/packages/react/src/functions/extract-text-styles.ts +0 -39
- package/packages/react/src/functions/fast-clone.ts +0 -5
- package/packages/react/src/functions/get-block-actions-handler.ts +0 -20
- package/packages/react/src/functions/get-block-actions.ts +0 -25
- package/packages/react/src/functions/get-block-component-options.ts +0 -12
- package/packages/react/src/functions/get-block-properties.ts +0 -75
- package/packages/react/src/functions/get-builder-search-params/fn.test.ts +0 -19
- package/packages/react/src/functions/get-builder-search-params/index.ts +0 -50
- package/packages/react/src/functions/get-content/ab-testing.ts +0 -132
- package/packages/react/src/functions/get-content/generate-content-url.test.ts +0 -95
- package/packages/react/src/functions/get-content/generate-content-url.ts +0 -59
- package/packages/react/src/functions/get-content/index.ts +0 -62
- package/packages/react/src/functions/get-content/types.ts +0 -53
- package/packages/react/src/functions/get-fetch.ts +0 -18
- package/packages/react/src/functions/get-global-this.ts +0 -17
- package/packages/react/src/functions/get-processed-block.test.ts +0 -33
- package/packages/react/src/functions/get-processed-block.ts +0 -54
- package/packages/react/src/functions/get-react-native-block-styles.ts +0 -33
- package/packages/react/src/functions/if-target.ts +0 -20
- package/packages/react/src/functions/is-browser.ts +0 -3
- package/packages/react/src/functions/is-editing.ts +0 -10
- package/packages/react/src/functions/is-iframe.ts +0 -5
- package/packages/react/src/functions/is-previewing.ts +0 -14
- package/packages/react/src/functions/on-change.test.ts +0 -23
- package/packages/react/src/functions/on-change.ts +0 -29
- package/packages/react/src/functions/register-component.ts +0 -50
- package/packages/react/src/functions/register.ts +0 -46
- package/packages/react/src/functions/sanitize-react-native-block-styles.ts +0 -65
- package/packages/react/src/functions/set-editor-settings.ts +0 -16
- package/packages/react/src/functions/set.test.ts +0 -19
- package/packages/react/src/functions/set.ts +0 -26
- package/packages/react/src/functions/track/helpers.ts +0 -67
- package/packages/react/src/functions/track/index.ts +0 -136
- package/packages/react/src/functions/track/interaction.ts +0 -80
- package/packages/react/src/functions/transform-block-properties.ts +0 -3
- package/packages/react/src/functions/transform-block.ts +0 -6
- package/packages/react/src/helpers/ab-tests.ts +0 -22
- package/packages/react/src/helpers/cookie.ts +0 -107
- package/packages/react/src/helpers/css.ts +0 -42
- package/packages/react/src/helpers/flatten.ts +0 -24
- package/packages/react/src/helpers/localStorage.ts +0 -40
- package/packages/react/src/helpers/logger.ts +0 -6
- package/packages/react/src/helpers/nullable.ts +0 -4
- package/packages/react/src/helpers/sessionId.ts +0 -38
- package/packages/react/src/helpers/time.ts +0 -4
- package/packages/react/src/helpers/url.test.ts +0 -23
- package/packages/react/src/helpers/url.ts +0 -16
- package/packages/react/src/helpers/uuid.ts +0 -17
- package/packages/react/src/helpers/visitorId.ts +0 -40
- package/packages/react/src/index-helpers/blocks-exports.ts +0 -10
- package/packages/react/src/index-helpers/top-of-file.ts +0 -4
- package/packages/react/src/index.ts +0 -14
- package/packages/react/src/scripts/init-editing.ts +0 -123
- package/packages/react/src/types/api-version.ts +0 -2
- package/packages/react/src/types/builder-block.ts +0 -69
- package/packages/react/src/types/builder-content.ts +0 -46
- package/packages/react/src/types/can-track.ts +0 -3
- package/packages/react/src/types/components.ts +0 -117
- package/packages/react/src/types/deep-partial.ts +0 -7
- package/packages/react/src/types/element.ts +0 -60
- package/packages/react/src/types/input.ts +0 -125
- package/packages/react/src/types/targets.ts +0 -6
- package/packages/react/src/types/typescript.ts +0 -7
- package/packages/rsc/src/blocks/BaseText.jsx +0 -12
- package/packages/rsc/src/blocks/button/button.jsx +0 -37
- package/packages/rsc/src/blocks/button/component-info.js +0 -40
- package/packages/rsc/src/blocks/columns/columns.jsx +0 -172
- package/packages/rsc/src/blocks/columns/component-info.js +0 -241
- package/packages/rsc/src/blocks/custom-code/component-info.js +0 -30
- package/packages/rsc/src/blocks/custom-code/custom-code.jsx +0 -57
- package/packages/rsc/src/blocks/embed/component-info.js +0 -43
- package/packages/rsc/src/blocks/embed/embed.jsx +0 -45
- package/packages/rsc/src/blocks/embed/helpers.js +0 -9
- package/packages/rsc/src/blocks/form/component-info.js +0 -261
- package/packages/rsc/src/blocks/form/form.jsx +0 -260
- package/packages/rsc/src/blocks/fragment/component-info.js +0 -10
- package/packages/rsc/src/blocks/fragment/fragment.jsx +0 -9
- package/packages/rsc/src/blocks/image/component-info.js +0 -150
- package/packages/rsc/src/blocks/image/image.helpers.js +0 -48
- package/packages/rsc/src/blocks/image/image.jsx +0 -122
- package/packages/rsc/src/blocks/img/component-info.js +0 -19
- package/packages/rsc/src/blocks/img/img.jsx +0 -21
- package/packages/rsc/src/blocks/input/component-info.js +0 -73
- package/packages/rsc/src/blocks/input/input.jsx +0 -23
- package/packages/rsc/src/blocks/raw-text/component-info.js +0 -15
- package/packages/rsc/src/blocks/raw-text/raw-text.jsx +0 -14
- package/packages/rsc/src/blocks/section/component-info.js +0 -48
- package/packages/rsc/src/blocks/section/section.jsx +0 -27
- package/packages/rsc/src/blocks/select/component-info.js +0 -58
- package/packages/rsc/src/blocks/select/select.jsx +0 -24
- package/packages/rsc/src/blocks/submit-button/component-info.js +0 -27
- package/packages/rsc/src/blocks/submit-button/submit-button.jsx +0 -13
- package/packages/rsc/src/blocks/symbol/component-info.js +0 -42
- package/packages/rsc/src/blocks/symbol/symbol.jsx +0 -89
- package/packages/rsc/src/blocks/text/component-info.js +0 -23
- package/packages/rsc/src/blocks/text/text.jsx +0 -17
- package/packages/rsc/src/blocks/textarea/component-info.js +0 -46
- package/packages/rsc/src/blocks/textarea/textarea.jsx +0 -17
- package/packages/rsc/src/blocks/util.js +0 -8
- package/packages/rsc/src/blocks/video/component-info.js +0 -105
- package/packages/rsc/src/blocks/video/video.jsx +0 -63
- package/packages/rsc/src/components/render-block/block-styles.jsx +0 -88
- package/packages/rsc/src/components/render-block/render-block.helpers.js +0 -129
- package/packages/rsc/src/components/render-block/render-block.jsx +0 -201
- package/packages/rsc/src/components/render-block/render-component.jsx +0 -39
- package/packages/rsc/src/components/render-block/render-repeated-block.jsx +0 -27
- package/packages/rsc/src/components/render-block/types.js +0 -0
- package/packages/rsc/src/components/render-blocks.jsx +0 -92
- package/packages/rsc/src/components/render-content/builder-editing.jsx +0 -64
- package/packages/rsc/src/components/render-content/components/render-styles.helpers.js +0 -57
- package/packages/rsc/src/components/render-content/components/render-styles.jsx +0 -39
- package/packages/rsc/src/components/render-content/index.js +0 -4
- package/packages/rsc/src/components/render-content/render-content.helpers.js +0 -48
- package/packages/rsc/src/components/render-content/render-content.jsx +0 -253
- package/packages/rsc/src/components/render-content/render-content.types.js +0 -0
- package/packages/rsc/src/components/render-inlined-styles.jsx +0 -33
- package/packages/rsc/src/constants/builder-registered-components.js +0 -54
- package/packages/rsc/src/constants/device-sizes.js +0 -48
- package/packages/rsc/src/constants/target.js +0 -4
- package/packages/rsc/src/context/builder.context.js +0 -14
- package/packages/rsc/src/context/types.js +0 -0
- package/packages/rsc/src/functions/camel-to-kebab-case.js +0 -4
- package/packages/rsc/src/functions/evaluate.js +0 -6
- package/packages/rsc/src/functions/event-handler-name.js +0 -7
- package/packages/rsc/src/functions/extract-text-styles.js +0 -22
- package/packages/rsc/src/functions/fast-clone.js +0 -4
- package/packages/rsc/src/functions/get-block-actions-handler.js +0 -11
- package/packages/rsc/src/functions/get-block-actions.js +0 -18
- package/packages/rsc/src/functions/get-block-component-options.js +0 -28
- package/packages/rsc/src/functions/get-block-properties.js +0 -53
- package/packages/rsc/src/functions/get-builder-search-params/fn.test.js +0 -13
- package/packages/rsc/src/functions/get-builder-search-params/index.js +0 -38
- package/packages/rsc/src/functions/get-content/ab-testing.js +0 -99
- package/packages/rsc/src/functions/get-content/generate-content-url.js +0 -60
- package/packages/rsc/src/functions/get-content/generate-content-url.test.js +0 -82
- package/packages/rsc/src/functions/get-content/index.js +0 -83
- package/packages/rsc/src/functions/get-content/types.js +0 -0
- package/packages/rsc/src/functions/get-fetch.js +0 -14
- package/packages/rsc/src/functions/get-global-this.js +0 -18
- package/packages/rsc/src/functions/get-processed-block.js +0 -59
- package/packages/rsc/src/functions/get-processed-block.test.js +0 -32
- package/packages/rsc/src/functions/get-react-native-block-styles.js +0 -33
- package/packages/rsc/src/functions/if-target.js +0 -15
- package/packages/rsc/src/functions/is-browser.js +0 -6
- package/packages/rsc/src/functions/is-editing.js +0 -8
- package/packages/rsc/src/functions/is-iframe.js +0 -7
- package/packages/rsc/src/functions/is-previewing.js +0 -14
- package/packages/rsc/src/functions/on-change.js +0 -27
- package/packages/rsc/src/functions/on-change.test.js +0 -19
- package/packages/rsc/src/functions/register-component.js +0 -68
- package/packages/rsc/src/functions/register.js +0 -29
- package/packages/rsc/src/functions/sanitize-react-native-block-styles.js +0 -66
- package/packages/rsc/src/functions/set-editor-settings.js +0 -15
- package/packages/rsc/src/functions/set.js +0 -11
- package/packages/rsc/src/functions/set.test.js +0 -16
- package/packages/rsc/src/functions/track/helpers.js +0 -50
- package/packages/rsc/src/functions/track/index.js +0 -129
- package/packages/rsc/src/functions/track/interaction.js +0 -53
- package/packages/rsc/src/functions/transform-block-properties.js +0 -6
- package/packages/rsc/src/functions/transform-block.js +0 -6
- package/packages/rsc/src/helpers/ab-tests.js +0 -16
- package/packages/rsc/src/helpers/cookie.js +0 -81
- package/packages/rsc/src/helpers/css.js +0 -34
- package/packages/rsc/src/helpers/flatten.js +0 -34
- package/packages/rsc/src/helpers/localStorage.js +0 -35
- package/packages/rsc/src/helpers/logger.js +0 -9
- package/packages/rsc/src/helpers/nullable.js +0 -4
- package/packages/rsc/src/helpers/sessionId.js +0 -52
- package/packages/rsc/src/helpers/time.js +0 -5
- package/packages/rsc/src/helpers/url.js +0 -13
- package/packages/rsc/src/helpers/url.test.js +0 -21
- package/packages/rsc/src/helpers/uuid.js +0 -13
- package/packages/rsc/src/helpers/visitorId.js +0 -34
- package/packages/rsc/src/index-helpers/blocks-exports.js +0 -22
- package/packages/rsc/src/index-helpers/top-of-file.js +0 -2
- package/packages/rsc/src/index.js +0 -13
- package/packages/rsc/src/scripts/init-editing.js +0 -93
- package/packages/rsc/src/types/api-version.js +0 -4
- package/packages/rsc/src/types/builder-block.js +0 -0
- package/packages/rsc/src/types/builder-content.js +0 -0
- package/packages/rsc/src/types/can-track.js +0 -0
- package/packages/rsc/src/types/components.js +0 -0
- package/packages/rsc/src/types/deep-partial.js +0 -0
- package/packages/rsc/src/types/element.js +0 -0
- package/packages/rsc/src/types/input.js +0 -0
- package/packages/rsc/src/types/targets.js +0 -0
- package/packages/rsc/src/types/typescript.js +0 -0
- package/tsconfig.json +0 -28
- package/tsconfig.sdk.json +0 -10
- package/tsconfig.server.json +0 -10
- package/vite.config.ts +0 -91
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
|
|
|
@@ -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;
|
|
@@ -5,7 +5,8 @@ function Image(props) {
|
|
|
5
5
|
function srcSetToUse() {
|
|
6
6
|
const imageToUse = props.image || props.src;
|
|
7
7
|
const url = imageToUse;
|
|
8
|
-
if (!url ||
|
|
8
|
+
if (!url ||
|
|
9
|
+
// We can auto add srcset for cdn.builder.io and shopify
|
|
9
10
|
// images, otherwise you can supply this prop manually
|
|
10
11
|
!(url.match(/builder\.io/) || url.match(/cdn\.shopify\.com/))) {
|
|
11
12
|
return props.srcset;
|
|
@@ -51,23 +52,23 @@ function Image(props) {
|
|
|
51
52
|
...aspectRatioCss(),
|
|
52
53
|
}, className: "builder-image" +
|
|
53
54
|
(props.className ? " " + props.className : "") +
|
|
54
|
-
" img-
|
|
55
|
+
" img-3c135cd4", src: props.image, srcSet: srcSetToUse(), sizes: props.sizes })),
|
|
55
56
|
props.aspectRatio &&
|
|
56
57
|
!(props.builderBlock?.children?.length && props.fitContent) ? (React.createElement(React.Fragment, null,
|
|
57
|
-
React.createElement("div", { className: "builder-image-sizer div-
|
|
58
|
+
React.createElement("div", { className: "builder-image-sizer div-3c135cd4", style: {
|
|
58
59
|
paddingTop: props.aspectRatio * 100 + "%",
|
|
59
60
|
} }))) : null,
|
|
60
61
|
props.builderBlock?.children?.length && props.fitContent ? (React.createElement(React.Fragment, null, props.children)) : null,
|
|
61
62
|
!props.fitContent && props.children ? (React.createElement(React.Fragment, null,
|
|
62
|
-
React.createElement("div", { className: "div-
|
|
63
|
-
React.createElement("style", null, `.img-
|
|
63
|
+
React.createElement("div", { className: "div-3c135cd4-2" }, props.children))) : null),
|
|
64
|
+
React.createElement("style", null, `.img-3c135cd4 {
|
|
64
65
|
opacity: 1;
|
|
65
66
|
transition: opacity 0.2s ease-in-out;
|
|
66
|
-
}.div-
|
|
67
|
+
}.div-3c135cd4 {
|
|
67
68
|
width: 100%;
|
|
68
69
|
pointer-events: none;
|
|
69
70
|
font-size: 0;
|
|
70
|
-
}.div-
|
|
71
|
+
}.div-3c135cd4-2 {
|
|
71
72
|
display: flex;
|
|
72
73
|
flex-direction: column;
|
|
73
74
|
align-items: stretch;
|
|
@@ -31,7 +31,8 @@ function Symbol(props) {
|
|
|
31
31
|
* then we want to re-fetch the symbol content.
|
|
32
32
|
*/
|
|
33
33
|
if (!contentToUse &&
|
|
34
|
-
props.symbol?.model &&
|
|
34
|
+
props.symbol?.model &&
|
|
35
|
+
// This is a hack, we should not need to check for this, but it is needed for Svelte.
|
|
35
36
|
builderContext?.apiKey) {
|
|
36
37
|
getContent({
|
|
37
38
|
model: props.symbol.model,
|
|
@@ -61,7 +62,7 @@ function Symbol(props) {
|
|
|
61
62
|
return (React.createElement("div", { ...props.attributes, className: className },
|
|
62
63
|
React.createElement(RenderContent, { apiVersion: builderContext.apiVersion, apiKey: builderContext.apiKey, context: builderContext.context, customComponents: Object.values(builderContext.registeredComponents), data: {
|
|
63
64
|
...props.symbol?.data,
|
|
64
|
-
...builderContext.
|
|
65
|
+
...builderContext.localState,
|
|
65
66
|
...contentToUse?.data?.state,
|
|
66
67
|
}, model: props.symbol?.model, content: contentToUse })));
|
|
67
68
|
}
|
|
@@ -31,7 +31,10 @@ function Video(props) {
|
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
function spreadProps() {
|
|
34
|
-
return {
|
|
34
|
+
return {
|
|
35
|
+
...props.attributes,
|
|
36
|
+
...videoProps(),
|
|
37
|
+
};
|
|
35
38
|
}
|
|
36
39
|
return (React.createElement("video", { ...spreadProps(), style: {
|
|
37
40
|
width: "100%",
|
|
@@ -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
|
-
};
|
|
@@ -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,16 +17,20 @@ 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
|
});
|
|
@@ -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
|
};
|
|
@@ -109,7 +115,10 @@ function RenderBlock(props) {
|
|
|
109
115
|
...(!component?.noWrap
|
|
110
116
|
? {}
|
|
111
117
|
: {
|
|
112
|
-
attributes: {
|
|
118
|
+
attributes: {
|
|
119
|
+
...attributes(),
|
|
120
|
+
...actions(),
|
|
121
|
+
},
|
|
113
122
|
}),
|
|
114
123
|
},
|
|
115
124
|
context: childrenContext(),
|
|
@@ -119,8 +128,8 @@ function RenderBlock(props) {
|
|
|
119
128
|
return (React.createElement(React.Fragment, null, canShowBlock() ? (React.createElement(React.Fragment, null, !component?.noWrap ? (React.createElement(React.Fragment, null,
|
|
120
129
|
isEmptyHtmlElement(tag) ? (React.createElement(React.Fragment, null,
|
|
121
130
|
React.createElement(TagRef, { ...attributes(), ...actions() }))) : null,
|
|
122
|
-
!isEmptyHtmlElement(tag) &&
|
|
123
|
-
!isEmptyHtmlElement(tag) && !
|
|
131
|
+
!isEmptyHtmlElement(tag) && repeatItem() ? (React.createElement(React.Fragment, null, repeatItem()?.map((data, index) => (React.createElement(RenderRepeatedBlock, { key: index, repeatContext: data.context, block: data.block }))))) : null,
|
|
132
|
+
!isEmptyHtmlElement(tag) && !repeatItem() ? (React.createElement(React.Fragment, null,
|
|
124
133
|
React.createElement(TagRef, { ...attributes(), ...actions() },
|
|
125
134
|
React.createElement(RenderComponent, { ...renderComponentProps() }),
|
|
126
135
|
childrenWithoutParentComponent()?.map((child) => (React.createElement(RenderBlock, { key: "render-block-" + child.id, block: child, context: childrenContext() }))),
|
|
@@ -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,
|
|
@@ -31,7 +31,10 @@ function RenderContent(props) {
|
|
|
31
31
|
setUseContent({
|
|
32
32
|
...useContent,
|
|
33
33
|
...newContent,
|
|
34
|
-
data: {
|
|
34
|
+
data: {
|
|
35
|
+
...useContent?.data,
|
|
36
|
+
...newContent?.data,
|
|
37
|
+
},
|
|
35
38
|
meta: {
|
|
36
39
|
...useContent?.meta,
|
|
37
40
|
...newContent?.meta,
|
|
@@ -42,7 +45,10 @@ function RenderContent(props) {
|
|
|
42
45
|
function setBreakpoints(breakpoints) {
|
|
43
46
|
setUseContent({
|
|
44
47
|
...useContent,
|
|
45
|
-
meta: {
|
|
48
|
+
meta: {
|
|
49
|
+
...useContent?.meta,
|
|
50
|
+
breakpoints,
|
|
51
|
+
},
|
|
46
52
|
});
|
|
47
53
|
}
|
|
48
54
|
const [update, setUpdate] = useState(() => 0);
|
|
@@ -52,18 +58,22 @@ function RenderContent(props) {
|
|
|
52
58
|
data: props.data,
|
|
53
59
|
locale: props.locale,
|
|
54
60
|
}));
|
|
55
|
-
function
|
|
56
|
-
setContentState(
|
|
61
|
+
function contentSetState(newRootState) {
|
|
62
|
+
setContentState(newRootState);
|
|
57
63
|
}
|
|
58
64
|
const [allRegisteredComponents, setAllRegisteredComponents] = useState(() => [
|
|
59
65
|
...getDefaultRegisteredComponents(),
|
|
66
|
+
// While this `components` object is deprecated, we must maintain support for it.
|
|
60
67
|
// Since users are able to override our default components, we need to make sure that we do not break such
|
|
61
68
|
// existing usage.
|
|
62
69
|
// This is why we spread `components` after the default Builder.io components, but before the `props.customComponents`,
|
|
63
70
|
// which is the new standard way of providing custom components, and must therefore take precedence.
|
|
64
71
|
...components,
|
|
65
72
|
...(props.customComponents || []),
|
|
66
|
-
].reduce((acc, curr) => ({
|
|
73
|
+
].reduce((acc, curr) => ({
|
|
74
|
+
...acc,
|
|
75
|
+
[curr.name]: curr,
|
|
76
|
+
}), {}));
|
|
67
77
|
function processMessage(event) {
|
|
68
78
|
const { data } = event;
|
|
69
79
|
if (data) {
|
|
@@ -107,7 +117,9 @@ function RenderContent(props) {
|
|
|
107
117
|
evaluate({
|
|
108
118
|
code: jsCode,
|
|
109
119
|
context: props.context || {},
|
|
110
|
-
|
|
120
|
+
localState: undefined,
|
|
121
|
+
rootState: contentState,
|
|
122
|
+
rootSetState: contentSetState,
|
|
111
123
|
});
|
|
112
124
|
}
|
|
113
125
|
}
|
|
@@ -135,15 +147,20 @@ function RenderContent(props) {
|
|
|
135
147
|
return expression.replace(/{{([^}]+)}}/g, (_match, group) => evaluate({
|
|
136
148
|
code: group,
|
|
137
149
|
context: props.context || {},
|
|
138
|
-
|
|
150
|
+
localState: undefined,
|
|
151
|
+
rootState: contentState,
|
|
152
|
+
rootSetState: contentSetState,
|
|
139
153
|
}));
|
|
140
154
|
}
|
|
141
155
|
function handleRequest({ url, key }) {
|
|
142
156
|
fetch(url)
|
|
143
157
|
.then((response) => response.json())
|
|
144
158
|
.then((json) => {
|
|
145
|
-
const newState = {
|
|
146
|
-
|
|
159
|
+
const newState = {
|
|
160
|
+
...contentState,
|
|
161
|
+
[key]: json,
|
|
162
|
+
};
|
|
163
|
+
contentSetState(newState);
|
|
147
164
|
})
|
|
148
165
|
.catch((err) => {
|
|
149
166
|
console.error("error fetching dynamic data", url, err);
|
|
@@ -210,7 +227,8 @@ function RenderContent(props) {
|
|
|
210
227
|
apiKey: props.apiKey,
|
|
211
228
|
variationId: variationId !== contentId ? variationId : undefined,
|
|
212
229
|
});
|
|
213
|
-
}
|
|
230
|
+
}
|
|
231
|
+
// override normal content in preview mode
|
|
214
232
|
if (isPreviewing()) {
|
|
215
233
|
const searchParams = new URL(location.href).searchParams;
|
|
216
234
|
const searchParamPreviewModel = searchParams.get("builder.preview");
|
|
@@ -266,8 +284,9 @@ function RenderContent(props) {
|
|
|
266
284
|
}, []);
|
|
267
285
|
return (React.createElement(builderContext.Provider, { value: {
|
|
268
286
|
content: useContent,
|
|
269
|
-
|
|
270
|
-
|
|
287
|
+
localState: undefined,
|
|
288
|
+
rootState: contentState,
|
|
289
|
+
rootSetState: TARGET === "qwik" ? undefined : contentSetState,
|
|
271
290
|
context: props.context || {},
|
|
272
291
|
apiKey: props.apiKey,
|
|
273
292
|
apiVersion: props.apiVersion,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Nullable } from '../../helpers/nullable';
|
|
2
|
+
import type { BuilderContent } from '../../types/builder-content';
|
|
3
|
+
export declare const checkShouldRunVariants: ({ canTrack, content, }: {
|
|
4
|
+
canTrack: Nullable<boolean>;
|
|
5
|
+
content: Nullable<BuilderContent>;
|
|
6
|
+
}) => boolean;
|
|
7
|
+
type VariantData = {
|
|
8
|
+
id: string;
|
|
9
|
+
testRatio?: number;
|
|
10
|
+
};
|
|
11
|
+
export declare const getVariantsScriptString: (variants: VariantData[], contentId: string) => string;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { isBrowser } from '../../functions/is-browser';
|
|
2
|
+
export const checkShouldRunVariants = ({ canTrack, content, }) => {
|
|
3
|
+
const hasVariants = Object.keys(content?.variations || {}).length > 0;
|
|
4
|
+
if (!hasVariants) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
if (!canTrack) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
if (isBrowser()) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return true;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* NOTE: when this function is stringified, single-line comments can cause weird issues when compiled by Sveltekit.
|
|
17
|
+
* Make sure to write multi-line comments only.
|
|
18
|
+
*/
|
|
19
|
+
const variantScriptFn = function main(contentId, variants) {
|
|
20
|
+
function templateSelectorById(id) {
|
|
21
|
+
return `template[data-template-variant-id="${id}"]`;
|
|
22
|
+
}
|
|
23
|
+
function removeTemplatesAndScript() {
|
|
24
|
+
variants.forEach((template) => {
|
|
25
|
+
const el = document.querySelector(templateSelectorById(template.id));
|
|
26
|
+
if (el) {
|
|
27
|
+
el.remove();
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
const el = document.getElementById(`variants-script-${contentId}`);
|
|
31
|
+
if (el) {
|
|
32
|
+
el.remove();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Replace the old parent with the new one.
|
|
37
|
+
*
|
|
38
|
+
* NOTE: replacing the old parent with the new one means that any other children of that parent will be removed.
|
|
39
|
+
*
|
|
40
|
+
* ```jsx
|
|
41
|
+
* <div> <-- templatesParent.parentNode
|
|
42
|
+
* <div> <-- templatesParent
|
|
43
|
+
* <h1>Page Title</h1> <-- will disappear?
|
|
44
|
+
* <RenderContentVariants>
|
|
45
|
+
* <template>...</template>
|
|
46
|
+
* <template>...</template>
|
|
47
|
+
* <template>...</template>
|
|
48
|
+
* <script /> <-- this script
|
|
49
|
+
* </RenderContentVariants>
|
|
50
|
+
* <footer>Footer Content</foote> <-- will disappear?
|
|
51
|
+
* </div>
|
|
52
|
+
* </div>
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* Since `RenderContentVariants will replace its parent, the rest of the content will be removed.
|
|
56
|
+
*/
|
|
57
|
+
function injectVariant() {
|
|
58
|
+
if (!navigator.cookieEnabled) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* TO-DO: what is this check doing?
|
|
63
|
+
* seems like a template polyfill check
|
|
64
|
+
*/
|
|
65
|
+
if (typeof document.createElement('template').content === 'undefined') {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
function getAndSetVariantId() {
|
|
69
|
+
function setCookie(name, value, days) {
|
|
70
|
+
let expires = '';
|
|
71
|
+
if (days) {
|
|
72
|
+
const date = new Date();
|
|
73
|
+
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
74
|
+
expires = '; expires=' + date.toUTCString();
|
|
75
|
+
}
|
|
76
|
+
document.cookie =
|
|
77
|
+
name +
|
|
78
|
+
'=' +
|
|
79
|
+
(value || '') +
|
|
80
|
+
expires +
|
|
81
|
+
'; path=/' +
|
|
82
|
+
'; Secure; SameSite=None';
|
|
83
|
+
}
|
|
84
|
+
function getCookie(name) {
|
|
85
|
+
const nameEQ = name + '=';
|
|
86
|
+
const ca = document.cookie.split(';');
|
|
87
|
+
for (let i = 0; i < ca.length; i++) {
|
|
88
|
+
let c = ca[i];
|
|
89
|
+
while (c.charAt(0) === ' ')
|
|
90
|
+
c = c.substring(1, c.length);
|
|
91
|
+
if (c.indexOf(nameEQ) === 0)
|
|
92
|
+
return c.substring(nameEQ.length, c.length);
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const cookieName = `builder.tests.${contentId}`;
|
|
97
|
+
const variantInCookie = getCookie(cookieName);
|
|
98
|
+
const availableIDs = variants.map((vr) => vr.id).concat(contentId);
|
|
99
|
+
/**
|
|
100
|
+
* cookie already exists
|
|
101
|
+
*/
|
|
102
|
+
if (variantInCookie && availableIDs.includes(variantInCookie)) {
|
|
103
|
+
console.log('[DEBUG]: cookie exists: ', variantInCookie);
|
|
104
|
+
return variantInCookie;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* no cookie exists, find variant
|
|
108
|
+
*/
|
|
109
|
+
let n = 0;
|
|
110
|
+
const random = Math.random();
|
|
111
|
+
for (let i = 0; i < variants.length; i++) {
|
|
112
|
+
const variant = variants[i];
|
|
113
|
+
const testRatio = variant.testRatio;
|
|
114
|
+
n += testRatio;
|
|
115
|
+
if (random < n) {
|
|
116
|
+
setCookie(cookieName, variant.id);
|
|
117
|
+
return variant.id;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* no variant found, assign default content
|
|
122
|
+
*/
|
|
123
|
+
setCookie(cookieName, contentId);
|
|
124
|
+
return contentId;
|
|
125
|
+
}
|
|
126
|
+
const variantId = getAndSetVariantId();
|
|
127
|
+
if (variantId === contentId) {
|
|
128
|
+
console.log('[DEBUG]: variantId === contentId');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const winningTemplate = document.querySelector(templateSelectorById(variantId));
|
|
132
|
+
if (!winningTemplate) {
|
|
133
|
+
/**
|
|
134
|
+
* TO-DO: what do in this case? throw? warn?
|
|
135
|
+
*/
|
|
136
|
+
console.log('[DEBUG]: no winning template');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const templatesParent = winningTemplate.parentNode;
|
|
140
|
+
const newParent = templatesParent.cloneNode(false);
|
|
141
|
+
newParent.appendChild(winningTemplate.content.firstElementChild);
|
|
142
|
+
templatesParent.parentNode.replaceChild(newParent, templatesParent);
|
|
143
|
+
console.log('[DEBUG]: injected variant');
|
|
144
|
+
}
|
|
145
|
+
injectVariant();
|
|
146
|
+
removeTemplatesAndScript();
|
|
147
|
+
};
|
|
148
|
+
export const getVariantsScriptString = (variants, contentId) => {
|
|
149
|
+
const fnStr = variantScriptFn.toString().replace(/\s+/g, ' ');
|
|
150
|
+
return `
|
|
151
|
+
${fnStr}
|
|
152
|
+
main("${contentId}", ${JSON.stringify(variants)})
|
|
153
|
+
`;
|
|
154
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
type VariantsProviderProps = RenderContentProps;
|
|
3
|
+
import type { RenderContentProps } from "../render-content/render-content.types";
|
|
4
|
+
declare function RenderContentVariants(props: VariantsProviderProps): JSX.Element;
|
|
5
|
+
export default RenderContentVariants;
|