@builder.io/sdk-react-native 0.1.11 → 0.1.13

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.
@@ -33,50 +33,75 @@ const render_blocks_1 = __importDefault(require("../../components/render-blocks"
33
33
  const device_sizes_1 = require("../../constants/device-sizes");
34
34
  const render_inlined_styles_1 = __importDefault(require("../../components/render-inlined-styles"));
35
35
  const target_js_1 = require("../../constants/target.js");
36
- const css_1 = require("../../helpers/css");
37
36
  const builder_context_js_1 = __importDefault(require("../../context/builder.context.js"));
38
37
  function Columns(props) {
39
38
  var _a;
40
- function getGutterSize() {
41
- return typeof props.space === "number" ? props.space || 0 : 20;
42
- }
43
- function getColumns() {
44
- return props.columns || [];
45
- }
39
+ const [gutterSize, setGutterSize] = (0, react_1.useState)(() => typeof props.space === "number" ? props.space || 0 : 20);
40
+ const [cols, setCols] = (0, react_1.useState)(() => props.columns || []);
41
+ const [stackAt, setStackAt] = (0, react_1.useState)(() => props.stackColumnsAt || "tablet");
46
42
  function getWidth(index) {
47
43
  var _a;
48
- const columns = getColumns();
49
- return ((_a = columns[index]) === null || _a === void 0 ? void 0 : _a.width) || 100 / columns.length;
44
+ return ((_a = cols[index]) === null || _a === void 0 ? void 0 : _a.width) || 100 / cols.length;
50
45
  }
51
46
  function getColumnCssWidth(index) {
52
- const columns = getColumns();
53
- const gutterSize = getGutterSize();
54
- const subtractWidth = (gutterSize * (columns.length - 1)) / columns.length;
47
+ const subtractWidth = (gutterSize * (cols.length - 1)) / cols.length;
55
48
  return `calc(${getWidth(index)}% - ${subtractWidth}px)`;
56
49
  }
57
- function maybeApplyForTablet(prop) {
58
- const _stackColumnsAt = props.stackColumnsAt || "tablet";
59
- return _stackColumnsAt === "tablet" ? prop : "inherit";
50
+ function getTabletStyle({ stackedStyle, desktopStyle }) {
51
+ return stackAt === "tablet" ? stackedStyle : desktopStyle;
60
52
  }
53
+ function getMobileStyle({ stackedStyle, desktopStyle }) {
54
+ return stackAt === "never" ? desktopStyle : stackedStyle;
55
+ }
56
+ const [flexDir, setFlexDir] = (0, react_1.useState)(() => props.stackColumnsAt === "never"
57
+ ? "row"
58
+ : props.reverseColumnsWhenStacked
59
+ ? "column-reverse"
60
+ : "column");
61
61
  function columnsCssVars() {
62
- const flexDir = props.stackColumnsAt === "never"
63
- ? "inherit"
64
- : props.reverseColumnsWhenStacked
65
- ? "column-reverse"
66
- : "column";
62
+ if (target_js_1.TARGET === "reactNative") {
63
+ return {
64
+ flexDirection: flexDir,
65
+ };
66
+ }
67
67
  return {
68
68
  "--flex-dir": flexDir,
69
- "--flex-dir-tablet": maybeApplyForTablet(flexDir),
69
+ "--flex-dir-tablet": getTabletStyle({
70
+ stackedStyle: flexDir,
71
+ desktopStyle: "row",
72
+ }),
70
73
  };
71
74
  }
72
- function columnCssVars() {
73
- const width = "100%";
74
- const marginLeft = "0";
75
+ function columnCssVars(index) {
76
+ const width = getColumnCssWidth(index);
77
+ const gutter = `${index === 0 ? 0 : gutterSize}px`;
78
+ if (target_js_1.TARGET === "reactNative") {
79
+ return {
80
+ width,
81
+ marginLeft: props.stackColumnsAt === "never" ? gutter : "0",
82
+ };
83
+ }
84
+ const mobileWidth = "100%";
85
+ const mobileMarginLeft = "0";
75
86
  return {
76
- "--column-width": width,
77
- "--column-margin-left": marginLeft,
78
- "--column-width-tablet": maybeApplyForTablet(width),
79
- "--column-margin-left-tablet": maybeApplyForTablet(marginLeft),
87
+ width,
88
+ "margin-left": gutter,
89
+ "--column-width-mobile": getMobileStyle({
90
+ stackedStyle: mobileWidth,
91
+ desktopStyle: width,
92
+ }),
93
+ "--column-margin-left-mobile": getMobileStyle({
94
+ stackedStyle: mobileMarginLeft,
95
+ desktopStyle: gutter,
96
+ }),
97
+ "--column-width-tablet": getTabletStyle({
98
+ stackedStyle: mobileWidth,
99
+ desktopStyle: width,
100
+ }),
101
+ "--column-margin-left-tablet": getTabletStyle({
102
+ stackedStyle: mobileMarginLeft,
103
+ desktopStyle: gutter,
104
+ }),
80
105
  };
81
106
  }
82
107
  function getWidthForBreakpointSize(size) {
@@ -84,64 +109,42 @@ function Columns(props) {
84
109
  const breakpointSizes = (0, device_sizes_1.getSizesForBreakpoints)(((_b = (_a = builderContext.content) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.breakpoints) || {});
85
110
  return breakpointSizes[size].max;
86
111
  }
87
- function columnStyleObjects() {
88
- return {
89
- columns: {
90
- small: {
91
- flexDirection: "var(--flex-dir)",
92
- alignItems: "stretch",
93
- },
94
- medium: {
95
- flexDirection: "var(--flex-dir-tablet)",
96
- alignItems: "stretch",
97
- },
98
- },
99
- column: {
100
- small: {
101
- width: "var(--column-width) !important",
102
- marginLeft: "var(--column-margin-left) !important",
103
- },
104
- medium: {
105
- width: "var(--column-width-tablet) !important",
106
- marginLeft: "var(--column-margin-left-tablet) !important",
107
- },
108
- },
109
- };
110
- }
111
112
  function columnsStyles() {
112
113
  return `
113
114
  @media (max-width: ${getWidthForBreakpointSize("medium")}px) {
114
115
  .${props.builderBlock.id}-breakpoints {
115
- ${(0, css_1.convertStyleMapToCSS)(columnStyleObjects().columns.medium)}
116
+ flex-direction: var(--flex-dir-tablet);
117
+ align-items: stretch;
116
118
  }
117
119
 
118
120
  .${props.builderBlock.id}-breakpoints > .builder-column {
119
- ${(0, css_1.convertStyleMapToCSS)(columnStyleObjects().column.medium)}
121
+ width: var(--column-width-tablet) !important;
122
+ margin-left: var(--column-margin-left-tablet) !important;
120
123
  }
121
124
  }
122
125
 
123
126
  @media (max-width: ${getWidthForBreakpointSize("small")}px) {
124
127
  .${props.builderBlock.id}-breakpoints {
125
- ${(0, css_1.convertStyleMapToCSS)(columnStyleObjects().columns.small)}
128
+ flex-direction: var(--flex-dir);
129
+ align-items: stretch;
126
130
  }
127
131
 
128
132
  .${props.builderBlock.id}-breakpoints > .builder-column {
129
- ${(0, css_1.convertStyleMapToCSS)(columnStyleObjects().column.small)}
133
+ width: var(--column-width-mobile) !important;
134
+ margin-left: var(--column-margin-left-mobile) !important;
130
135
  }
131
136
  },
132
137
  `;
133
138
  }
134
- function reactNativeColumnsStyles() {
135
- return columnStyleObjects.columns.small;
136
- }
137
- function reactNativeColumnStyles() {
138
- return columnStyleObjects.column.small;
139
- }
140
139
  const builderContext = (0, react_1.useContext)(builder_context_js_1.default);
141
- return (React.createElement(react_native_1.View, { style: styles.view1 },
140
+ return (React.createElement(react_native_1.View, { style: columnsCssVars(), dataSet: {
141
+ "builder-block-name": "builder-columns",
142
+ } },
142
143
  target_js_1.TARGET !== "reactNative" ? (React.createElement(React.Fragment, null,
143
144
  React.createElement(render_inlined_styles_1.default, { styles: columnsStyles() }))) : null, (_a = props.columns) === null || _a === void 0 ? void 0 :
144
- _a.map((column, index) => (React.createElement(react_native_1.View, { style: styles.view2, key: index },
145
+ _a.map((column, index) => (React.createElement(react_native_1.View, { style: columnCssVars(index), dataSet: {
146
+ "builder-block-name": "builder-column",
147
+ }, key: index },
145
148
  React.createElement(render_blocks_1.default, { blocks: column.blocks, path: `component.options.columns.${index}.blocks`, parent: props.builderBlock.id, styleProp: {
146
149
  flexGrow: "1",
147
150
  } }))))));
@@ -34,8 +34,8 @@ const builder_context_js_1 = __importDefault(require("../../context/builder.cont
34
34
  const index_js_1 = require("../../functions/get-content/index.js");
35
35
  const target_1 = require("../../constants/target");
36
36
  function Symbol(props) {
37
- var _a, _b, _c, _d, _e;
38
- function className() {
37
+ var _a, _b, _c;
38
+ const [className, setClassName] = (0, react_1.useState)(() => {
39
39
  var _a, _b;
40
40
  return [
41
41
  ...(target_1.TARGET === "vue2" || target_1.TARGET === "vue3"
@@ -49,15 +49,10 @@ function Symbol(props) {
49
49
  ]
50
50
  .filter(Boolean)
51
51
  .join(" ");
52
- }
53
- const [fetchedContent, setFetchedContent] = (0, react_1.useState)(() => null);
54
- function contentToUse() {
52
+ });
53
+ const [contentToUse, setContentToUse] = (0, react_1.useState)(() => { var _a; return (_a = props.symbol) === null || _a === void 0 ? void 0 : _a.content; });
54
+ function fetchContent() {
55
55
  var _a;
56
- return ((_a = props.symbol) === null || _a === void 0 ? void 0 : _a.content) || fetchedContent;
57
- }
58
- const builderContext = (0, react_1.useContext)(builder_context_js_1.default);
59
- (0, react_1.useEffect)(() => {
60
- const symbolToUse = props.symbol;
61
56
  /**
62
57
  * If:
63
58
  * - we have a symbol prop
@@ -67,31 +62,43 @@ function Symbol(props) {
67
62
  *
68
63
  * then we want to re-fetch the symbol content.
69
64
  */
70
- if (symbolToUse &&
71
- !symbolToUse.content &&
72
- !fetchedContent &&
73
- symbolToUse.model &&
65
+ if (!contentToUse &&
66
+ ((_a = props.symbol) === null || _a === void 0 ? void 0 : _a.model) &&
74
67
  (
75
68
  // This is a hack, we should not need to check for this, but it is needed for Svelte.
76
69
  builderContext === null || builderContext === void 0 ? void 0 : builderContext.apiKey)) {
77
70
  (0, index_js_1.getContent)({
78
- model: symbolToUse.model,
71
+ model: props.symbol.model,
79
72
  apiKey: builderContext.apiKey,
73
+ apiVersion: builderContext.apiVersion,
80
74
  query: {
81
- id: symbolToUse.entry,
75
+ id: props.symbol.entry,
82
76
  },
83
- }).then((response) => {
84
- setFetchedContent(response);
77
+ })
78
+ .then((response) => {
79
+ if (response) {
80
+ setContentToUse(response);
81
+ }
82
+ })
83
+ .catch((err) => {
84
+ console.error("[Builder.io]: Could not fetch symbol content: ", err);
85
85
  });
86
86
  }
87
- }, [props.symbol, fetchedContent]);
87
+ }
88
+ const builderContext = (0, react_1.useContext)(builder_context_js_1.default);
89
+ (0, react_1.useEffect)(() => {
90
+ fetchContent();
91
+ }, []);
92
+ (0, react_1.useEffect)(() => {
93
+ fetchContent();
94
+ }, [props.symbol]);
88
95
  return (React.createElement(react_native_1.View, { ...props.attributes, dataSet: {
89
- class: className(),
96
+ class: className,
90
97
  } },
91
- React.createElement(render_content_1.default, { apiKey: builderContext.apiKey, context: builderContext.context, customComponents: Object.values(builderContext.registeredComponents), data: {
98
+ React.createElement(render_content_1.default, { apiVersion: builderContext.apiVersion, apiKey: builderContext.apiKey, context: builderContext.context, customComponents: Object.values(builderContext.registeredComponents), data: {
92
99
  ...(_a = props.symbol) === null || _a === void 0 ? void 0 : _a.data,
93
100
  ...builderContext.state,
94
- ...(_d = (_c = (_b = props.symbol) === null || _b === void 0 ? void 0 : _b.content) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.state,
95
- }, model: (_e = props.symbol) === null || _e === void 0 ? void 0 : _e.model, content: contentToUse() })));
101
+ ...(_b = contentToUse === null || contentToUse === void 0 ? void 0 : contentToUse.data) === null || _b === void 0 ? void 0 : _b.state,
102
+ }, model: (_c = props.symbol) === null || _c === void 0 ? void 0 : _c.model, content: contentToUse })));
96
103
  }
97
104
  exports.default = Symbol;
@@ -66,7 +66,7 @@ function RenderBlocks(props) {
66
66
  const builderContext = (0, react_1.useContext)(builder_context_js_1.default);
67
67
  return (React.createElement(react_native_1.ScrollView, { "builder-path": props.path, "builder-parent-id": props.parent, dataSet: {
68
68
  class: className(),
69
- }, contentContainerStyle: styles.scrollView1, onClick: (event) => onClick(), onMouseEnter: (event) => onMouseEnter() },
69
+ }, contentContainerStyle: props.styleProp, onClick: (event) => onClick(), onMouseEnter: (event) => onMouseEnter() },
70
70
  props.blocks ? (React.createElement(React.Fragment, null, (_a = props.blocks) === null || _a === void 0 ? void 0 : _a.map((block) => (React.createElement(render_block_1.default, { key: "render-block-" + block.id, block: block, context: builderContext }))))) : null,
71
71
  props.blocks ? (React.createElement(React.Fragment, null, (_b = props.blocks) === null || _b === void 0 ? void 0 : _b.map((block) => (React.createElement(block_styles_1.default, { key: "block-style-" + block.id, block: block, context: builderContext }))))) : null));
72
72
  }
@@ -275,6 +275,7 @@ function RenderContent(props) {
275
275
  (0, index_js_1.getContent)({
276
276
  model: props.model,
277
277
  apiKey: props.apiKey,
278
+ apiVersion: props.apiVersion,
278
279
  }).then((content) => {
279
280
  if (content) {
280
281
  mergeNewContent(content);
@@ -287,6 +288,11 @@ function RenderContent(props) {
287
288
  emitStateUpdate();
288
289
  }
289
290
  }, []);
291
+ (0, react_1.useEffect)(() => {
292
+ if (props.content) {
293
+ mergeNewContent(props.content);
294
+ }
295
+ }, [props.content]);
290
296
  (0, react_1.useEffect)(() => {
291
297
  evaluateJsCode();
292
298
  }, [(_a = useContent === null || useContent === void 0 ? void 0 : useContent.data) === null || _a === void 0 ? void 0 : _a.jsCode, contentState]);
@@ -310,6 +316,7 @@ function RenderContent(props) {
310
316
  setState: setContextState,
311
317
  context: props.context || {},
312
318
  apiKey: props.apiKey,
319
+ apiVersion: props.apiVersion,
313
320
  registeredComponents: allRegisteredComponents,
314
321
  } }, useContent ? (React.createElement(React.Fragment, null,
315
322
  React.createElement(react_native_1.ScrollView, { ref: elementRef, onClick: (event) => onClick(event), "builder-content-id": useContent === null || useContent === void 0 ? void 0 : useContent.id, "builder-model": props.model },
@@ -9,6 +9,7 @@ var stdin_default = (0, react_1.createContext)({
9
9
  setState() {
10
10
  },
11
11
  apiKey: null,
12
+ apiVersion: void 0,
12
13
  registeredComponents: {},
13
14
  inheritedStyles: {}
14
15
  });
@@ -20,11 +20,14 @@ var __spreadValues = (a, b) => {
20
20
  const flatten_js_1 = require("../../helpers/flatten.js");
21
21
  const index_js_1 = require("../get-builder-search-params/index.js");
22
22
  const generateContentUrl = (options) => {
23
- const { limit = 30, userAttributes, query, noTraverse = false, model, apiKey, includeRefs = true, locale } = options;
23
+ const { limit = 30, userAttributes, query, noTraverse = false, model, apiKey, includeRefs = true, locale, apiVersion = "v2" } = options;
24
24
  if (!apiKey) {
25
25
  throw new Error("Missing API key");
26
26
  }
27
- const url = new URL(`https://cdn.builder.io/api/v2/content/${model}?apiKey=${apiKey}&limit=${limit}&noTraverse=${noTraverse}&includeRefs=${includeRefs}${locale ? `&locale=${locale}` : ""}`);
27
+ if (!["v2", "v3"].includes(apiVersion)) {
28
+ throw new Error(`Invalid apiVersion: expected 'v2' or 'v3', received '${apiVersion}'`);
29
+ }
30
+ const url = new URL(`https://cdn.builder.io/api/${apiVersion}/content/${model}?apiKey=${apiKey}&limit=${limit}&noTraverse=${noTraverse}&includeRefs=${includeRefs}${locale ? `&locale=${locale}` : ""}`);
28
31
  const queryOptions = __spreadValues(__spreadValues({}, (0, index_js_1.getBuilderSearchParamsFromWindow)()), (0, index_js_1.normalizeSearchParams)(options.options || {}));
29
32
  const flattened = (0, flatten_js_1.flatten)(queryOptions);
30
33
  for (const key in flattened) {
@@ -30,4 +30,46 @@ describe("Generate Content URL", () => {
30
30
  });
31
31
  expect(output).toMatchSnapshot();
32
32
  });
33
+ test("generate content url with apiVersion as v2", () => {
34
+ const output = (0, generate_content_url_1.generateContentUrl)({
35
+ apiKey: testKey,
36
+ model: testModel,
37
+ query: { id: testId },
38
+ options,
39
+ apiVersion: "v2"
40
+ });
41
+ expect(output).toMatchSnapshot();
42
+ });
43
+ test("generate content url with apiVersion as v3", () => {
44
+ const output = (0, generate_content_url_1.generateContentUrl)({
45
+ apiKey: testKey,
46
+ model: testModel,
47
+ query: { id: testId },
48
+ options,
49
+ apiVersion: "v3"
50
+ });
51
+ expect(output).toMatchSnapshot();
52
+ });
53
+ test("throw error when trying to generate content url with apiVersion as v1", () => {
54
+ expect(() => {
55
+ (0, generate_content_url_1.generateContentUrl)({
56
+ apiKey: testKey,
57
+ model: testModel,
58
+ query: { id: testId },
59
+ options,
60
+ apiVersion: "v1"
61
+ });
62
+ }).toThrow(`Invalid apiVersion: expected 'v2' or 'v3', received 'v1'`);
63
+ });
64
+ test("throw error when trying to generate content url with an invalid apiVersion value", () => {
65
+ expect(() => {
66
+ (0, generate_content_url_1.generateContentUrl)({
67
+ apiKey: testKey,
68
+ model: testModel,
69
+ query: { id: testId },
70
+ options,
71
+ apiVersion: "INVALID_API_VERSION"
72
+ });
73
+ }).toThrow(`Invalid apiVersion: expected 'v2' or 'v3', received 'INVALID_API_VERSION'`);
74
+ });
33
75
  });
@@ -0,0 +1 @@
1
+ "use strict";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@builder.io/sdk-react-native",
3
3
  "description": "Builder.io SDK for React Native",
4
- "version": "0.1.11",
4
+ "version": "0.1.13",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -7,61 +7,94 @@ import {
7
7
  Image,
8
8
  Text,
9
9
  } from "react-native";
10
- import { useContext } from "react";
10
+ import { useState, useContext } from "react";
11
11
  import RenderBlocks from "../../components/render-blocks";
12
12
  import { getSizesForBreakpoints } from "../../constants/device-sizes";
13
13
  import RenderInlinedStyles from "../../components/render-inlined-styles";
14
14
  import { TARGET } from "../../constants/target.js";
15
- import { convertStyleMapToCSS } from "../../helpers/css";
16
15
  import BuilderContext from "../../context/builder.context.js";
17
16
 
18
17
  function Columns(props) {
19
- function getGutterSize() {
20
- return typeof props.space === "number" ? props.space || 0 : 20;
21
- }
18
+ const [gutterSize, setGutterSize] = useState(() =>
19
+ typeof props.space === "number" ? props.space || 0 : 20
20
+ );
22
21
 
23
- function getColumns() {
24
- return props.columns || [];
25
- }
22
+ const [cols, setCols] = useState(() => props.columns || []);
23
+
24
+ const [stackAt, setStackAt] = useState(
25
+ () => props.stackColumnsAt || "tablet"
26
+ );
26
27
 
27
28
  function getWidth(index) {
28
- const columns = getColumns();
29
- return columns[index]?.width || 100 / columns.length;
29
+ return cols[index]?.width || 100 / cols.length;
30
30
  }
31
31
 
32
32
  function getColumnCssWidth(index) {
33
- const columns = getColumns();
34
- const gutterSize = getGutterSize();
35
- const subtractWidth = (gutterSize * (columns.length - 1)) / columns.length;
33
+ const subtractWidth = (gutterSize * (cols.length - 1)) / cols.length;
36
34
  return `calc(${getWidth(index)}% - ${subtractWidth}px)`;
37
35
  }
38
36
 
39
- function maybeApplyForTablet(prop) {
40
- const _stackColumnsAt = props.stackColumnsAt || "tablet";
41
- return _stackColumnsAt === "tablet" ? prop : "inherit";
37
+ function getTabletStyle({ stackedStyle, desktopStyle }) {
38
+ return stackAt === "tablet" ? stackedStyle : desktopStyle;
42
39
  }
43
40
 
41
+ function getMobileStyle({ stackedStyle, desktopStyle }) {
42
+ return stackAt === "never" ? desktopStyle : stackedStyle;
43
+ }
44
+
45
+ const [flexDir, setFlexDir] = useState(() =>
46
+ props.stackColumnsAt === "never"
47
+ ? "row"
48
+ : props.reverseColumnsWhenStacked
49
+ ? "column-reverse"
50
+ : "column"
51
+ );
52
+
44
53
  function columnsCssVars() {
45
- const flexDir =
46
- props.stackColumnsAt === "never"
47
- ? "inherit"
48
- : props.reverseColumnsWhenStacked
49
- ? "column-reverse"
50
- : "column";
54
+ if (TARGET === "reactNative") {
55
+ return {
56
+ flexDirection: flexDir,
57
+ };
58
+ }
51
59
  return {
52
60
  "--flex-dir": flexDir,
53
- "--flex-dir-tablet": maybeApplyForTablet(flexDir),
61
+ "--flex-dir-tablet": getTabletStyle({
62
+ stackedStyle: flexDir,
63
+ desktopStyle: "row",
64
+ }),
54
65
  };
55
66
  }
56
67
 
57
- function columnCssVars() {
58
- const width = "100%";
59
- const marginLeft = "0";
68
+ function columnCssVars(index) {
69
+ const width = getColumnCssWidth(index);
70
+ const gutter = `${index === 0 ? 0 : gutterSize}px`;
71
+ if (TARGET === "reactNative") {
72
+ return {
73
+ width,
74
+ marginLeft: props.stackColumnsAt === "never" ? gutter : "0",
75
+ };
76
+ }
77
+ const mobileWidth = "100%";
78
+ const mobileMarginLeft = "0";
60
79
  return {
61
- "--column-width": width,
62
- "--column-margin-left": marginLeft,
63
- "--column-width-tablet": maybeApplyForTablet(width),
64
- "--column-margin-left-tablet": maybeApplyForTablet(marginLeft),
80
+ width,
81
+ "margin-left": gutter,
82
+ "--column-width-mobile": getMobileStyle({
83
+ stackedStyle: mobileWidth,
84
+ desktopStyle: width,
85
+ }),
86
+ "--column-margin-left-mobile": getMobileStyle({
87
+ stackedStyle: mobileMarginLeft,
88
+ desktopStyle: gutter,
89
+ }),
90
+ "--column-width-tablet": getTabletStyle({
91
+ stackedStyle: mobileWidth,
92
+ desktopStyle: width,
93
+ }),
94
+ "--column-margin-left-tablet": getTabletStyle({
95
+ stackedStyle: mobileMarginLeft,
96
+ desktopStyle: gutter,
97
+ }),
65
98
  };
66
99
  }
67
100
 
@@ -72,67 +105,43 @@ function Columns(props) {
72
105
  return breakpointSizes[size].max;
73
106
  }
74
107
 
75
- function columnStyleObjects() {
76
- return {
77
- columns: {
78
- small: {
79
- flexDirection: "var(--flex-dir)",
80
- alignItems: "stretch",
81
- },
82
- medium: {
83
- flexDirection: "var(--flex-dir-tablet)",
84
- alignItems: "stretch",
85
- },
86
- },
87
- column: {
88
- small: {
89
- width: "var(--column-width) !important",
90
- marginLeft: "var(--column-margin-left) !important",
91
- },
92
- medium: {
93
- width: "var(--column-width-tablet) !important",
94
- marginLeft: "var(--column-margin-left-tablet) !important",
95
- },
96
- },
97
- };
98
- }
99
-
100
108
  function columnsStyles() {
101
109
  return `
102
110
  @media (max-width: ${getWidthForBreakpointSize("medium")}px) {
103
111
  .${props.builderBlock.id}-breakpoints {
104
- ${convertStyleMapToCSS(columnStyleObjects().columns.medium)}
112
+ flex-direction: var(--flex-dir-tablet);
113
+ align-items: stretch;
105
114
  }
106
115
 
107
116
  .${props.builderBlock.id}-breakpoints > .builder-column {
108
- ${convertStyleMapToCSS(columnStyleObjects().column.medium)}
117
+ width: var(--column-width-tablet) !important;
118
+ margin-left: var(--column-margin-left-tablet) !important;
109
119
  }
110
120
  }
111
121
 
112
122
  @media (max-width: ${getWidthForBreakpointSize("small")}px) {
113
123
  .${props.builderBlock.id}-breakpoints {
114
- ${convertStyleMapToCSS(columnStyleObjects().columns.small)}
124
+ flex-direction: var(--flex-dir);
125
+ align-items: stretch;
115
126
  }
116
127
 
117
128
  .${props.builderBlock.id}-breakpoints > .builder-column {
118
- ${convertStyleMapToCSS(columnStyleObjects().column.small)}
129
+ width: var(--column-width-mobile) !important;
130
+ margin-left: var(--column-margin-left-mobile) !important;
119
131
  }
120
132
  },
121
133
  `;
122
134
  }
123
135
 
124
- function reactNativeColumnsStyles() {
125
- return columnStyleObjects.columns.small;
126
- }
127
-
128
- function reactNativeColumnStyles() {
129
- return columnStyleObjects.column.small;
130
- }
131
-
132
136
  const builderContext = useContext(BuilderContext);
133
137
 
134
138
  return (
135
- <View style={styles.view1}>
139
+ <View
140
+ style={columnsCssVars()}
141
+ dataSet={{
142
+ "builder-block-name": "builder-columns",
143
+ }}
144
+ >
136
145
  {TARGET !== "reactNative" ? (
137
146
  <>
138
147
  <RenderInlinedStyles styles={columnsStyles()} />
@@ -140,7 +149,13 @@ function Columns(props) {
140
149
  ) : null}
141
150
 
142
151
  {props.columns?.map((column, index) => (
143
- <View style={styles.view2} key={index}>
152
+ <View
153
+ style={columnCssVars(index)}
154
+ dataSet={{
155
+ "builder-block-name": "builder-column",
156
+ }}
157
+ key={index}
158
+ >
144
159
  <RenderBlocks
145
160
  blocks={column.blocks}
146
161
  path={`component.options.columns.${index}.blocks`}
@@ -14,8 +14,8 @@ import { getContent } from "../../functions/get-content/index.js";
14
14
  import { TARGET } from "../../constants/target";
15
15
 
16
16
  function Symbol(props) {
17
- function className() {
18
- return [
17
+ const [className, setClassName] = useState(() =>
18
+ [
19
19
  ...(TARGET === "vue2" || TARGET === "vue3"
20
20
  ? Object.keys(props.attributes.class)
21
21
  : [props.attributes.class]),
@@ -26,20 +26,12 @@ function Symbol(props) {
26
26
  : undefined,
27
27
  ]
28
28
  .filter(Boolean)
29
- .join(" ");
30
- }
31
-
32
- const [fetchedContent, setFetchedContent] = useState(() => null);
33
-
34
- function contentToUse() {
35
- return props.symbol?.content || fetchedContent;
36
- }
37
-
38
- const builderContext = useContext(BuilderContext);
29
+ .join(" ")
30
+ );
39
31
 
40
- useEffect(() => {
41
- const symbolToUse = props.symbol;
32
+ const [contentToUse, setContentToUse] = useState(() => props.symbol?.content);
42
33
 
34
+ function fetchContent() {
43
35
  /**
44
36
  * If:
45
37
  * - we have a symbol prop
@@ -50,43 +42,59 @@ function Symbol(props) {
50
42
  * then we want to re-fetch the symbol content.
51
43
  */
52
44
  if (
53
- symbolToUse &&
54
- !symbolToUse.content &&
55
- !fetchedContent &&
56
- symbolToUse.model &&
45
+ !contentToUse &&
46
+ props.symbol?.model &&
57
47
  // This is a hack, we should not need to check for this, but it is needed for Svelte.
58
48
  builderContext?.apiKey
59
49
  ) {
60
50
  getContent({
61
- model: symbolToUse.model,
51
+ model: props.symbol.model,
62
52
  apiKey: builderContext.apiKey,
53
+ apiVersion: builderContext.apiVersion,
63
54
  query: {
64
- id: symbolToUse.entry,
55
+ id: props.symbol.entry,
65
56
  },
66
- }).then((response) => {
67
- setFetchedContent(response);
68
- });
57
+ })
58
+ .then((response) => {
59
+ if (response) {
60
+ setContentToUse(response);
61
+ }
62
+ })
63
+ .catch((err) => {
64
+ console.error("[Builder.io]: Could not fetch symbol content: ", err);
65
+ });
69
66
  }
70
- }, [props.symbol, fetchedContent]);
67
+ }
68
+
69
+ const builderContext = useContext(BuilderContext);
70
+
71
+ useEffect(() => {
72
+ fetchContent();
73
+ }, []);
74
+
75
+ useEffect(() => {
76
+ fetchContent();
77
+ }, [props.symbol]);
71
78
 
72
79
  return (
73
80
  <View
74
81
  {...props.attributes}
75
82
  dataSet={{
76
- class: className(),
83
+ class: className,
77
84
  }}
78
85
  >
79
86
  <RenderContent
87
+ apiVersion={builderContext.apiVersion}
80
88
  apiKey={builderContext.apiKey}
81
89
  context={builderContext.context}
82
90
  customComponents={Object.values(builderContext.registeredComponents)}
83
91
  data={{
84
92
  ...props.symbol?.data,
85
93
  ...builderContext.state,
86
- ...props.symbol?.content?.data?.state,
94
+ ...contentToUse?.data?.state,
87
95
  }}
88
96
  model={props.symbol?.model}
89
- content={contentToUse()}
97
+ content={contentToUse}
90
98
  />
91
99
  </View>
92
100
  );
@@ -57,7 +57,7 @@ function RenderBlocks(props) {
57
57
  dataSet={{
58
58
  class: className(),
59
59
  }}
60
- contentContainerStyle={styles.scrollView1}
60
+ contentContainerStyle={props.styleProp}
61
61
  onClick={(event) => onClick()}
62
62
  onMouseEnter={(event) => onMouseEnter()}
63
63
  >
@@ -308,6 +308,7 @@ function RenderContent(props) {
308
308
  getContent({
309
309
  model: props.model,
310
310
  apiKey: props.apiKey,
311
+ apiVersion: props.apiVersion,
311
312
  }).then((content) => {
312
313
  if (content) {
313
314
  mergeNewContent(content);
@@ -321,6 +322,11 @@ function RenderContent(props) {
321
322
  }
322
323
  }, []);
323
324
 
325
+ useEffect(() => {
326
+ if (props.content) {
327
+ mergeNewContent(props.content);
328
+ }
329
+ }, [props.content]);
324
330
  useEffect(() => {
325
331
  evaluateJsCode();
326
332
  }, [useContent?.data?.jsCode, contentState]);
@@ -351,6 +357,7 @@ function RenderContent(props) {
351
357
  setState: setContextState,
352
358
  context: props.context || {},
353
359
  apiKey: props.apiKey,
360
+ apiVersion: props.apiVersion,
354
361
  registeredComponents: allRegisteredComponents,
355
362
  }}
356
363
  >
@@ -6,6 +6,7 @@ var stdin_default = createContext({
6
6
  setState() {
7
7
  },
8
8
  apiKey: null,
9
+ apiVersion: void 0,
9
10
  registeredComponents: {},
10
11
  inheritedStyles: {}
11
12
  });
@@ -28,12 +28,16 @@ const generateContentUrl = (options) => {
28
28
  model,
29
29
  apiKey,
30
30
  includeRefs = true,
31
- locale
31
+ locale,
32
+ apiVersion = "v2"
32
33
  } = options;
33
34
  if (!apiKey) {
34
35
  throw new Error("Missing API key");
35
36
  }
36
- const url = new URL(`https://cdn.builder.io/api/v2/content/${model}?apiKey=${apiKey}&limit=${limit}&noTraverse=${noTraverse}&includeRefs=${includeRefs}${locale ? `&locale=${locale}` : ""}`);
37
+ if (!["v2", "v3"].includes(apiVersion)) {
38
+ throw new Error(`Invalid apiVersion: expected 'v2' or 'v3', received '${apiVersion}'`);
39
+ }
40
+ const url = new URL(`https://cdn.builder.io/api/${apiVersion}/content/${model}?apiKey=${apiKey}&limit=${limit}&noTraverse=${noTraverse}&includeRefs=${includeRefs}${locale ? `&locale=${locale}` : ""}`);
37
41
  const queryOptions = __spreadValues(__spreadValues({}, getBuilderSearchParamsFromWindow()), normalizeSearchParams(options.options || {}));
38
42
  const flattened = flatten(queryOptions);
39
43
  for (const key in flattened) {
@@ -28,4 +28,46 @@ describe("Generate Content URL", () => {
28
28
  });
29
29
  expect(output).toMatchSnapshot();
30
30
  });
31
+ test("generate content url with apiVersion as v2", () => {
32
+ const output = generateContentUrl({
33
+ apiKey: testKey,
34
+ model: testModel,
35
+ query: { id: testId },
36
+ options,
37
+ apiVersion: "v2"
38
+ });
39
+ expect(output).toMatchSnapshot();
40
+ });
41
+ test("generate content url with apiVersion as v3", () => {
42
+ const output = generateContentUrl({
43
+ apiKey: testKey,
44
+ model: testModel,
45
+ query: { id: testId },
46
+ options,
47
+ apiVersion: "v3"
48
+ });
49
+ expect(output).toMatchSnapshot();
50
+ });
51
+ test("throw error when trying to generate content url with apiVersion as v1", () => {
52
+ expect(() => {
53
+ generateContentUrl({
54
+ apiKey: testKey,
55
+ model: testModel,
56
+ query: { id: testId },
57
+ options,
58
+ apiVersion: "v1"
59
+ });
60
+ }).toThrow(`Invalid apiVersion: expected 'v2' or 'v3', received 'v1'`);
61
+ });
62
+ test("throw error when trying to generate content url with an invalid apiVersion value", () => {
63
+ expect(() => {
64
+ generateContentUrl({
65
+ apiKey: testKey,
66
+ model: testModel,
67
+ query: { id: testId },
68
+ options,
69
+ apiVersion: "INVALID_API_VERSION"
70
+ });
71
+ }).toThrow(`Invalid apiVersion: expected 'v2' or 'v3', received 'INVALID_API_VERSION'`);
72
+ });
31
73
  });
File without changes