@builder.io/sdk-svelte 0.0.1-19 → 0.0.1-21

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 (32) hide show
  1. package/package.json +1 -1
  2. package/src/blocks/button/button.svelte +17 -48
  3. package/src/blocks/columns/columns.svelte +110 -102
  4. package/src/blocks/custom-code/custom-code.svelte +59 -61
  5. package/src/blocks/embed/embed.svelte +50 -57
  6. package/src/blocks/form/form.svelte +264 -294
  7. package/src/blocks/fragment/fragment.svelte +1 -26
  8. package/src/blocks/image/image.svelte +85 -117
  9. package/src/blocks/img/img.svelte +22 -32
  10. package/src/blocks/input/input.svelte +17 -30
  11. package/src/blocks/raw-text/raw-text.svelte +4 -26
  12. package/src/blocks/section/section.svelte +20 -36
  13. package/src/blocks/select/select.svelte +16 -36
  14. package/src/blocks/submit-button/submit-button.svelte +4 -30
  15. package/src/blocks/symbol/symbol.svelte +64 -52
  16. package/src/blocks/text/text.svelte +1 -25
  17. package/src/blocks/textarea/textarea.svelte +5 -29
  18. package/src/blocks/video/video.svelte +35 -43
  19. package/src/components/render-block/block-styles.svelte +49 -59
  20. package/src/components/render-block/render-block.svelte +197 -167
  21. package/src/components/render-block/render-component.svelte +13 -51
  22. package/src/components/render-block/render-repeated-block.svelte +29 -0
  23. package/src/components/render-blocks.svelte +74 -98
  24. package/src/components/render-content/components/render-styles.svelte +42 -62
  25. package/src/components/render-content/render-content.svelte +257 -231
  26. package/src/components/render-inlined-styles.svelte +15 -45
  27. package/src/context/builder.context.js +7 -1
  28. package/src/functions/convert-style-object.js +6 -0
  29. package/src/functions/get-block-styles.js +6 -3
  30. package/src/functions/get-processed-block.js +15 -8
  31. package/src/functions/get-processed-block.test.js +2 -1
  32. package/src/functions/sanitize-styles.js +5 -0
@@ -1,333 +1,303 @@
1
1
  <script>
2
-
3
-
4
-
5
-
6
- import RenderBlock from '../../components/render-block/render-block.svelte';
7
- import { isEditing } from '../../functions/is-editing.js';
8
-
9
-
10
-
11
-
12
-
13
-
14
- export let formRef;
15
- export let previewState;
16
- export let sendWithJs;
17
- export let sendSubmissionsTo;
18
- export let action;
19
- export let customHeaders;
20
- export let contentType;
21
- export let sendSubmissionsToEmail;
22
- export let name;
23
- export let method;
24
- export let errorMessagePath;
25
- export let resetFormOnSubmit;
26
- export let successUrl;
27
- export let validate;
28
- export let attributes;
29
- export let builderBlock;
30
- export let errorMessage;
31
- export let sendingMessage;
32
- export let successMessage;
33
-
34
- function onSubmit(event) {
35
- const sendWithJs = sendWithJs || sendSubmissionsTo === 'email';
36
-
37
- if (sendSubmissionsTo === 'zapier') {
38
- event.preventDefault();
39
- } else if (sendWithJs) {
40
- if (!(action || sendSubmissionsTo === 'email')) {
41
- event.preventDefault();
42
- return;
43
- }
44
-
45
- event.preventDefault();
46
- const el = event.currentTarget;
47
- const headers = customHeaders || {};
48
- let body;
49
- const formData = new FormData(el); // TODO: maybe support null
2
+ import RenderBlock from "../../components/render-block/render-block.svelte";
3
+ import { isEditing } from "../../functions/is-editing.js";
4
+
5
+ export let formRef;
6
+ export let previewState;
7
+ export let sendWithJs;
8
+ export let sendSubmissionsTo;
9
+ export let action;
10
+ export let customHeaders;
11
+ export let contentType;
12
+ export let sendSubmissionsToEmail;
13
+ export let name;
14
+ export let method;
15
+ export let errorMessagePath;
16
+ export let resetFormOnSubmit;
17
+ export let successUrl;
18
+ export let validate;
19
+ export let attributes;
20
+ export let builderBlock;
21
+ export let errorMessage;
22
+ export let sendingMessage;
23
+ export let successMessage;
24
+
25
+ const onSubmit = function onSubmit(event) {
26
+ const sendWithJs = sendWithJs || sendSubmissionsTo === "email";
27
+
28
+ if (sendSubmissionsTo === "zapier") {
29
+ event.preventDefault();
30
+ } else if (sendWithJs) {
31
+ if (!(action || sendSubmissionsTo === "email")) {
32
+ event.preventDefault();
33
+ return;
34
+ }
50
35
 
51
- const formPairs = Array.from(event.currentTarget.querySelectorAll('input,select,textarea')).filter(el => !!el.name).map(el => {
52
- let value;
53
- const key = el.name;
36
+ event.preventDefault();
37
+ const el = event.currentTarget;
38
+ const headers = customHeaders || {};
39
+ let body;
40
+ const formData = new FormData(el); // TODO: maybe support null
41
+
42
+ const formPairs = Array.from(
43
+ event.currentTarget.querySelectorAll("input,select,textarea")
44
+ )
45
+ .filter((el) => !!el.name)
46
+ .map((el) => {
47
+ let value;
48
+ const key = el.name;
49
+
50
+ if (el instanceof HTMLInputElement) {
51
+ if (el.type === "radio") {
52
+ if (el.checked) {
53
+ value = el.name;
54
+ return {
55
+ key,
56
+ value,
57
+ };
58
+ }
59
+ } else if (el.type === "checkbox") {
60
+ value = el.checked;
61
+ } else if (el.type === "number" || el.type === "range") {
62
+ const num = el.valueAsNumber;
63
+
64
+ if (!isNaN(num)) {
65
+ value = num;
66
+ }
67
+ } else if (el.type === "file") {
68
+ // TODO: one vs multiple files
69
+ value = el.files;
70
+ } else {
71
+ value = el.value;
72
+ }
73
+ } else {
74
+ value = el.value;
75
+ }
54
76
 
55
- if (el instanceof HTMLInputElement) {
56
- if (el.type === 'radio') {
57
- if (el.checked) {
58
- value = el.name;
59
77
  return {
60
78
  key,
61
- value
79
+ value,
62
80
  };
63
- }
64
- } else if (el.type === 'checkbox') {
65
- value = el.checked;
66
- } else if (el.type === 'number' || el.type === 'range') {
67
- const num = el.valueAsNumber;
81
+ });
82
+ let contentType = contentType;
68
83
 
69
- if (!isNaN(num)) {
70
- value = num;
71
- }
72
- } else if (el.type === 'file') {
73
- // TODO: one vs multiple files
74
- value = el.files;
75
- } else {
76
- value = el.value;
84
+ if (sendSubmissionsTo === "email") {
85
+ contentType = "multipart/form-data";
77
86
  }
78
- } else {
79
- value = el.value;
80
- }
81
-
82
- return {
83
- key,
84
- value
85
- };
86
- });
87
- let contentType = contentType;
88
-
89
- if (sendSubmissionsTo === 'email') {
90
- contentType = 'multipart/form-data';
91
- }
92
-
93
- Array.from(formPairs).forEach(({
94
- value
95
- }) => {
96
- if (value instanceof File || Array.isArray(value) && value[0] instanceof File || value instanceof FileList) {
97
- contentType = 'multipart/form-data';
98
- }
99
- }); // TODO: send as urlEncoded or multipart by default
100
- // because of ease of use and reliability in browser API
101
- // for encoding the form?
102
-
103
- if (contentType !== 'application/json') {
104
- body = formData;
105
- } else {
106
- // Json
107
- const json = {};
108
- Array.from(formPairs).forEach(({
109
- value,
110
- key
111
- }) => {
112
- set(json, key, value);
113
- });
114
- body = JSON.stringify(json);
115
- }
116
-
117
- if (contentType && contentType !== 'multipart/form-data') {
118
- if (
119
- /* Zapier doesn't allow content-type header to be sent from browsers */
120
- !(sendWithJs && action?.includes('zapier.com'))) {
121
- headers['content-type'] = contentType;
122
- }
123
- }
124
-
125
- const presubmitEvent = new CustomEvent('presubmit', {
126
- detail: {
127
- body
128
- }
129
- });
130
-
131
- if (formRef) {
132
- formRef.dispatchEvent(presubmitEvent);
133
-
134
- if (presubmitEvent.defaultPrevented) {
135
- return;
136
- }
137
- }
138
87
 
139
- formState = 'sending';
140
- const formUrl = `${builder.env === 'dev' ? 'http://localhost:5000' : 'https://builder.io'}/api/v1/form-submit?apiKey=${builder.apiKey}&to=${btoa(sendSubmissionsToEmail || '')}&name=${encodeURIComponent(name || '')}`;
141
- fetch(sendSubmissionsTo === 'email' ? formUrl : action
142
- /* TODO: throw error if no action URL */
143
- , {
144
- body,
145
- headers,
146
- method: method || 'post'
147
- }).then(async res => {
148
- let body;
149
- const contentType = res.headers.get('content-type');
150
-
151
- if (contentType && contentType.indexOf('application/json') !== -1) {
152
- body = await res.json();
153
- } else {
154
- body = await res.text();
155
- }
156
-
157
- if (!res.ok && errorMessagePath) {
158
- /* TODO: allow supplying an error formatter function */
159
- let message = get(body, errorMessagePath);
160
-
161
- if (message) {
162
- if (typeof message !== 'string') {
163
- /* TODO: ideally convert json to yaml so it woul dbe like
164
- error: - email has been taken */
165
- message = JSON.stringify(message);
88
+ Array.from(formPairs).forEach(({ value }) => {
89
+ if (
90
+ value instanceof File ||
91
+ (Array.isArray(value) && value[0] instanceof File) ||
92
+ value instanceof FileList
93
+ ) {
94
+ contentType = "multipart/form-data";
166
95
  }
96
+ }); // TODO: send as urlEncoded or multipart by default
97
+ // because of ease of use and reliability in browser API
98
+ // for encoding the form?
167
99
 
168
- formErrorMessage = message;
100
+ if (contentType !== "application/json") {
101
+ body = formData;
102
+ } else {
103
+ // Json
104
+ const json = {};
105
+ Array.from(formPairs).forEach(({ value, key }) => {
106
+ set(json, key, value);
107
+ });
108
+ body = JSON.stringify(json);
169
109
  }
170
- }
171
110
 
172
- responseData = body;
173
- formState = res.ok ? 'success' : 'error';
111
+ if (contentType && contentType !== "multipart/form-data") {
112
+ if (
113
+ /* Zapier doesn't allow content-type header to be sent from browsers */
114
+ !(sendWithJs && action?.includes("zapier.com"))
115
+ ) {
116
+ headers["content-type"] = contentType;
117
+ }
118
+ }
174
119
 
175
- if (res.ok) {
176
- const submitSuccessEvent = new CustomEvent('submit:success', {
120
+ const presubmitEvent = new CustomEvent("presubmit", {
177
121
  detail: {
178
- res,
179
- body
180
- }
122
+ body,
123
+ },
181
124
  });
182
125
 
183
126
  if (formRef) {
184
- formRef.dispatchEvent(submitSuccessEvent);
127
+ formRef.dispatchEvent(presubmitEvent);
185
128
 
186
- if (submitSuccessEvent.defaultPrevented) {
129
+ if (presubmitEvent.defaultPrevented) {
187
130
  return;
188
131
  }
189
- /* TODO: option to turn this on/off? */
190
-
191
-
192
- if (resetFormOnSubmit !== false) {
193
- formRef.reset();
194
- }
195
132
  }
196
- /* TODO: client side route event first that can be preventDefaulted */
197
133
 
198
-
199
- if (successUrl) {
200
- if (formRef) {
201
- const event = new CustomEvent('route', {
202
- detail: {
203
- url: successUrl
204
- }
205
- });
206
- formRef.dispatchEvent(event);
207
-
208
- if (!event.defaultPrevented) {
209
- location.href = successUrl;
210
- }
211
- } else {
212
- location.href = successUrl;
134
+ formState = "sending";
135
+ const formUrl = `${
136
+ builder.env === "dev" ? "http://localhost:5000" : "https://builder.io"
137
+ }/api/v1/form-submit?apiKey=${builder.apiKey}&to=${btoa(
138
+ sendSubmissionsToEmail || ""
139
+ )}&name=${encodeURIComponent(name || "")}`;
140
+ fetch(
141
+ sendSubmissionsTo === "email" ? formUrl : action,
142
+ /* TODO: throw error if no action URL */
143
+ {
144
+ body,
145
+ headers,
146
+ method: method || "post",
213
147
  }
214
- }
215
- }
216
- }, err => {
217
- const submitErrorEvent = new CustomEvent('submit:error', {
218
- detail: {
219
- error: err
220
- }
221
- });
222
-
223
- if (formRef) {
224
- formRef.dispatchEvent(submitErrorEvent);
225
-
226
- if (submitErrorEvent.defaultPrevented) {
227
- return;
228
- }
229
- }
230
-
231
- responseData = err;
232
- formState = 'error';
233
- });
234
- }
235
- }
236
- $: submissionState = () => {
237
- return isEditing() && previewState || formState;
238
- };
239
-
240
-
241
-
242
- let formState = 'unsubmitted';
243
- let responseData = null;
244
- let formErrorMessage = '';
245
-
246
-
247
-
248
-
249
-
250
-
251
- </script>
252
-
253
- <form {...attributes} validate={validate} bind:this={formRef} action={!sendWithJs && action} method={method} name={name} on:submit="{event => onSubmit(event)}" >
254
-
255
-
256
- {#if builderBlock && builderBlock.children }
257
-
258
-
259
-
260
- {#each builderBlock?.children as block, index }
261
- <RenderBlock block={block} ></RenderBlock>
262
- {/each}
263
-
264
-
265
-
266
-
267
-
268
- {/if}
269
-
270
-
271
-
272
-
273
- {#if submissionState() === 'error' }
274
-
275
-
276
- <svelte:component dataPath="errorMessage" blocks={errorMessage} this={BuilderBlocks} ></svelte:component>
277
-
278
-
279
-
280
-
281
- {/if}
148
+ ).then(
149
+ async (res) => {
150
+ let body;
151
+ const contentType = res.headers.get("content-type");
152
+
153
+ if (contentType && contentType.indexOf("application/json") !== -1) {
154
+ body = await res.json();
155
+ } else {
156
+ body = await res.text();
157
+ }
282
158
 
159
+ if (!res.ok && errorMessagePath) {
160
+ /* TODO: allow supplying an error formatter function */
161
+ let message = get(body, errorMessagePath);
283
162
 
284
-
163
+ if (message) {
164
+ if (typeof message !== "string") {
165
+ /* TODO: ideally convert json to yaml so it woul dbe like
166
+ error: - email has been taken */
167
+ message = JSON.stringify(message);
168
+ }
285
169
 
286
- {#if submissionState() === 'sending' }
170
+ formErrorMessage = message;
171
+ }
172
+ }
287
173
 
288
-
289
- <svelte:component dataPath="sendingMessage" blocks={sendingMessage} this={BuilderBlocks} ></svelte:component>
174
+ responseData = body;
175
+ formState = res.ok ? "success" : "error";
290
176
 
291
-
177
+ if (res.ok) {
178
+ const submitSuccessEvent = new CustomEvent("submit:success", {
179
+ detail: {
180
+ res,
181
+ body,
182
+ },
183
+ });
292
184
 
185
+ if (formRef) {
186
+ formRef.dispatchEvent(submitSuccessEvent);
293
187
 
294
- {/if}
188
+ if (submitSuccessEvent.defaultPrevented) {
189
+ return;
190
+ }
191
+ /* TODO: option to turn this on/off? */
295
192
 
193
+ if (resetFormOnSubmit !== false) {
194
+ formRef.reset();
195
+ }
196
+ }
197
+ /* TODO: client side route event first that can be preventDefaulted */
198
+
199
+ if (successUrl) {
200
+ if (formRef) {
201
+ const event = new CustomEvent("route", {
202
+ detail: {
203
+ url: successUrl,
204
+ },
205
+ });
206
+ formRef.dispatchEvent(event);
207
+
208
+ if (!event.defaultPrevented) {
209
+ location.href = successUrl;
210
+ }
211
+ } else {
212
+ location.href = successUrl;
213
+ }
214
+ }
215
+ }
216
+ },
217
+ (err) => {
218
+ const submitErrorEvent = new CustomEvent("submit:error", {
219
+ detail: {
220
+ error: err,
221
+ },
222
+ });
296
223
 
297
-
224
+ if (formRef) {
225
+ formRef.dispatchEvent(submitErrorEvent);
298
226
 
299
- {#if submissionState() === 'error' && responseData }
227
+ if (submitErrorEvent.defaultPrevented) {
228
+ return;
229
+ }
230
+ }
300
231
 
301
-
302
- <pre class="builder-form-error-text pre" >
232
+ responseData = err;
233
+ formState = "error";
234
+ }
235
+ );
236
+ }
237
+ };
238
+ $: submissionState = () => {
239
+ return (isEditing() && previewState) || formState;
240
+ };
241
+
242
+ let formState = "unsubmitted";
243
+ let responseData = null;
244
+ let formErrorMessage = "";
245
+ </script>
246
+
247
+ <form
248
+ {...attributes}
249
+ {validate}
250
+ bind:this={formRef}
251
+ action={!sendWithJs && action}
252
+ {method}
253
+ {name}
254
+ on:submit={(event) => {
255
+ onSubmit(event);
256
+ }}
257
+ >
258
+ {#if builderBlock && builderBlock.children}
259
+ {#each builderBlock?.children as block, undefined}
260
+ <RenderBlock {block} />
261
+ {/each}
262
+ {/if}
263
+
264
+ {#if submissionState() === "error"}
265
+ <svelte:component
266
+ this={BuilderBlocks}
267
+ dataPath="errorMessage"
268
+ blocks={errorMessage}
269
+ />
270
+ {/if}
271
+
272
+ {#if submissionState() === "sending"}
273
+ <svelte:component
274
+ this={BuilderBlocks}
275
+ dataPath="sendingMessage"
276
+ blocks={sendingMessage}
277
+ />
278
+ {/if}
279
+
280
+ {#if submissionState() === "error" && responseData}
281
+ <pre class="builder-form-error-text pre">
303
282
 
304
283
  {JSON.stringify(responseData, null, 2)}
305
284
 
306
285
  </pre>
307
-
308
-
309
-
310
-
311
- {/if}
312
-
313
-
314
-
315
-
316
- {#if submissionState() === 'success' }
317
-
318
-
319
- <svelte:component dataPath="successMessage" blocks={successMessage} this={BuilderBlocks} ></svelte:component>
320
-
321
-
322
-
323
-
324
- {/if}
325
-
326
- </form>
327
-
328
- <style>
329
- .pre {
330
- padding: 10px;
331
- color: red;
332
- text-align: center; }
333
- </style>
286
+ {/if}
287
+
288
+ {#if submissionState() === "success"}
289
+ <svelte:component
290
+ this={BuilderBlocks}
291
+ dataPath="successMessage"
292
+ blocks={successMessage}
293
+ />
294
+ {/if}
295
+ </form>
296
+
297
+ <style>
298
+ .pre {
299
+ padding: 10px;
300
+ color: red;
301
+ text-align: center;
302
+ }
303
+ </style>
@@ -1,29 +1,4 @@
1
1
  <script>
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
2
  </script>
28
3
 
29
- <span ><slot></slot></span>
4
+ <span><slot /></span>