@builder.io/sdk-react-native 1.0.33 → 1.0.34

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 (262) hide show
  1. package/lib/browser/commonjs/blocks/text/text.js +1 -1
  2. package/lib/browser/commonjs/constants/sdk-version.js +1 -1
  3. package/lib/browser/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js +4 -18
  4. package/lib/browser/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  5. package/lib/browser/commonjs/helpers/cookie.js +12 -2
  6. package/lib/browser/commonjs/helpers/cookie.js.map +1 -1
  7. package/lib/browser/module/blocks/text/text.js +1 -1
  8. package/lib/browser/module/blocks/text/text.js.map +1 -1
  9. package/lib/browser/module/constants/sdk-version.js +1 -1
  10. package/lib/browser/module/functions/evaluate/node-runtime/safeDynamicRequire.js +5 -18
  11. package/lib/browser/module/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  12. package/lib/browser/module/helpers/cookie.js +11 -2
  13. package/lib/browser/module/helpers/cookie.js.map +1 -1
  14. package/lib/browser/typescript/constants/sdk-version.d.ts +1 -1
  15. package/lib/browser/typescript/helpers/cookie.d.ts +1 -0
  16. package/lib/browser/typescript/helpers/cookie.d.ts.map +1 -1
  17. package/lib/edge/commonjs/blocks/text/text.js +1 -1
  18. package/lib/edge/commonjs/constants/sdk-version.js +1 -1
  19. package/lib/edge/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js +4 -18
  20. package/lib/edge/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  21. package/lib/edge/commonjs/helpers/cookie.js +12 -2
  22. package/lib/edge/commonjs/helpers/cookie.js.map +1 -1
  23. package/lib/edge/module/blocks/text/text.js +1 -1
  24. package/lib/edge/module/blocks/text/text.js.map +1 -1
  25. package/lib/edge/module/constants/sdk-version.js +1 -1
  26. package/lib/edge/module/functions/evaluate/node-runtime/safeDynamicRequire.js +5 -18
  27. package/lib/edge/module/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  28. package/lib/edge/module/helpers/cookie.js +11 -2
  29. package/lib/edge/module/helpers/cookie.js.map +1 -1
  30. package/lib/edge/typescript/constants/sdk-version.d.ts +1 -1
  31. package/lib/edge/typescript/helpers/cookie.d.ts +1 -0
  32. package/lib/edge/typescript/helpers/cookie.d.ts.map +1 -1
  33. package/lib/node/commonjs/blocks/text/text.js +1 -1
  34. package/lib/node/commonjs/constants/sdk-version.js +1 -1
  35. package/lib/node/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js +4 -18
  36. package/lib/node/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  37. package/lib/node/commonjs/helpers/cookie.js +12 -2
  38. package/lib/node/commonjs/helpers/cookie.js.map +1 -1
  39. package/lib/node/module/blocks/text/text.js +1 -1
  40. package/lib/node/module/blocks/text/text.js.map +1 -1
  41. package/lib/node/module/constants/sdk-version.js +1 -1
  42. package/lib/node/module/functions/evaluate/node-runtime/safeDynamicRequire.js +5 -18
  43. package/lib/node/module/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
  44. package/lib/node/module/helpers/cookie.js +11 -2
  45. package/lib/node/module/helpers/cookie.js.map +1 -1
  46. package/lib/node/typescript/constants/sdk-version.d.ts +1 -1
  47. package/lib/node/typescript/helpers/cookie.d.ts +1 -0
  48. package/lib/node/typescript/helpers/cookie.d.ts.map +1 -1
  49. package/package.json +10 -7
  50. package/src/blocks/BaseText.tsx +17 -0
  51. package/src/blocks/accordion/accordion.tsx +181 -0
  52. package/src/blocks/accordion/accordion.types.ts +12 -0
  53. package/src/blocks/accordion/component-info.ts +124 -0
  54. package/src/blocks/accordion/helpers.ts +3 -0
  55. package/src/blocks/accordion/index.ts +1 -0
  56. package/src/blocks/button/button.tsx +56 -0
  57. package/src/blocks/button/button.types.ts +7 -0
  58. package/src/blocks/button/component-info.ts +35 -0
  59. package/src/blocks/button/index.ts +1 -0
  60. package/src/blocks/columns/columns.tsx +199 -0
  61. package/src/blocks/columns/columns.types.ts +14 -0
  62. package/src/blocks/columns/component-info.ts +219 -0
  63. package/src/blocks/columns/helpers.ts +3 -0
  64. package/src/blocks/columns/index.ts +1 -0
  65. package/src/blocks/custom-code/component-info.ts +24 -0
  66. package/src/blocks/custom-code/custom-code.tsx +71 -0
  67. package/src/blocks/custom-code/index.ts +1 -0
  68. package/src/blocks/embed/component-info.ts +38 -0
  69. package/src/blocks/embed/embed.tsx +62 -0
  70. package/src/blocks/embed/helpers.ts +2 -0
  71. package/src/blocks/embed/index.ts +1 -0
  72. package/src/blocks/form/form/component-info.ts +233 -0
  73. package/src/blocks/form/form/form.tsx +324 -0
  74. package/src/blocks/form/form/index.ts +1 -0
  75. package/src/blocks/form/input/component-info.ts +47 -0
  76. package/src/blocks/form/input/index.ts +1 -0
  77. package/src/blocks/form/input/input.tsx +49 -0
  78. package/src/blocks/form/select/component-info.ts +44 -0
  79. package/src/blocks/form/select/index.ts +1 -0
  80. package/src/blocks/form/select/select.tsx +54 -0
  81. package/src/blocks/form/submit-button/component-info.ts +27 -0
  82. package/src/blocks/form/submit-button/index.ts +1 -0
  83. package/src/blocks/form/submit-button/submit-button.tsx +34 -0
  84. package/src/blocks/fragment/component-info.ts +8 -0
  85. package/src/blocks/fragment/fragment.tsx +18 -0
  86. package/src/blocks/fragment/fragment.types.ts +5 -0
  87. package/src/blocks/fragment/index.ts +1 -0
  88. package/src/blocks/helpers.ts +43 -0
  89. package/src/blocks/image/component-info.ts +129 -0
  90. package/src/blocks/image/image.helpers.ts +47 -0
  91. package/src/blocks/image/image.tsx +65 -0
  92. package/src/blocks/image/image.types.ts +20 -0
  93. package/src/blocks/image/index.ts +1 -0
  94. package/src/blocks/img/component-info.ts +16 -0
  95. package/src/blocks/img/img.tsx +55 -0
  96. package/src/blocks/img/index.ts +1 -0
  97. package/src/blocks/raw-text/component-info.ts +11 -0
  98. package/src/blocks/raw-text/index.ts +1 -0
  99. package/src/blocks/raw-text/raw-text.tsx +1 -0
  100. package/src/blocks/section/component-info.ts +41 -0
  101. package/src/blocks/section/index.ts +1 -0
  102. package/src/blocks/section/section.tsx +39 -0
  103. package/src/blocks/section/section.types.ts +6 -0
  104. package/src/blocks/slot/component-info.ts +15 -0
  105. package/src/blocks/slot/index.ts +1 -0
  106. package/src/blocks/slot/slot.tsx +42 -0
  107. package/src/blocks/symbol/component-info.ts +35 -0
  108. package/src/blocks/symbol/index.ts +1 -0
  109. package/src/blocks/symbol/symbol.helpers.ts +47 -0
  110. package/src/blocks/symbol/symbol.tsx +100 -0
  111. package/src/blocks/symbol/symbol.types.ts +17 -0
  112. package/src/blocks/tabs/component-info.ts +139 -0
  113. package/src/blocks/tabs/index.ts +1 -0
  114. package/src/blocks/tabs/tabs.tsx +79 -0
  115. package/src/blocks/tabs/tabs.types.ts +13 -0
  116. package/src/blocks/text/component-info.ts +20 -0
  117. package/src/blocks/text/index.ts +1 -0
  118. package/src/blocks/text/text.tsx +105 -0
  119. package/src/blocks/text/text.types.ts +4 -0
  120. package/src/blocks/textarea/component-info.ts +38 -0
  121. package/src/blocks/textarea/index.ts +1 -0
  122. package/src/blocks/textarea/textarea.tsx +41 -0
  123. package/src/blocks/video/component-info.ts +83 -0
  124. package/src/blocks/video/index.ts +1 -0
  125. package/src/blocks/video/video.tsx +70 -0
  126. package/src/blocks/video/video.types.ts +21 -0
  127. package/src/components/block/animator.ts +220 -0
  128. package/src/components/block/block.helpers.ts +124 -0
  129. package/src/components/block/block.tsx +232 -0
  130. package/src/components/block/components/block-styles.tsx +136 -0
  131. package/src/components/block/components/block-wrapper.tsx +52 -0
  132. package/src/components/block/components/component-ref/component-ref.helpers.ts +55 -0
  133. package/src/components/block/components/component-ref/component-ref.tsx +66 -0
  134. package/src/components/block/components/interactive-element.tsx +53 -0
  135. package/src/components/block/components/repeated-block.tsx +37 -0
  136. package/src/components/block/types.ts +6 -0
  137. package/src/components/blocks/blocks-wrapper.tsx +93 -0
  138. package/src/components/blocks/blocks.tsx +57 -0
  139. package/src/components/blocks/blocks.types.ts +7 -0
  140. package/src/components/blocks/index.ts +1 -0
  141. package/src/components/content/components/enable-editor.tsx +472 -0
  142. package/src/components/content/components/styles.helpers.ts +101 -0
  143. package/src/components/content/components/styles.tsx +42 -0
  144. package/src/components/content/content.helpers.ts +40 -0
  145. package/src/components/content/content.tsx +150 -0
  146. package/src/components/content/content.types.ts +13 -0
  147. package/src/components/content/contentProps.types.ts +17 -0
  148. package/src/components/content/index.ts +1 -0
  149. package/src/components/content/wrap-component-ref.ts +6 -0
  150. package/src/components/content-variants/content-variants.tsx +146 -0
  151. package/src/components/content-variants/content-variants.types.ts +84 -0
  152. package/src/components/content-variants/helpers.ts +72 -0
  153. package/src/components/content-variants/index.ts +1 -0
  154. package/src/components/content-variants/inlined-fns.ts +22 -0
  155. package/src/components/dynamic-div.tsx +30 -0
  156. package/src/components/dynamic-renderer/dynamic-renderer.helpers.ts +7 -0
  157. package/src/components/dynamic-renderer/dynamic-renderer.tsx +47 -0
  158. package/src/components/error-boundary.tsx +38 -0
  159. package/src/components/inlined-script.tsx +10 -0
  160. package/src/components/inlined-styles.tsx +10 -0
  161. package/src/constants/builder-registered-components.ts +59 -0
  162. package/src/constants/device-sizes.ts +59 -0
  163. package/src/constants/extra-components.ts +1 -0
  164. package/src/constants/sdk-version.ts +1 -0
  165. package/src/constants/target.ts +3 -0
  166. package/src/context/builder.context.ts +15 -0
  167. package/src/context/components.context.ts +3 -0
  168. package/src/context/index.ts +1 -0
  169. package/src/context/types.ts +38 -0
  170. package/src/functions/apply-patch-with-mutation.ts +61 -0
  171. package/src/functions/camel-to-kebab-case.ts +1 -0
  172. package/src/functions/deopt.ts +6 -0
  173. package/src/functions/evaluate/browser-runtime/browser.ts +61 -0
  174. package/src/functions/evaluate/browser-runtime/index.ts +1 -0
  175. package/src/functions/evaluate/choose-eval.ts +23 -0
  176. package/src/functions/evaluate/edge-runtime/acorn-interpreter.ts +2891 -0
  177. package/src/functions/evaluate/edge-runtime/edge-runtime.ts +89 -0
  178. package/src/functions/evaluate/edge-runtime/index.ts +1 -0
  179. package/src/functions/evaluate/evaluate.ts +76 -0
  180. package/src/functions/evaluate/helpers.ts +56 -0
  181. package/src/functions/evaluate/index.ts +1 -0
  182. package/src/functions/evaluate/node-runtime/index.ts +1 -0
  183. package/src/functions/evaluate/node-runtime/init.ts +33 -0
  184. package/src/functions/evaluate/node-runtime/node-runtime.ts +176 -0
  185. package/src/functions/evaluate/node-runtime/safeDynamicRequire.ts +14 -0
  186. package/src/functions/evaluate/placeholder-runtime.ts +4 -0
  187. package/src/functions/evaluate/should-force-browser-runtime-in-node.ts +16 -0
  188. package/src/functions/event-handler-name.ts +4 -0
  189. package/src/functions/extract-text-styles.ts +24 -0
  190. package/src/functions/fast-clone.ts +4 -0
  191. package/src/functions/fetch-builder-props.ts +75 -0
  192. package/src/functions/get-block-actions-handler.ts +17 -0
  193. package/src/functions/get-block-actions.ts +35 -0
  194. package/src/functions/get-block-component-options.ts +7 -0
  195. package/src/functions/get-block-properties.ts +62 -0
  196. package/src/functions/get-builder-search-params/index.ts +33 -0
  197. package/src/functions/get-class-prop-name.ts +15 -0
  198. package/src/functions/get-content/generate-content-url.ts +88 -0
  199. package/src/functions/get-content/index.ts +99 -0
  200. package/src/functions/get-content/types.ts +157 -0
  201. package/src/functions/get-env.ts +5 -0
  202. package/src/functions/get-fetch.ts +11 -0
  203. package/src/functions/get-global-this.ts +16 -0
  204. package/src/functions/get-processed-block.ts +70 -0
  205. package/src/functions/get-style.ts +38 -0
  206. package/src/functions/get.ts +4 -0
  207. package/src/functions/is-browser.ts +3 -0
  208. package/src/functions/is-edge-runtime.ts +9 -0
  209. package/src/functions/is-editing.ts +8 -0
  210. package/src/functions/is-from-trusted-host.ts +11 -0
  211. package/src/functions/is-iframe.ts +4 -0
  212. package/src/functions/is-node-runtime.ts +8 -0
  213. package/src/functions/is-previewing.ts +16 -0
  214. package/src/functions/on-change.ts +29 -0
  215. package/src/functions/register-component.ts +30 -0
  216. package/src/functions/register.ts +44 -0
  217. package/src/functions/set-editor-settings.ts +15 -0
  218. package/src/functions/set.ts +14 -0
  219. package/src/functions/track/helpers.ts +51 -0
  220. package/src/functions/track/index.ts +131 -0
  221. package/src/functions/track/interaction.ts +63 -0
  222. package/src/functions/transform-block-properties.ts +33 -0
  223. package/src/functions/transform-block.ts +30 -0
  224. package/src/functions/transform-style-property.ts +296 -0
  225. package/src/helpers/ab-tests.ts +166 -0
  226. package/src/helpers/canTrack.ts +2 -0
  227. package/src/helpers/cookie.ts +109 -0
  228. package/src/helpers/css.ts +33 -0
  229. package/src/helpers/flatten.ts +41 -0
  230. package/src/helpers/localStorage.ts +36 -0
  231. package/src/helpers/logger.ts +7 -0
  232. package/src/helpers/nullable.ts +2 -0
  233. package/src/helpers/omit.ts +7 -0
  234. package/src/helpers/preview-lru-cache/get.ts +4 -0
  235. package/src/helpers/preview-lru-cache/helpers.ts +1 -0
  236. package/src/helpers/preview-lru-cache/init.ts +7 -0
  237. package/src/helpers/preview-lru-cache/set.ts +12 -0
  238. package/src/helpers/preview-lru-cache/types.ts +1 -0
  239. package/src/helpers/search/search.ts +18 -0
  240. package/src/helpers/sessionId.ts +37 -0
  241. package/src/helpers/subscribe-to-editor.ts +95 -0
  242. package/src/helpers/time.ts +2 -0
  243. package/src/helpers/url.ts +15 -0
  244. package/src/helpers/uuid.ts +17 -0
  245. package/src/helpers/visitorId.ts +37 -0
  246. package/src/index-helpers/blocks-exports.ts +16 -0
  247. package/src/index-helpers/top-of-file.ts +2 -0
  248. package/src/index.ts +15 -0
  249. package/src/scripts/init-editing.ts +119 -0
  250. package/src/server-index.ts +43 -0
  251. package/src/types/api-version.ts +2 -0
  252. package/src/types/builder-block.ts +89 -0
  253. package/src/types/builder-content.ts +47 -0
  254. package/src/types/builder-props.ts +12 -0
  255. package/src/types/can-track.ts +3 -0
  256. package/src/types/components.ts +119 -0
  257. package/src/types/deep-partial.ts +1 -0
  258. package/src/types/element.ts +57 -0
  259. package/src/types/enforced-partials.ts +19 -0
  260. package/src/types/input.ts +123 -0
  261. package/src/types/targets.ts +1 -0
  262. package/src/types/typescript.ts +9 -0
@@ -0,0 +1,93 @@
1
+ import * as React from "react";
2
+ import {
3
+ FlatList,
4
+ ScrollView,
5
+ View,
6
+ StyleSheet,
7
+ Image,
8
+ Text,
9
+ Pressable,
10
+ TextInput,
11
+ } from "react-native";
12
+
13
+ export type BlocksWrapperProps = {
14
+ blocks: BuilderBlock[] | undefined;
15
+ parent: string | undefined;
16
+ path: string | undefined;
17
+ styleProp: Record<string, any> | undefined;
18
+ /**
19
+ * The element that wraps each list of blocks. Defaults to a `div` element ('ScrollView' in React Native).
20
+ */
21
+ BlocksWrapper: any;
22
+ /**
23
+ * Additonal props to pass to `blocksWrapper`. Defaults to `{}`.
24
+ */
25
+ BlocksWrapperProps: any;
26
+ children?: any;
27
+ };
28
+ import { isEditing } from "../../functions/is-editing";
29
+ import type { BuilderBlock } from "../../types/builder-block";
30
+
31
+ function BlocksWrapper(props: BlocksWrapperProps) {
32
+ function className() {
33
+ return "builder-blocks" + (!props.blocks?.length ? " no-blocks" : "");
34
+ }
35
+
36
+ function onClick() {
37
+ if (isEditing() && !props.blocks?.length) {
38
+ window.parent?.postMessage(
39
+ {
40
+ type: "builder.clickEmptyBlocks",
41
+ data: {
42
+ parentElementId: props.parent,
43
+ dataPath: props.path,
44
+ },
45
+ },
46
+ "*"
47
+ );
48
+ }
49
+ }
50
+
51
+ function onMouseEnter() {
52
+ if (isEditing() && !props.blocks?.length) {
53
+ window.parent?.postMessage(
54
+ {
55
+ type: "builder.hoverEmptyBlocks",
56
+ data: {
57
+ parentElementId: props.parent,
58
+ dataPath: props.path,
59
+ },
60
+ },
61
+ "*"
62
+ );
63
+ }
64
+ }
65
+
66
+ return (
67
+ <props.BlocksWrapper
68
+ builder-path={props.path}
69
+ builder-parent-id={props.parent}
70
+ {...{
71
+ dataSet: {
72
+ class: className(),
73
+ },
74
+ }}
75
+ style={{
76
+ ...styles.propsBlocksWrapper1,
77
+ ...props.styleProp,
78
+ }}
79
+ onPress={(event) => onClick()}
80
+ onMouseEnter={(event) => onMouseEnter()}
81
+ onKeyPress={(event) => onClick()}
82
+ {...props.BlocksWrapperProps}
83
+ >
84
+ {props.children}
85
+ </props.BlocksWrapper>
86
+ );
87
+ }
88
+
89
+ const styles = StyleSheet.create({
90
+ propsBlocksWrapper1: { display: "flex", flexDirection: "column" },
91
+ });
92
+
93
+ export default BlocksWrapper;
@@ -0,0 +1,57 @@
1
+ import * as React from "react";
2
+ import {
3
+ FlatList,
4
+ ScrollView,
5
+ View,
6
+ StyleSheet,
7
+ Image,
8
+ Text,
9
+ Pressable,
10
+ TextInput,
11
+ } from "react-native";
12
+ import { useContext } from "react";
13
+ import BuilderContext from "../../context/builder.context";
14
+ import ComponentsContext from "../../context/components.context";
15
+ import Block from "../block/block";
16
+ import BlocksWrapper from "./blocks-wrapper";
17
+ import type { BlocksProps } from "./blocks.types";
18
+
19
+ function Blocks(props: BlocksProps) {
20
+ const builderContext = useContext(BuilderContext);
21
+
22
+ const componentsContext = useContext(ComponentsContext);
23
+
24
+ return (
25
+ <BlocksWrapper
26
+ blocks={props.blocks}
27
+ parent={props.parent}
28
+ path={props.path}
29
+ styleProp={props.styleProp}
30
+ BlocksWrapper={
31
+ props.context?.BlocksWrapper || builderContext.BlocksWrapper
32
+ }
33
+ BlocksWrapperProps={
34
+ props.context?.BlocksWrapperProps || builderContext.BlocksWrapperProps
35
+ }
36
+ >
37
+ {props.blocks ? (
38
+ <>
39
+ {props.blocks?.map((block) => (
40
+ <Block
41
+ key={block.id}
42
+ block={block}
43
+ linkComponent={props.linkComponent}
44
+ context={props.context || builderContext}
45
+ registeredComponents={
46
+ props.registeredComponents ||
47
+ componentsContext.registeredComponents
48
+ }
49
+ />
50
+ ))}
51
+ </>
52
+ ) : null}
53
+ </BlocksWrapper>
54
+ );
55
+ }
56
+
57
+ export default Blocks;
@@ -0,0 +1,7 @@
1
+ import type { BuilderContextInterface, RegisteredComponents } from '../../context/types';
2
+ import type { BlocksWrapperProps } from './blocks-wrapper';
3
+ export type BlocksProps = Partial<Omit<BlocksWrapperProps, 'BlocksWrapper' | 'BlocksWrapperProps'>> & {
4
+ context?: BuilderContextInterface;
5
+ registeredComponents?: RegisteredComponents;
6
+ linkComponent?: any;
7
+ }
@@ -0,0 +1 @@
1
+ export { default } from './blocks'
@@ -0,0 +1,472 @@
1
+ import * as React from "react";
2
+ import {
3
+ FlatList,
4
+ ScrollView,
5
+ View,
6
+ StyleSheet,
7
+ Image,
8
+ Text,
9
+ Pressable,
10
+ TextInput,
11
+ } from "react-native";
12
+ import { useState, useContext, useRef, useEffect } from "react";
13
+
14
+ type BuilderEditorProps = Omit<
15
+ ContentProps,
16
+ | "customComponents"
17
+ | "apiVersion"
18
+ | "isSsrAbTest"
19
+ | "blocksWrapper"
20
+ | "blocksWrapperProps"
21
+ | "isNestedRender"
22
+ | "linkComponent"
23
+ > & {
24
+ builderContextSignal: BuilderContextInterface;
25
+ setBuilderContextSignal?: (signal: any) => any;
26
+ children?: any;
27
+ };
28
+ import builderContext from "../../../context/builder.context";
29
+ import type { BuilderContextInterface } from "../../../context/types";
30
+ import { evaluate } from "../../../functions/evaluate/index";
31
+ import { fastClone } from "../../../functions/fast-clone";
32
+ import { fetchOneEntry } from "../../../functions/get-content/index";
33
+ import { fetch } from "../../../functions/get-fetch";
34
+ import { isBrowser } from "../../../functions/is-browser";
35
+ import { isEditing } from "../../../functions/is-editing";
36
+ import { isPreviewing } from "../../../functions/is-previewing";
37
+ import { createRegisterComponentMessage } from "../../../functions/register-component";
38
+ import { _track } from "../../../functions/track/index";
39
+ import { getInteractionPropertiesForEvent } from "../../../functions/track/interaction";
40
+ import { getDefaultCanTrack } from "../../../helpers/canTrack";
41
+ import { logger } from "../../../helpers/logger";
42
+ import { postPreviewContent } from "../../../helpers/preview-lru-cache/set";
43
+ import { createEditorListener } from "../../../helpers/subscribe-to-editor";
44
+ import {
45
+ registerInsertMenu,
46
+ setupBrowserForEditing,
47
+ } from "../../../scripts/init-editing";
48
+ import type { BuilderContent } from "../../../types/builder-content";
49
+ import type { ComponentInfo } from "../../../types/components";
50
+ import type { Dictionary } from "../../../types/typescript";
51
+ import { triggerAnimation } from "../../block/animator";
52
+ import DynamicDiv from "../../dynamic-div";
53
+ import type {
54
+ BuilderComponentStateChange,
55
+ ContentProps,
56
+ } from "../content.types";
57
+ import { getWrapperClassName } from "./styles.helpers";
58
+
59
+ function EnableEditor(props: BuilderEditorProps) {
60
+ const elementRef = useRef<HTMLDivElement>(null);
61
+ function mergeNewRootState(newData: Dictionary<any>) {
62
+ const combinedState = {
63
+ ...props.builderContextSignal.rootState,
64
+ ...newData,
65
+ };
66
+ if (props.builderContextSignal.rootSetState) {
67
+ props.builderContextSignal.rootSetState?.(combinedState);
68
+ } else {
69
+ props.setBuilderContextSignal((PREVIOUS_VALUE) => ({
70
+ ...PREVIOUS_VALUE,
71
+ rootState: combinedState,
72
+ }));
73
+ }
74
+ }
75
+
76
+ function mergeNewContent(newContent: BuilderContent) {
77
+ const newContentValue = {
78
+ ...props.builderContextSignal.content,
79
+ ...newContent,
80
+ data: {
81
+ ...props.builderContextSignal.content?.data,
82
+ ...newContent?.data,
83
+ },
84
+ meta: {
85
+ ...props.builderContextSignal.content?.meta,
86
+ ...newContent?.meta,
87
+ breakpoints:
88
+ newContent?.meta?.breakpoints ||
89
+ props.builderContextSignal.content?.meta?.breakpoints,
90
+ },
91
+ };
92
+ props.setBuilderContextSignal((PREVIOUS_VALUE) => ({
93
+ ...PREVIOUS_VALUE,
94
+ content: newContentValue,
95
+ }));
96
+ }
97
+
98
+ function showContentProps() {
99
+ return props.showContent
100
+ ? {}
101
+ : {
102
+ hidden: true,
103
+ "aria-hidden": true,
104
+ };
105
+ }
106
+
107
+ const [ContentWrapper, setContentWrapper] = useState(
108
+ () => props.contentWrapper || ScrollView
109
+ );
110
+
111
+ function processMessage(event: MessageEvent) {
112
+ return createEditorListener({
113
+ model: props.model,
114
+ trustedHosts: props.trustedHosts,
115
+ callbacks: {
116
+ configureSdk: (messageContent) => {
117
+ const { breakpoints, contentId } = messageContent;
118
+ if (
119
+ !contentId ||
120
+ contentId !== props.builderContextSignal.content?.id
121
+ ) {
122
+ return;
123
+ }
124
+ if (breakpoints) {
125
+ mergeNewContent({
126
+ meta: {
127
+ breakpoints,
128
+ },
129
+ });
130
+ }
131
+ },
132
+ animation: (animation) => {
133
+ triggerAnimation(animation);
134
+ },
135
+ contentUpdate: (newContent) => {
136
+ mergeNewContent(newContent);
137
+ },
138
+ },
139
+ })(event);
140
+ }
141
+
142
+ function evaluateJsCode() {
143
+ // run any dynamic JS code attached to content
144
+ const jsCode = props.builderContextSignal.content?.data?.jsCode;
145
+ if (jsCode) {
146
+ evaluate({
147
+ code: jsCode,
148
+ context: props.context || {},
149
+ localState: undefined,
150
+ rootState: props.builderContextSignal.rootState,
151
+ rootSetState: props.builderContextSignal.rootSetState,
152
+ /**
153
+ * We don't want to cache the result of the JS code, since it's arbitrary side effect code.
154
+ */
155
+ enableCache: false,
156
+ });
157
+ }
158
+ }
159
+
160
+ const [httpReqsData, setHttpReqsData] = useState(() => ({}));
161
+
162
+ const [httpReqsPending, setHttpReqsPending] = useState(() => ({}));
163
+
164
+ const [clicked, setClicked] = useState(() => false);
165
+
166
+ function onClick(event: any) {
167
+ if (props.builderContextSignal.content) {
168
+ const variationId = props.builderContextSignal.content?.testVariationId;
169
+ const contentId = props.builderContextSignal.content?.id;
170
+ _track({
171
+ type: "click",
172
+ canTrack: getDefaultCanTrack(props.canTrack),
173
+ contentId,
174
+ apiKey: props.apiKey,
175
+ variationId: variationId !== contentId ? variationId : undefined,
176
+ ...getInteractionPropertiesForEvent(event),
177
+ unique: !clicked,
178
+ });
179
+ }
180
+ if (!clicked) {
181
+ setClicked(true);
182
+ }
183
+ }
184
+
185
+ function runHttpRequests() {
186
+ const requests: {
187
+ [key: string]: string;
188
+ } = props.builderContextSignal.content?.data?.httpRequests ?? {};
189
+ Object.entries(requests).forEach(([key, url]) => {
190
+ if (!url) return;
191
+
192
+ // request already in progress
193
+ if (httpReqsPending[key]) return;
194
+
195
+ // request already completed, and not in edit mode
196
+ if (httpReqsData[key] && !isEditing()) return;
197
+ httpReqsPending[key] = true;
198
+ const evaluatedUrl = url.replace(/{{([^}]+)}}/g, (_match, group) =>
199
+ String(
200
+ evaluate({
201
+ code: group,
202
+ context: props.context || {},
203
+ localState: undefined,
204
+ rootState: props.builderContextSignal.rootState,
205
+ rootSetState: props.builderContextSignal.rootSetState,
206
+ enableCache: true,
207
+ })
208
+ )
209
+ );
210
+ fetch(evaluatedUrl)
211
+ .then((response) => response.json())
212
+ .then((json) => {
213
+ mergeNewRootState({
214
+ [key]: json,
215
+ });
216
+ httpReqsData[key] = true;
217
+ })
218
+ .catch((err) => {
219
+ console.error("error fetching dynamic data", url, err);
220
+ })
221
+ .finally(() => {
222
+ httpReqsPending[key] = false;
223
+ });
224
+ });
225
+ }
226
+
227
+ function emitStateUpdate() {
228
+ if (isEditing()) {
229
+ window.dispatchEvent(
230
+ new CustomEvent<BuilderComponentStateChange>(
231
+ "builder:component:stateChange",
232
+ {
233
+ detail: {
234
+ state: fastClone(props.builderContextSignal.rootState),
235
+ ref: {
236
+ name: props.model,
237
+ },
238
+ },
239
+ }
240
+ )
241
+ );
242
+ }
243
+ }
244
+
245
+ function elementRef_onIniteditingbldr(event) {
246
+ window.addEventListener("message", processMessage);
247
+ registerInsertMenu();
248
+ setupBrowserForEditing({
249
+ ...(props.locale
250
+ ? {
251
+ locale: props.locale,
252
+ }
253
+ : {}),
254
+ ...(props.enrich
255
+ ? {
256
+ enrich: props.enrich,
257
+ }
258
+ : {}),
259
+ ...(props.trustedHosts
260
+ ? {
261
+ trustedHosts: props.trustedHosts,
262
+ }
263
+ : {}),
264
+ });
265
+ Object.values<ComponentInfo>(
266
+ props.builderContextSignal.componentInfos
267
+ ).forEach((registeredComponent) => {
268
+ const message = createRegisterComponentMessage(registeredComponent);
269
+ window.parent?.postMessage(message, "*");
270
+ });
271
+ window.addEventListener(
272
+ "builder:component:stateChangeListenerActivated",
273
+ emitStateUpdate
274
+ );
275
+ }
276
+
277
+ function elementRef_onInitpreviewingbldr(event) {
278
+ const searchParams = new URL(location.href).searchParams;
279
+ const searchParamPreviewModel = searchParams.get("builder.preview");
280
+ const searchParamPreviewId = searchParams.get(
281
+ `builder.overrides.${searchParamPreviewModel}`
282
+ );
283
+ const previewApiKey =
284
+ searchParams.get("apiKey") || searchParams.get("builder.space");
285
+
286
+ /**
287
+ * Make sure that:
288
+ * - 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.
289
+ * - if there is content, that the preview ID is the same as that of the one we receive.
290
+ *
291
+ * TO-DO: should we only update the state when there is a change?
292
+ **/
293
+ if (
294
+ searchParamPreviewModel === props.model &&
295
+ previewApiKey === props.apiKey &&
296
+ (!props.content || searchParamPreviewId === props.content.id)
297
+ ) {
298
+ fetchOneEntry({
299
+ model: props.model,
300
+ apiKey: props.apiKey,
301
+ apiVersion: props.builderContextSignal.apiVersion,
302
+ }).then((content) => {
303
+ if (content) {
304
+ mergeNewContent(content);
305
+ }
306
+ });
307
+ }
308
+ }
309
+
310
+ useEffect(() => {
311
+ if (isBrowser()) {
312
+ if (isEditing()) {
313
+ window.addEventListener("message", processMessage);
314
+ registerInsertMenu();
315
+ setupBrowserForEditing({
316
+ ...(props.locale
317
+ ? {
318
+ locale: props.locale,
319
+ }
320
+ : {}),
321
+ ...(props.enrich
322
+ ? {
323
+ enrich: props.enrich,
324
+ }
325
+ : {}),
326
+ ...(props.trustedHosts
327
+ ? {
328
+ trustedHosts: props.trustedHosts,
329
+ }
330
+ : {}),
331
+ });
332
+ Object.values<ComponentInfo>(
333
+ props.builderContextSignal.componentInfos
334
+ ).forEach((registeredComponent) => {
335
+ const message = createRegisterComponentMessage(registeredComponent);
336
+ window.parent?.postMessage(message, "*");
337
+ });
338
+ window.addEventListener(
339
+ "builder:component:stateChangeListenerActivated",
340
+ emitStateUpdate
341
+ );
342
+ }
343
+ const shouldTrackImpression =
344
+ props.builderContextSignal.content &&
345
+ getDefaultCanTrack(props.canTrack);
346
+ if (shouldTrackImpression) {
347
+ const variationId = props.builderContextSignal.content?.testVariationId;
348
+ const contentId = props.builderContextSignal.content?.id;
349
+ const apiKeyProp = props.apiKey;
350
+ _track({
351
+ type: "impression",
352
+ canTrack: true,
353
+ contentId,
354
+ apiKey: apiKeyProp!,
355
+ variationId: variationId !== contentId ? variationId : undefined,
356
+ });
357
+ }
358
+
359
+ /**
360
+ * Override normal content in preview mode.
361
+ * We ignore this when editing, since the edited content is already being sent from the editor via post messages.
362
+ */
363
+ if (isPreviewing() && !isEditing()) {
364
+ const searchParams = new URL(location.href).searchParams;
365
+ const searchParamPreviewModel = searchParams.get("builder.preview");
366
+ const searchParamPreviewId = searchParams.get(
367
+ `builder.overrides.${searchParamPreviewModel}`
368
+ );
369
+ const previewApiKey =
370
+ searchParams.get("apiKey") || searchParams.get("builder.space");
371
+
372
+ /**
373
+ * Make sure that:
374
+ * - 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.
375
+ * - if there is content, that the preview ID is the same as that of the one we receive.
376
+ *
377
+ * TO-DO: should we only update the state when there is a change?
378
+ **/
379
+ if (
380
+ searchParamPreviewModel === props.model &&
381
+ previewApiKey === props.apiKey &&
382
+ (!props.content || searchParamPreviewId === props.content.id)
383
+ ) {
384
+ fetchOneEntry({
385
+ model: props.model,
386
+ apiKey: props.apiKey,
387
+ apiVersion: props.builderContextSignal.apiVersion,
388
+ }).then((content) => {
389
+ if (content) {
390
+ mergeNewContent(content);
391
+ }
392
+ });
393
+ }
394
+ }
395
+ }
396
+ }, []);
397
+ useEffect(() => {
398
+ if (!props.apiKey) {
399
+ logger.error(
400
+ "No API key provided to `Content` component. This can cause issues. Please provide an API key using the `apiKey` prop."
401
+ );
402
+ }
403
+ evaluateJsCode();
404
+ runHttpRequests();
405
+ emitStateUpdate();
406
+ }, []);
407
+
408
+ useEffect(() => {
409
+ if (props.content) {
410
+ mergeNewContent(props.content);
411
+ }
412
+ }, [props.content]);
413
+ useEffect(() => {
414
+ evaluateJsCode();
415
+ }, [props.builderContextSignal.content?.data?.jsCode]);
416
+ useEffect(() => {
417
+ runHttpRequests();
418
+ }, [props.builderContextSignal.content?.data?.httpRequests]);
419
+ useEffect(() => {
420
+ emitStateUpdate();
421
+ }, [props.builderContextSignal.rootState]);
422
+ useEffect(() => {
423
+ if (props.data) {
424
+ mergeNewRootState(props.data);
425
+ }
426
+ }, [props.data]);
427
+ useEffect(() => {
428
+ if (props.locale) {
429
+ mergeNewRootState({
430
+ locale: props.locale,
431
+ });
432
+ }
433
+ }, [props.locale]);
434
+
435
+ useEffect(() => {
436
+ return () => {
437
+ if (isBrowser()) {
438
+ window.removeEventListener("message", processMessage);
439
+ window.removeEventListener(
440
+ "builder:component:stateChangeListenerActivated",
441
+ emitStateUpdate
442
+ );
443
+ }
444
+ };
445
+ }, []);
446
+
447
+ return (
448
+ <builderContext.Provider value={props.builderContextSignal}>
449
+ {props.builderContextSignal.content ? (
450
+ <ContentWrapper
451
+ {...{}}
452
+ ref={elementRef}
453
+ onPress={(event) => onClick(event)}
454
+ builder-content-id={props.builderContextSignal.content?.id}
455
+ builder-model={props.model}
456
+ {...{
457
+ // 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.
458
+ dataSet: {
459
+ "builder-content-id": "",
460
+ },
461
+ }}
462
+ {...showContentProps()}
463
+ {...props.contentWrapperProps}
464
+ >
465
+ {props.children}
466
+ </ContentWrapper>
467
+ ) : null}
468
+ </builderContext.Provider>
469
+ );
470
+ }
471
+
472
+ export default EnableEditor;