@builder.io/sdk-react 0.2.0 → 0.2.2

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