@builder.io/sdk-svelte 0.0.6 → 0.0.8
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 +3 -3
- package/package/blocks/button/button.svelte +35 -3
- 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 +29 -1
- package/package/blocks/image/component-info.js +2 -2
- package/package/blocks/img/img.svelte +29 -1
- package/package/blocks/input/input.svelte +29 -1
- package/package/blocks/section/section.svelte +30 -2
- package/package/blocks/select/select.svelte +29 -1
- package/package/blocks/submit-button/submit-button.svelte +33 -2
- package/package/blocks/symbol/symbol.svelte +33 -8
- package/package/blocks/textarea/textarea.svelte +36 -2
- package/package/blocks/util.d.ts +4 -1
- package/package/blocks/util.js +13 -4
- package/package/blocks/video/video.svelte +30 -2
- package/package/components/render-block/block-styles.svelte +5 -3
- package/package/components/render-block/render-block.svelte +36 -15
- 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 +6 -5
- 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/evaluate.d.ts +2 -1
- package/package/functions/evaluate.js +8 -5
- package/package/functions/event-handler-name.js +1 -4
- package/package/functions/get-block-actions-handler.d.ts +5 -2
- package/package/functions/get-block-actions-handler.js +7 -8
- package/package/functions/get-block-actions.js +2 -2
- package/package/functions/get-builder-search-params/index.d.ts +1 -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/functions/track.d.ts +6 -1
- package/package/functions/track.js +4 -0
- 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 +2 -2
- package/src/blocks/button/button.svelte +41 -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 +36 -1
- package/src/blocks/image/component-info.ts +2 -2
- package/src/blocks/img/img.svelte +36 -1
- package/src/blocks/input/input.svelte +36 -1
- package/src/blocks/section/section.svelte +36 -1
- package/src/blocks/select/select.svelte +36 -1
- package/src/blocks/submit-button/submit-button.svelte +39 -1
- package/src/blocks/symbol/symbol.svelte +40 -8
- package/src/blocks/textarea/textarea.svelte +42 -1
- package/src/blocks/util.ts +18 -6
- package/src/blocks/video/video.svelte +36 -1
- package/src/components/render-block/block-styles.svelte +16 -3
- package/src/components/render-block/render-block.svelte +41 -15
- 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 +8 -5
- package/src/components/render-inlined-styles.svelte +3 -3
- package/src/constants/device-sizes.ts +39 -2
- package/src/functions/evaluate.ts +11 -6
- package/src/functions/event-handler-name.ts +1 -6
- package/src/functions/get-block-actions-handler.ts +10 -9
- package/src/functions/get-block-actions.ts +2 -2
- package/src/functions/get-builder-search-params/index.ts +1 -1
- 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/functions/track.ts +13 -1
- package/src/index.ts +3 -1
- package/src/scripts/init-editing.ts +6 -0
- package/src/types/builder-content.ts +7 -0
- package/package/functions/mark-mutable.d.ts +0 -2
- package/package/functions/mark-mutable.js +0 -6
- package/src/functions/mark-mutable.ts +0 -7
|
@@ -14,6 +14,22 @@ import { extractTextStyles } from "../../functions/extract-text-styles.js";
|
|
|
14
14
|
import RenderComponentWithContext from "./render-component-with-context.svelte";
|
|
15
15
|
import RenderComponent from "./render-component.svelte";
|
|
16
16
|
import { getReactNativeBlockStyles } from "../../functions/get-react-native-block-styles.js";
|
|
17
|
+
const setAttrs = (node, attrs) => {
|
|
18
|
+
const attrKeys = Object.keys(attrs);
|
|
19
|
+
const setup = (attr) => node.addEventListener(attr.substr(3), attrs[attr]);
|
|
20
|
+
const teardown = (attr) => node.removeEventListener(attr.substr(3), attrs[attr]);
|
|
21
|
+
attrKeys.map(setup);
|
|
22
|
+
return {
|
|
23
|
+
update(attrs) {
|
|
24
|
+
const attrKeys = Object.keys(attrs);
|
|
25
|
+
attrKeys.map(teardown);
|
|
26
|
+
attrKeys.map(setup);
|
|
27
|
+
},
|
|
28
|
+
destroy() {
|
|
29
|
+
attrKeys.map(teardown);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
};
|
|
17
33
|
export let block;
|
|
18
34
|
export let context;
|
|
19
35
|
$: component = () => {
|
|
@@ -38,7 +54,7 @@ $: component = () => {
|
|
|
38
54
|
return ref;
|
|
39
55
|
}
|
|
40
56
|
};
|
|
41
|
-
$:
|
|
57
|
+
$: tag = () => {
|
|
42
58
|
return getBlockTag(useBlock());
|
|
43
59
|
};
|
|
44
60
|
$: useBlock = () => {
|
|
@@ -51,14 +67,16 @@ $: useBlock = () => {
|
|
|
51
67
|
shouldEvaluateBindings: true,
|
|
52
68
|
});
|
|
53
69
|
};
|
|
70
|
+
$: actions = () => {
|
|
71
|
+
return getBlockActions({
|
|
72
|
+
block: useBlock(),
|
|
73
|
+
state: context.state,
|
|
74
|
+
context: context.context,
|
|
75
|
+
});
|
|
76
|
+
};
|
|
54
77
|
$: attributes = () => {
|
|
55
78
|
return {
|
|
56
79
|
...getBlockProperties(useBlock()),
|
|
57
|
-
...getBlockActions({
|
|
58
|
-
block: useBlock(),
|
|
59
|
-
state: context.state,
|
|
60
|
-
context: context.context,
|
|
61
|
-
}),
|
|
62
80
|
...(TARGET === "reactNative"
|
|
63
81
|
? {
|
|
64
82
|
style: getReactNativeBlockStyles({
|
|
@@ -74,7 +92,7 @@ $: shouldWrap = () => {
|
|
|
74
92
|
};
|
|
75
93
|
$: renderComponentProps = () => {
|
|
76
94
|
return {
|
|
77
|
-
blockChildren:
|
|
95
|
+
blockChildren: useChildren(),
|
|
78
96
|
componentRef: component?.()?.component,
|
|
79
97
|
componentOptions: {
|
|
80
98
|
...getBlockComponentOptions(useBlock()),
|
|
@@ -85,13 +103,16 @@ $: renderComponentProps = () => {
|
|
|
85
103
|
...(shouldWrap()
|
|
86
104
|
? {}
|
|
87
105
|
: {
|
|
88
|
-
attributes:
|
|
106
|
+
attributes: {
|
|
107
|
+
...attributes(),
|
|
108
|
+
...actions(),
|
|
109
|
+
},
|
|
89
110
|
}),
|
|
90
111
|
},
|
|
91
112
|
context: childrenContext(),
|
|
92
113
|
};
|
|
93
114
|
};
|
|
94
|
-
$:
|
|
115
|
+
$: useChildren = () => {
|
|
95
116
|
// TO-DO: When should `canHaveChildren` dictate rendering?
|
|
96
117
|
// This is currently commented out because some Builder components (e.g. Box) do not have `canHaveChildren: true`,
|
|
97
118
|
// but still receive and need to render children.
|
|
@@ -106,7 +127,7 @@ $: childrenWithoutParentComponent = () => {
|
|
|
106
127
|
* blocks, and the children will be repeated within those blocks.
|
|
107
128
|
*/
|
|
108
129
|
const shouldRenderChildrenOutsideRef = !component?.()?.component && !repeatItemData();
|
|
109
|
-
return shouldRenderChildrenOutsideRef ?
|
|
130
|
+
return shouldRenderChildrenOutsideRef ? useChildren() : [];
|
|
110
131
|
};
|
|
111
132
|
$: repeatItemData = () => {
|
|
112
133
|
/**
|
|
@@ -177,18 +198,18 @@ $: renderComponentTag = () => {
|
|
|
177
198
|
</script>
|
|
178
199
|
|
|
179
200
|
{#if shouldWrap()}
|
|
180
|
-
{#if isEmptyHtmlElement(
|
|
181
|
-
<svelte:element this={
|
|
201
|
+
{#if isEmptyHtmlElement(tag())}
|
|
202
|
+
<svelte:element this={tag()} {...attributes()} use:setAttrs={actions()} />
|
|
182
203
|
{/if}
|
|
183
204
|
|
|
184
|
-
{#if !isEmptyHtmlElement(
|
|
205
|
+
{#if !isEmptyHtmlElement(tag()) && repeatItemData()}
|
|
185
206
|
{#each repeatItemData() as data, index (index)}
|
|
186
207
|
<RenderRepeatedBlock repeatContext={data.context} block={data.block} />
|
|
187
208
|
{/each}
|
|
188
209
|
{/if}
|
|
189
210
|
|
|
190
|
-
{#if !isEmptyHtmlElement(
|
|
191
|
-
<svelte:element this={
|
|
211
|
+
{#if !isEmptyHtmlElement(tag()) && !repeatItemData()}
|
|
212
|
+
<svelte:element this={tag()} {...attributes()} use:setAttrs={actions()}>
|
|
192
213
|
<svelte:component
|
|
193
214
|
this={renderComponentTag()}
|
|
194
215
|
{...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 {};
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
<script>import { onDestroy, onMount, setContext, } from "svelte";
|
|
4
4
|
import { getDefaultRegisteredComponents } from "../../constants/builder-registered-components.js";
|
|
5
5
|
import { TARGET } from "../../constants/target.js";
|
|
6
|
-
import BuilderContext from "../../context/builder.context.js";
|
|
7
6
|
import { evaluate } from "../../functions/evaluate.js";
|
|
8
7
|
import { getContent } from "../../functions/get-content/index.js";
|
|
9
8
|
import { getFetch } from "../../functions/get-fetch.js";
|
|
@@ -14,8 +13,8 @@ import { components, createRegisterComponentMessage, } from "../../functions/reg
|
|
|
14
13
|
import { _track } from "../../functions/track.js";
|
|
15
14
|
import RenderBlocks from "../render-blocks.svelte";
|
|
16
15
|
import RenderContentStyles from "./components/render-styles.svelte";
|
|
16
|
+
import BuilderContext from "../../context/builder.context.js";
|
|
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;
|
|
@@ -193,10 +192,12 @@ let overrideContent = null;
|
|
|
193
192
|
let update = 0;
|
|
194
193
|
let overrideState = {};
|
|
195
194
|
onMount(() => {
|
|
195
|
+
if (!apiKey) {
|
|
196
|
+
console.error("[Builder.io]: No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop.");
|
|
197
|
+
}
|
|
196
198
|
if (isBrowser()) {
|
|
197
199
|
if (isEditing()) {
|
|
198
200
|
forceReRenderCount = forceReRenderCount + 1;
|
|
199
|
-
// QWIK-REPLACE: _useMutableProps
|
|
200
201
|
registerInsertMenu();
|
|
201
202
|
setupBrowserForEditing();
|
|
202
203
|
Object.values(allRegisteredComponents()).forEach((registeredComponent) => {
|
|
@@ -242,7 +243,7 @@ onMount(() => {
|
|
|
242
243
|
function onUpdateFn_0() {
|
|
243
244
|
evaluateJsCode();
|
|
244
245
|
}
|
|
245
|
-
$: onUpdateFn_0(...[useContent?.()?.data?.jsCode]);
|
|
246
|
+
$: onUpdateFn_0(...[useContent?.()?.data?.jsCode, contentState()]);
|
|
246
247
|
function onUpdateFn_1() {
|
|
247
248
|
runHttpRequests();
|
|
248
249
|
}
|
|
@@ -275,7 +276,7 @@ onDestroy(() => {
|
|
|
275
276
|
/>
|
|
276
277
|
{/if}
|
|
277
278
|
<RenderBlocks
|
|
278
|
-
blocks={
|
|
279
|
+
blocks={useContent?.()?.data?.blocks}
|
|
279
280
|
key={forceReRenderCount}
|
|
280
281
|
/>
|
|
281
282
|
</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
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BuilderContextInterface } from '../context/types.js';
|
|
2
|
-
export declare function evaluate({ code, context, state, event, }: {
|
|
2
|
+
export declare function evaluate({ code, context, state, event, isExpression, }: {
|
|
3
3
|
code: string;
|
|
4
4
|
event?: Event;
|
|
5
|
+
isExpression?: boolean;
|
|
5
6
|
} & Pick<BuilderContextInterface, 'state' | 'context'>): any;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isBrowser } from './is-browser.js';
|
|
2
2
|
import { isEditing } from './is-editing.js';
|
|
3
|
-
export function evaluate({ code, context, state, event, }) {
|
|
3
|
+
export function evaluate({ code, context, state, event, isExpression = true, }) {
|
|
4
4
|
if (code === '') {
|
|
5
5
|
console.warn('Skipping evaluation of empty code block.');
|
|
6
6
|
return;
|
|
@@ -12,14 +12,17 @@ export function evaluate({ code, context, state, event, }) {
|
|
|
12
12
|
};
|
|
13
13
|
// Be able to handle simple expressions like "state.foo" or "1 + 1"
|
|
14
14
|
// as well as full blocks like "var foo = "bar"; return foo"
|
|
15
|
-
const useReturn =
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
const useReturn =
|
|
16
|
+
// we disable this for cases where we definitely don't want a return
|
|
17
|
+
isExpression &&
|
|
18
|
+
!(code.includes(';') ||
|
|
19
|
+
code.includes(' return ') ||
|
|
20
|
+
code.trim().startsWith('return '));
|
|
18
21
|
const useCode = useReturn ? `return (${code});` : code;
|
|
19
22
|
try {
|
|
20
23
|
return new Function('builder', 'Builder' /* <- legacy */, 'state', 'context', 'event', useCode)(builder, builder, state, context, event);
|
|
21
24
|
}
|
|
22
25
|
catch (e) {
|
|
23
|
-
console.warn('Builder custom code error: \n While Evaluating: \n ', useCode, '\n', e
|
|
26
|
+
console.warn('Builder custom code error: \n While Evaluating: \n ', useCode, '\n', e);
|
|
24
27
|
}
|
|
25
28
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { BuilderContextInterface } from '../context/types.js';
|
|
2
2
|
import type { BuilderBlock } from '../types/builder-block.js';
|
|
3
|
-
|
|
3
|
+
declare type Options = {
|
|
4
4
|
block: BuilderBlock;
|
|
5
|
-
} & Pick<BuilderContextInterface, 'state' | 'context'
|
|
5
|
+
} & Pick<BuilderContextInterface, 'state' | 'context'>;
|
|
6
|
+
declare type EventHandler = (event: Event) => any;
|
|
7
|
+
export declare const createEventHandler: (value: string, options: Options) => EventHandler;
|
|
8
|
+
export {};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { evaluate } from './evaluate.js';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
2
|
+
export const createEventHandler = (value, options) => (event) => evaluate({
|
|
3
|
+
code: value,
|
|
4
|
+
context: options.context,
|
|
5
|
+
state: options.state,
|
|
6
|
+
event,
|
|
7
|
+
isExpression: false,
|
|
8
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getEventHandlerName } from './event-handler-name.js';
|
|
2
|
-
import {
|
|
2
|
+
import { createEventHandler } from './get-block-actions-handler.js';
|
|
3
3
|
export function getBlockActions(options) {
|
|
4
4
|
const obj = {};
|
|
5
5
|
const optionActions = options.block.actions ?? {};
|
|
@@ -9,7 +9,7 @@ export function getBlockActions(options) {
|
|
|
9
9
|
continue;
|
|
10
10
|
}
|
|
11
11
|
const value = optionActions[key];
|
|
12
|
-
obj[getEventHandlerName(key)] =
|
|
12
|
+
obj[getEventHandlerName(key)] = createEventHandler(value, options);
|
|
13
13
|
}
|
|
14
14
|
return obj;
|
|
15
15
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare type QueryObject = Record<string, string>;
|
|
1
|
+
declare type QueryObject = Record<string, string | string[]>;
|
|
2
2
|
export declare const convertSearchParamsToQueryObject: (searchParams: URLSearchParams) => QueryObject;
|
|
3
3
|
export declare const getBuilderSearchParams: (_options: QueryObject | URLSearchParams | undefined) => QueryObject;
|
|
4
4
|
export declare const getBuilderSearchParamsFromWindow: () => QueryObject;
|
|
@@ -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]) => ({
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { CanTrack } from '../types/can-track.js';
|
|
2
2
|
interface Event {
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The type of your event.
|
|
5
|
+
*
|
|
6
|
+
* Examples: `click`, `conversion`, `pageview`, `impression`
|
|
7
|
+
*/
|
|
8
|
+
type: string;
|
|
4
9
|
data: {
|
|
5
10
|
/**
|
|
6
11
|
* (Optional) The content's ID. Useful if this event pertains to a specific piece of content.
|
|
@@ -24,6 +24,10 @@ const createEvent = async ({ type: eventType, canTrack, apiKey, metadata, ...pro
|
|
|
24
24
|
},
|
|
25
25
|
});
|
|
26
26
|
export async function _track(eventProps) {
|
|
27
|
+
if (!eventProps.apiKey) {
|
|
28
|
+
console.error('[Builder.io]: Missing API key for track call. Please provide your API key.');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
27
31
|
if (!eventProps.canTrack) {
|
|
28
32
|
return;
|
|
29
33
|
}
|
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
|
@@ -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.8",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"package",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"main": "./package/index.js",
|
|
17
17
|
"module": "./package/index.js",
|
|
18
|
-
"svelte": "./
|
|
18
|
+
"svelte": "./package/index.js",
|
|
19
19
|
"exports": {
|
|
20
20
|
"./src": {
|
|
21
21
|
"import": "./src/index.js",
|
|
@@ -8,6 +8,40 @@
|
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<script lang="ts">
|
|
11
|
+
const isEvent = (attr) => attr.startsWith("on:");
|
|
12
|
+
const isNonEvent = (attr) => !attr.startsWith("on:");
|
|
13
|
+
|
|
14
|
+
const filterAttrs = (attrs, filter) => {
|
|
15
|
+
const validAttr = {};
|
|
16
|
+
Object.keys(attrs).forEach((attr) => {
|
|
17
|
+
if (filter(attr)) {
|
|
18
|
+
validAttr[attr] = attrs[attr];
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return validAttr;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const setAttrs = (node, attrs) => {
|
|
25
|
+
const attrKeys = Object.keys(attrs);
|
|
26
|
+
|
|
27
|
+
const setup = (attr) => node.addEventListener(attr.substr(3), attrs[attr]);
|
|
28
|
+
const teardown = (attr) =>
|
|
29
|
+
node.removeEventListener(attr.substr(3), attrs[attr]);
|
|
30
|
+
|
|
31
|
+
attrKeys.map(setup);
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
update(attrs) {
|
|
35
|
+
const attrKeys = Object.keys(attrs);
|
|
36
|
+
attrKeys.map(teardown);
|
|
37
|
+
attrKeys.map(setup);
|
|
38
|
+
},
|
|
39
|
+
destroy() {
|
|
40
|
+
attrKeys.map(teardown);
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
11
45
|
export let attributes: ButtonProps["attributes"];
|
|
12
46
|
export let text: ButtonProps["text"];
|
|
13
47
|
export let link: ButtonProps["link"];
|
|
@@ -16,15 +50,20 @@
|
|
|
16
50
|
|
|
17
51
|
{#if link}
|
|
18
52
|
<a
|
|
19
|
-
{...attributes}
|
|
20
53
|
role="button"
|
|
54
|
+
{...filterAttrs(attributes, isNonEvent)}
|
|
21
55
|
href={link}
|
|
22
56
|
target={openLinkInNewTab ? "_blank" : undefined}
|
|
57
|
+
use:setAttrs={filterAttrs(attributes, isEvent)}
|
|
23
58
|
>
|
|
24
59
|
{text}
|
|
25
60
|
</a>
|
|
26
61
|
{:else}
|
|
27
|
-
<button
|
|
62
|
+
<button
|
|
63
|
+
class="button"
|
|
64
|
+
{...filterAttrs(attributes, isNonEvent)}
|
|
65
|
+
use:setAttrs={filterAttrs(attributes, isEvent)}
|
|
66
|
+
>
|
|
28
67
|
{text}
|
|
29
68
|
</button>
|
|
30
69
|
{/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...');
|