@builder.io/sdk-react-native 0.0.1-25 → 0.0.1-26
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.
- package/package.json +3 -2
- package/src/blocks/button.js +66 -22
- package/src/blocks/button.lite.tsx +4 -4
- package/src/blocks/columns.js +247 -36
- package/src/blocks/columns.lite.tsx +7 -7
- package/src/blocks/custom-code.js +73 -47
- package/src/blocks/custom-code.lite.tsx +12 -16
- package/src/blocks/embed.js +66 -47
- package/src/blocks/embed.lite.tsx +11 -13
- package/src/blocks/form.js +436 -195
- package/src/blocks/form.lite.tsx +65 -72
- package/src/blocks/fragment.js +16 -8
- package/src/blocks/fragment.lite.tsx +3 -3
- package/src/blocks/image.js +88 -80
- package/src/blocks/image.lite.tsx +14 -15
- package/src/blocks/img.js +45 -28
- package/src/blocks/img.lite.tsx +7 -7
- package/src/blocks/input.js +93 -28
- package/src/blocks/input.lite.tsx +5 -7
- package/src/blocks/raw-text.js +16 -12
- package/src/blocks/raw-text.lite.tsx +3 -3
- package/src/blocks/section.js +66 -23
- package/src/blocks/section.lite.tsx +4 -4
- package/src/blocks/select.js +67 -28
- package/src/blocks/select.lite.tsx +6 -8
- package/src/blocks/submit-button.js +41 -21
- package/src/blocks/submit-button.lite.tsx +3 -3
- package/src/blocks/symbol.js +18 -16
- package/src/blocks/symbol.lite.tsx +5 -5
- package/src/blocks/text.js +29 -27
- package/src/blocks/text.lite.tsx +4 -9
- package/src/blocks/textarea.js +53 -24
- package/src/blocks/textarea.lite.tsx +3 -3
- package/src/blocks/video.js +112 -46
- package/src/blocks/video.lite.tsx +6 -6
- package/src/components/block-styles.js +2 -4
- package/src/components/block-styles.lite.tsx +3 -3
- package/src/components/error-boundary.js +11 -9
- package/src/components/error-boundary.lite.tsx +3 -3
- package/src/components/render-block.js +85 -40
- package/src/components/render-block.lite.tsx +17 -25
- package/src/components/render-blocks.js +56 -32
- package/src/components/render-blocks.lite.tsx +14 -14
- package/src/components/render-content.js +100 -52
- package/src/components/render-content.lite.tsx +32 -41
- package/src/constants/device-sizes.js +8 -11
- package/src/context/builder.context.js +2 -4
- package/src/functions/evaluate.js +17 -9
- package/src/functions/get-block-actions.js +9 -10
- package/src/functions/get-block-component-options.js +11 -10
- package/src/functions/get-block-properties.js +15 -17
- package/src/functions/get-block-styles.js +19 -16
- package/src/functions/get-block-tag.js +2 -4
- package/src/functions/get-content.js +40 -29
- package/src/functions/get-fetch.js +5 -7
- package/src/functions/get-global-this.js +5 -7
- package/src/functions/get-processed-block.js +11 -13
- package/src/functions/get-processed-block.test.js +14 -14
- package/src/functions/get-target.js +2 -4
- package/src/functions/if-target.js +1 -3
- package/src/functions/is-browser.js +3 -5
- package/src/functions/is-editing.js +3 -5
- package/src/functions/is-iframe.js +2 -4
- package/src/functions/is-previewing.js +4 -6
- package/src/functions/is-react-native.js +2 -4
- package/src/functions/macro-eval.js +2 -5
- package/src/functions/on-change.js +4 -7
- package/src/functions/on-change.test.js +10 -10
- package/src/functions/previewing-model-name.js +3 -5
- package/src/functions/register-component.js +33 -28
- package/src/functions/register.js +8 -10
- package/src/functions/set-editor-settings.js +5 -7
- package/src/functions/set.js +10 -4
- package/src/functions/set.test.js +14 -14
- package/src/functions/track.js +6 -8
- package/src/index.js +20 -18
- package/src/scripts/init-editing.js +64 -40
package/src/blocks/form.lite.tsx
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import { View, StyleSheet, Image, Text } from
|
|
3
|
-
import { useState, useContext, useRef } from
|
|
4
|
-
import RenderBlock from
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View, StyleSheet, Image, Text } from 'react-native';
|
|
3
|
+
import { useState, useContext, useRef } from 'react';
|
|
4
|
+
import RenderBlock from '../components/render-block.lite';
|
|
5
5
|
|
|
6
6
|
export default function FormComponent(props) {
|
|
7
|
-
const [state, setState] = useState(() =>
|
|
7
|
+
const [state, setState] = useState(() => 'unsubmitted');
|
|
8
8
|
|
|
9
9
|
const [responseData, setResponseData] = useState(() => null);
|
|
10
10
|
|
|
11
|
-
const [formErrorMessage, setFormErrorMessage] = useState(() =>
|
|
11
|
+
const [formErrorMessage, setFormErrorMessage] = useState(() => '');
|
|
12
12
|
|
|
13
13
|
function submissionState() {
|
|
14
14
|
return (Builder.isEditing && props.previewState) || state;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
function onSubmit(event) {
|
|
18
|
-
const sendWithJs = props.sendWithJs || props.sendSubmissionsTo ===
|
|
18
|
+
const sendWithJs = props.sendWithJs || props.sendSubmissionsTo === 'email';
|
|
19
19
|
|
|
20
|
-
if (props.sendSubmissionsTo ===
|
|
20
|
+
if (props.sendSubmissionsTo === 'zapier') {
|
|
21
21
|
event.preventDefault();
|
|
22
22
|
} else if (sendWithJs) {
|
|
23
|
-
if (!(props.action || props.sendSubmissionsTo ===
|
|
23
|
+
if (!(props.action || props.sendSubmissionsTo === 'email')) {
|
|
24
24
|
event.preventDefault();
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
@@ -31,16 +31,14 @@ export default function FormComponent(props) {
|
|
|
31
31
|
let body;
|
|
32
32
|
const formData = new FormData(el); // TODO: maybe support null
|
|
33
33
|
|
|
34
|
-
const formPairs = Array.from(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
.filter((el) => !!el.name)
|
|
38
|
-
.map((el) => {
|
|
34
|
+
const formPairs = Array.from(event.currentTarget.querySelectorAll('input,select,textarea'))
|
|
35
|
+
.filter(el => !!el.name)
|
|
36
|
+
.map(el => {
|
|
39
37
|
let value;
|
|
40
38
|
const key = el.name;
|
|
41
39
|
|
|
42
40
|
if (el instanceof HTMLInputElement) {
|
|
43
|
-
if (el.type ===
|
|
41
|
+
if (el.type === 'radio') {
|
|
44
42
|
if (el.checked) {
|
|
45
43
|
value = el.name;
|
|
46
44
|
return {
|
|
@@ -48,15 +46,15 @@ export default function FormComponent(props) {
|
|
|
48
46
|
value,
|
|
49
47
|
};
|
|
50
48
|
}
|
|
51
|
-
} else if (el.type ===
|
|
49
|
+
} else if (el.type === 'checkbox') {
|
|
52
50
|
value = el.checked;
|
|
53
|
-
} else if (el.type ===
|
|
51
|
+
} else if (el.type === 'number' || el.type === 'range') {
|
|
54
52
|
const num = el.valueAsNumber;
|
|
55
53
|
|
|
56
54
|
if (!isNaN(num)) {
|
|
57
55
|
value = num;
|
|
58
56
|
}
|
|
59
|
-
} else if (el.type ===
|
|
57
|
+
} else if (el.type === 'file') {
|
|
60
58
|
// TODO: one vs multiple files
|
|
61
59
|
value = el.files;
|
|
62
60
|
} else {
|
|
@@ -73,8 +71,8 @@ export default function FormComponent(props) {
|
|
|
73
71
|
});
|
|
74
72
|
let contentType = props.contentType;
|
|
75
73
|
|
|
76
|
-
if (props.sendSubmissionsTo ===
|
|
77
|
-
contentType =
|
|
74
|
+
if (props.sendSubmissionsTo === 'email') {
|
|
75
|
+
contentType = 'multipart/form-data';
|
|
78
76
|
}
|
|
79
77
|
|
|
80
78
|
Array.from(formPairs).forEach(({ value }) => {
|
|
@@ -83,13 +81,13 @@ export default function FormComponent(props) {
|
|
|
83
81
|
(Array.isArray(value) && value[0] instanceof File) ||
|
|
84
82
|
value instanceof FileList
|
|
85
83
|
) {
|
|
86
|
-
contentType =
|
|
84
|
+
contentType = 'multipart/form-data';
|
|
87
85
|
}
|
|
88
86
|
}); // TODO: send as urlEncoded or multipart by default
|
|
89
87
|
// because of ease of use and reliability in browser API
|
|
90
88
|
// for encoding the form?
|
|
91
89
|
|
|
92
|
-
if (contentType !==
|
|
90
|
+
if (contentType !== 'application/json') {
|
|
93
91
|
body = formData;
|
|
94
92
|
} else {
|
|
95
93
|
// Json
|
|
@@ -100,57 +98,60 @@ export default function FormComponent(props) {
|
|
|
100
98
|
body = JSON.stringify(json);
|
|
101
99
|
}
|
|
102
100
|
|
|
103
|
-
if (contentType && contentType !==
|
|
101
|
+
if (contentType && contentType !== 'multipart/form-data') {
|
|
104
102
|
if (
|
|
105
103
|
/* Zapier doesn't allow content-type header to be sent from browsers */ !(
|
|
106
|
-
sendWithJs && props.action?.includes(
|
|
104
|
+
sendWithJs && props.action?.includes('zapier.com')
|
|
107
105
|
)
|
|
108
106
|
) {
|
|
109
|
-
headers[
|
|
107
|
+
headers['content-type'] = contentType;
|
|
110
108
|
}
|
|
111
109
|
}
|
|
112
|
-
const presubmitEvent = new CustomEvent(
|
|
110
|
+
const presubmitEvent = new CustomEvent('presubmit', { detail: { body } });
|
|
113
111
|
if (formRef.current) {
|
|
114
112
|
formRef.current.dispatchEvent(presubmitEvent);
|
|
115
113
|
if (presubmitEvent.defaultPrevented) {
|
|
116
114
|
return;
|
|
117
115
|
}
|
|
118
116
|
}
|
|
119
|
-
setState(
|
|
117
|
+
setState('sending');
|
|
120
118
|
const formUrl = `${
|
|
121
|
-
builder.env ===
|
|
119
|
+
builder.env === 'dev' ? 'http://localhost:5000' : 'https://builder.io'
|
|
122
120
|
}/api/v1/form-submit?apiKey=${builder.apiKey}&to=${btoa(
|
|
123
|
-
props.sendSubmissionsToEmail ||
|
|
124
|
-
)}&name=${encodeURIComponent(props.name ||
|
|
121
|
+
props.sendSubmissionsToEmail || ''
|
|
122
|
+
)}&name=${encodeURIComponent(props.name || '')}`;
|
|
125
123
|
fetch(
|
|
126
|
-
props.sendSubmissionsTo ===
|
|
124
|
+
props.sendSubmissionsTo === 'email'
|
|
127
125
|
? formUrl
|
|
128
126
|
: props.action /* TODO: throw error if no action URL */,
|
|
129
|
-
{ body, headers, method: props.method ||
|
|
127
|
+
{ body, headers, method: props.method || 'post' }
|
|
130
128
|
).then(
|
|
131
|
-
async
|
|
129
|
+
async res => {
|
|
132
130
|
let body;
|
|
133
|
-
const contentType = res.headers.get(
|
|
134
|
-
if (contentType && contentType.indexOf(
|
|
131
|
+
const contentType = res.headers.get('content-type');
|
|
132
|
+
if (contentType && contentType.indexOf('application/json') !== -1) {
|
|
135
133
|
body = await res.json();
|
|
136
134
|
} else {
|
|
137
135
|
body = await res.text();
|
|
138
136
|
}
|
|
139
137
|
if (!res.ok && props.errorMessagePath) {
|
|
140
|
-
/* TODO: allow supplying an error formatter function */ let message =
|
|
141
|
-
|
|
138
|
+
/* TODO: allow supplying an error formatter function */ let message = get(
|
|
139
|
+
body,
|
|
140
|
+
props.errorMessagePath
|
|
141
|
+
);
|
|
142
142
|
if (message) {
|
|
143
|
-
if (typeof message !==
|
|
144
|
-
/* TODO: ideally convert json to yaml so it woul dbe like error: - email has been taken */ message =
|
|
145
|
-
|
|
143
|
+
if (typeof message !== 'string') {
|
|
144
|
+
/* TODO: ideally convert json to yaml so it woul dbe like error: - email has been taken */ message = JSON.stringify(
|
|
145
|
+
message
|
|
146
|
+
);
|
|
146
147
|
}
|
|
147
148
|
setFormErrorMessage(message);
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
setResponseData(body);
|
|
151
|
-
setState(res.ok ?
|
|
152
|
+
setState(res.ok ? 'success' : 'error');
|
|
152
153
|
if (res.ok) {
|
|
153
|
-
const submitSuccessEvent = new CustomEvent(
|
|
154
|
+
const submitSuccessEvent = new CustomEvent('submit:success', {
|
|
154
155
|
detail: { res, body },
|
|
155
156
|
});
|
|
156
157
|
if (formRef.current) {
|
|
@@ -158,9 +159,7 @@ export default function FormComponent(props) {
|
|
|
158
159
|
if (submitSuccessEvent.defaultPrevented) {
|
|
159
160
|
return;
|
|
160
161
|
}
|
|
161
|
-
/* TODO: option to turn this on/off? */ if (
|
|
162
|
-
props.resetFormOnSubmit !== false
|
|
163
|
-
) {
|
|
162
|
+
/* TODO: option to turn this on/off? */ if (props.resetFormOnSubmit !== false) {
|
|
164
163
|
formRef.current.reset();
|
|
165
164
|
}
|
|
166
165
|
}
|
|
@@ -168,7 +167,7 @@ export default function FormComponent(props) {
|
|
|
168
167
|
props.successUrl
|
|
169
168
|
) {
|
|
170
169
|
if (formRef.current) {
|
|
171
|
-
const event = new CustomEvent(
|
|
170
|
+
const event = new CustomEvent('route', {
|
|
172
171
|
detail: { url: props.successUrl },
|
|
173
172
|
});
|
|
174
173
|
formRef.current.dispatchEvent(event);
|
|
@@ -181,8 +180,8 @@ export default function FormComponent(props) {
|
|
|
181
180
|
}
|
|
182
181
|
}
|
|
183
182
|
},
|
|
184
|
-
|
|
185
|
-
const submitErrorEvent = new CustomEvent(
|
|
183
|
+
err => {
|
|
184
|
+
const submitErrorEvent = new CustomEvent('submit:error', {
|
|
186
185
|
detail: { error: err },
|
|
187
186
|
});
|
|
188
187
|
if (formRef.current) {
|
|
@@ -192,7 +191,7 @@ export default function FormComponent(props) {
|
|
|
192
191
|
}
|
|
193
192
|
}
|
|
194
193
|
setResponseData(err);
|
|
195
|
-
setState(
|
|
194
|
+
setState('error');
|
|
196
195
|
}
|
|
197
196
|
);
|
|
198
197
|
}
|
|
@@ -206,48 +205,42 @@ export default function FormComponent(props) {
|
|
|
206
205
|
action={!props.sendWithJs && props.action}
|
|
207
206
|
method={props.method}
|
|
208
207
|
name={props.name}
|
|
209
|
-
onSubmit={
|
|
208
|
+
onSubmit={event => onSubmit(event)}
|
|
210
209
|
>
|
|
211
|
-
{
|
|
210
|
+
{' '}
|
|
212
211
|
{props.builderBlock && props.builderBlock.children ? (
|
|
213
212
|
<>
|
|
214
|
-
{props.builderBlock?.children?.map(
|
|
213
|
+
{props.builderBlock?.children?.map(block => (
|
|
215
214
|
<RenderBlock block={block} />
|
|
216
215
|
))}
|
|
217
216
|
</>
|
|
218
|
-
) : null}{
|
|
219
|
-
{submissionState() ===
|
|
217
|
+
) : null}{' '}
|
|
218
|
+
{submissionState() === 'error' ? (
|
|
220
219
|
<>
|
|
221
220
|
<BuilderBlocks dataPath="errorMessage" blocks={props.errorMessage} />
|
|
222
221
|
</>
|
|
223
|
-
) : null}{
|
|
224
|
-
{submissionState() ===
|
|
222
|
+
) : null}{' '}
|
|
223
|
+
{submissionState() === 'sending' ? (
|
|
225
224
|
<>
|
|
226
|
-
<BuilderBlocks
|
|
227
|
-
dataPath="sendingMessage"
|
|
228
|
-
blocks={props.sendingMessage}
|
|
229
|
-
/>
|
|
225
|
+
<BuilderBlocks dataPath="sendingMessage" blocks={props.sendingMessage} />
|
|
230
226
|
</>
|
|
231
|
-
) : null}{
|
|
232
|
-
{submissionState() ===
|
|
227
|
+
) : null}{' '}
|
|
228
|
+
{submissionState() === 'error' && responseData ? (
|
|
233
229
|
<>
|
|
234
230
|
<View className="builder-form-error-text" style={styles.view1}>
|
|
235
|
-
{
|
|
236
|
-
<Text>{JSON.stringify(responseData, null, 2)}</Text>{
|
|
231
|
+
{' '}
|
|
232
|
+
<Text>{JSON.stringify(responseData, null, 2)}</Text>{' '}
|
|
237
233
|
</View>
|
|
238
234
|
</>
|
|
239
|
-
) : null}{
|
|
240
|
-
{submissionState() ===
|
|
235
|
+
) : null}{' '}
|
|
236
|
+
{submissionState() === 'success' ? (
|
|
241
237
|
<>
|
|
242
|
-
<BuilderBlocks
|
|
243
|
-
dataPath="successMessage"
|
|
244
|
-
blocks={props.successMessage}
|
|
245
|
-
/>
|
|
238
|
+
<BuilderBlocks dataPath="successMessage" blocks={props.successMessage} />
|
|
246
239
|
</>
|
|
247
|
-
) : null}{
|
|
240
|
+
) : null}{' '}
|
|
248
241
|
</View>
|
|
249
242
|
);
|
|
250
243
|
}
|
|
251
244
|
const styles = StyleSheet.create({
|
|
252
|
-
view1: { padding: 10, color:
|
|
245
|
+
view1: { padding: 10, color: 'red', textAlign: 'center' },
|
|
253
246
|
});
|
package/src/blocks/fragment.js
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { registerComponent } from '../functions/register-component';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
import { View, Text } from
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { View, Text } from 'react-native';
|
|
5
5
|
function FragmentComponent(props) {
|
|
6
|
-
return /* @__PURE__ */ React.createElement(
|
|
6
|
+
return /* @__PURE__ */ React.createElement(
|
|
7
|
+
View,
|
|
8
|
+
null,
|
|
9
|
+
/* @__PURE__ */ React.createElement(Text, null, props.children)
|
|
10
|
+
);
|
|
7
11
|
}
|
|
8
|
-
export {
|
|
9
|
-
FragmentComponent as default
|
|
10
|
-
};
|
|
12
|
+
export { FragmentComponent as default };
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
registerComponent(FragmentComponent, {
|
|
15
|
+
name: 'Fragment',
|
|
16
|
+
static: true,
|
|
17
|
+
hidden: true,
|
|
18
|
+
builtIn: true,
|
|
19
|
+
canHaveChildren: true,
|
|
20
|
+
noWrap: true,
|
|
21
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import { View, StyleSheet, Image, Text } from
|
|
3
|
-
import { useContext } from
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { View, StyleSheet, Image, Text } from 'react-native';
|
|
3
|
+
import { useContext } from 'react';
|
|
4
4
|
|
|
5
5
|
export default function FragmentComponent(props) {
|
|
6
6
|
return (
|
package/src/blocks/image.js
CHANGED
|
@@ -1,121 +1,129 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { Image as ReactImage, View } from
|
|
3
|
-
import { registerComponent } from
|
|
2
|
+
import { Image as ReactImage, View } from 'react-native';
|
|
3
|
+
import { registerComponent } from '../functions/register-component';
|
|
4
4
|
function Image(props) {
|
|
5
|
-
return /* @__PURE__ */ React.createElement(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
return /* @__PURE__ */ React.createElement(
|
|
6
|
+
View,
|
|
7
|
+
{
|
|
8
|
+
style: { position: 'relative' },
|
|
9
|
+
},
|
|
10
|
+
/* @__PURE__ */ React.createElement(ReactImage, {
|
|
11
|
+
resizeMode: props.backgroundSize || 'contain',
|
|
12
|
+
style: { position: 'absolute', top: 0, bottom: 0, left: 0, right: 0 },
|
|
13
|
+
source: { uri: props.image },
|
|
14
|
+
}),
|
|
15
|
+
/* @__PURE__ */ React.createElement(View, {
|
|
16
|
+
style: {
|
|
17
|
+
width: '100%',
|
|
18
|
+
paddingTop: props.aspectRatio * 100 + '%',
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
);
|
|
17
22
|
}
|
|
18
23
|
registerComponent(Image, {
|
|
19
|
-
name:
|
|
24
|
+
name: 'Image',
|
|
20
25
|
static: true,
|
|
21
26
|
builtIn: true,
|
|
22
|
-
image:
|
|
27
|
+
image:
|
|
28
|
+
'https://firebasestorage.googleapis.com/v0/b/builder-3b0a2.appspot.com/o/images%2Fbaseline-insert_photo-24px.svg?alt=media&token=4e5d0ef4-f5e8-4e57-b3a9-38d63a9b9dc4',
|
|
23
29
|
defaultStyles: {
|
|
24
|
-
position:
|
|
25
|
-
minHeight:
|
|
26
|
-
minWidth:
|
|
27
|
-
overflow:
|
|
30
|
+
position: 'relative',
|
|
31
|
+
minHeight: '20px',
|
|
32
|
+
minWidth: '20px',
|
|
33
|
+
overflow: 'hidden',
|
|
28
34
|
},
|
|
29
35
|
canHaveChildren: true,
|
|
30
36
|
inputs: [
|
|
31
37
|
{
|
|
32
|
-
name:
|
|
33
|
-
type:
|
|
38
|
+
name: 'image',
|
|
39
|
+
type: 'file',
|
|
34
40
|
bubble: true,
|
|
35
|
-
allowedFileTypes: [
|
|
41
|
+
allowedFileTypes: ['jpeg', 'jpg', 'png', 'svg'],
|
|
36
42
|
required: true,
|
|
37
|
-
defaultValue:
|
|
38
|
-
|
|
43
|
+
defaultValue:
|
|
44
|
+
'https://cdn.builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d',
|
|
45
|
+
onChange:
|
|
46
|
+
" const DEFAULT_ASPECT_RATIO = 0.7041; options.delete('srcset'); options.delete('noWebp'); function loadImage(url, timeout) { return new Promise((resolve, reject) => { const img = document.createElement('img'); let loaded = false; img.onload = () => { loaded = true; resolve(img); }; img.addEventListener('error', event => { console.warn('Image load failed', event.error); reject(event.error); }); img.src = url; setTimeout(() => { if (!loaded) { reject(new Error('Image load timed out')); } }, timeout); }); } function round(num) { return Math.round(num * 1000) / 1000; } const value = options.get('image'); const aspectRatio = options.get('aspectRatio'); // For SVG images - don't render as webp, keep them as SVG fetch(value) .then(res => res.blob()) .then(blob => { if (blob.type.includes('svg')) { options.set('noWebp', true); } }); if (value && (!aspectRatio || aspectRatio === DEFAULT_ASPECT_RATIO)) { return loadImage(value).then(img => { const possiblyUpdatedAspectRatio = options.get('aspectRatio'); if ( options.get('image') === value && (!possiblyUpdatedAspectRatio || possiblyUpdatedAspectRatio === DEFAULT_ASPECT_RATIO) ) { if (img.width && img.height) { options.set('aspectRatio', round(img.height / img.width)); options.set('height', img.height); options.set('width', img.width); } } }); }",
|
|
39
47
|
},
|
|
40
48
|
{
|
|
41
|
-
name:
|
|
42
|
-
type:
|
|
43
|
-
defaultValue:
|
|
49
|
+
name: 'backgroundSize',
|
|
50
|
+
type: 'text',
|
|
51
|
+
defaultValue: 'cover',
|
|
44
52
|
enum: [
|
|
45
53
|
{
|
|
46
|
-
label:
|
|
47
|
-
value:
|
|
48
|
-
helperText:
|
|
54
|
+
label: 'contain',
|
|
55
|
+
value: 'contain',
|
|
56
|
+
helperText: 'The image should never get cropped',
|
|
49
57
|
},
|
|
50
58
|
{
|
|
51
|
-
label:
|
|
52
|
-
value:
|
|
53
|
-
helperText: `The image should fill it's box, cropping when needed
|
|
54
|
-
}
|
|
55
|
-
]
|
|
59
|
+
label: 'cover',
|
|
60
|
+
value: 'cover',
|
|
61
|
+
helperText: `The image should fill it's box, cropping when needed`,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
56
64
|
},
|
|
57
65
|
{
|
|
58
|
-
name:
|
|
59
|
-
type:
|
|
60
|
-
defaultValue:
|
|
66
|
+
name: 'backgroundPosition',
|
|
67
|
+
type: 'text',
|
|
68
|
+
defaultValue: 'center',
|
|
61
69
|
enum: [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
]
|
|
70
|
+
'center',
|
|
71
|
+
'top',
|
|
72
|
+
'left',
|
|
73
|
+
'right',
|
|
74
|
+
'bottom',
|
|
75
|
+
'top left',
|
|
76
|
+
'top right',
|
|
77
|
+
'bottom left',
|
|
78
|
+
'bottom right',
|
|
79
|
+
],
|
|
72
80
|
},
|
|
73
81
|
{
|
|
74
|
-
name:
|
|
75
|
-
type:
|
|
76
|
-
helperText:
|
|
82
|
+
name: 'altText',
|
|
83
|
+
type: 'string',
|
|
84
|
+
helperText: 'Text to display when the user has images off',
|
|
77
85
|
},
|
|
78
86
|
{
|
|
79
|
-
name:
|
|
80
|
-
type:
|
|
81
|
-
hideFromUI: true
|
|
87
|
+
name: 'height',
|
|
88
|
+
type: 'number',
|
|
89
|
+
hideFromUI: true,
|
|
82
90
|
},
|
|
83
91
|
{
|
|
84
|
-
name:
|
|
85
|
-
type:
|
|
86
|
-
hideFromUI: true
|
|
92
|
+
name: 'width',
|
|
93
|
+
type: 'number',
|
|
94
|
+
hideFromUI: true,
|
|
87
95
|
},
|
|
88
96
|
{
|
|
89
|
-
name:
|
|
90
|
-
type:
|
|
91
|
-
hideFromUI: true
|
|
97
|
+
name: 'sizes',
|
|
98
|
+
type: 'string',
|
|
99
|
+
hideFromUI: true,
|
|
92
100
|
},
|
|
93
101
|
{
|
|
94
|
-
name:
|
|
95
|
-
type:
|
|
96
|
-
hideFromUI: true
|
|
102
|
+
name: 'srcset',
|
|
103
|
+
type: 'string',
|
|
104
|
+
hideFromUI: true,
|
|
97
105
|
},
|
|
98
106
|
{
|
|
99
|
-
name:
|
|
100
|
-
type:
|
|
107
|
+
name: 'lazy',
|
|
108
|
+
type: 'boolean',
|
|
101
109
|
defaultValue: true,
|
|
102
|
-
hideFromUI: true
|
|
110
|
+
hideFromUI: true,
|
|
103
111
|
},
|
|
104
112
|
{
|
|
105
|
-
name:
|
|
106
|
-
type:
|
|
107
|
-
helperText:
|
|
108
|
-
|
|
113
|
+
name: 'fitContent',
|
|
114
|
+
type: 'boolean',
|
|
115
|
+
helperText:
|
|
116
|
+
"When child blocks are provided, fit to them instead of using the image's aspect ratio",
|
|
117
|
+
defaultValue: true,
|
|
109
118
|
},
|
|
110
119
|
{
|
|
111
|
-
name:
|
|
112
|
-
type:
|
|
113
|
-
helperText:
|
|
120
|
+
name: 'aspectRatio',
|
|
121
|
+
type: 'number',
|
|
122
|
+
helperText:
|
|
123
|
+
"This is the ratio of height/width, e.g. set to 1.5 for a 300px wide and 200px tall photo. Set to 0 to not force the image to maintain it's aspect ratio",
|
|
114
124
|
advanced: true,
|
|
115
|
-
defaultValue: 0.7041
|
|
116
|
-
}
|
|
117
|
-
]
|
|
125
|
+
defaultValue: 0.7041,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
118
128
|
});
|
|
119
|
-
export {
|
|
120
|
-
Image as default
|
|
121
|
-
};
|
|
129
|
+
export { Image as default };
|