@builder.io/sdk-svelte 0.0.6 → 0.0.7
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/--package.json +2 -1
- package/package/blocks/button/button.svelte +2 -2
- package/package/blocks/columns/columns.svelte +1 -2
- package/package/blocks/columns/component-info.js +2 -2
- package/package/blocks/embed/component-info.js +2 -2
- package/package/blocks/form/form.svelte +1 -1
- package/package/blocks/image/component-info.js +2 -2
- package/package/blocks/img/img.svelte +1 -1
- package/package/blocks/section/section.svelte +1 -1
- package/package/blocks/submit-button/submit-button.svelte +1 -1
- package/package/blocks/symbol/symbol.svelte +4 -7
- package/package/blocks/util.d.ts +4 -1
- package/package/blocks/util.js +13 -4
- package/package/blocks/video/video.svelte +1 -1
- package/package/components/render-block/block-styles.svelte +5 -3
- package/package/components/render-block/render-block.svelte +9 -9
- package/package/components/render-block/render-component.svelte +1 -2
- package/package/components/render-content/builder-editing.svelte +4 -0
- package/package/components/render-content/builder-editing.svelte.d.ts +14 -0
- package/package/components/render-content/render-content.svelte +1 -3
- package/package/components/render-inlined-styles.svelte +3 -3
- package/package/constants/device-sizes.d.ts +12 -1
- package/package/constants/device-sizes.js +27 -1
- package/package/functions/get-content/index.js +5 -2
- package/package/functions/get-content/types.d.ts +4 -0
- package/package/functions/register-component.js +1 -13
- package/package/index.d.ts +3 -1
- package/package/index.js +1 -1
- package/package/scripts/init-editing.js +6 -0
- package/package/types/builder-content.d.ts +7 -0
- package/package.json +1 -1
- package/src/blocks/button/button.svelte +2 -2
- package/src/blocks/columns/columns.svelte +1 -2
- package/src/blocks/columns/component-info.ts +2 -2
- package/src/blocks/embed/component-info.ts +2 -2
- package/src/blocks/form/form.svelte +1 -1
- package/src/blocks/image/component-info.ts +2 -2
- package/src/blocks/img/img.svelte +1 -1
- package/src/blocks/section/section.svelte +1 -1
- package/src/blocks/submit-button/submit-button.svelte +1 -1
- package/src/blocks/symbol/symbol.svelte +4 -7
- package/src/blocks/util.ts +18 -6
- package/src/blocks/video/video.svelte +1 -1
- package/src/components/render-block/block-styles.svelte +16 -3
- package/src/components/render-block/render-block.svelte +9 -9
- package/src/components/render-block/render-component.svelte +1 -2
- package/src/components/render-content/builder-editing.svelte +4 -0
- package/src/components/render-content/render-content.svelte +1 -3
- package/src/components/render-inlined-styles.svelte +3 -3
- package/src/constants/device-sizes.ts +39 -2
- package/src/functions/get-content/index.ts +6 -1
- package/src/functions/get-content/types.ts +5 -0
- package/src/functions/register-component.ts +1 -18
- package/src/index.ts +3 -1
- package/src/scripts/init-editing.ts +6 -0
- package/src/types/builder-content.ts +7 -0
package/package/--package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@builder.io/sdk-svelte",
|
|
3
3
|
"description": "Builder.io SDK for Svelte",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.6",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"package",
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"./components/render-block/render-repeated-block.svelte": "./components/render-block/render-repeated-block.svelte",
|
|
73
73
|
"./components/render-block/types": "./components/render-block/types.js",
|
|
74
74
|
"./components/render-blocks.svelte": "./components/render-blocks.svelte",
|
|
75
|
+
"./components/render-content/builder-editing.svelte": "./components/render-content/builder-editing.svelte",
|
|
75
76
|
"./components/render-content/components/render-styles.svelte": "./components/render-content/components/render-styles.svelte",
|
|
76
77
|
"./components/render-content": "./components/render-content/index.js",
|
|
77
78
|
"./components/render-content/render-content.svelte": "./components/render-content/render-content.svelte",
|
|
@@ -8,15 +8,15 @@ export let openLinkInNewTab;
|
|
|
8
8
|
|
|
9
9
|
{#if link}
|
|
10
10
|
<a
|
|
11
|
-
{...attributes}
|
|
12
11
|
role="button"
|
|
12
|
+
{...attributes}
|
|
13
13
|
href={link}
|
|
14
14
|
target={openLinkInNewTab ? "_blank" : undefined}
|
|
15
15
|
>
|
|
16
16
|
{text}
|
|
17
17
|
</a>
|
|
18
18
|
{:else}
|
|
19
|
-
<button
|
|
19
|
+
<button class="button" {...attributes}>
|
|
20
20
|
{text}
|
|
21
21
|
</button>
|
|
22
22
|
{/if}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
3
|
<script>import RenderBlocks from "../../components/render-blocks.svelte";
|
|
4
|
-
import { markMutable } from "../../functions/mark-mutable";
|
|
5
4
|
export let space;
|
|
6
5
|
export let columns;
|
|
7
6
|
export let stackColumnsAt;
|
|
@@ -71,7 +70,7 @@ $: columnCssVars = () => {
|
|
|
71
70
|
class="builder-column div-2"
|
|
72
71
|
>
|
|
73
72
|
<RenderBlocks
|
|
74
|
-
blocks={
|
|
73
|
+
blocks={column.blocks}
|
|
75
74
|
path={`component.options.columns.${index}.blocks`}
|
|
76
75
|
parent={builderBlock.id}
|
|
77
76
|
styleProp={{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { serializeFn } from '../util.js';
|
|
2
2
|
export const componentInfo = {
|
|
3
3
|
// TODO: ways to statically preprocess JSON for references, functions, etc
|
|
4
4
|
name: 'Columns',
|
|
@@ -188,7 +188,7 @@ export const componentInfo = {
|
|
|
188
188
|
],
|
|
189
189
|
},
|
|
190
190
|
],
|
|
191
|
-
onChange:
|
|
191
|
+
onChange: serializeFn((options) => {
|
|
192
192
|
function clearWidths() {
|
|
193
193
|
columns.forEach((col) => {
|
|
194
194
|
col.delete('width');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { serializeFn } from '../util.js';
|
|
2
2
|
export const componentInfo = {
|
|
3
3
|
name: 'Embed',
|
|
4
4
|
static: true,
|
|
@@ -10,7 +10,7 @@ export const componentInfo = {
|
|
|
10
10
|
required: true,
|
|
11
11
|
defaultValue: '',
|
|
12
12
|
helperText: 'e.g. enter a youtube url, google map, etc',
|
|
13
|
-
onChange:
|
|
13
|
+
onChange: serializeFn((options) => {
|
|
14
14
|
const url = options.get('url');
|
|
15
15
|
if (url) {
|
|
16
16
|
options.set('content', 'Loading...');
|
|
@@ -217,7 +217,6 @@ let formErrorMessage = "";
|
|
|
217
217
|
</script>
|
|
218
218
|
|
|
219
219
|
<form
|
|
220
|
-
{...attributes}
|
|
221
220
|
{validate}
|
|
222
221
|
bind:this={formRef}
|
|
223
222
|
action={!sendWithJs && action}
|
|
@@ -226,6 +225,7 @@ let formErrorMessage = "";
|
|
|
226
225
|
on:submit={(event) => {
|
|
227
226
|
onSubmit(event);
|
|
228
227
|
}}
|
|
228
|
+
{...attributes}
|
|
229
229
|
>
|
|
230
230
|
{#if builderBlock && builderBlock.children}
|
|
231
231
|
{#each builderBlock?.children as block}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { serializeFn } from '../util.js';
|
|
2
2
|
export const componentInfo = {
|
|
3
3
|
name: 'Image',
|
|
4
4
|
static: true,
|
|
@@ -19,7 +19,7 @@ export const componentInfo = {
|
|
|
19
19
|
allowedFileTypes: ['jpeg', 'jpg', 'png', 'svg'],
|
|
20
20
|
required: true,
|
|
21
21
|
defaultValue: 'https://cdn.builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d',
|
|
22
|
-
onChange:
|
|
22
|
+
onChange: serializeFn((options) => {
|
|
23
23
|
const DEFAULT_ASPECT_RATIO = 0.7041;
|
|
24
24
|
options.delete('srcset');
|
|
25
25
|
options.delete('noWebp');
|
|
@@ -20,7 +20,6 @@ function mitosis_styling(node, vars) {
|
|
|
20
20
|
</script>
|
|
21
21
|
|
|
22
22
|
<img
|
|
23
|
-
{...attributes}
|
|
24
23
|
use:mitosis_styling={{
|
|
25
24
|
objectFit: backgroundSize || "cover",
|
|
26
25
|
objectPosition: backgroundPosition || "center",
|
|
@@ -28,4 +27,5 @@ function mitosis_styling(node, vars) {
|
|
|
28
27
|
key={(isEditing() && imgSrc) || "default-key"}
|
|
29
28
|
alt={altText}
|
|
30
29
|
src={imgSrc || image}
|
|
30
|
+
{...attributes}
|
|
31
31
|
/>
|
|
@@ -15,12 +15,12 @@ function mitosis_styling(node, vars) {
|
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
17
|
<section
|
|
18
|
-
{...attributes}
|
|
19
18
|
use:mitosis_styling={maxWidth && typeof maxWidth === "number"
|
|
20
19
|
? {
|
|
21
20
|
maxWidth: maxWidth,
|
|
22
21
|
}
|
|
23
22
|
: undefined}
|
|
23
|
+
{...attributes}
|
|
24
24
|
>
|
|
25
25
|
<slot />
|
|
26
26
|
</section>
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import RenderContent from "../../components/render-content/render-content.svelte";
|
|
5
5
|
import BuilderContext from "../../context/builder.context.js";
|
|
6
6
|
import { getContent } from "../../functions/get-content/index.js";
|
|
7
|
-
import { markMutable } from "../../functions/mark-mutable";
|
|
8
7
|
export let symbol;
|
|
9
8
|
export let attributes;
|
|
10
9
|
let builderContext = getContext(BuilderContext.key);
|
|
@@ -52,15 +51,13 @@ $: onUpdateFn_0(...[symbol, fetchedContent]);
|
|
|
52
51
|
<RenderContent
|
|
53
52
|
apiKey={builderContext.apiKey}
|
|
54
53
|
context={builderContext.context}
|
|
55
|
-
customComponents={
|
|
56
|
-
|
|
57
|
-
)}
|
|
58
|
-
data={markMutable({
|
|
54
|
+
customComponents={Object.values(builderContext.registeredComponents)}
|
|
55
|
+
data={{
|
|
59
56
|
...symbol?.data,
|
|
60
57
|
...builderContext.state,
|
|
61
58
|
...symbol?.content?.data?.state,
|
|
62
|
-
}
|
|
59
|
+
}}
|
|
63
60
|
model={symbol?.model}
|
|
64
|
-
content={
|
|
61
|
+
content={contentToUse()}
|
|
65
62
|
/>
|
|
66
63
|
</div>
|
package/package/blocks/util.d.ts
CHANGED
package/package/blocks/util.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Input attributes that are functions must be converted to strings before being serialized to JSON.
|
|
3
|
+
*/
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
5
|
+
export const serializeFn = (fnValue) => {
|
|
6
|
+
const fnStr = fnValue.toString().trim();
|
|
7
|
+
// we need to account for a few different fn syntaxes:
|
|
8
|
+
// 1. `function name(args) => {code}`
|
|
9
|
+
// 2. `name(args) => {code}`
|
|
10
|
+
// 3. `(args) => {}`
|
|
11
|
+
const appendFunction = !fnStr.startsWith('function') && !fnStr.startsWith('(');
|
|
12
|
+
return `return (${appendFunction ? 'function ' : ''}${fnStr}).apply(this, arguments)`;
|
|
13
|
+
};
|
|
@@ -58,7 +58,6 @@ $: spreadProps = () => {
|
|
|
58
58
|
</script>
|
|
59
59
|
|
|
60
60
|
<video
|
|
61
|
-
{...spreadProps()}
|
|
62
61
|
use:mitosis_styling={{
|
|
63
62
|
width: "100%",
|
|
64
63
|
height: "100%",
|
|
@@ -69,6 +68,7 @@ $: spreadProps = () => {
|
|
|
69
68
|
// not have the video overflow
|
|
70
69
|
borderRadius: 1,
|
|
71
70
|
}}
|
|
71
|
+
{...spreadProps()}
|
|
72
72
|
src={video || "no-src"}
|
|
73
73
|
poster={posterImage}
|
|
74
74
|
/>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
|
-
<script>import { getMaxWidthQueryForSize } from "../../constants/device-sizes.js";
|
|
3
|
+
<script>import { getMaxWidthQueryForSize, getSizesForBreakpoints, } from "../../constants/device-sizes.js";
|
|
4
4
|
import { TARGET } from "../../constants/target.js";
|
|
5
5
|
import { getProcessedBlock } from "../../functions/get-processed-block.js";
|
|
6
6
|
import { createCssClass } from "../../helpers/css.js";
|
|
@@ -17,6 +17,8 @@ $: useBlock = () => {
|
|
|
17
17
|
};
|
|
18
18
|
$: css = () => {
|
|
19
19
|
const styles = useBlock().responsiveStyles;
|
|
20
|
+
const content = context.content;
|
|
21
|
+
const sizesWithUpdatedBreakpoints = getSizesForBreakpoints(content?.meta?.breakpoints || {});
|
|
20
22
|
const largeStyles = styles?.large;
|
|
21
23
|
const mediumStyles = styles?.medium;
|
|
22
24
|
const smallStyles = styles?.small;
|
|
@@ -31,14 +33,14 @@ $: css = () => {
|
|
|
31
33
|
? createCssClass({
|
|
32
34
|
className,
|
|
33
35
|
styles: mediumStyles,
|
|
34
|
-
mediaQuery: getMaxWidthQueryForSize("medium"),
|
|
36
|
+
mediaQuery: getMaxWidthQueryForSize("medium", sizesWithUpdatedBreakpoints),
|
|
35
37
|
})
|
|
36
38
|
: "";
|
|
37
39
|
const smallStylesClass = smallStyles
|
|
38
40
|
? createCssClass({
|
|
39
41
|
className,
|
|
40
42
|
styles: smallStyles,
|
|
41
|
-
mediaQuery: getMaxWidthQueryForSize("small"),
|
|
43
|
+
mediaQuery: getMaxWidthQueryForSize("small", sizesWithUpdatedBreakpoints),
|
|
42
44
|
})
|
|
43
45
|
: "";
|
|
44
46
|
return [largeStylesClass, mediumStylesClass, smallStylesClass].join(" ");
|
|
@@ -38,7 +38,7 @@ $: component = () => {
|
|
|
38
38
|
return ref;
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
|
-
$:
|
|
41
|
+
$: tag = () => {
|
|
42
42
|
return getBlockTag(useBlock());
|
|
43
43
|
};
|
|
44
44
|
$: useBlock = () => {
|
|
@@ -74,7 +74,7 @@ $: shouldWrap = () => {
|
|
|
74
74
|
};
|
|
75
75
|
$: renderComponentProps = () => {
|
|
76
76
|
return {
|
|
77
|
-
blockChildren:
|
|
77
|
+
blockChildren: useChildren(),
|
|
78
78
|
componentRef: component?.()?.component,
|
|
79
79
|
componentOptions: {
|
|
80
80
|
...getBlockComponentOptions(useBlock()),
|
|
@@ -91,7 +91,7 @@ $: renderComponentProps = () => {
|
|
|
91
91
|
context: childrenContext(),
|
|
92
92
|
};
|
|
93
93
|
};
|
|
94
|
-
$:
|
|
94
|
+
$: useChildren = () => {
|
|
95
95
|
// TO-DO: When should `canHaveChildren` dictate rendering?
|
|
96
96
|
// This is currently commented out because some Builder components (e.g. Box) do not have `canHaveChildren: true`,
|
|
97
97
|
// but still receive and need to render children.
|
|
@@ -106,7 +106,7 @@ $: childrenWithoutParentComponent = () => {
|
|
|
106
106
|
* blocks, and the children will be repeated within those blocks.
|
|
107
107
|
*/
|
|
108
108
|
const shouldRenderChildrenOutsideRef = !component?.()?.component && !repeatItemData();
|
|
109
|
-
return shouldRenderChildrenOutsideRef ?
|
|
109
|
+
return shouldRenderChildrenOutsideRef ? useChildren() : [];
|
|
110
110
|
};
|
|
111
111
|
$: repeatItemData = () => {
|
|
112
112
|
/**
|
|
@@ -177,18 +177,18 @@ $: renderComponentTag = () => {
|
|
|
177
177
|
</script>
|
|
178
178
|
|
|
179
179
|
{#if shouldWrap()}
|
|
180
|
-
{#if isEmptyHtmlElement(
|
|
181
|
-
<svelte:element this={
|
|
180
|
+
{#if isEmptyHtmlElement(tag())}
|
|
181
|
+
<svelte:element this={tag()} {...attributes()} />
|
|
182
182
|
{/if}
|
|
183
183
|
|
|
184
|
-
{#if !isEmptyHtmlElement(
|
|
184
|
+
{#if !isEmptyHtmlElement(tag()) && repeatItemData()}
|
|
185
185
|
{#each repeatItemData() as data, index (index)}
|
|
186
186
|
<RenderRepeatedBlock repeatContext={data.context} block={data.block} />
|
|
187
187
|
{/each}
|
|
188
188
|
{/if}
|
|
189
189
|
|
|
190
|
-
{#if !isEmptyHtmlElement(
|
|
191
|
-
<svelte:element this={
|
|
190
|
+
{#if !isEmptyHtmlElement(tag()) && !repeatItemData()}
|
|
191
|
+
<svelte:element this={tag()} {...attributes()}>
|
|
192
192
|
<svelte:component
|
|
193
193
|
this={renderComponentTag()}
|
|
194
194
|
{...renderComponentProps()}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
<script>import BlockStyles from "./block-styles.svelte";
|
|
4
4
|
import RenderBlock from "./render-block.svelte";
|
|
5
|
-
import { markPropsMutable } from "../../functions/mark-mutable.js";
|
|
6
5
|
export let componentRef;
|
|
7
6
|
export let componentOptions;
|
|
8
7
|
export let blockChildren;
|
|
@@ -10,7 +9,7 @@ export let context;
|
|
|
10
9
|
</script>
|
|
11
10
|
|
|
12
11
|
{#if componentRef}
|
|
13
|
-
<svelte:component this={componentRef} {...
|
|
12
|
+
<svelte:component this={componentRef} {...componentOptions}>
|
|
14
13
|
{#each blockChildren as child ("render-block-" + child.id)}
|
|
15
14
|
<RenderBlock block={child} {context} />
|
|
16
15
|
{/each}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {};
|
|
4
|
+
events: {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
};
|
|
7
|
+
slots: {};
|
|
8
|
+
};
|
|
9
|
+
export declare type BuilderEditingProps = typeof __propDef.props;
|
|
10
|
+
export declare type BuilderEditingEvents = typeof __propDef.events;
|
|
11
|
+
export declare type BuilderEditingSlots = typeof __propDef.slots;
|
|
12
|
+
export default class BuilderEditing extends SvelteComponentTyped<BuilderEditingProps, BuilderEditingEvents, BuilderEditingSlots> {
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -15,7 +15,6 @@ import { _track } from "../../functions/track.js";
|
|
|
15
15
|
import RenderBlocks from "../render-blocks.svelte";
|
|
16
16
|
import RenderContentStyles from "./components/render-styles.svelte";
|
|
17
17
|
import { registerInsertMenu, setupBrowserForEditing, } from "../../scripts/init-editing.js";
|
|
18
|
-
import { markMutable } from "../../functions/mark-mutable.js";
|
|
19
18
|
export let content;
|
|
20
19
|
export let data;
|
|
21
20
|
export let canTrack;
|
|
@@ -196,7 +195,6 @@ onMount(() => {
|
|
|
196
195
|
if (isBrowser()) {
|
|
197
196
|
if (isEditing()) {
|
|
198
197
|
forceReRenderCount = forceReRenderCount + 1;
|
|
199
|
-
// QWIK-REPLACE: _useMutableProps
|
|
200
198
|
registerInsertMenu();
|
|
201
199
|
setupBrowserForEditing();
|
|
202
200
|
Object.values(allRegisteredComponents()).forEach((registeredComponent) => {
|
|
@@ -275,7 +273,7 @@ onDestroy(() => {
|
|
|
275
273
|
/>
|
|
276
274
|
{/if}
|
|
277
275
|
<RenderBlocks
|
|
278
|
-
blocks={
|
|
276
|
+
blocks={useContent?.()?.data?.blocks}
|
|
279
277
|
key={forceReRenderCount}
|
|
280
278
|
/>
|
|
281
279
|
</div>
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
<script>import { TARGET } from "../constants/target.js";
|
|
4
4
|
export let styles;
|
|
5
5
|
$: injectedStyleScript = () => {
|
|
6
|
-
return `<${
|
|
6
|
+
return `<${tag()}>${styles}</${tag()}>`;
|
|
7
7
|
};
|
|
8
|
-
$:
|
|
8
|
+
$: tag = () => {
|
|
9
9
|
// NOTE: we have to obfusctate the name of the tag due to a limitation in the svelte-preprocessor plugin.
|
|
10
10
|
// https://github.com/sveltejs/vite-plugin-svelte/issues/315#issuecomment-1109000027
|
|
11
11
|
return "sty" + "le";
|
|
@@ -15,5 +15,5 @@ $: tagName = () => {
|
|
|
15
15
|
{#if TARGET === "svelte"}
|
|
16
16
|
{@html injectedStyleScript()}
|
|
17
17
|
{:else}
|
|
18
|
-
<svelte:element this={
|
|
18
|
+
<svelte:element this={tag()}>{styles}</svelte:element>
|
|
19
19
|
{/if}
|
|
@@ -1,2 +1,13 @@
|
|
|
1
1
|
export declare type SizeName = 'large' | 'medium' | 'small';
|
|
2
|
-
|
|
2
|
+
interface Size {
|
|
3
|
+
min: number;
|
|
4
|
+
default: number;
|
|
5
|
+
max: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const getMaxWidthQueryForSize: (size: SizeName, sizeValues?: Record<SizeName, Size>) => string;
|
|
8
|
+
interface Breakpoints {
|
|
9
|
+
small?: number;
|
|
10
|
+
medium?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare const getSizesForBreakpoints: ({ small, medium }: Breakpoints) => Record<SizeName, Size>;
|
|
13
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fastClone } from '../functions/fast-clone';
|
|
1
2
|
const SIZES = {
|
|
2
3
|
small: {
|
|
3
4
|
min: 320,
|
|
@@ -15,4 +16,29 @@ const SIZES = {
|
|
|
15
16
|
max: 1200,
|
|
16
17
|
},
|
|
17
18
|
};
|
|
18
|
-
export const getMaxWidthQueryForSize = (size) => `@media (max-width: ${
|
|
19
|
+
export const getMaxWidthQueryForSize = (size, sizeValues = SIZES) => `@media (max-width: ${sizeValues[size].max}px)`;
|
|
20
|
+
export const getSizesForBreakpoints = ({ small, medium }) => {
|
|
21
|
+
const newSizes = fastClone(SIZES); // Note: this helps to get a deep clone of fields like small, medium etc
|
|
22
|
+
if (!small || !medium) {
|
|
23
|
+
return newSizes;
|
|
24
|
+
}
|
|
25
|
+
const smallMin = Math.floor(small / 2);
|
|
26
|
+
newSizes.small = {
|
|
27
|
+
max: small,
|
|
28
|
+
min: smallMin,
|
|
29
|
+
default: smallMin + 1,
|
|
30
|
+
};
|
|
31
|
+
const mediumMin = newSizes.small.max + 1;
|
|
32
|
+
newSizes.medium = {
|
|
33
|
+
max: medium,
|
|
34
|
+
min: mediumMin,
|
|
35
|
+
default: mediumMin + 1,
|
|
36
|
+
};
|
|
37
|
+
const largeMin = newSizes.medium.max + 1;
|
|
38
|
+
newSizes.large = {
|
|
39
|
+
max: 2000,
|
|
40
|
+
min: largeMin,
|
|
41
|
+
default: largeMin + 1,
|
|
42
|
+
};
|
|
43
|
+
return newSizes;
|
|
44
|
+
};
|
|
@@ -6,8 +6,11 @@ export async function getContent(options) {
|
|
|
6
6
|
return (await getAllContent({ ...options, limit: 1 })).results[0] || null;
|
|
7
7
|
}
|
|
8
8
|
export const generateContentUrl = (options) => {
|
|
9
|
-
const { limit = 30, userAttributes, query, noTraverse = false, model, apiKey, } = options;
|
|
10
|
-
|
|
9
|
+
const { limit = 30, userAttributes, query, noTraverse = false, model, apiKey, includeRefs = true, } = options;
|
|
10
|
+
if (!apiKey) {
|
|
11
|
+
throw new Error('Missing API key');
|
|
12
|
+
}
|
|
13
|
+
const url = new URL(`https://cdn.builder.io/api/v2/content/${model}?apiKey=${apiKey}&limit=${limit}&noTraverse=${noTraverse}&includeRefs=${includeRefs}`);
|
|
11
14
|
const queryOptions = {
|
|
12
15
|
...getBuilderSearchParamsFromWindow(),
|
|
13
16
|
...normalizeSearchParams(options.options || {}),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { serializeFn } from '../blocks/util.js';
|
|
1
2
|
import { fastClone } from './fast-clone.js';
|
|
2
3
|
/**
|
|
3
4
|
* @deprecated. Use the `customComponents` prop in RenderContent instead to provide your custom components to the builder SDK.
|
|
@@ -16,19 +17,6 @@ export const createRegisterComponentMessage = ({ component: _, ...info }) => ({
|
|
|
16
17
|
data: prepareComponentInfoToSend(info),
|
|
17
18
|
});
|
|
18
19
|
const serializeValue = (value) => typeof value === 'function' ? serializeFn(value) : fastClone(value);
|
|
19
|
-
/**
|
|
20
|
-
* Input attributes that are functions must be converted to strings before being serialized to JSON.
|
|
21
|
-
*/
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
23
|
-
const serializeFn = (fnValue) => {
|
|
24
|
-
const fnStr = fnValue.toString().trim();
|
|
25
|
-
// we need to account for a few different fn syntaxes:
|
|
26
|
-
// 1. `function name(args) => {code}`
|
|
27
|
-
// 2. `name(args) => {code}`
|
|
28
|
-
// 3. `(args) => {}`
|
|
29
|
-
const appendFunction = !fnStr.startsWith('function') && !fnStr.startsWith('(');
|
|
30
|
-
return `return (${appendFunction ? 'function ' : ''}${fnStr}).apply(this, arguments)`;
|
|
31
|
-
};
|
|
32
20
|
const prepareComponentInfoToSend = ({ inputs, ...info }) => ({
|
|
33
21
|
...fastClone(info),
|
|
34
22
|
inputs: inputs?.map((input) => Object.entries(input).reduce((acc, [key, value]) => ({
|
package/package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
export * from './index-helpers/top-of-file.js';
|
|
2
2
|
import './scripts/init-editing.js';
|
|
3
3
|
export * from './index-helpers/blocks-exports.js';
|
|
4
4
|
export * from './functions/is-editing.js';
|
|
@@ -9,3 +9,5 @@ export * from './functions/set-editor-settings.js';
|
|
|
9
9
|
export * from './functions/get-content/index.js';
|
|
10
10
|
export * from './functions/get-builder-search-params/index.js';
|
|
11
11
|
export { track } from './functions/track';
|
|
12
|
+
export type { RegisteredComponent } from './context/types';
|
|
13
|
+
export type { ComponentInfo } from './types/components';
|
package/package/index.js
CHANGED
|
@@ -21,7 +21,12 @@ export const registerInsertMenu = () => {
|
|
|
21
21
|
],
|
|
22
22
|
});
|
|
23
23
|
};
|
|
24
|
+
let isSetupForEditing = false;
|
|
24
25
|
export const setupBrowserForEditing = () => {
|
|
26
|
+
if (isSetupForEditing) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
isSetupForEditing = true;
|
|
25
30
|
if (isBrowser()) {
|
|
26
31
|
window.parent?.postMessage({
|
|
27
32
|
type: 'builder.sdkInfo',
|
|
@@ -34,6 +39,7 @@ export const setupBrowserForEditing = () => {
|
|
|
34
39
|
// Supports builder-model="..." attribute which is needed to
|
|
35
40
|
// scope our '+ add block' button styling
|
|
36
41
|
supportsAddBlockScoping: true,
|
|
42
|
+
supportsCustomBreakpoints: true,
|
|
37
43
|
},
|
|
38
44
|
}, '*');
|
|
39
45
|
window.addEventListener('message', ({ data }) => {
|
|
@@ -18,6 +18,13 @@ export interface BuilderContentVariation {
|
|
|
18
18
|
name?: string;
|
|
19
19
|
testRatio?: number;
|
|
20
20
|
id?: string;
|
|
21
|
+
meta?: {
|
|
22
|
+
breakpoints?: {
|
|
23
|
+
small: number;
|
|
24
|
+
medium: number;
|
|
25
|
+
};
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
};
|
|
21
28
|
}
|
|
22
29
|
export interface BuilderContent extends BuilderContentVariation {
|
|
23
30
|
'@version'?: number;
|
package/package.json
CHANGED
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
|
|
17
17
|
{#if link}
|
|
18
18
|
<a
|
|
19
|
-
{...attributes}
|
|
20
19
|
role="button"
|
|
20
|
+
{...attributes}
|
|
21
21
|
href={link}
|
|
22
22
|
target={openLinkInNewTab ? "_blank" : undefined}
|
|
23
23
|
>
|
|
24
24
|
{text}
|
|
25
25
|
</a>
|
|
26
26
|
{:else}
|
|
27
|
-
<button
|
|
27
|
+
<button class="button" {...attributes}>
|
|
28
28
|
{text}
|
|
29
29
|
</button>
|
|
30
30
|
{/if}
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
|
|
29
29
|
<script lang="ts">
|
|
30
30
|
import RenderBlocks from "../../components/render-blocks.svelte";
|
|
31
|
-
import { markMutable } from "../../functions/mark-mutable";
|
|
32
31
|
|
|
33
32
|
export let space: ColumnProps["space"];
|
|
34
33
|
export let columns: ColumnProps["columns"];
|
|
@@ -101,7 +100,7 @@
|
|
|
101
100
|
class="builder-column div-2"
|
|
102
101
|
>
|
|
103
102
|
<RenderBlocks
|
|
104
|
-
blocks={
|
|
103
|
+
blocks={column.blocks}
|
|
105
104
|
path={`component.options.columns.${index}.blocks`}
|
|
106
105
|
parent={builderBlock.id}
|
|
107
106
|
styleProp={{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ComponentInfo } from '../../types/components';
|
|
2
|
-
import {
|
|
2
|
+
import { serializeFn } from '../util.js';
|
|
3
3
|
|
|
4
4
|
export const componentInfo: ComponentInfo = {
|
|
5
5
|
// TODO: ways to statically preprocess JSON for references, functions, etc
|
|
@@ -194,7 +194,7 @@ export const componentInfo: ComponentInfo = {
|
|
|
194
194
|
],
|
|
195
195
|
},
|
|
196
196
|
],
|
|
197
|
-
onChange:
|
|
197
|
+
onChange: serializeFn((options: Map<string, any>) => {
|
|
198
198
|
function clearWidths() {
|
|
199
199
|
columns.forEach((col) => {
|
|
200
200
|
col.delete('width');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ComponentInfo } from '../../types/components';
|
|
2
|
-
import {
|
|
2
|
+
import { serializeFn } from '../util.js';
|
|
3
3
|
|
|
4
4
|
export const componentInfo: ComponentInfo = {
|
|
5
5
|
name: 'Embed',
|
|
@@ -12,7 +12,7 @@ export const componentInfo: ComponentInfo = {
|
|
|
12
12
|
required: true,
|
|
13
13
|
defaultValue: '',
|
|
14
14
|
helperText: 'e.g. enter a youtube url, google map, etc',
|
|
15
|
-
onChange:
|
|
15
|
+
onChange: serializeFn((options: Map<string, any>) => {
|
|
16
16
|
const url = options.get('url');
|
|
17
17
|
if (url) {
|
|
18
18
|
options.set('content', 'Loading...');
|
|
@@ -288,7 +288,6 @@
|
|
|
288
288
|
</script>
|
|
289
289
|
|
|
290
290
|
<form
|
|
291
|
-
{...attributes}
|
|
292
291
|
{validate}
|
|
293
292
|
bind:this={formRef}
|
|
294
293
|
action={!sendWithJs && action}
|
|
@@ -297,6 +296,7 @@
|
|
|
297
296
|
on:submit={(event) => {
|
|
298
297
|
onSubmit(event);
|
|
299
298
|
}}
|
|
299
|
+
{...attributes}
|
|
300
300
|
>
|
|
301
301
|
{#if builderBlock && builderBlock.children}
|
|
302
302
|
{#each builderBlock?.children as block}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ComponentInfo } from '../../types/components';
|
|
2
|
-
import {
|
|
2
|
+
import { serializeFn } from '../util.js';
|
|
3
3
|
|
|
4
4
|
export const componentInfo: ComponentInfo = {
|
|
5
5
|
name: 'Image',
|
|
@@ -23,7 +23,7 @@ export const componentInfo: ComponentInfo = {
|
|
|
23
23
|
required: true,
|
|
24
24
|
defaultValue:
|
|
25
25
|
'https://cdn.builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d',
|
|
26
|
-
onChange:
|
|
26
|
+
onChange: serializeFn((options: Map<string, any>) => {
|
|
27
27
|
const DEFAULT_ASPECT_RATIO = 0.7041;
|
|
28
28
|
options.delete('srcset');
|
|
29
29
|
options.delete('noWebp');
|
|
@@ -40,7 +40,6 @@
|
|
|
40
40
|
</script>
|
|
41
41
|
|
|
42
42
|
<img
|
|
43
|
-
{...attributes}
|
|
44
43
|
use:mitosis_styling={{
|
|
45
44
|
objectFit: backgroundSize || "cover",
|
|
46
45
|
objectPosition: backgroundPosition || "center",
|
|
@@ -48,4 +47,5 @@
|
|
|
48
47
|
key={(isEditing() && imgSrc) || "default-key"}
|
|
49
48
|
alt={altText}
|
|
50
49
|
src={imgSrc || image}
|
|
50
|
+
{...attributes}
|
|
51
51
|
/>
|
|
@@ -30,7 +30,6 @@
|
|
|
30
30
|
import RenderContent from "../../components/render-content/render-content.svelte";
|
|
31
31
|
import BuilderContext from "../../context/builder.context.js";
|
|
32
32
|
import { getContent } from "../../functions/get-content/index.js";
|
|
33
|
-
import { markMutable } from "../../functions/mark-mutable";
|
|
34
33
|
|
|
35
34
|
export let symbol: SymbolProps["symbol"];
|
|
36
35
|
export let attributes: SymbolProps["attributes"];
|
|
@@ -86,15 +85,13 @@
|
|
|
86
85
|
<RenderContent
|
|
87
86
|
apiKey={builderContext.apiKey}
|
|
88
87
|
context={builderContext.context}
|
|
89
|
-
customComponents={
|
|
90
|
-
|
|
91
|
-
)}
|
|
92
|
-
data={markMutable({
|
|
88
|
+
customComponents={Object.values(builderContext.registeredComponents)}
|
|
89
|
+
data={{
|
|
93
90
|
...symbol?.data,
|
|
94
91
|
...builderContext.state,
|
|
95
92
|
...symbol?.content?.data?.state,
|
|
96
|
-
}
|
|
93
|
+
}}
|
|
97
94
|
model={symbol?.model}
|
|
98
|
-
content={
|
|
95
|
+
content={contentToUse()}
|
|
99
96
|
/>
|
|
100
97
|
</div>
|
package/src/blocks/util.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Input attributes that are functions must be converted to strings before being serialized to JSON.
|
|
3
|
+
*/
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
5
|
+
export const serializeFn = (fnValue: Function) => {
|
|
6
|
+
const fnStr = fnValue.toString().trim();
|
|
7
|
+
|
|
8
|
+
// we need to account for a few different fn syntaxes:
|
|
9
|
+
// 1. `function name(args) => {code}`
|
|
10
|
+
// 2. `name(args) => {code}`
|
|
11
|
+
// 3. `(args) => {}`
|
|
12
|
+
const appendFunction =
|
|
13
|
+
!fnStr.startsWith('function') && !fnStr.startsWith('(');
|
|
14
|
+
|
|
15
|
+
return `return (${
|
|
16
|
+
appendFunction ? 'function ' : ''
|
|
17
|
+
}${fnStr}).apply(this, arguments)`;
|
|
18
|
+
};
|
|
@@ -86,7 +86,6 @@
|
|
|
86
86
|
</script>
|
|
87
87
|
|
|
88
88
|
<video
|
|
89
|
-
{...spreadProps()}
|
|
90
89
|
use:mitosis_styling={{
|
|
91
90
|
width: "100%",
|
|
92
91
|
height: "100%",
|
|
@@ -97,6 +96,7 @@
|
|
|
97
96
|
// not have the video overflow
|
|
98
97
|
borderRadius: 1,
|
|
99
98
|
}}
|
|
99
|
+
{...spreadProps()}
|
|
100
100
|
src={video || "no-src"}
|
|
101
101
|
poster={posterImage}
|
|
102
102
|
/>
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<script lang="ts">
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
getMaxWidthQueryForSize,
|
|
15
|
+
getSizesForBreakpoints,
|
|
16
|
+
} from "../../constants/device-sizes.js";
|
|
14
17
|
import { TARGET } from "../../constants/target.js";
|
|
15
18
|
import { getProcessedBlock } from "../../functions/get-processed-block.js";
|
|
16
19
|
import { createCssClass } from "../../helpers/css.js";
|
|
@@ -29,6 +32,10 @@
|
|
|
29
32
|
};
|
|
30
33
|
$: css = () => {
|
|
31
34
|
const styles = useBlock().responsiveStyles;
|
|
35
|
+
const content = context.content;
|
|
36
|
+
const sizesWithUpdatedBreakpoints = getSizesForBreakpoints(
|
|
37
|
+
content?.meta?.breakpoints || {}
|
|
38
|
+
);
|
|
32
39
|
const largeStyles = styles?.large;
|
|
33
40
|
const mediumStyles = styles?.medium;
|
|
34
41
|
const smallStyles = styles?.small;
|
|
@@ -43,14 +50,20 @@
|
|
|
43
50
|
? createCssClass({
|
|
44
51
|
className,
|
|
45
52
|
styles: mediumStyles,
|
|
46
|
-
mediaQuery: getMaxWidthQueryForSize(
|
|
53
|
+
mediaQuery: getMaxWidthQueryForSize(
|
|
54
|
+
"medium",
|
|
55
|
+
sizesWithUpdatedBreakpoints
|
|
56
|
+
),
|
|
47
57
|
})
|
|
48
58
|
: "";
|
|
49
59
|
const smallStylesClass = smallStyles
|
|
50
60
|
? createCssClass({
|
|
51
61
|
className,
|
|
52
62
|
styles: smallStyles,
|
|
53
|
-
mediaQuery: getMaxWidthQueryForSize(
|
|
63
|
+
mediaQuery: getMaxWidthQueryForSize(
|
|
64
|
+
"small",
|
|
65
|
+
sizesWithUpdatedBreakpoints
|
|
66
|
+
),
|
|
54
67
|
})
|
|
55
68
|
: "";
|
|
56
69
|
return [largeStylesClass, mediumStylesClass, smallStylesClass].join(" ");
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
return ref;
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
|
-
$:
|
|
61
|
+
$: tag = () => {
|
|
62
62
|
return getBlockTag(useBlock());
|
|
63
63
|
};
|
|
64
64
|
$: useBlock = () => {
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
};
|
|
95
95
|
$: renderComponentProps = () => {
|
|
96
96
|
return {
|
|
97
|
-
blockChildren:
|
|
97
|
+
blockChildren: useChildren(),
|
|
98
98
|
componentRef: component?.()?.component,
|
|
99
99
|
componentOptions: {
|
|
100
100
|
...getBlockComponentOptions(useBlock()),
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
context: childrenContext(),
|
|
112
112
|
};
|
|
113
113
|
};
|
|
114
|
-
$:
|
|
114
|
+
$: useChildren = () => {
|
|
115
115
|
// TO-DO: When should `canHaveChildren` dictate rendering?
|
|
116
116
|
// This is currently commented out because some Builder components (e.g. Box) do not have `canHaveChildren: true`,
|
|
117
117
|
// but still receive and need to render children.
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
*/
|
|
128
128
|
const shouldRenderChildrenOutsideRef =
|
|
129
129
|
!component?.()?.component && !repeatItemData();
|
|
130
|
-
return shouldRenderChildrenOutsideRef ?
|
|
130
|
+
return shouldRenderChildrenOutsideRef ? useChildren() : [];
|
|
131
131
|
};
|
|
132
132
|
$: repeatItemData = () => {
|
|
133
133
|
/**
|
|
@@ -197,18 +197,18 @@
|
|
|
197
197
|
</script>
|
|
198
198
|
|
|
199
199
|
{#if shouldWrap()}
|
|
200
|
-
{#if isEmptyHtmlElement(
|
|
201
|
-
<svelte:element this={
|
|
200
|
+
{#if isEmptyHtmlElement(tag())}
|
|
201
|
+
<svelte:element this={tag()} {...attributes()} />
|
|
202
202
|
{/if}
|
|
203
203
|
|
|
204
|
-
{#if !isEmptyHtmlElement(
|
|
204
|
+
{#if !isEmptyHtmlElement(tag()) && repeatItemData()}
|
|
205
205
|
{#each repeatItemData() as data, index (index)}
|
|
206
206
|
<RenderRepeatedBlock repeatContext={data.context} block={data.block} />
|
|
207
207
|
{/each}
|
|
208
208
|
{/if}
|
|
209
209
|
|
|
210
|
-
{#if !isEmptyHtmlElement(
|
|
211
|
-
<svelte:element this={
|
|
210
|
+
{#if !isEmptyHtmlElement(tag()) && !repeatItemData()}
|
|
211
|
+
<svelte:element this={tag()} {...attributes()}>
|
|
212
212
|
<svelte:component
|
|
213
213
|
this={renderComponentTag()}
|
|
214
214
|
{...renderComponentProps()}
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
<script lang="ts">
|
|
15
15
|
import BlockStyles from "./block-styles.svelte";
|
|
16
16
|
import RenderBlock from "./render-block.svelte";
|
|
17
|
-
import { markPropsMutable } from "../../functions/mark-mutable.js";
|
|
18
17
|
|
|
19
18
|
export let componentRef: RenderComponentProps["componentRef"];
|
|
20
19
|
export let componentOptions: RenderComponentProps["componentOptions"];
|
|
@@ -23,7 +22,7 @@
|
|
|
23
22
|
</script>
|
|
24
23
|
|
|
25
24
|
{#if componentRef}
|
|
26
|
-
<svelte:component this={componentRef} {...
|
|
25
|
+
<svelte:component this={componentRef} {...componentOptions}>
|
|
27
26
|
{#each blockChildren as child ("render-block-" + child.id)}
|
|
28
27
|
<RenderBlock block={child} {context} />
|
|
29
28
|
{/each}
|
|
@@ -64,7 +64,6 @@
|
|
|
64
64
|
registerInsertMenu,
|
|
65
65
|
setupBrowserForEditing,
|
|
66
66
|
} from "../../scripts/init-editing.js";
|
|
67
|
-
import { markMutable } from "../../functions/mark-mutable.js";
|
|
68
67
|
|
|
69
68
|
export let content: RenderContentProps["content"];
|
|
70
69
|
export let data: RenderContentProps["data"];
|
|
@@ -262,7 +261,6 @@
|
|
|
262
261
|
if (isBrowser()) {
|
|
263
262
|
if (isEditing()) {
|
|
264
263
|
forceReRenderCount = forceReRenderCount + 1;
|
|
265
|
-
// QWIK-REPLACE: _useMutableProps
|
|
266
264
|
registerInsertMenu();
|
|
267
265
|
setupBrowserForEditing();
|
|
268
266
|
Object.values(allRegisteredComponents()).forEach(
|
|
@@ -353,7 +351,7 @@
|
|
|
353
351
|
/>
|
|
354
352
|
{/if}
|
|
355
353
|
<RenderBlocks
|
|
356
|
-
blocks={
|
|
354
|
+
blocks={useContent?.()?.data?.blocks}
|
|
357
355
|
key={forceReRenderCount}
|
|
358
356
|
/>
|
|
359
357
|
</div>
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
export let styles: Props["styles"];
|
|
11
11
|
|
|
12
12
|
$: injectedStyleScript = () => {
|
|
13
|
-
return `<${
|
|
13
|
+
return `<${tag()}>${styles}</${tag()}>`;
|
|
14
14
|
};
|
|
15
|
-
$:
|
|
15
|
+
$: tag = () => {
|
|
16
16
|
// NOTE: we have to obfusctate the name of the tag due to a limitation in the svelte-preprocessor plugin.
|
|
17
17
|
// https://github.com/sveltejs/vite-plugin-svelte/issues/315#issuecomment-1109000027
|
|
18
18
|
return "sty" + "le";
|
|
@@ -22,5 +22,5 @@
|
|
|
22
22
|
{#if TARGET === "svelte"}
|
|
23
23
|
{@html injectedStyleScript()}
|
|
24
24
|
{:else}
|
|
25
|
-
<svelte:element this={
|
|
25
|
+
<svelte:element this={tag()}>{styles}</svelte:element>
|
|
26
26
|
{/if}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fastClone } from '../functions/fast-clone';
|
|
1
2
|
export type SizeName = 'large' | 'medium' | 'small';
|
|
2
3
|
|
|
3
4
|
interface Size {
|
|
@@ -24,5 +25,41 @@ const SIZES: Record<SizeName, Size> = {
|
|
|
24
25
|
},
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
export const getMaxWidthQueryForSize = (size: SizeName) =>
|
|
28
|
-
`@media (max-width: ${
|
|
28
|
+
export const getMaxWidthQueryForSize = (size: SizeName, sizeValues = SIZES) =>
|
|
29
|
+
`@media (max-width: ${sizeValues[size].max}px)`;
|
|
30
|
+
|
|
31
|
+
interface Breakpoints {
|
|
32
|
+
small?: number;
|
|
33
|
+
medium?: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const getSizesForBreakpoints = ({ small, medium }: Breakpoints) => {
|
|
37
|
+
const newSizes = fastClone(SIZES); // Note: this helps to get a deep clone of fields like small, medium etc
|
|
38
|
+
|
|
39
|
+
if (!small || !medium) {
|
|
40
|
+
return newSizes;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const smallMin = Math.floor(small / 2);
|
|
44
|
+
newSizes.small = {
|
|
45
|
+
max: small,
|
|
46
|
+
min: smallMin,
|
|
47
|
+
default: smallMin + 1,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const mediumMin = newSizes.small.max + 1;
|
|
51
|
+
newSizes.medium = {
|
|
52
|
+
max: medium,
|
|
53
|
+
min: mediumMin,
|
|
54
|
+
default: mediumMin + 1,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const largeMin = newSizes.medium.max + 1;
|
|
58
|
+
newSizes.large = {
|
|
59
|
+
max: 2000, // TODO: decide upper limit
|
|
60
|
+
min: largeMin,
|
|
61
|
+
default: largeMin + 1,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return newSizes;
|
|
65
|
+
};
|
|
@@ -23,10 +23,15 @@ export const generateContentUrl = (options: GetContentOptions): URL => {
|
|
|
23
23
|
noTraverse = false,
|
|
24
24
|
model,
|
|
25
25
|
apiKey,
|
|
26
|
+
includeRefs = true,
|
|
26
27
|
} = options;
|
|
27
28
|
|
|
29
|
+
if (!apiKey) {
|
|
30
|
+
throw new Error('Missing API key');
|
|
31
|
+
}
|
|
32
|
+
|
|
28
33
|
const url = new URL(
|
|
29
|
-
`https://cdn.builder.io/api/v2/content/${model}?apiKey=${apiKey}&limit=${limit}&noTraverse=${noTraverse}`
|
|
34
|
+
`https://cdn.builder.io/api/v2/content/${model}?apiKey=${apiKey}&limit=${limit}&noTraverse=${noTraverse}&includeRefs=${includeRefs}`
|
|
30
35
|
);
|
|
31
36
|
|
|
32
37
|
const queryOptions = {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { serializeFn } from '../blocks/util.js';
|
|
1
2
|
import type { RegisteredComponent } from '../context/types.js';
|
|
2
3
|
import type { ComponentInfo, Input } from '../types/components.js';
|
|
3
4
|
import { fastClone } from './fast-clone.js';
|
|
@@ -31,24 +32,6 @@ export const createRegisterComponentMessage = ({
|
|
|
31
32
|
const serializeValue = (value: object): any =>
|
|
32
33
|
typeof value === 'function' ? serializeFn(value) : fastClone(value);
|
|
33
34
|
|
|
34
|
-
/**
|
|
35
|
-
* Input attributes that are functions must be converted to strings before being serialized to JSON.
|
|
36
|
-
*/
|
|
37
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
38
|
-
const serializeFn = (fnValue: Function) => {
|
|
39
|
-
const fnStr = fnValue.toString().trim();
|
|
40
|
-
// we need to account for a few different fn syntaxes:
|
|
41
|
-
// 1. `function name(args) => {code}`
|
|
42
|
-
// 2. `name(args) => {code}`
|
|
43
|
-
// 3. `(args) => {}`
|
|
44
|
-
const appendFunction =
|
|
45
|
-
!fnStr.startsWith('function') && !fnStr.startsWith('(');
|
|
46
|
-
|
|
47
|
-
return `return (${
|
|
48
|
-
appendFunction ? 'function ' : ''
|
|
49
|
-
}${fnStr}).apply(this, arguments)`;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
35
|
const prepareComponentInfoToSend = ({
|
|
53
36
|
inputs,
|
|
54
37
|
...info
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
export * from './index-helpers/top-of-file.js';
|
|
2
2
|
import './scripts/init-editing.js';
|
|
3
3
|
|
|
4
4
|
export * from './index-helpers/blocks-exports.js';
|
|
@@ -11,3 +11,5 @@ export * from './functions/set-editor-settings.js';
|
|
|
11
11
|
export * from './functions/get-content/index.js';
|
|
12
12
|
export * from './functions/get-builder-search-params/index.js';
|
|
13
13
|
export { track } from './functions/track';
|
|
14
|
+
export type { RegisteredComponent } from './context/types';
|
|
15
|
+
export type { ComponentInfo } from './types/components';
|
|
@@ -23,7 +23,12 @@ export const registerInsertMenu = () => {
|
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
let isSetupForEditing = false;
|
|
26
27
|
export const setupBrowserForEditing = () => {
|
|
28
|
+
if (isSetupForEditing) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
isSetupForEditing = true;
|
|
27
32
|
if (isBrowser()) {
|
|
28
33
|
window.parent?.postMessage(
|
|
29
34
|
{
|
|
@@ -37,6 +42,7 @@ export const setupBrowserForEditing = () => {
|
|
|
37
42
|
// Supports builder-model="..." attribute which is needed to
|
|
38
43
|
// scope our '+ add block' button styling
|
|
39
44
|
supportsAddBlockScoping: true,
|
|
45
|
+
supportsCustomBreakpoints: true,
|
|
40
46
|
},
|
|
41
47
|
},
|
|
42
48
|
'*'
|
|
@@ -17,6 +17,13 @@ export interface BuilderContentVariation {
|
|
|
17
17
|
name?: string;
|
|
18
18
|
testRatio?: number;
|
|
19
19
|
id?: string;
|
|
20
|
+
meta?: {
|
|
21
|
+
breakpoints?: {
|
|
22
|
+
small: number;
|
|
23
|
+
medium: number;
|
|
24
|
+
};
|
|
25
|
+
[key: string]: any;
|
|
26
|
+
};
|
|
20
27
|
}
|
|
21
28
|
|
|
22
29
|
// TODO: separate full and partial versions
|