@builder.io/sdk-svelte 0.0.4 → 0.0.6

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 (123) hide show
  1. package/package/--package.json +3 -2
  2. package/package/components/render-content/render-content.svelte +13 -7
  3. package/package/functions/track.d.ts +35 -5
  4. package/package/functions/track.js +5 -4
  5. package/package/index.d.ts +1 -0
  6. package/package/index.js +1 -0
  7. package/package.json +3 -2
  8. package/src/blocks/BaseText.svelte +27 -0
  9. package/src/blocks/button/button.svelte +36 -0
  10. package/src/blocks/button/component-info.ts +42 -0
  11. package/src/blocks/columns/columns.svelte +148 -0
  12. package/src/blocks/columns/component-info.ts +254 -0
  13. package/src/blocks/custom-code/component-info.ts +31 -0
  14. package/src/blocks/custom-code/custom-code.svelte +66 -0
  15. package/src/blocks/embed/component-info.ts +53 -0
  16. package/src/blocks/embed/embed.svelte +51 -0
  17. package/src/blocks/embed/helpers.ts +8 -0
  18. package/src/blocks/form/component-info.ts +282 -0
  19. package/src/blocks/form/form.svelte +332 -0
  20. package/src/blocks/fragment/component-info.ts +10 -0
  21. package/src/blocks/fragment/fragment.svelte +12 -0
  22. package/src/blocks/image/component-info.ts +170 -0
  23. package/src/blocks/image/image.helpers.ts +75 -0
  24. package/src/blocks/image/image.svelte +145 -0
  25. package/src/blocks/img/component-info.ts +21 -0
  26. package/src/blocks/img/img.svelte +51 -0
  27. package/src/blocks/input/component-info.ts +78 -0
  28. package/src/blocks/input/input.svelte +34 -0
  29. package/src/blocks/raw-text/component-info.ts +15 -0
  30. package/src/blocks/raw-text/raw-text.svelte +16 -0
  31. package/src/blocks/section/component-info.ts +50 -0
  32. package/src/blocks/section/section.svelte +34 -0
  33. package/src/blocks/select/component-info.ts +61 -0
  34. package/src/blocks/select/select.svelte +34 -0
  35. package/src/blocks/submit-button/component-info.ts +32 -0
  36. package/src/blocks/submit-button/submit-button.svelte +15 -0
  37. package/src/blocks/symbol/component-info.ts +43 -0
  38. package/src/blocks/symbol/symbol.svelte +100 -0
  39. package/src/blocks/text/component-info.ts +24 -0
  40. package/src/blocks/text/text.svelte +11 -0
  41. package/src/blocks/textarea/component-info.ts +48 -0
  42. package/src/blocks/textarea/textarea.svelte +19 -0
  43. package/src/blocks/util.ts +6 -0
  44. package/src/blocks/video/component-info.ts +109 -0
  45. package/src/blocks/video/video.svelte +102 -0
  46. package/src/components/render-block/block-styles.svelte +62 -0
  47. package/src/components/render-block/render-block.helpers.ts +27 -0
  48. package/src/components/render-block/render-block.svelte +228 -0
  49. package/src/components/render-block/render-component-with-context.svelte +38 -0
  50. package/src/components/render-block/render-component.svelte +35 -0
  51. package/src/components/render-block/render-repeated-block.svelte +53 -0
  52. package/src/components/render-block/types.ts +7 -0
  53. package/src/components/render-blocks.svelte +104 -0
  54. package/src/components/render-content/components/render-styles.svelte +80 -0
  55. package/src/components/render-content/index.ts +1 -0
  56. package/src/components/render-content/render-content.svelte +360 -0
  57. package/src/components/render-inlined-styles.svelte +26 -0
  58. package/src/constants/builder-registered-components.ts +42 -0
  59. package/src/constants/device-sizes.ts +28 -0
  60. package/src/constants/target.ts +2 -0
  61. package/src/context/builder.context.ts +13 -0
  62. package/src/context/types.ts +23 -0
  63. package/src/functions/camel-to-kebab-case.ts +2 -0
  64. package/src/functions/evaluate.ts +52 -0
  65. package/src/functions/event-handler-name.ts +6 -0
  66. package/src/functions/extract-text-styles.ts +39 -0
  67. package/src/functions/fast-clone.ts +5 -0
  68. package/src/functions/get-block-actions-handler.ts +19 -0
  69. package/src/functions/get-block-actions.ts +25 -0
  70. package/src/functions/get-block-component-options.ts +12 -0
  71. package/src/functions/get-block-properties.ts +11 -0
  72. package/src/functions/get-block-tag.ts +7 -0
  73. package/src/functions/get-builder-search-params/fn.test.ts +19 -0
  74. package/src/functions/get-builder-search-params/index.ts +48 -0
  75. package/src/functions/get-content/ab-testing.ts +132 -0
  76. package/src/functions/get-content/fn.test.ts +35 -0
  77. package/src/functions/get-content/index.ts +77 -0
  78. package/src/functions/get-content/types.ts +36 -0
  79. package/src/functions/get-fetch.ts +14 -0
  80. package/src/functions/get-global-this.ts +15 -0
  81. package/src/functions/get-processed-block.test.ts +33 -0
  82. package/src/functions/get-processed-block.ts +54 -0
  83. package/src/functions/get-react-native-block-styles.ts +30 -0
  84. package/src/functions/if-target.ts +20 -0
  85. package/src/functions/is-browser.ts +3 -0
  86. package/src/functions/is-editing.ts +7 -0
  87. package/src/functions/is-iframe.ts +5 -0
  88. package/src/functions/is-previewing.ts +14 -0
  89. package/src/functions/mark-mutable.ts +7 -0
  90. package/src/functions/on-change.test.ts +23 -0
  91. package/src/functions/on-change.ts +29 -0
  92. package/src/functions/register-component.ts +67 -0
  93. package/src/functions/register.ts +46 -0
  94. package/src/functions/sanitize-react-native-block-styles.ts +65 -0
  95. package/src/functions/set-editor-settings.ts +16 -0
  96. package/src/functions/set.test.ts +19 -0
  97. package/src/functions/set.ts +26 -0
  98. package/src/functions/track.ts +124 -0
  99. package/src/functions/transform-block.ts +6 -0
  100. package/src/helpers/ab-tests.ts +22 -0
  101. package/src/helpers/cookie.ts +102 -0
  102. package/src/helpers/css.ts +33 -0
  103. package/src/helpers/flatten.ts +24 -0
  104. package/src/helpers/localStorage.ts +38 -0
  105. package/src/helpers/nullable.ts +4 -0
  106. package/src/helpers/sessionId.ts +34 -0
  107. package/src/helpers/time.ts +4 -0
  108. package/src/helpers/url.test.ts +16 -0
  109. package/src/helpers/url.ts +12 -0
  110. package/src/helpers/uuid.ts +17 -0
  111. package/src/helpers/visitorId.ts +38 -0
  112. package/src/index-helpers/blocks-exports.ts +10 -0
  113. package/src/index-helpers/top-of-file.ts +4 -0
  114. package/src/index.ts +13 -0
  115. package/src/scripts/init-editing.ts +102 -0
  116. package/src/types/builder-block.ts +58 -0
  117. package/src/types/builder-content.ts +39 -0
  118. package/src/types/can-track.ts +3 -0
  119. package/src/types/components.ts +188 -0
  120. package/src/types/deep-partial.ts +7 -0
  121. package/src/types/element.ts +60 -0
  122. package/src/types/targets.ts +6 -0
  123. package/src/types/typescript.ts +7 -0
@@ -0,0 +1,31 @@
1
+ import type { ComponentInfo } from '../../types/components';
2
+
3
+ export const componentInfo: ComponentInfo = {
4
+ name: 'Custom Code',
5
+ static: true,
6
+ builtIn: true,
7
+ requiredPermissions: ['editCode'],
8
+ inputs: [
9
+ {
10
+ name: 'code',
11
+ type: 'html',
12
+ required: true,
13
+ defaultValue: '<p>Hello there, I am custom HTML code!</p>',
14
+ code: true,
15
+ },
16
+ {
17
+ name: 'replaceNodes',
18
+ type: 'boolean',
19
+ helperText: 'Preserve server rendered dom nodes',
20
+ advanced: true,
21
+ },
22
+ {
23
+ name: 'scriptsClientOnly',
24
+ type: 'boolean',
25
+ defaultValue: false,
26
+ helperText:
27
+ 'Only print and run scripts on the client. Important when scripts influence DOM that could be replaced when client loads',
28
+ advanced: true,
29
+ },
30
+ ],
31
+ };
@@ -0,0 +1,66 @@
1
+ <script context="module" lang="ts">
2
+ export interface CustomCodeProps {
3
+ code: string;
4
+ replaceNodes?: boolean;
5
+ }
6
+ </script>
7
+
8
+ <script lang="ts">
9
+ import { onMount } from "svelte";
10
+
11
+ export let replaceNodes: CustomCodeProps["replaceNodes"];
12
+ export let code: CustomCodeProps["code"];
13
+
14
+ function findAndRunScripts() {
15
+ // TODO: Move this function to standalone one in '@builder.io/utils'
16
+ if (elem && elem.getElementsByTagName && typeof window !== "undefined") {
17
+ const scripts = elem.getElementsByTagName("script");
18
+ for (let i = 0; i < scripts.length; i++) {
19
+ const script = scripts[i];
20
+ if (script.src) {
21
+ if (scriptsInserted.includes(script.src)) {
22
+ continue;
23
+ }
24
+ scriptsInserted.push(script.src);
25
+ const newScript = document.createElement("script");
26
+ newScript.async = true;
27
+ newScript.src = script.src;
28
+ document.head.appendChild(newScript);
29
+ } else if (
30
+ !script.type ||
31
+ [
32
+ "text/javascript",
33
+ "application/javascript",
34
+ "application/ecmascript",
35
+ ].includes(script.type)
36
+ ) {
37
+ if (scriptsRun.includes(script.innerText)) {
38
+ continue;
39
+ }
40
+ try {
41
+ scriptsRun.push(script.innerText);
42
+ new Function(script.innerText)();
43
+ } catch (error) {
44
+ console.warn("`CustomCode`: Error running script:", error);
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ let elem;
52
+
53
+ let scriptsInserted = [];
54
+ let scriptsRun = [];
55
+
56
+ onMount(() => {
57
+ findAndRunScripts();
58
+ });
59
+ </script>
60
+
61
+ <div
62
+ bind:this={elem}
63
+ class={"builder-custom-code" + (replaceNodes ? " replace-nodes" : "")}
64
+ >
65
+ {@html code}
66
+ </div>
@@ -0,0 +1,53 @@
1
+ import type { ComponentInfo } from '../../types/components';
2
+ import { markSerializable } from '../util.js';
3
+
4
+ export const componentInfo: ComponentInfo = {
5
+ name: 'Embed',
6
+ static: true,
7
+ builtIn: true,
8
+ inputs: [
9
+ {
10
+ name: 'url',
11
+ type: 'url',
12
+ required: true,
13
+ defaultValue: '',
14
+ helperText: 'e.g. enter a youtube url, google map, etc',
15
+ onChange: markSerializable((options: Map<string, any>) => {
16
+ const url = options.get('url');
17
+ if (url) {
18
+ options.set('content', 'Loading...');
19
+ // TODO: get this out of here!
20
+ const apiKey = 'ae0e60e78201a3f2b0de4b';
21
+ return fetch(
22
+ `https://iframe.ly/api/iframely?url=${url}&api_key=${apiKey}`
23
+ )
24
+ .then((res) => res.json())
25
+ .then((data) => {
26
+ if (options.get('url') === url) {
27
+ if (data.html) {
28
+ options.set('content', data.html);
29
+ } else {
30
+ options.set('content', 'Invalid url, please try another');
31
+ }
32
+ }
33
+ })
34
+ .catch((_err) => {
35
+ options.set(
36
+ 'content',
37
+ 'There was an error embedding this URL, please try again or another URL'
38
+ );
39
+ });
40
+ } else {
41
+ options.delete('content');
42
+ }
43
+ }),
44
+ },
45
+ {
46
+ name: 'content',
47
+ type: 'html',
48
+ defaultValue:
49
+ '<div style="padding: 20px; text-align: center">(Choose an embed URL)<div>',
50
+ hideFromUI: true,
51
+ },
52
+ ],
53
+ };
@@ -0,0 +1,51 @@
1
+ <script context="module" lang="ts">
2
+ export interface EmbedProps {
3
+ content: string;
4
+ }
5
+ </script>
6
+
7
+ <script lang="ts">
8
+ import { afterUpdate } from "svelte";
9
+
10
+ import { isJsScript } from "./helpers.js";
11
+
12
+ export let content: EmbedProps["content"];
13
+
14
+ function findAndRunScripts() {
15
+ if (!elem || !elem.getElementsByTagName) return;
16
+ const scripts = elem.getElementsByTagName("script");
17
+ for (let i = 0; i < scripts.length; i++) {
18
+ const script = scripts[i];
19
+ if (script.src && !scriptsInserted.includes(script.src)) {
20
+ scriptsInserted.push(script.src);
21
+ const newScript = document.createElement("script");
22
+ newScript.async = true;
23
+ newScript.src = script.src;
24
+ document.head.appendChild(newScript);
25
+ } else if (isJsScript(script) && !scriptsRun.includes(script.innerText)) {
26
+ try {
27
+ scriptsRun.push(script.innerText);
28
+ new Function(script.innerText)();
29
+ } catch (error) {
30
+ console.warn("`Embed`: Error running script:", error);
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ let elem;
37
+
38
+ let scriptsInserted = [];
39
+ let scriptsRun = [];
40
+ let ranInitFn = false;
41
+
42
+ function onUpdateFn_0() {
43
+ if (elem && !ranInitFn) {
44
+ ranInitFn = true;
45
+ findAndRunScripts();
46
+ }
47
+ }
48
+ $: onUpdateFn_0(...[elem, ranInitFn]);
49
+ </script>
50
+
51
+ <div class="builder-embed" bind:this={elem}>{@html content}</div>
@@ -0,0 +1,8 @@
1
+ const SCRIPT_MIME_TYPES = [
2
+ 'text/javascript',
3
+ 'application/javascript',
4
+ 'application/ecmascript',
5
+ ];
6
+
7
+ export const isJsScript = (script: HTMLScriptElement) =>
8
+ SCRIPT_MIME_TYPES.includes(script.type);
@@ -0,0 +1,282 @@
1
+ import type { ComponentInfo } from '../../types/components';
2
+
3
+ export const componentInfo: ComponentInfo = {
4
+ name: 'Form:Form',
5
+ builtIn: true,
6
+ // editableTags: ['builder-form-error']
7
+ defaults: {
8
+ responsiveStyles: {
9
+ large: {
10
+ marginTop: '15px',
11
+ paddingBottom: '15px',
12
+ },
13
+ },
14
+ },
15
+ image:
16
+ 'https://cdn.builder.io/api/v1/image/assets%2FIsxPKMo2gPRRKeakUztj1D6uqed2%2Fef36d2a846134910b64b88e6d18c5ca5',
17
+ inputs: [
18
+ {
19
+ name: 'sendSubmissionsTo',
20
+ type: 'string',
21
+ // TODO: save to builder data and user can download as csv
22
+ // TODO: easy for mode too or computed add/remove fields form mode
23
+ // so you can edit details and high level mode at same time...
24
+ // Later - more integrations like mailchimp
25
+ // /api/v1/form-submit?to=mailchimp
26
+ enum: [
27
+ {
28
+ label: 'Send to email',
29
+ value: 'email',
30
+ helperText:
31
+ 'Send form submissions to the email address of your choosing',
32
+ },
33
+ {
34
+ label: 'Custom',
35
+ value: 'custom',
36
+ helperText:
37
+ 'Handle where the form requests go manually with a little code, e.g. to your own custom backend',
38
+ },
39
+ ],
40
+ defaultValue: 'email',
41
+ },
42
+ {
43
+ name: 'sendSubmissionsToEmail',
44
+ type: 'string',
45
+ required: true, // TODO: required: () => options.get("sendSubmissionsTo") === "email"
46
+ defaultValue: 'your@email.com',
47
+ showIf: 'options.get("sendSubmissionsTo") === "email"',
48
+ },
49
+ {
50
+ name: 'sendWithJs',
51
+ type: 'boolean',
52
+ helperText: 'Set to false to use basic html form action',
53
+ defaultValue: true,
54
+ showIf: 'options.get("sendSubmissionsTo") === "custom"',
55
+ },
56
+ {
57
+ name: 'name',
58
+ type: 'string',
59
+ defaultValue: 'My form',
60
+ // advanced: true
61
+ },
62
+ {
63
+ name: 'action',
64
+ type: 'string',
65
+ helperText: 'URL to send the form data to',
66
+ showIf: 'options.get("sendSubmissionsTo") === "custom"',
67
+ },
68
+ {
69
+ name: 'contentType',
70
+ type: 'string',
71
+ defaultValue: 'application/json',
72
+ advanced: true,
73
+ // TODO: do automatically if file input
74
+ enum: [
75
+ 'application/json',
76
+ 'multipart/form-data',
77
+ 'application/x-www-form-urlencoded',
78
+ ],
79
+ showIf:
80
+ 'options.get("sendSubmissionsTo") === "custom" && options.get("sendWithJs") === true',
81
+ },
82
+ {
83
+ name: 'method',
84
+ type: 'string',
85
+ showIf: 'options.get("sendSubmissionsTo") === "custom"',
86
+ defaultValue: 'POST',
87
+ advanced: true,
88
+ },
89
+ {
90
+ name: 'previewState',
91
+ type: 'string',
92
+ // TODO: persist: false flag
93
+ enum: ['unsubmitted', 'sending', 'success', 'error'],
94
+ defaultValue: 'unsubmitted',
95
+ helperText:
96
+ 'Choose a state to edit, e.g. choose "success" to show what users see on success and edit the message',
97
+ showIf:
98
+ 'options.get("sendSubmissionsTo") !== "zapier" && options.get("sendWithJs") === true',
99
+ },
100
+ {
101
+ name: 'successUrl',
102
+ type: 'url',
103
+ helperText:
104
+ 'Optional URL to redirect the user to on form submission success',
105
+ showIf:
106
+ 'options.get("sendSubmissionsTo") !== "zapier" && options.get("sendWithJs") === true',
107
+ },
108
+ {
109
+ name: 'resetFormOnSubmit',
110
+ type: 'boolean',
111
+ showIf:
112
+ "options.get('sendSubmissionsTo') === 'custom' && options.get('sendWithJs') === true",
113
+ advanced: true,
114
+ },
115
+ {
116
+ name: 'successMessage',
117
+ type: 'uiBlocks',
118
+ hideFromUI: true,
119
+ defaultValue: [
120
+ {
121
+ '@type': '@builder.io/sdk:Element',
122
+ responsiveStyles: {
123
+ large: {
124
+ marginTop: '10px',
125
+ },
126
+ },
127
+ component: {
128
+ name: 'Text',
129
+ options: {
130
+ text: '<span>Thanks!</span>',
131
+ },
132
+ },
133
+ },
134
+ ],
135
+ },
136
+ {
137
+ name: 'validate',
138
+ type: 'boolean',
139
+ defaultValue: true,
140
+ advanced: true,
141
+ },
142
+ {
143
+ name: 'errorMessagePath',
144
+ type: 'text',
145
+ advanced: true,
146
+ helperText:
147
+ 'Path to where to get the error message from in a JSON response to display to the user, e.g. "error.message" for a response like { "error": { "message": "this username is taken" }}',
148
+ },
149
+ {
150
+ name: 'errorMessage',
151
+ type: 'uiBlocks',
152
+ hideFromUI: true,
153
+ defaultValue: [
154
+ {
155
+ '@type': '@builder.io/sdk:Element',
156
+ responsiveStyles: {
157
+ large: {
158
+ marginTop: '10px',
159
+ },
160
+ },
161
+ bindings: {
162
+ 'component.options.text':
163
+ 'state.formErrorMessage || block.component.options.text',
164
+ },
165
+ component: {
166
+ name: 'Text',
167
+ options: {
168
+ text: '<span>Form submission error :( Please check your answers and try again</span>',
169
+ },
170
+ },
171
+ },
172
+ ],
173
+ },
174
+ {
175
+ name: 'sendingMessage',
176
+ type: 'uiBlocks',
177
+ hideFromUI: true,
178
+ defaultValue: [
179
+ {
180
+ '@type': '@builder.io/sdk:Element',
181
+ responsiveStyles: {
182
+ large: {
183
+ marginTop: '10px',
184
+ },
185
+ },
186
+ component: {
187
+ name: 'Text',
188
+ options: {
189
+ text: '<span>Sending...</span>',
190
+ },
191
+ },
192
+ },
193
+ ],
194
+ },
195
+ {
196
+ name: 'customHeaders',
197
+ type: 'map',
198
+ valueType: {
199
+ type: 'string',
200
+ },
201
+ advanced: true,
202
+ showIf:
203
+ 'options.get("sendSubmissionsTo") === "custom" && options.get("sendWithJs") === true',
204
+ },
205
+ ],
206
+ noWrap: true,
207
+ canHaveChildren: true,
208
+ defaultChildren: [
209
+ {
210
+ '@type': '@builder.io/sdk:Element',
211
+ responsiveStyles: {
212
+ large: {
213
+ marginTop: '10px',
214
+ },
215
+ },
216
+ component: {
217
+ name: 'Text',
218
+ options: {
219
+ text: '<span>Enter your name</span>',
220
+ },
221
+ },
222
+ },
223
+ {
224
+ '@type': '@builder.io/sdk:Element',
225
+ responsiveStyles: {
226
+ large: {
227
+ marginTop: '10px',
228
+ },
229
+ },
230
+ component: {
231
+ name: 'Form:Input',
232
+ options: {
233
+ name: 'name',
234
+ placeholder: 'Jane Doe',
235
+ },
236
+ },
237
+ },
238
+ {
239
+ '@type': '@builder.io/sdk:Element',
240
+ responsiveStyles: {
241
+ large: {
242
+ marginTop: '10px',
243
+ },
244
+ },
245
+ component: {
246
+ name: 'Text',
247
+ options: {
248
+ text: '<span>Enter your email</span>',
249
+ },
250
+ },
251
+ },
252
+ {
253
+ '@type': '@builder.io/sdk:Element',
254
+ responsiveStyles: {
255
+ large: {
256
+ marginTop: '10px',
257
+ },
258
+ },
259
+ component: {
260
+ name: 'Form:Input',
261
+ options: {
262
+ name: 'email',
263
+ placeholder: 'jane@doe.com',
264
+ },
265
+ },
266
+ },
267
+ {
268
+ '@type': '@builder.io/sdk:Element',
269
+ responsiveStyles: {
270
+ large: {
271
+ marginTop: '10px',
272
+ },
273
+ },
274
+ component: {
275
+ name: 'Form:SubmitButton',
276
+ options: {
277
+ text: 'Submit',
278
+ },
279
+ },
280
+ },
281
+ ],
282
+ };