@builder.io/sdk-solid 0.1.2 → 0.1.3-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.
Files changed (34) hide show
  1. package/dist/sdk-solid.cjs +34 -0
  2. package/dist/sdk-solid.js +3863 -0
  3. package/package.json +5 -6
  4. package/src/blocks/BaseText.jsx +5 -1
  5. package/src/blocks/button/button.jsx +25 -7
  6. package/src/blocks/columns/columns.jsx +84 -38
  7. package/src/blocks/custom-code/custom-code.jsx +25 -3
  8. package/src/blocks/embed/embed.jsx +14 -2
  9. package/src/blocks/form/form.jsx +175 -121
  10. package/src/blocks/fragment/fragment.jsx +2 -1
  11. package/src/blocks/image/image.jsx +75 -38
  12. package/src/blocks/img/img.jsx +15 -5
  13. package/src/blocks/input/input.jsx +17 -2
  14. package/src/blocks/raw-text/raw-text.jsx +8 -2
  15. package/src/blocks/section/section.jsx +24 -14
  16. package/src/blocks/select/select.jsx +21 -6
  17. package/src/blocks/submit-button/submit-button.jsx +6 -3
  18. package/src/blocks/symbol/symbol.jsx +54 -15
  19. package/src/blocks/text/text.jsx +2 -1
  20. package/src/blocks/textarea/textarea.jsx +11 -2
  21. package/src/blocks/video/video.jsx +49 -27
  22. package/src/components/render-block/block-styles.jsx +45 -21
  23. package/src/components/render-block/render-block.helpers.js +90 -0
  24. package/src/components/render-block/render-block.jsx +110 -131
  25. package/src/components/render-block/render-component.jsx +26 -9
  26. package/src/components/render-block/render-repeated-block.jsx +20 -24
  27. package/src/components/render-blocks.jsx +70 -30
  28. package/src/components/render-content/builder-editing.jsx +2 -1
  29. package/src/components/render-content/components/render-styles.jsx +17 -8
  30. package/src/components/render-content/render-content.jsx +224 -146
  31. package/src/components/render-inlined-styles.jsx +14 -4
  32. package/vite.config.ts +18 -0
  33. package/solid-index.jsx +0 -5
  34. package/src/components/render-block/render-component-with-context.jsx +0 -28
@@ -1,78 +1,80 @@
1
- import { Show, For } from "solid-js";
1
+ import { Show, For, createSignal } from "solid-js";
2
2
  import { Dynamic } from "solid-js/web";
3
+
3
4
  import { getBlockActions } from "../../functions/get-block-actions.js";
4
5
  import { getBlockComponentOptions } from "../../functions/get-block-component-options.js";
5
6
  import { getBlockProperties } from "../../functions/get-block-properties.js";
6
7
  import { getBlockTag } from "../../functions/get-block-tag.js";
7
8
  import { getProcessedBlock } from "../../functions/get-processed-block.js";
8
- import { evaluate } from "../../functions/evaluate.js";
9
9
  import BlockStyles from "./block-styles.jsx";
10
- import { isEmptyHtmlElement } from "./render-block.helpers.js";
10
+ import {
11
+ getComponent,
12
+ getRepeatItemData,
13
+ isEmptyHtmlElement,
14
+ } from "./render-block.helpers.js";
11
15
  import RenderRepeatedBlock from "./render-repeated-block.jsx";
12
16
  import { TARGET } from "../../constants/target.js";
13
17
  import { extractTextStyles } from "../../functions/extract-text-styles.js";
14
- import RenderComponentWithContext from "./render-component-with-context.jsx";
15
18
  import RenderComponent from "./render-component.jsx";
16
19
  import { getReactNativeBlockStyles } from "../../functions/get-react-native-block-styles.js";
20
+
17
21
  function RenderBlock(props) {
18
- function component() {
19
- const componentName = getProcessedBlock({
22
+ const [component, setComponent] = createSignal(
23
+ getComponent({
20
24
  block: props.block,
21
- state: props.context.state,
22
- context: props.context.context,
23
- shouldEvaluateBindings: false
24
- }).component?.name;
25
- if (!componentName) {
26
- return null;
27
- }
28
- const ref = props.context.registeredComponents[componentName];
29
- if (!ref) {
30
- // TODO: Public doc page with more info about this message
31
- console.warn(`
32
- Could not find a registered component named "${componentName}".
33
- If you registered it, is the file that registered it imported by the file that needs to render it?`);
34
- return undefined;
35
- } else {
36
- return ref;
37
- }
38
- }
25
+ context: props.context,
26
+ })
27
+ );
28
+
29
+ const [repeatItemData, setRepeatItemData] = createSignal(
30
+ getRepeatItemData({
31
+ block: props.block,
32
+ context: props.context,
33
+ })
34
+ );
35
+
39
36
  function tag() {
40
37
  return getBlockTag(useBlock());
41
38
  }
39
+
42
40
  function useBlock() {
43
- return repeatItemData() ? props.block : getProcessedBlock({
44
- block: props.block,
45
- state: props.context.state,
46
- context: props.context.context,
47
- shouldEvaluateBindings: true
48
- });
41
+ return repeatItemData()
42
+ ? props.block
43
+ : getProcessedBlock({
44
+ block: props.block,
45
+ state: props.context.state,
46
+ context: props.context.context,
47
+ shouldEvaluateBindings: true,
48
+ });
49
49
  }
50
+
50
51
  function actions() {
51
52
  return getBlockActions({
52
53
  block: useBlock(),
53
54
  state: props.context.state,
54
- context: props.context.context
55
+ context: props.context.context,
55
56
  });
56
57
  }
58
+
57
59
  function attributes() {
58
60
  const blockProperties = getBlockProperties(useBlock());
59
61
  return {
60
62
  ...blockProperties,
61
- ...(TARGET === "reactNative" ? {
62
- style: getReactNativeBlockStyles({
63
- block: useBlock(),
64
- context: props.context,
65
- blockStyles: blockProperties.style
66
- })
67
- } : {})
63
+ ...(TARGET === "reactNative"
64
+ ? {
65
+ style: getReactNativeBlockStyles({
66
+ block: useBlock(),
67
+ context: props.context,
68
+ blockStyles: blockProperties.style,
69
+ }),
70
+ }
71
+ : {}),
68
72
  };
69
73
  }
70
- function shouldWrap() {
71
- return !component()?.noWrap;
72
- }
74
+
73
75
  function renderComponentProps() {
74
76
  return {
75
- blockChildren: useChildren(),
77
+ blockChildren: useBlock().children ?? [],
76
78
  componentRef: component()?.component,
77
79
  componentOptions: {
78
80
  ...getBlockComponentOptions(useBlock()),
@@ -80,24 +82,20 @@ function RenderBlock(props) {
80
82
  * These attributes are passed to the wrapper element when there is one. If `noWrap` is set to true, then
81
83
  * they are provided to the component itself directly.
82
84
  */
83
- ...(shouldWrap() ? {} : {
84
- attributes: {
85
- ...attributes(),
86
- ...actions()
87
- }
88
- }),
89
- customBreakpoints: childrenContext()?.content?.meta?.breakpoints
85
+ ...(!component()?.noWrap
86
+ ? {}
87
+ : {
88
+ attributes: {
89
+ ...attributes(),
90
+ ...actions(),
91
+ },
92
+ }),
93
+ customBreakpoints: childrenContext()?.content?.meta?.breakpoints,
90
94
  },
91
- context: childrenContext()
95
+ context: childrenContext(),
92
96
  };
93
97
  }
94
- function useChildren() {
95
- // TO-DO: When should `canHaveChildren` dictate rendering?
96
- // This is currently commented out because some Builder components (e.g. Box) do not have `canHaveChildren: true`,
97
- // but still receive and need to render children.
98
- // return componentInfo?.canHaveChildren ? useBlock().children : [];
99
- return useBlock().children ?? [];
100
- }
98
+
101
99
  function childrenWithoutParentComponent() {
102
100
  /**
103
101
  * When there is no `componentRef`, there might still be children that need to be rendered. In this case,
@@ -105,106 +103,87 @@ function RenderBlock(props) {
105
103
  * NOTE: We make sure not to render this if `repeatItemData` is non-null, because that means we are rendering an array of
106
104
  * blocks, and the children will be repeated within those blocks.
107
105
  */
108
- const shouldRenderChildrenOutsideRef = !component()?.component && !repeatItemData();
109
- return shouldRenderChildrenOutsideRef ? useChildren() : [];
110
- }
111
- function repeatItemData() {
112
- /**
113
- * we don't use `useBlock()` here because the processing done within its logic includes evaluating the block's bindings,
114
- * which will not work if there is a repeat.
115
- */
116
- const {
117
- repeat,
118
- ...blockWithoutRepeat
119
- } = props.block;
120
- if (!repeat?.collection) {
121
- return undefined;
122
- }
123
- const itemsArray = evaluate({
124
- code: repeat.collection,
125
- state: props.context.state,
126
- context: props.context.context
127
- });
128
- if (!Array.isArray(itemsArray)) {
129
- return undefined;
130
- }
131
- const collectionName = repeat.collection.split(".").pop();
132
- const itemNameToUse = repeat.itemName || (collectionName ? collectionName + "Item" : "item");
133
- const repeatArray = itemsArray.map((item, index) => ({
134
- context: {
135
- ...props.context,
136
- state: {
137
- ...props.context.state,
138
- $index: index,
139
- $item: item,
140
- [itemNameToUse]: item,
141
- [`$${itemNameToUse}Index`]: index
142
- }
143
- },
144
- block: blockWithoutRepeat
145
- }));
146
- return repeatArray;
147
- }
148
- function inheritedTextStyles() {
149
- if (TARGET !== "reactNative") {
150
- return {};
151
- }
152
- const styles = getReactNativeBlockStyles({
153
- block: useBlock(),
154
- context: props.context,
155
- blockStyles: attributes().style
156
- });
157
- return extractTextStyles(styles);
106
+ const shouldRenderChildrenOutsideRef =
107
+ !component()?.component && !repeatItemData();
108
+ return shouldRenderChildrenOutsideRef ? useBlock().children ?? [] : [];
158
109
  }
110
+
159
111
  function childrenContext() {
112
+ const getInheritedTextStyles = () => {
113
+ if (TARGET !== "reactNative") {
114
+ return {};
115
+ }
116
+ return extractTextStyles(
117
+ getReactNativeBlockStyles({
118
+ block: useBlock(),
119
+ context: props.context,
120
+ blockStyles: attributes().style,
121
+ })
122
+ );
123
+ };
160
124
  return {
161
125
  apiKey: props.context.apiKey,
162
126
  state: props.context.state,
163
127
  content: props.context.content,
164
128
  context: props.context.context,
165
129
  registeredComponents: props.context.registeredComponents,
166
- inheritedStyles: inheritedTextStyles()
130
+ inheritedStyles: getInheritedTextStyles(),
167
131
  };
168
132
  }
169
- function renderComponentTag() {
170
- if (TARGET === "reactNative") {
171
- return RenderComponentWithContext;
172
- } else if (TARGET === "vue3") {
173
- // vue3 expects a string for the component tag
174
- return "RenderComponent";
175
- } else {
176
- return RenderComponent;
177
- }
178
- }
179
- return <Show fallback={<Dynamic {...renderComponentProps()} component={renderComponentTag()}></Dynamic>} when={shouldWrap()}>
133
+
134
+ return (
135
+ <Show
136
+ fallback={<RenderComponent {...renderComponentProps()}></RenderComponent>}
137
+ when={!component()?.noWrap}
138
+ >
180
139
  <Show when={isEmptyHtmlElement(tag())}>
181
140
  <Dynamic {...attributes()} {...actions()} component={tag()}></Dynamic>
182
141
  </Show>
183
142
  <Show when={!isEmptyHtmlElement(tag()) && repeatItemData()}>
184
143
  <For each={repeatItemData()}>
185
144
  {(data, _index) => {
186
- const index = _index();
187
- return <RenderRepeatedBlock key={index} repeatContext={data.context} block={data.block}></RenderRepeatedBlock>;
188
- }}
145
+ const index = _index();
146
+ return (
147
+ <RenderRepeatedBlock
148
+ key={index}
149
+ repeatContext={data.context}
150
+ block={data.block}
151
+ ></RenderRepeatedBlock>
152
+ );
153
+ }}
189
154
  </For>
190
155
  </Show>
191
156
  <Show when={!isEmptyHtmlElement(tag()) && !repeatItemData()}>
192
157
  <Dynamic {...attributes()} {...actions()} component={tag()}>
193
- <Dynamic {...renderComponentProps()} component={renderComponentTag()}></Dynamic>
158
+ <RenderComponent {...renderComponentProps()}></RenderComponent>
194
159
  <For each={childrenWithoutParentComponent()}>
195
160
  {(child, _index) => {
196
- const index = _index();
197
- return <RenderBlock key={"render-block-" + child.id} block={child} context={childrenContext()}></RenderBlock>;
198
- }}
161
+ const index = _index();
162
+ return (
163
+ <RenderBlock
164
+ key={"render-block-" + child.id}
165
+ block={child}
166
+ context={childrenContext()}
167
+ ></RenderBlock>
168
+ );
169
+ }}
199
170
  </For>
200
171
  <For each={childrenWithoutParentComponent()}>
201
172
  {(child, _index) => {
202
- const index = _index();
203
- return <BlockStyles key={"block-style-" + child.id} block={child} context={childrenContext()}></BlockStyles>;
204
- }}
173
+ const index = _index();
174
+ return (
175
+ <BlockStyles
176
+ key={"block-style-" + child.id}
177
+ block={child}
178
+ context={childrenContext()}
179
+ ></BlockStyles>
180
+ );
181
+ }}
205
182
  </For>
206
183
  </Dynamic>
207
184
  </Show>
208
- </Show>;
185
+ </Show>
186
+ );
209
187
  }
210
- export default RenderBlock;
188
+
189
+ export default RenderBlock;
@@ -1,23 +1,40 @@
1
1
  import { Show, For } from "solid-js";
2
2
  import { Dynamic } from "solid-js/web";
3
+
3
4
  import BlockStyles from "./block-styles.jsx";
4
5
  import RenderBlock from "./render-block.jsx";
6
+
5
7
  function RenderComponent(props) {
6
- return <Show when={props.componentRef}>
8
+ return (
9
+ <Show when={props.componentRef}>
7
10
  <Dynamic {...props.componentOptions} component={props.componentRef}>
8
11
  <For each={props.blockChildren}>
9
12
  {(child, _index) => {
10
- const index = _index();
11
- return <RenderBlock key={"render-block-" + child.id} block={child} context={props.context}></RenderBlock>;
12
- }}
13
+ const index = _index();
14
+ return (
15
+ <RenderBlock
16
+ key={"render-block-" + child.id}
17
+ block={child}
18
+ context={props.context}
19
+ ></RenderBlock>
20
+ );
21
+ }}
13
22
  </For>
14
23
  <For each={props.blockChildren}>
15
24
  {(child, _index) => {
16
- const index = _index();
17
- return <BlockStyles key={"block-style-" + child.id} block={child} context={props.context}></BlockStyles>;
18
- }}
25
+ const index = _index();
26
+ return (
27
+ <BlockStyles
28
+ key={"block-style-" + child.id}
29
+ block={child}
30
+ context={props.context}
31
+ ></BlockStyles>
32
+ );
33
+ }}
19
34
  </For>
20
35
  </Dynamic>
21
- </Show>;
36
+ </Show>
37
+ );
22
38
  }
23
- export default RenderComponent;
39
+
40
+ export default RenderComponent;
@@ -1,28 +1,24 @@
1
- import { Dynamic } from "solid-js/web";
2
1
  import BuilderContext from "../../context/builder.context.js";
3
2
  import RenderBlock from "./render-block.jsx";
3
+
4
4
  function RenderRepeatedBlock(props) {
5
- return <Dynamic value={{
6
- get content() {
7
- return props.repeatContext.content;
8
- },
9
- get state() {
10
- return props.repeatContext.state;
11
- },
12
- get context() {
13
- return props.repeatContext.context;
14
- },
15
- get apiKey() {
16
- return props.repeatContext.apiKey;
17
- },
18
- get registeredComponents() {
19
- return props.repeatContext.registeredComponents;
20
- },
21
- get inheritedStyles() {
22
- return props.repeatContext.inheritedStyles;
23
- }
24
- }} component={BuilderContext.Provider}>
25
- <RenderBlock block={props.block} context={props.repeatContext}></RenderBlock>
26
- </Dynamic>;
5
+ return (
6
+ <BuilderContext.Provider
7
+ value={{
8
+ content: props.repeatContext.content,
9
+ state: props.repeatContext.state,
10
+ context: props.repeatContext.context,
11
+ apiKey: props.repeatContext.apiKey,
12
+ registeredComponents: props.repeatContext.registeredComponents,
13
+ inheritedStyles: props.repeatContext.inheritedStyles,
14
+ }}
15
+ >
16
+ <RenderBlock
17
+ block={props.block}
18
+ context={props.repeatContext}
19
+ ></RenderBlock>
20
+ </BuilderContext.Provider>
21
+ );
27
22
  }
28
- export default RenderRepeatedBlock;
23
+
24
+ export default RenderRepeatedBlock;
@@ -1,59 +1,99 @@
1
- import { useContext, Show, For } from "solid-js";
1
+ import { useContext, Show, For, createSignal } from "solid-js";
2
+
2
3
  import { css } from "solid-styled-components";
4
+
3
5
  import BuilderContext from "../context/builder.context.js";
4
6
  import { isEditing } from "../functions/is-editing.js";
5
7
  import BlockStyles from "./render-block/block-styles.jsx";
6
8
  import RenderBlock from "./render-block/render-block.jsx";
9
+
7
10
  function RenderBlocks(props) {
8
11
  function className() {
9
12
  return "builder-blocks" + (!props.blocks?.length ? " no-blocks" : "");
10
13
  }
14
+
11
15
  function onClick() {
12
16
  if (isEditing() && !props.blocks?.length) {
13
- window.parent?.postMessage({
14
- type: "builder.clickEmptyBlocks",
15
- data: {
16
- parentElementId: props.parent,
17
- dataPath: props.path
18
- }
19
- }, "*");
17
+ window.parent?.postMessage(
18
+ {
19
+ type: "builder.clickEmptyBlocks",
20
+ data: {
21
+ parentElementId: props.parent,
22
+ dataPath: props.path,
23
+ },
24
+ },
25
+ "*"
26
+ );
20
27
  }
21
28
  }
29
+
22
30
  function onMouseEnter() {
23
31
  if (isEditing() && !props.blocks?.length) {
24
- window.parent?.postMessage({
25
- type: "builder.hoverEmptyBlocks",
26
- data: {
27
- parentElementId: props.parent,
28
- dataPath: props.path
29
- }
30
- }, "*");
32
+ window.parent?.postMessage(
33
+ {
34
+ type: "builder.hoverEmptyBlocks",
35
+ data: {
36
+ parentElementId: props.parent,
37
+ dataPath: props.path,
38
+ },
39
+ },
40
+ "*"
41
+ );
31
42
  }
32
43
  }
44
+
33
45
  const builderContext = useContext(BuilderContext);
34
- return <div class={className() + " " + css({
35
- display: "flex",
36
- flexDirection: "column",
37
- alignItems: "stretch"
38
- })} builder-path={props.path} builder-parent-id={props.parent} dataSet={{
39
- class: className()
40
- }} style={props.styleProp} onClick={event => onClick()} onMouseEnter={event => onMouseEnter()}>
46
+
47
+ return (
48
+ <div
49
+ class={
50
+ className() +
51
+ " " +
52
+ css({
53
+ display: "flex",
54
+ flexDirection: "column",
55
+ alignItems: "stretch",
56
+ })
57
+ }
58
+ builder-path={props.path}
59
+ builder-parent-id={props.parent}
60
+ dataSet={{
61
+ class: className(),
62
+ }}
63
+ style={props.styleProp}
64
+ onClick={(event) => onClick()}
65
+ onMouseEnter={(event) => onMouseEnter()}
66
+ >
41
67
  <Show when={props.blocks}>
42
68
  <For each={props.blocks}>
43
69
  {(block, _index) => {
44
- const index = _index();
45
- return <RenderBlock key={"render-block-" + block.id} block={block} context={builderContext}></RenderBlock>;
46
- }}
70
+ const index = _index();
71
+ return (
72
+ <RenderBlock
73
+ key={"render-block-" + block.id}
74
+ block={block}
75
+ context={builderContext}
76
+ ></RenderBlock>
77
+ );
78
+ }}
47
79
  </For>
48
80
  </Show>
49
81
  <Show when={props.blocks}>
50
82
  <For each={props.blocks}>
51
83
  {(block, _index) => {
52
- const index = _index();
53
- return <BlockStyles key={"block-style-" + block.id} block={block} context={builderContext}></BlockStyles>;
54
- }}
84
+ const index = _index();
85
+ return (
86
+ <BlockStyles
87
+ key={"block-style-" + block.id}
88
+ block={block}
89
+ context={builderContext}
90
+ ></BlockStyles>
91
+ );
92
+ }}
55
93
  </For>
56
94
  </Show>
57
- </div>;
95
+ </div>
96
+ );
58
97
  }
59
- export default RenderBlocks;
98
+
99
+ export default RenderBlocks;
@@ -1,4 +1,5 @@
1
1
  function BuilderEditing(props) {
2
2
  return <div></div>;
3
3
  }
4
- export default BuilderEditing;
4
+
5
+ export default BuilderEditing;
@@ -1,8 +1,13 @@
1
+ import { createSignal } from "solid-js";
2
+
1
3
  import RenderInlinedStyles from "../../render-inlined-styles.jsx";
4
+
2
5
  function RenderContentStyles(props) {
3
6
  function getCssFromFont(font) {
4
7
  // TODO: compute what font sizes are used and only load those.......
5
- const family = font.family + (font.kind && !font.kind.includes("#") ? ", " + font.kind : "");
8
+ const family =
9
+ font.family +
10
+ (font.kind && !font.kind.includes("#") ? ", " + font.kind : "");
6
11
  const name = family.split(",")[0];
7
12
  const url = font.fileUrl ?? font?.files?.regular;
8
13
  let str = "";
@@ -38,23 +43,27 @@ function RenderContentStyles(props) {
38
43
  }
39
44
  return str;
40
45
  }
41
- function getFontCss({
42
- customFonts
43
- }) {
46
+
47
+ function getFontCss({ customFonts }) {
44
48
  // TODO: flag for this
45
49
  // if (!this.builder.allowCustomFonts) {
46
50
  // return '';
47
51
  // }
48
52
  // TODO: separate internal data from external
49
- return customFonts?.map(font => this.getCssFromFont(font))?.join(" ") || "";
53
+ return (
54
+ customFonts?.map((font) => this.getCssFromFont(font))?.join(" ") || ""
55
+ );
50
56
  }
57
+
51
58
  function injectedStyles() {
52
59
  return `
53
60
  ${props.cssCode || ""}
54
61
  ${getFontCss({
55
- customFonts: props.customFonts
56
- })}`;
62
+ customFonts: props.customFonts,
63
+ })}`;
57
64
  }
65
+
58
66
  return <RenderInlinedStyles styles={injectedStyles()}></RenderInlinedStyles>;
59
67
  }
60
- export default RenderContentStyles;
68
+
69
+ export default RenderContentStyles;