@builder.io/sdk-react 0.4.3 → 0.4.5

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.
Files changed (64) hide show
  1. package/dist/sdk/blocks/columns/columns.js +6 -6
  2. package/dist/sdk/blocks/symbol/symbol.js +7 -5
  3. package/dist/sdk/blocks/text/text.d.ts +1 -1
  4. package/dist/sdk/blocks/text/text.js +1 -1
  5. package/dist/sdk/components/block/block.d.ts +11 -0
  6. package/dist/sdk/components/block/block.helpers.d.ts +12 -0
  7. package/dist/sdk/components/block/block.helpers.js +86 -0
  8. package/dist/sdk/components/block/block.js +124 -0
  9. package/dist/sdk/components/block/components/block-styles.d.ts +9 -0
  10. package/dist/sdk/components/block/components/block-styles.js +65 -0
  11. package/dist/sdk/components/block/components/component.d.ts +20 -0
  12. package/dist/sdk/components/block/components/component.js +11 -0
  13. package/dist/sdk/components/block/components/repeated-block.d.ts +11 -0
  14. package/dist/sdk/components/block/components/repeated-block.js +11 -0
  15. package/dist/sdk/components/block/types.d.ts +6 -0
  16. package/dist/sdk/components/block/types.js +1 -0
  17. package/dist/sdk/components/blocks/blocks-wrapper.d.ts +13 -0
  18. package/dist/sdk/components/blocks/blocks-wrapper.js +38 -0
  19. package/dist/sdk/components/blocks/blocks.d.ts +10 -0
  20. package/dist/sdk/components/blocks/blocks.js +11 -0
  21. package/dist/sdk/components/content/components/content-styles.d.ts +9 -0
  22. package/dist/sdk/components/content/components/content-styles.helpers.d.ts +15 -0
  23. package/dist/sdk/components/content/components/content-styles.helpers.js +59 -0
  24. package/dist/sdk/components/content/components/content-styles.js +32 -0
  25. package/dist/sdk/components/content/components/enable-editor.d.ts +13 -0
  26. package/dist/sdk/components/content/components/enable-editor.js +278 -0
  27. package/dist/sdk/components/content/content.d.ts +4 -0
  28. package/dist/sdk/components/content/content.helpers.d.ts +7 -0
  29. package/dist/sdk/components/content/content.helpers.js +30 -0
  30. package/dist/sdk/components/content/content.js +97 -0
  31. package/dist/sdk/components/content/content.types.d.ts +38 -0
  32. package/dist/sdk/components/content/content.types.js +1 -0
  33. package/dist/sdk/components/content/index.d.ts +1 -0
  34. package/dist/sdk/components/content/index.js +1 -0
  35. package/dist/sdk/components/content/wrap-component-ref.d.ts +6 -0
  36. package/dist/sdk/components/content/wrap-component-ref.js +6 -0
  37. package/dist/sdk/components/content-variants/content-variants.d.ts +5 -0
  38. package/dist/sdk/components/content-variants/content-variants.js +37 -0
  39. package/dist/sdk/components/content-variants/helpers.d.ts +17 -0
  40. package/dist/sdk/components/content-variants/helpers.js +184 -0
  41. package/dist/sdk/components/inlined-script.d.ts +7 -0
  42. package/dist/sdk/components/inlined-script.js +6 -0
  43. package/dist/sdk/components/inlined-styles.d.ts +7 -0
  44. package/dist/sdk/components/inlined-styles.js +6 -0
  45. package/dist/sdk/components/render-block/block-styles.js +2 -2
  46. package/dist/sdk/components/render-content/components/render-styles.js +2 -2
  47. package/dist/sdk/components/render-content/render-content.js +8 -6
  48. package/dist/sdk/components/render-content/render-content.types.d.ts +9 -23
  49. package/dist/sdk/components/render-content-variants/helpers.d.ts +27 -3
  50. package/dist/sdk/components/render-content-variants/helpers.js +38 -24
  51. package/dist/sdk/components/render-content-variants/render-content-variants.d.ts +7 -2
  52. package/dist/sdk/components/render-content-variants/render-content-variants.js +29 -21
  53. package/dist/sdk/components/render-content-variants/render-content-variants.types.d.ts +20 -0
  54. package/dist/sdk/components/render-content-variants/render-content-variants.types.js +1 -0
  55. package/dist/sdk/constants/sdk-version.d.ts +1 -1
  56. package/dist/sdk/constants/sdk-version.js +1 -1
  57. package/dist/sdk/functions/track/index.js +1 -1
  58. package/dist/sdk/helpers/ab-tests.js +6 -0
  59. package/dist/sdk/types/builder-props.d.ts +10 -0
  60. package/dist/sdk/types/builder-props.js +1 -0
  61. package/dist/sdk/types/enforced-partials.d.ts +21 -0
  62. package/dist/sdk/types/enforced-partials.js +1 -0
  63. package/dist/sdk/types/typescript.d.ts +3 -0
  64. package/package.json +1 -1
@@ -0,0 +1,32 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { useState } from "react";
4
+ import InlinedStyles from "../../inlined-styles";
5
+ import { getCss } from "./content-styles.helpers";
6
+ import { getFontCss } from "./content-styles.helpers";
7
+ function ContentStyles(props) {
8
+ const [injectedStyles, setInjectedStyles] = useState(() => `
9
+ ${getCss({
10
+ cssCode: props.cssCode,
11
+ contentId: props.contentId,
12
+ })}
13
+ ${getFontCss({
14
+ customFonts: props.customFonts,
15
+ })}
16
+
17
+ .builder-text > p:first-of-type, .builder-text > .builder-paragraph:first-of-type {
18
+ margin: 0;
19
+ }
20
+ .builder-text > p, .builder-text > .builder-paragraph {
21
+ color: inherit;
22
+ line-height: inherit;
23
+ letter-spacing: inherit;
24
+ font-weight: inherit;
25
+ font-size: inherit;
26
+ text-align: inherit;
27
+ font-family: inherit;
28
+ }
29
+ `.trim());
30
+ return React.createElement(InlinedStyles, { styles: injectedStyles });
31
+ }
32
+ export default ContentStyles;
@@ -0,0 +1,13 @@
1
+ /// <reference types="react" />
2
+ type BuilderEditorProps = Omit<ContentProps, "customComponents"> & {
3
+ customComponents: Dictionary<ComponentInfo>;
4
+ builderContextSignal: BuilderContextInterface;
5
+ setBuilderContextSignal: any;
6
+ children?: any;
7
+ };
8
+ import type { BuilderContextInterface } from "../../../context/types.js";
9
+ import type { ContentProps } from "../content.types.js";
10
+ import type { Dictionary } from "../../../types/typescript.js";
11
+ import type { ComponentInfo } from "../../../types/components.js";
12
+ declare function EnableEditor(props: BuilderEditorProps): JSX.Element;
13
+ export default EnableEditor;
@@ -0,0 +1,278 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { useState, useRef, useEffect } from "react";
4
+ import { evaluate } from "../../../functions/evaluate.js";
5
+ import { getContent } from "../../../functions/get-content/index.js";
6
+ import { fetch } from "../../../functions/get-fetch.js";
7
+ import { isBrowser } from "../../../functions/is-browser.js";
8
+ import { isEditing } from "../../../functions/is-editing.js";
9
+ import { isPreviewing } from "../../../functions/is-previewing.js";
10
+ import { createRegisterComponentMessage } from "../../../functions/register-component.js";
11
+ import { _track } from "../../../functions/track/index.js";
12
+ import builderContext from "../../../context/builder.context.js";
13
+ import { registerInsertMenu, setupBrowserForEditing, } from "../../../scripts/init-editing.js";
14
+ import { checkIsDefined } from "../../../helpers/nullable.js";
15
+ import { getInteractionPropertiesForEvent } from "../../../functions/track/interaction.js";
16
+ import { TARGET } from "../../../constants/target.js";
17
+ import { logger } from "../../../helpers/logger.js";
18
+ function EnableEditor(props) {
19
+ const elementRef = useRef(null);
20
+ const [forceReRenderCount, setForceReRenderCount] = useState(() => 0);
21
+ function mergeNewContent(newContent) {
22
+ props.setBuilderContextSignal((PREVIOUS_VALUE) => ({
23
+ ...PREVIOUS_VALUE,
24
+ content: {
25
+ ...props.builderContextSignal.content,
26
+ ...newContent,
27
+ data: {
28
+ ...props.builderContextSignal.content?.data,
29
+ ...newContent?.data,
30
+ },
31
+ meta: {
32
+ ...props.builderContextSignal.content?.meta,
33
+ ...newContent?.meta,
34
+ breakpoints: newContent?.meta?.breakpoints ||
35
+ props.builderContextSignal.content?.meta?.breakpoints,
36
+ },
37
+ },
38
+ }));
39
+ }
40
+ const [canTrackToUse, setCanTrackToUse] = useState(() => checkIsDefined(props.canTrack) ? props.canTrack : true);
41
+ function processMessage(event) {
42
+ const { data } = event;
43
+ if (data) {
44
+ switch (data.type) {
45
+ case "builder.configureSdk": {
46
+ const messageContent = data.data;
47
+ const { breakpoints, contentId } = messageContent;
48
+ if (!contentId ||
49
+ contentId !== props.builderContextSignal.content?.id) {
50
+ return;
51
+ }
52
+ if (breakpoints) {
53
+ mergeNewContent({
54
+ meta: {
55
+ breakpoints,
56
+ },
57
+ });
58
+ }
59
+ setForceReRenderCount(forceReRenderCount + 1); // This is a hack to force Qwik to re-render.
60
+ break;
61
+ }
62
+ case "builder.contentUpdate": {
63
+ const messageContent = data.data;
64
+ const key = messageContent.key ||
65
+ messageContent.alias ||
66
+ messageContent.entry ||
67
+ messageContent.modelName;
68
+ const contentData = messageContent.data;
69
+ if (key === props.model) {
70
+ mergeNewContent(contentData);
71
+ setForceReRenderCount(forceReRenderCount + 1); // This is a hack to force Qwik to re-render.
72
+ }
73
+ break;
74
+ }
75
+ case "builder.patchUpdates": {
76
+ // TODO
77
+ break;
78
+ }
79
+ }
80
+ }
81
+ }
82
+ function evaluateJsCode() {
83
+ // run any dynamic JS code attached to content
84
+ const jsCode = props.builderContextSignal.content?.data?.jsCode;
85
+ if (jsCode) {
86
+ evaluate({
87
+ code: jsCode,
88
+ context: props.context || {},
89
+ localState: undefined,
90
+ rootState: props.builderContextSignal.rootState,
91
+ rootSetState: props.builderContextSignal.rootSetState,
92
+ });
93
+ }
94
+ }
95
+ const [httpReqsData, setHttpReqsData] = useState(() => ({}));
96
+ const [clicked, setClicked] = useState(() => false);
97
+ function onClick(event) {
98
+ if (props.builderContextSignal.content) {
99
+ const variationId = props.builderContextSignal.content?.testVariationId;
100
+ const contentId = props.builderContextSignal.content?.id;
101
+ _track({
102
+ type: "click",
103
+ canTrack: canTrackToUse,
104
+ contentId,
105
+ apiKey: props.apiKey,
106
+ variationId: variationId !== contentId ? variationId : undefined,
107
+ ...getInteractionPropertiesForEvent(event),
108
+ unique: !clicked,
109
+ });
110
+ }
111
+ if (!clicked) {
112
+ setClicked(true);
113
+ }
114
+ }
115
+ function evalExpression(expression) {
116
+ return expression.replace(/{{([^}]+)}}/g, (_match, group) => evaluate({
117
+ code: group,
118
+ context: props.context || {},
119
+ localState: undefined,
120
+ rootState: props.builderContextSignal.rootState,
121
+ rootSetState: props.builderContextSignal.rootSetState,
122
+ }));
123
+ }
124
+ function handleRequest({ url, key }) {
125
+ fetch(url)
126
+ .then((response) => response.json())
127
+ .then((json) => {
128
+ const newState = {
129
+ ...props.builderContextSignal.rootState,
130
+ [key]: json,
131
+ };
132
+ props.builderContextSignal.rootSetState?.(newState);
133
+ httpReqsData[key] = true;
134
+ })
135
+ .catch((err) => {
136
+ console.error("error fetching dynamic data", url, err);
137
+ });
138
+ }
139
+ function runHttpRequests() {
140
+ const requests = props.builderContextSignal.content?.data?.httpRequests ?? {};
141
+ Object.entries(requests).forEach(([key, url]) => {
142
+ if (url && (!httpReqsData[key] || isEditing())) {
143
+ const evaluatedUrl = evalExpression(url);
144
+ handleRequest({
145
+ url: evaluatedUrl,
146
+ key,
147
+ });
148
+ }
149
+ });
150
+ }
151
+ function emitStateUpdate() {
152
+ if (isEditing()) {
153
+ window.dispatchEvent(new CustomEvent("builder:component:stateChange", {
154
+ detail: {
155
+ state: props.builderContextSignal.rootState,
156
+ ref: {
157
+ name: props.model,
158
+ },
159
+ },
160
+ }));
161
+ }
162
+ }
163
+ useEffect(() => {
164
+ if (!props.apiKey) {
165
+ logger.error("No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop.");
166
+ }
167
+ if (isBrowser()) {
168
+ if (isEditing()) {
169
+ setForceReRenderCount(forceReRenderCount + 1);
170
+ registerInsertMenu();
171
+ setupBrowserForEditing({
172
+ ...(props.locale
173
+ ? {
174
+ locale: props.locale,
175
+ }
176
+ : {}),
177
+ ...(props.includeRefs
178
+ ? {
179
+ includeRefs: props.includeRefs,
180
+ }
181
+ : {}),
182
+ ...(props.enrich
183
+ ? {
184
+ enrich: props.enrich,
185
+ }
186
+ : {}),
187
+ });
188
+ Object.values(props.builderContextSignal.registeredComponents).forEach((registeredComponent) => {
189
+ const message = createRegisterComponentMessage(registeredComponent);
190
+ window.parent?.postMessage(message, "*");
191
+ });
192
+ window.addEventListener("message", processMessage);
193
+ window.addEventListener("builder:component:stateChangeListenerActivated", emitStateUpdate);
194
+ }
195
+ if (props.builderContextSignal.content) {
196
+ const variationId = props.builderContextSignal.content?.testVariationId;
197
+ const contentId = props.builderContextSignal.content?.id;
198
+ _track({
199
+ type: "impression",
200
+ canTrack: canTrackToUse,
201
+ contentId,
202
+ apiKey: props.apiKey,
203
+ variationId: variationId !== contentId ? variationId : undefined,
204
+ });
205
+ }
206
+ // override normal content in preview mode
207
+ if (isPreviewing()) {
208
+ const searchParams = new URL(location.href).searchParams;
209
+ const searchParamPreviewModel = searchParams.get("builder.preview");
210
+ const searchParamPreviewId = searchParams.get(`builder.preview.${searchParamPreviewModel}`);
211
+ const previewApiKey = searchParams.get("apiKey") || searchParams.get("builder.space");
212
+ /**
213
+ * Make sure that:
214
+ * - the preview model name is the same as the one we're rendering, since there can be multiple models rendered * at the same time, e.g. header/page/footer. * - the API key is the same, since we don't want to preview content from other organizations.
215
+ * - if there is content, that the preview ID is the same as that of the one we receive.
216
+ *
217
+ * TO-DO: should we only update the state when there is a change?
218
+ **/
219
+ if (searchParamPreviewModel === props.model &&
220
+ previewApiKey === props.apiKey &&
221
+ (!props.content || searchParamPreviewId === props.content.id)) {
222
+ getContent({
223
+ model: props.model,
224
+ apiKey: props.apiKey,
225
+ apiVersion: props.apiVersion,
226
+ }).then((content) => {
227
+ if (content) {
228
+ mergeNewContent(content);
229
+ }
230
+ });
231
+ }
232
+ }
233
+ evaluateJsCode();
234
+ runHttpRequests();
235
+ emitStateUpdate();
236
+ }
237
+ }, []);
238
+ useEffect(() => {
239
+ if (props.content) {
240
+ mergeNewContent(props.content);
241
+ }
242
+ }, [props.content]);
243
+ useEffect(() => {
244
+ evaluateJsCode();
245
+ }, [
246
+ props.builderContextSignal.content?.data?.jsCode,
247
+ props.builderContextSignal.rootState,
248
+ ]);
249
+ useEffect(() => {
250
+ runHttpRequests();
251
+ }, [props.builderContextSignal.content?.data?.httpRequests]);
252
+ useEffect(() => {
253
+ emitStateUpdate();
254
+ }, [props.builderContextSignal.rootState]);
255
+ useEffect(() => {
256
+ return () => {
257
+ if (isBrowser()) {
258
+ window.removeEventListener("message", processMessage);
259
+ window.removeEventListener("builder:component:stateChangeListenerActivated", emitStateUpdate);
260
+ }
261
+ };
262
+ }, []);
263
+ return (React.createElement(builderContext.Provider, { value: props.builderContextSignal }, props.builderContextSignal.content ? (React.createElement(React.Fragment, null,
264
+ React.createElement("div", { ref: elementRef, onClick: (event) => onClick(event), "builder-content-id": props.builderContextSignal.content?.id, "builder-model": props.model, key: forceReRenderCount, ...(TARGET === "reactNative"
265
+ ? {
266
+ dataSet: {
267
+ // 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.
268
+ "builder-content-id": "",
269
+ },
270
+ }
271
+ : {}), ...(props.hideContent
272
+ ? {
273
+ hidden: true,
274
+ "aria-hidden": true,
275
+ }
276
+ : {}), className: props.classNameProp }, props.children))) : null));
277
+ }
278
+ export default EnableEditor;
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import type { ContentProps } from "./content.types.js";
3
+ declare function Content(props: ContentProps): JSX.Element;
4
+ export default Content;
@@ -0,0 +1,7 @@
1
+ import type { BuilderContent } from '../../types/builder-content';
2
+ import type { Nullable } from '../../types/typescript';
3
+ import type { ContentProps } from './content.types';
4
+ export declare const getContextStateInitialValue: ({ content, data, locale, }: Pick<ContentProps, 'content' | 'data' | 'locale'>) => {
5
+ [x: string]: unknown;
6
+ };
7
+ export declare const getContentInitialValue: ({ content, data, }: Pick<ContentProps, 'content' | 'data'>) => Nullable<BuilderContent>;
@@ -0,0 +1,30 @@
1
+ export const getContextStateInitialValue = ({ content, data, locale, }) => {
2
+ const defaultValues = {};
3
+ // set default values for content state inputs
4
+ content?.data?.inputs?.forEach((input) => {
5
+ if (input.name &&
6
+ input.defaultValue !== undefined &&
7
+ content?.data?.state &&
8
+ content.data.state[input.name] === undefined) {
9
+ defaultValues[input.name] = input.defaultValue;
10
+ }
11
+ });
12
+ const stateToUse = {
13
+ ...content?.data?.state,
14
+ ...data,
15
+ ...(locale ? { locale } : {}),
16
+ };
17
+ return { ...defaultValues, ...stateToUse };
18
+ };
19
+ export const getContentInitialValue = ({ content, data, }) => {
20
+ return !content
21
+ ? undefined
22
+ : {
23
+ ...content,
24
+ data: {
25
+ ...content?.data,
26
+ ...data,
27
+ },
28
+ meta: content?.meta,
29
+ };
30
+ };
@@ -0,0 +1,97 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { useState, useEffect } from "react";
4
+ import { getDefaultRegisteredComponents } from "../../constants/builder-registered-components.js";
5
+ import { components } from "../../functions/register-component.js";
6
+ import Blocks from "../blocks/blocks";
7
+ import ContentStyles from "./components/content-styles";
8
+ import { getContentInitialValue, getContextStateInitialValue, } from "./content.helpers.js";
9
+ import { TARGET } from "../../constants/target.js";
10
+ import { getRenderContentScriptString } from "../content-variants/helpers.js";
11
+ import { wrapComponentRef } from "./wrap-component-ref.js";
12
+ import EnableEditor from "./components/enable-editor";
13
+ function Content(props) {
14
+ const [scriptStr, setScriptStr] = useState(() => getRenderContentScriptString({
15
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
16
+ contentId: props.content?.id,
17
+ parentContentId: props.parentContentId,
18
+ }));
19
+ function contentSetState(newRootState) {
20
+ setBuilderContextSignal((PREVIOUS_VALUE) => ({
21
+ ...PREVIOUS_VALUE,
22
+ rootState: newRootState,
23
+ }));
24
+ }
25
+ const [customComps, setCustomComps] = useState(() => [
26
+ ...getDefaultRegisteredComponents(),
27
+ // While this `components` object is deprecated, we must maintain support for it.
28
+ // Since users are able to override our default components, we need to make sure that we do not break such
29
+ // existing usage.
30
+ // This is why we spread `components` after the default Builder.io components, but before the `props.customComponents`,
31
+ // which is the new standard way of providing custom components, and must therefore take precedence.
32
+ ...components,
33
+ ...(props.customComponents || []),
34
+ ].reduce((acc, info) => ({
35
+ ...acc,
36
+ [info.name]: info,
37
+ }), {}));
38
+ function customComponentsInfo() {
39
+ // TO-DO: fix once we remove `useStore<any>` hack in Qwik generator.
40
+ return Object.values(customComps).reduce((acc, { component: _, ...info }) => ({
41
+ ...acc,
42
+ [info.name]: info,
43
+ }), {});
44
+ }
45
+ function tempContextSignalSetter() {
46
+ return setBuilderContextSignal;
47
+ }
48
+ const [builderContextSignal, setBuilderContextSignal] = useState(() => ({
49
+ content: getContentInitialValue({
50
+ content: props.content,
51
+ data: props.data,
52
+ }),
53
+ localState: undefined,
54
+ rootState: getContextStateInitialValue({
55
+ content: props.content,
56
+ data: props.data,
57
+ locale: props.locale,
58
+ }),
59
+ rootSetState: undefined,
60
+ context: props.context || {},
61
+ apiKey: props.apiKey,
62
+ apiVersion: props.apiVersion,
63
+ registeredComponents: [
64
+ ...getDefaultRegisteredComponents(),
65
+ // While this `components` object is deprecated, we must maintain support for it.
66
+ // Since users are able to override our default components, we need to make sure that we do not break such
67
+ // existing usage.
68
+ // This is why we spread `components` after the default Builder.io components, but before the `props.customComponents`,
69
+ // which is the new standard way of providing custom components, and must therefore take precedence.
70
+ ...components,
71
+ ...(props.customComponents || []),
72
+ ].reduce((acc, { component, ...curr }) => ({
73
+ ...acc,
74
+ [curr.name]: {
75
+ component: TARGET === "vue3" ? wrapComponentRef(component) : component,
76
+ ...curr,
77
+ },
78
+ }), {}),
79
+ inheritedStyles: {},
80
+ }));
81
+ useEffect(() => {
82
+ if (!builderContextSignal.content) {
83
+ builderContextSignal.content = getContentInitialValue({
84
+ content: props.content,
85
+ data: props.data,
86
+ });
87
+ }
88
+ }, [props.content, props.data, props.locale]);
89
+ return (React.createElement(React.Fragment, null, builderContextSignal.content ? (React.createElement(React.Fragment, null,
90
+ React.createElement(EnableEditor, { content: props.content, model: props.model, data: props.data, context: props.context, apiKey: props.apiKey, apiVersion: props.apiVersion, customComponents: customComponentsInfo(), canTrack: props.canTrack, locale: props.locale, includeRefs: props.includeRefs, enrich: props.enrich, classNameProp: props.classNameProp, hideContent: props.hideContent, parentContentId: props.parentContentId, isSsrAbTest: props.isSsrAbTest, builderContextSignal: builderContextSignal, setBuilderContextSignal: tempContextSignalSetter() },
91
+ props.isSsrAbTest ? (React.createElement(React.Fragment, null,
92
+ React.createElement("script", { dangerouslySetInnerHTML: { __html: scriptStr } }))) : null,
93
+ TARGET !== "reactNative" ? (React.createElement(React.Fragment, null,
94
+ React.createElement(ContentStyles, { contentId: builderContextSignal.content?.id, cssCode: builderContextSignal.content?.data?.cssCode, customFonts: builderContextSignal.content?.data?.customFonts }))) : null,
95
+ React.createElement(Blocks, { blocks: builderContextSignal.content?.data?.blocks, context: builderContextSignal, components: customComps })))) : null));
96
+ }
97
+ export default Content;
@@ -0,0 +1,38 @@
1
+ import type { BuilderRenderContext, RegisteredComponent, BuilderRenderState } from '../../context/types';
2
+ import type { BuilderContent } from '../../types/builder-content';
3
+ import type { Nullable } from '../../types/typescript';
4
+ import type { ApiVersion } from '../../types/api-version';
5
+ export interface ContentProps {
6
+ content?: Nullable<BuilderContent>;
7
+ model?: string;
8
+ data?: {
9
+ [key: string]: any;
10
+ };
11
+ context?: BuilderRenderContext;
12
+ apiKey: string;
13
+ apiVersion?: ApiVersion;
14
+ customComponents?: RegisteredComponent[];
15
+ canTrack?: boolean;
16
+ locale?: string;
17
+ /** @deprecated use `enrich` instead **/
18
+ includeRefs?: boolean;
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
+ }
28
+ export interface BuilderComponentStateChange {
29
+ state: BuilderRenderState;
30
+ ref: {
31
+ name?: string;
32
+ props?: {
33
+ builderBlock?: {
34
+ id?: string;
35
+ };
36
+ };
37
+ };
38
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export { default } from './content';
@@ -0,0 +1 @@
1
+ export { default } from './content';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Apply target-specific transformations to the component reference.
3
+ *
4
+ * See overrides/* for examples.
5
+ */
6
+ export declare const wrapComponentRef: (component: any) => any;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Apply target-specific transformations to the component reference.
3
+ *
4
+ * See overrides/* for examples.
5
+ */
6
+ export const wrapComponentRef = (component) => component;
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ type VariantsProviderProps = ContentProps;
3
+ import type { ContentProps } from "../content/content.types";
4
+ declare function RenderContentVariants(props: VariantsProviderProps): JSX.Element;
5
+ export default RenderContentVariants;
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { useState } from "react";
4
+ import { checkShouldRunVariants, getVariants, getVariantsScriptString, } from "./helpers";
5
+ import Content from "../content/content";
6
+ import { getDefaultCanTrack } from "../../helpers/canTrack";
7
+ import InlinedStyles from "../inlined-styles";
8
+ import { handleABTestingSync } from "../../helpers/ab-tests";
9
+ function RenderContentVariants(props) {
10
+ const [variantScriptStr, setVariantScriptStr] = useState(() => getVariantsScriptString(getVariants(props.content).map((value) => ({
11
+ id: value.id,
12
+ testRatio: value.testRatio,
13
+ })), props.content?.id || ""));
14
+ const [shouldRenderVariants, setShouldRenderVariants] = useState(() => checkShouldRunVariants({
15
+ canTrack: getDefaultCanTrack(props.canTrack),
16
+ content: props.content,
17
+ }));
18
+ const [hideVariantsStyleString, setHideVariantsStyleString] = useState(() => getVariants(props.content)
19
+ .map((value) => `.variant-${value.id} { display: none; } `)
20
+ .join(""));
21
+ const [contentToRender, setContentToRender] = useState(() => checkShouldRunVariants({
22
+ canTrack: getDefaultCanTrack(props.canTrack),
23
+ content: props.content,
24
+ })
25
+ ? props.content
26
+ : handleABTestingSync({
27
+ item: props.content,
28
+ canTrack: getDefaultCanTrack(props.canTrack),
29
+ }));
30
+ return (React.createElement(React.Fragment, null,
31
+ shouldRenderVariants ? (React.createElement(React.Fragment, null,
32
+ React.createElement(InlinedStyles, { id: `variants-styles-${props.content?.id}`, styles: hideVariantsStyleString }),
33
+ React.createElement("script", { id: `variants-script-${props.content?.id}`, dangerouslySetInnerHTML: { __html: variantScriptStr } }),
34
+ getVariants(props.content)?.map((variant) => (React.createElement(Content, { key: variant.id, content: variant, apiKey: props.apiKey, apiVersion: props.apiVersion, canTrack: props.canTrack, customComponents: props.customComponents, hideContent: true, parentContentId: props.content?.id, isSsrAbTest: shouldRenderVariants }))))) : null,
35
+ React.createElement(Content, { model: props.model, content: contentToRender, apiKey: props.apiKey, apiVersion: props.apiVersion, canTrack: props.canTrack, customComponents: props.customComponents, classNameProp: `variant-${props.content?.id}`, parentContentId: props.content?.id, isSsrAbTest: shouldRenderVariants })));
36
+ }
37
+ export default RenderContentVariants;
@@ -0,0 +1,17 @@
1
+ import type { Nullable } from '../../helpers/nullable';
2
+ import type { BuilderContent } from '../../types/builder-content';
3
+ export declare const getVariants: (content: Nullable<BuilderContent>) => import("../../types/builder-content").BuilderContentVariation[];
4
+ export declare const checkShouldRunVariants: ({ canTrack, content, }: {
5
+ canTrack: Nullable<boolean>;
6
+ content: Nullable<BuilderContent>;
7
+ }) => boolean;
8
+ type VariantData = {
9
+ id: string;
10
+ testRatio?: number;
11
+ };
12
+ export declare const getVariantsScriptString: (variants: VariantData[], contentId: string) => string;
13
+ export declare const getRenderContentScriptString: ({ parentContentId, contentId, }: {
14
+ contentId: string;
15
+ parentContentId: string;
16
+ }) => string;
17
+ export {};