@builder.io/sdk-svelte 0.0.9 → 0.0.10-0

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@builder.io/sdk-svelte",
3
3
  "description": "Builder.io SDK for Svelte",
4
- "version": "0.0.9-3",
4
+ "version": "0.0.9",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "package",
@@ -117,6 +117,7 @@
117
117
  "./functions/set.test": "./functions/set.test.js",
118
118
  "./functions/set": "./functions/set.js",
119
119
  "./functions/track": "./functions/track.js",
120
+ "./functions/transform-block-properties": "./functions/transform-block-properties.js",
120
121
  "./functions/transform-block": "./functions/transform-block.js",
121
122
  "./helpers/ab-tests": "./helpers/ab-tests.js",
122
123
  "./helpers/cookie": "./helpers/cookie.js",
@@ -1,10 +1,15 @@
1
1
  <script context="module"></script>
2
2
 
3
3
  <script>import RenderBlocks from "../../components/render-blocks.svelte";
4
+ import { getSizesForBreakpoints } from "../../constants/device-sizes";
5
+ import RenderInlinedStyles from "../../components/render-inlined-styles.svelte";
6
+ import { TARGET } from "../../constants/target.js";
7
+ import { convertStyleMapToCSS } from "../../helpers/css";
4
8
  export let space;
5
9
  export let columns;
6
10
  export let stackColumnsAt;
7
11
  export let reverseColumnsWhenStacked;
12
+ export let customBreakpoints;
8
13
  export let builderBlock;
9
14
  function mitosis_styling(node, vars) {
10
15
  Object.entries(vars || {}).forEach(([p, v]) => {
@@ -36,6 +41,10 @@ function maybeApplyForTablet(prop) {
36
41
  const _stackColumnsAt = stackColumnsAt || "tablet";
37
42
  return _stackColumnsAt === "tablet" ? prop : "inherit";
38
43
  }
44
+ function getWidthForBreakpointSize(size) {
45
+ const breakpointSizes = getSizesForBreakpoints(customBreakpoints || {});
46
+ return breakpointSizes[size].max;
47
+ }
39
48
  $: columnsCssVars = () => {
40
49
  const flexDir = stackColumnsAt === "never"
41
50
  ? "inherit"
@@ -57,14 +66,78 @@ $: columnCssVars = () => {
57
66
  "--column-margin-left-tablet": maybeApplyForTablet(marginLeft),
58
67
  };
59
68
  };
69
+ $: columnStyleObjects = () => {
70
+ return {
71
+ columns: {
72
+ small: {
73
+ flexDirection: "var(--flex-dir)",
74
+ alignItems: "stretch",
75
+ },
76
+ medium: {
77
+ flexDirection: "var(--flex-dir-tablet)",
78
+ alignItems: "stretch",
79
+ },
80
+ },
81
+ column: {
82
+ small: {
83
+ width: "var(--column-width) !important",
84
+ marginLeft: "var(--column-margin-left) !important",
85
+ },
86
+ medium: {
87
+ width: "var(--column-width-tablet) !important",
88
+ marginLeft: "var(--column-margin-left-tablet) !important",
89
+ },
90
+ },
91
+ };
92
+ };
93
+ $: columnsStyles = () => {
94
+ return `
95
+ @media (max-width: ${getWidthForBreakpointSize("medium")}px) {
96
+ .${builderBlock.id}-breakpoints {
97
+ ${convertStyleMapToCSS(columnStyleObjects().columns.medium)}
98
+ }
99
+
100
+ .${builderBlock.id}-breakpoints > .builder-column {
101
+ ${convertStyleMapToCSS(columnStyleObjects().column.medium)}
102
+ }
103
+ }
104
+
105
+ @media (max-width: ${getWidthForBreakpointSize("small")}px) {
106
+ .${builderBlock.id}-breakpoints {
107
+ ${convertStyleMapToCSS(columnStyleObjects().columns.small)}
108
+ }
109
+
110
+ .${builderBlock.id}-breakpoints > .builder-column {
111
+ ${convertStyleMapToCSS(columnStyleObjects().column.small)}
112
+ }
113
+ },
114
+ `;
115
+ };
116
+ $: reactNativeColumnsStyles = () => {
117
+ return columnStyleObjects.columns.small;
118
+ };
119
+ $: reactNativeColumnStyles = () => {
120
+ return columnStyleObjects.column.small;
121
+ };
60
122
  </script>
61
123
 
62
- <div use:mitosis_styling={columnsCssVars()} class="builder-columns div">
124
+ <div
125
+ use:mitosis_styling={{
126
+ ...(TARGET === "reactNative" ? reactNativeColumnsStyles() : {}),
127
+ ...columnsCssVars(),
128
+ }}
129
+ class={`builder-columns ${builderBlock.id}-breakpoints` + " div"}
130
+ >
131
+ {#if TARGET !== "reactNative"}
132
+ <RenderInlinedStyles styles={columnsStyles()} />
133
+ {/if}
134
+
63
135
  {#each columns as column, index (index)}
64
136
  <div
65
137
  use:mitosis_styling={{
66
138
  width: getColumnCssWidth(index),
67
139
  marginLeft: `${index === 0 ? 0 : getGutterSize()}px`,
140
+ ...(TARGET === "reactNative" ? reactNativeColumnStyles() : {}),
68
141
  ...columnCssVars(),
69
142
  }}
70
143
  class="builder-column div-2"
@@ -84,34 +157,11 @@ $: columnCssVars = () => {
84
157
  <style>
85
158
  .div {
86
159
  display: flex;
87
- align-items: stretch;
88
160
  line-height: normal;
89
161
  }
90
- @media (max-width: 991px) {
91
- .div {
92
- flex-direction: var(--flex-dir-tablet);
93
- }
94
- }
95
- @media (max-width: 639px) {
96
- .div {
97
- flex-direction: var(--flex-dir);
98
- }
99
- }
100
162
  .div-2 {
101
163
  display: flex;
102
164
  flex-direction: column;
103
165
  align-items: stretch;
104
166
  }
105
- @media (max-width: 991px) {
106
- .div-2 {
107
- width: var(--column-width-tablet) !important;
108
- margin-left: var(--column-margin-left-tablet) !important;
109
- }
110
- }
111
- @media (max-width: 639px) {
112
- .div-2 {
113
- width: var(--column-width) !important;
114
- margin-left: var(--column-margin-left) !important;
115
- }
116
- }
117
167
  </style>
@@ -1,5 +1,6 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  import type { BuilderBlock } from "../../types/builder-block";
3
+ import type { Breakpoints } from "../../types/builder-content";
3
4
  declare type Column = {
4
5
  blocks: any;
5
6
  width?: number;
@@ -11,6 +12,7 @@ export interface ColumnProps {
11
12
  space?: number;
12
13
  stackColumnsAt?: StackColumnsAt;
13
14
  reverseColumnsWhenStacked?: boolean;
15
+ customBreakpoints?: Breakpoints;
14
16
  }
15
17
  declare const __propDef: {
16
18
  props: {
@@ -18,6 +20,7 @@ declare const __propDef: {
18
20
  columns: ColumnProps["columns"];
19
21
  stackColumnsAt: ColumnProps["stackColumnsAt"];
20
22
  reverseColumnsWhenStacked: ColumnProps["reverseColumnsWhenStacked"];
23
+ customBreakpoints: ColumnProps["customBreakpoints"];
21
24
  builderBlock: ColumnProps["builderBlock"];
22
25
  };
23
26
  events: {
@@ -42,11 +42,18 @@ function mitosis_styling(node, vars) {
42
42
  </script>
43
43
 
44
44
  <section
45
- use:mitosis_styling={maxWidth && typeof maxWidth === "number"
46
- ? {
47
- maxWidth: maxWidth,
48
- }
49
- : undefined}
45
+ use:mitosis_styling={{
46
+ width: "100%",
47
+ alignSelf: "stretch",
48
+ flexGrow: "1",
49
+ boxSizing: "border-box",
50
+ maxWidth: `${maxWidth && typeof maxWidth === "number" ? maxWidth : 1200}px`,
51
+ display: "flex",
52
+ flexDirection: "column",
53
+ alignItems: "stretch",
54
+ marginLeft: "auto",
55
+ marginRight: "auto",
56
+ }}
50
57
  {...filterAttrs(attributes, isNonEvent)}
51
58
  use:setAttrs={filterAttrs(attributes, isEvent)}
52
59
  >
@@ -108,6 +108,7 @@ $: renderComponentProps = () => {
108
108
  ...actions(),
109
109
  },
110
110
  }),
111
+ customBreakpoints: childrenContext?.()?.content?.meta?.breakpoints,
111
112
  },
112
113
  context: childrenContext(),
113
114
  };
@@ -1,11 +1,13 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  import type { BuilderBlock } from "../../types/builder-block.js";
3
3
  import type { BuilderContextInterface } from "../../context/types.js";
4
+ import type { Breakpoints } from "../../types/builder-content.js";
4
5
  export interface RenderComponentProps {
5
6
  componentRef: any;
6
7
  componentOptions: any;
7
8
  blockChildren: BuilderBlock[];
8
9
  context: BuilderContextInterface;
10
+ customBreakpoints?: Breakpoints;
9
11
  }
10
12
  declare const __propDef: {
11
13
  props: {
@@ -45,6 +45,16 @@ function processMessage(event) {
45
45
  const { data } = event;
46
46
  if (data) {
47
47
  switch (data.type) {
48
+ case "builder.configureSdk": {
49
+ const messageContent = data.data;
50
+ const { breakpoints, contentId } = messageContent;
51
+ if (!contentId || contentId !== useContent?.()?.id) {
52
+ return;
53
+ }
54
+ useBreakpoints = breakpoints;
55
+ forceReRenderCount = forceReRenderCount + 1; // This is a hack to force Qwik to re-render.
56
+ break;
57
+ }
48
58
  case "builder.contentUpdate": {
49
59
  const messageContent = data.data;
50
60
  const key = messageContent.key ||
@@ -147,6 +157,13 @@ $: useContent = () => {
147
157
  ...data,
148
158
  ...overrideContent?.data,
149
159
  },
160
+ meta: {
161
+ ...content?.meta,
162
+ ...overrideContent?.meta,
163
+ breakpoints: useBreakpoints ||
164
+ overrideContent?.meta?.breakpoints ||
165
+ content?.meta?.breakpoints,
166
+ },
150
167
  };
151
168
  return mergedContent;
152
169
  };
@@ -197,6 +214,7 @@ let elementRef;
197
214
  let forceReRenderCount = 0;
198
215
  let overrideContent = null;
199
216
  let update = 0;
217
+ let useBreakpoints = null;
200
218
  let overrideState = {};
201
219
  onMount(() => {
202
220
  if (!apiKey) {
@@ -1,5 +1,6 @@
1
1
  import type { BuilderBlock } from '../types/builder-block.js';
2
2
  export declare function getBlockProperties(block: BuilderBlock): {
3
3
  'builder-id': string | undefined;
4
+ style: string | Partial<CSSStyleDeclaration> | undefined;
4
5
  class: string;
5
6
  };
@@ -1,9 +1,35 @@
1
+ import { TARGET } from '../constants/target.js';
2
+ import { convertStyleMapToCSSArray } from '../helpers/css.js';
3
+ import { transformBlockProperties } from './transform-block-properties.js';
1
4
  export function getBlockProperties(block) {
2
- return {
5
+ const properties = {
3
6
  ...block.properties,
4
7
  'builder-id': block.id,
8
+ style: getStyleAttribute(block.style),
5
9
  class: [block.id, 'builder-block', block.class, block.properties?.class]
6
10
  .filter(Boolean)
7
11
  .join(' '),
8
12
  };
13
+ return transformBlockProperties(properties);
14
+ }
15
+ /**
16
+ * Svelte does not support style attribute as an object so we need to flatten it.
17
+ *
18
+ * Additionally, Svelte, Vue and other frameworks use kebab-case styles, so we need to convert them.
19
+ */
20
+ function getStyleAttribute(style) {
21
+ if (!style) {
22
+ return undefined;
23
+ }
24
+ switch (TARGET) {
25
+ case 'svelte':
26
+ case 'vue2':
27
+ case 'vue3':
28
+ case 'solid':
29
+ return convertStyleMapToCSSArray(style).join(' ');
30
+ case 'qwik':
31
+ case 'reactNative':
32
+ case 'react':
33
+ return style;
34
+ }
9
35
  }
@@ -0,0 +1 @@
1
+ export declare function transformBlockProperties<T>(properties: T): T;
@@ -0,0 +1,3 @@
1
+ export function transformBlockProperties(properties) {
2
+ return properties;
3
+ }
@@ -1,3 +1,5 @@
1
+ export declare const convertStyleMapToCSSArray: (style: Partial<CSSStyleDeclaration>) => string[];
2
+ export declare const convertStyleMapToCSS: (style: Partial<CSSStyleDeclaration>) => string;
1
3
  export declare const createCssClass: ({ mediaQuery, className, styles, }: {
2
4
  mediaQuery?: string | undefined;
3
5
  className: string;
@@ -1,15 +1,20 @@
1
1
  import { camelToKebabCase } from '../functions/camel-to-kebab-case.js';
2
- const convertStyleMaptoCSS = (style) => {
2
+ import { checkIsDefined } from './nullable.js';
3
+ export const convertStyleMapToCSSArray = (style) => {
3
4
  const cssProps = Object.entries(style).map(([key, value]) => {
4
5
  if (typeof value === 'string') {
5
6
  return `${camelToKebabCase(key)}: ${value};`;
6
7
  }
8
+ else {
9
+ return undefined;
10
+ }
7
11
  });
8
- return cssProps.join('\n');
12
+ return cssProps.filter(checkIsDefined);
9
13
  };
14
+ export const convertStyleMapToCSS = (style) => convertStyleMapToCSSArray(style).join('\n');
10
15
  export const createCssClass = ({ mediaQuery, className, styles, }) => {
11
16
  const cssClass = `.${className} {
12
- ${convertStyleMaptoCSS(styles)}
17
+ ${convertStyleMapToCSS(styles)}
13
18
  }`;
14
19
  if (mediaQuery) {
15
20
  return `${mediaQuery} {
@@ -53,5 +53,6 @@ export interface BuilderBlock {
53
53
  itemName?: string;
54
54
  } | null;
55
55
  animations?: any[];
56
+ style?: Partial<CSSStyleDeclaration>;
56
57
  }
57
58
  export {};
@@ -1,5 +1,10 @@
1
1
  import type { BuilderBlock } from './builder-block.js';
2
+ import type { Nullable } from './typescript.js';
2
3
  declare type Input = any;
4
+ export interface Breakpoints {
5
+ small: number;
6
+ medium: number;
7
+ }
3
8
  export interface BuilderContentVariation {
4
9
  data?: {
5
10
  title?: string;
@@ -19,10 +24,7 @@ export interface BuilderContentVariation {
19
24
  testRatio?: number;
20
25
  id?: string;
21
26
  meta?: {
22
- breakpoints?: {
23
- small: number;
24
- medium: number;
25
- };
27
+ breakpoints?: Nullable<Breakpoints>;
26
28
  [key: string]: any;
27
29
  };
28
30
  }
@@ -1,3 +1,3 @@
1
1
  declare type MitosisTargets = import('@builder.io/mitosis').Target;
2
- export declare type Target = Extract<MitosisTargets, 'vue3' | 'vue2' | 'reactNative' | 'svelte' | 'qwik'>;
2
+ export declare type Target = Extract<MitosisTargets, 'vue3' | 'vue2' | 'reactNative' | 'svelte' | 'qwik' | 'react' | 'solid'>;
3
3
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@builder.io/sdk-svelte",
3
3
  "description": "Builder.io SDK for Svelte",
4
- "version": "0.0.9",
4
+ "version": "0.0.10-0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "package",
@@ -1,9 +1,9 @@
1
1
  <script context="module" lang="ts">
2
2
  import type { BuilderBlock } from "../../types/builder-block";
3
3
 
4
- type CSS = {
5
- [key: string]: string;
6
- };
4
+ import type { SizeName } from "../../constants/device-sizes";
5
+
6
+ import type { Breakpoints } from "../../types/builder-content";
7
7
 
8
8
  type Column = {
9
9
  blocks: any;
@@ -23,16 +23,22 @@
23
23
  stackColumnsAt?: StackColumnsAt;
24
24
  // TODO: Implement this when support for dynamic CSS lands
25
25
  reverseColumnsWhenStacked?: boolean;
26
+ customBreakpoints?: Breakpoints;
26
27
  }
27
28
  </script>
28
29
 
29
30
  <script lang="ts">
30
31
  import RenderBlocks from "../../components/render-blocks.svelte";
32
+ import { getSizesForBreakpoints } from "../../constants/device-sizes";
33
+ import RenderInlinedStyles from "../../components/render-inlined-styles.svelte";
34
+ import { TARGET } from "../../constants/target.js";
35
+ import { convertStyleMapToCSS } from "../../helpers/css";
31
36
 
32
37
  export let space: ColumnProps["space"];
33
38
  export let columns: ColumnProps["columns"];
34
39
  export let stackColumnsAt: ColumnProps["stackColumnsAt"];
35
40
  export let reverseColumnsWhenStacked: ColumnProps["reverseColumnsWhenStacked"];
41
+ export let customBreakpoints: ColumnProps["customBreakpoints"];
36
42
  export let builderBlock: ColumnProps["builderBlock"];
37
43
 
38
44
  function mitosis_styling(node, vars) {
@@ -65,6 +71,10 @@
65
71
  const _stackColumnsAt = stackColumnsAt || "tablet";
66
72
  return _stackColumnsAt === "tablet" ? prop : "inherit";
67
73
  }
74
+ function getWidthForBreakpointSize(size) {
75
+ const breakpointSizes = getSizesForBreakpoints(customBreakpoints || {});
76
+ return breakpointSizes[size].max;
77
+ }
68
78
  $: columnsCssVars = () => {
69
79
  const flexDir =
70
80
  stackColumnsAt === "never"
@@ -87,14 +97,78 @@
87
97
  "--column-margin-left-tablet": maybeApplyForTablet(marginLeft),
88
98
  };
89
99
  };
100
+ $: columnStyleObjects = () => {
101
+ return {
102
+ columns: {
103
+ small: {
104
+ flexDirection: "var(--flex-dir)",
105
+ alignItems: "stretch",
106
+ },
107
+ medium: {
108
+ flexDirection: "var(--flex-dir-tablet)",
109
+ alignItems: "stretch",
110
+ },
111
+ },
112
+ column: {
113
+ small: {
114
+ width: "var(--column-width) !important",
115
+ marginLeft: "var(--column-margin-left) !important",
116
+ },
117
+ medium: {
118
+ width: "var(--column-width-tablet) !important",
119
+ marginLeft: "var(--column-margin-left-tablet) !important",
120
+ },
121
+ },
122
+ };
123
+ };
124
+ $: columnsStyles = () => {
125
+ return `
126
+ @media (max-width: ${getWidthForBreakpointSize("medium")}px) {
127
+ .${builderBlock.id}-breakpoints {
128
+ ${convertStyleMapToCSS(columnStyleObjects().columns.medium)}
129
+ }
130
+
131
+ .${builderBlock.id}-breakpoints > .builder-column {
132
+ ${convertStyleMapToCSS(columnStyleObjects().column.medium)}
133
+ }
134
+ }
135
+
136
+ @media (max-width: ${getWidthForBreakpointSize("small")}px) {
137
+ .${builderBlock.id}-breakpoints {
138
+ ${convertStyleMapToCSS(columnStyleObjects().columns.small)}
139
+ }
140
+
141
+ .${builderBlock.id}-breakpoints > .builder-column {
142
+ ${convertStyleMapToCSS(columnStyleObjects().column.small)}
143
+ }
144
+ },
145
+ `;
146
+ };
147
+ $: reactNativeColumnsStyles = () => {
148
+ return columnStyleObjects.columns.small;
149
+ };
150
+ $: reactNativeColumnStyles = () => {
151
+ return columnStyleObjects.column.small;
152
+ };
90
153
  </script>
91
154
 
92
- <div use:mitosis_styling={columnsCssVars()} class="builder-columns div">
155
+ <div
156
+ use:mitosis_styling={{
157
+ ...(TARGET === "reactNative" ? reactNativeColumnsStyles() : {}),
158
+ ...columnsCssVars(),
159
+ }}
160
+ class={`builder-columns ${builderBlock.id}-breakpoints` + " div"}
161
+ >
162
+ {#if TARGET !== "reactNative"}
163
+ <RenderInlinedStyles styles={columnsStyles()} />
164
+ {/if}
165
+
93
166
  {#each columns as column, index (index)}
94
167
  <div
95
168
  use:mitosis_styling={{
96
169
  width: getColumnCssWidth(index),
97
170
  marginLeft: `${index === 0 ? 0 : getGutterSize()}px`,
171
+ ...(TARGET === "reactNative" ? reactNativeColumnStyles() : {}),
98
172
  ...columnCssVars(),
99
173
  }}
100
174
  class="builder-column div-2"
@@ -114,34 +188,11 @@
114
188
  <style>
115
189
  .div {
116
190
  display: flex;
117
- align-items: stretch;
118
191
  line-height: normal;
119
192
  }
120
- @media (max-width: 991px) {
121
- .div {
122
- flex-direction: var(--flex-dir-tablet);
123
- }
124
- }
125
- @media (max-width: 639px) {
126
- .div {
127
- flex-direction: var(--flex-dir);
128
- }
129
- }
130
193
  .div-2 {
131
194
  display: flex;
132
195
  flex-direction: column;
133
196
  align-items: stretch;
134
197
  }
135
- @media (max-width: 991px) {
136
- .div-2 {
137
- width: var(--column-width-tablet) !important;
138
- margin-left: var(--column-margin-left-tablet) !important;
139
- }
140
- }
141
- @media (max-width: 639px) {
142
- .div-2 {
143
- width: var(--column-width) !important;
144
- margin-left: var(--column-margin-left) !important;
145
- }
146
- }
147
198
  </style>
@@ -57,11 +57,18 @@
57
57
  </script>
58
58
 
59
59
  <section
60
- use:mitosis_styling={maxWidth && typeof maxWidth === "number"
61
- ? {
62
- maxWidth: maxWidth,
63
- }
64
- : undefined}
60
+ use:mitosis_styling={{
61
+ width: "100%",
62
+ alignSelf: "stretch",
63
+ flexGrow: "1",
64
+ boxSizing: "border-box",
65
+ maxWidth: `${maxWidth && typeof maxWidth === "number" ? maxWidth : 1200}px`,
66
+ display: "flex",
67
+ flexDirection: "column",
68
+ alignItems: "stretch",
69
+ marginLeft: "auto",
70
+ marginRight: "auto",
71
+ }}
65
72
  {...filterAttrs(attributes, isNonEvent)}
66
73
  use:setAttrs={filterAttrs(attributes, isEvent)}
67
74
  >
@@ -133,6 +133,7 @@
133
133
  ...actions(),
134
134
  },
135
135
  }),
136
+ customBreakpoints: childrenContext?.()?.content?.meta?.breakpoints,
136
137
  },
137
138
  context: childrenContext(),
138
139
  };
@@ -3,11 +3,14 @@
3
3
 
4
4
  import type { BuilderContextInterface } from "../../context/types.js";
5
5
 
6
+ import type { Breakpoints } from "../../types/builder-content.js";
7
+
6
8
  export interface RenderComponentProps {
7
9
  componentRef: any;
8
10
  componentOptions: any;
9
11
  blockChildren: BuilderBlock[];
10
12
  context: BuilderContextInterface;
13
+ customBreakpoints?: Breakpoints;
11
14
  }
12
15
  </script>
13
16
 
@@ -6,7 +6,10 @@
6
6
  RegisteredComponents,
7
7
  } from "../../context/types.js";
8
8
 
9
- import type { BuilderContent } from "../../types/builder-content.js";
9
+ import type {
10
+ Breakpoints,
11
+ BuilderContent,
12
+ } from "../../types/builder-content.js";
10
13
 
11
14
  import type { Dictionary, Nullable } from "../../types/typescript.js";
12
15
 
@@ -99,6 +102,16 @@
99
102
  const { data } = event;
100
103
  if (data) {
101
104
  switch (data.type) {
105
+ case "builder.configureSdk": {
106
+ const messageContent = data.data;
107
+ const { breakpoints, contentId } = messageContent;
108
+ if (!contentId || contentId !== useContent?.()?.id) {
109
+ return;
110
+ }
111
+ useBreakpoints = breakpoints;
112
+ forceReRenderCount = forceReRenderCount + 1; // This is a hack to force Qwik to re-render.
113
+ break;
114
+ }
102
115
  case "builder.contentUpdate": {
103
116
  const messageContent = data.data;
104
117
  const key =
@@ -207,6 +220,14 @@
207
220
  ...data,
208
221
  ...overrideContent?.data,
209
222
  },
223
+ meta: {
224
+ ...content?.meta,
225
+ ...overrideContent?.meta,
226
+ breakpoints:
227
+ useBreakpoints ||
228
+ overrideContent?.meta?.breakpoints ||
229
+ content?.meta?.breakpoints,
230
+ },
210
231
  };
211
232
  return mergedContent;
212
233
  };
@@ -264,6 +285,7 @@
264
285
  let forceReRenderCount = 0;
265
286
  let overrideContent = null;
266
287
  let update = 0;
288
+ let useBreakpoints = null;
267
289
  let overrideState = {};
268
290
 
269
291
  onMount(() => {
@@ -1,11 +1,41 @@
1
+ import { TARGET } from '../constants/target.js';
2
+ import { convertStyleMapToCSSArray } from '../helpers/css.js';
1
3
  import type { BuilderBlock } from '../types/builder-block.js';
4
+ import { transformBlockProperties } from './transform-block-properties.js';
2
5
 
3
6
  export function getBlockProperties(block: BuilderBlock) {
4
- return {
7
+ const properties = {
5
8
  ...block.properties,
6
9
  'builder-id': block.id,
10
+ style: getStyleAttribute(block.style),
7
11
  class: [block.id, 'builder-block', block.class, block.properties?.class]
8
12
  .filter(Boolean)
9
13
  .join(' '),
10
14
  };
15
+
16
+ return transformBlockProperties(properties);
17
+ }
18
+ /**
19
+ * Svelte does not support style attribute as an object so we need to flatten it.
20
+ *
21
+ * Additionally, Svelte, Vue and other frameworks use kebab-case styles, so we need to convert them.
22
+ */
23
+ function getStyleAttribute(
24
+ style: Partial<CSSStyleDeclaration> | undefined
25
+ ): string | Partial<CSSStyleDeclaration> | undefined {
26
+ if (!style) {
27
+ return undefined;
28
+ }
29
+
30
+ switch (TARGET) {
31
+ case 'svelte':
32
+ case 'vue2':
33
+ case 'vue3':
34
+ case 'solid':
35
+ return convertStyleMapToCSSArray(style).join(' ');
36
+ case 'qwik':
37
+ case 'reactNative':
38
+ case 'react':
39
+ return style;
40
+ }
11
41
  }
@@ -0,0 +1,3 @@
1
+ export function transformBlockProperties<T>(properties: T) {
2
+ return properties;
3
+ }
@@ -1,15 +1,24 @@
1
1
  import { camelToKebabCase } from '../functions/camel-to-kebab-case.js';
2
+ import { checkIsDefined } from './nullable.js';
2
3
 
3
- const convertStyleMaptoCSS = (style: Partial<CSSStyleDeclaration>): string => {
4
+ export const convertStyleMapToCSSArray = (
5
+ style: Partial<CSSStyleDeclaration>
6
+ ): string[] => {
4
7
  const cssProps = Object.entries(style).map(([key, value]) => {
5
8
  if (typeof value === 'string') {
6
9
  return `${camelToKebabCase(key)}: ${value};`;
10
+ } else {
11
+ return undefined;
7
12
  }
8
13
  });
9
14
 
10
- return cssProps.join('\n');
15
+ return cssProps.filter(checkIsDefined);
11
16
  };
12
17
 
18
+ export const convertStyleMapToCSS = (
19
+ style: Partial<CSSStyleDeclaration>
20
+ ): string => convertStyleMapToCSSArray(style).join('\n');
21
+
13
22
  export const createCssClass = ({
14
23
  mediaQuery,
15
24
  className,
@@ -20,7 +29,7 @@ export const createCssClass = ({
20
29
  styles: Partial<CSSStyleDeclaration>;
21
30
  }) => {
22
31
  const cssClass = `.${className} {
23
- ${convertStyleMaptoCSS(styles)}
32
+ ${convertStyleMapToCSS(styles)}
24
33
  }`;
25
34
 
26
35
  if (mediaQuery) {
@@ -55,4 +55,5 @@ export interface BuilderBlock {
55
55
  itemName?: string;
56
56
  } | null;
57
57
  animations?: any[]; // TODO: type the animation spec
58
+ style?: Partial<CSSStyleDeclaration>;
58
59
  }
@@ -1,8 +1,13 @@
1
1
  import type { BuilderBlock } from './builder-block.js';
2
+ import type { Nullable } from './typescript.js';
2
3
 
3
4
  // TODO
4
5
  type Input = any;
5
6
 
7
+ export interface Breakpoints {
8
+ small: number;
9
+ medium: number;
10
+ }
6
11
  export interface BuilderContentVariation {
7
12
  data?: {
8
13
  title?: string;
@@ -18,10 +23,7 @@ export interface BuilderContentVariation {
18
23
  testRatio?: number;
19
24
  id?: string;
20
25
  meta?: {
21
- breakpoints?: {
22
- small: number;
23
- medium: number;
24
- };
26
+ breakpoints?: Nullable<Breakpoints>;
25
27
  [key: string]: any;
26
28
  };
27
29
  }
@@ -2,5 +2,5 @@ type MitosisTargets = import('@builder.io/mitosis').Target;
2
2
 
3
3
  export type Target = Extract<
4
4
  MitosisTargets,
5
- 'vue3' | 'vue2' | 'reactNative' | 'svelte' | 'qwik'
5
+ 'vue3' | 'vue2' | 'reactNative' | 'svelte' | 'qwik' | 'react' | 'solid'
6
6
  >;