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