@builder.io/sdk-svelte 0.12.6 → 0.12.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.
Files changed (47) hide show
  1. package/lib/browser/components/block/animator.d.ts +5 -0
  2. package/lib/browser/components/block/animator.js +243 -0
  3. package/lib/browser/components/block/block.svelte +15 -1
  4. package/lib/browser/components/content/components/enable-editor.svelte +18 -27
  5. package/lib/browser/components/content/components/enable-editor.svelte.d.ts +1 -1
  6. package/lib/browser/components/content-variants/helpers.d.ts +1 -1
  7. package/lib/browser/constants/sdk-version.d.ts +1 -1
  8. package/lib/browser/constants/sdk-version.js +1 -1
  9. package/lib/browser/helpers/subscribe-to-editor.d.ts +35 -0
  10. package/lib/browser/helpers/subscribe-to-editor.js +60 -0
  11. package/lib/browser/server-index.d.ts +18 -3
  12. package/lib/browser/server-index.js +8 -1
  13. package/lib/browser/types/builder-block.d.ts +18 -1
  14. package/lib/edge/components/block/animator.d.ts +5 -0
  15. package/lib/edge/components/block/animator.js +243 -0
  16. package/lib/edge/components/block/block.svelte +15 -1
  17. package/lib/edge/components/content/components/enable-editor.svelte +18 -27
  18. package/lib/edge/components/content/components/enable-editor.svelte.d.ts +1 -1
  19. package/lib/edge/components/content-variants/helpers.d.ts +1 -1
  20. package/lib/edge/constants/sdk-version.d.ts +1 -1
  21. package/lib/edge/constants/sdk-version.js +1 -1
  22. package/lib/edge/helpers/subscribe-to-editor.d.ts +35 -0
  23. package/lib/edge/helpers/subscribe-to-editor.js +60 -0
  24. package/lib/edge/server-index.d.ts +18 -3
  25. package/lib/edge/server-index.js +8 -1
  26. package/lib/edge/types/builder-block.d.ts +18 -1
  27. package/lib/node/components/block/animator.d.ts +5 -0
  28. package/lib/node/components/block/animator.js +243 -0
  29. package/lib/node/components/block/block.svelte +15 -1
  30. package/lib/node/components/content/components/enable-editor.svelte +18 -27
  31. package/lib/node/components/content/components/enable-editor.svelte.d.ts +1 -1
  32. package/lib/node/components/content-variants/helpers.d.ts +1 -1
  33. package/lib/node/constants/sdk-version.d.ts +1 -1
  34. package/lib/node/constants/sdk-version.js +1 -1
  35. package/lib/node/helpers/subscribe-to-editor.d.ts +35 -0
  36. package/lib/node/helpers/subscribe-to-editor.js +60 -0
  37. package/lib/node/server-index.d.ts +18 -3
  38. package/lib/node/server-index.js +8 -1
  39. package/lib/node/types/builder-block.d.ts +18 -1
  40. package/package.json +1 -1
  41. package/src/components/block/animator.ts +254 -0
  42. package/src/components/block/block.svelte +17 -0
  43. package/src/components/content/components/enable-editor.svelte +18 -28
  44. package/src/constants/sdk-version.ts +1 -1
  45. package/src/helpers/subscribe-to-editor.ts +95 -0
  46. package/src/server-index.ts +23 -4
  47. package/src/types/builder-block.ts +23 -2
@@ -0,0 +1,254 @@
1
+ import type { BuilderAnimation } from '../../types/builder-block.js';
2
+
3
+ // eslint-disable-next-line @typescript-eslint/ban-types
4
+ function throttle(func: Function, wait: number, options: any = {}) {
5
+ let context: any;
6
+ let args: any;
7
+ let result: any;
8
+ let timeout = (null as any);
9
+ let previous = 0;
10
+ const later = function () {
11
+ previous = options.leading === false ? 0 : Date.now();
12
+ timeout = null;
13
+ result = func.apply(context, args);
14
+ if (!timeout) context = args = null;
15
+ };
16
+ return function (this: any) {
17
+ const now = Date.now();
18
+ if (!previous && options.leading === false) previous = now;
19
+ const remaining = wait - (now - previous);
20
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
21
+ context = this;
22
+ // eslint-disable-next-line prefer-rest-params
23
+ args = arguments;
24
+ if (remaining <= 0 || remaining > wait) {
25
+ if (timeout) {
26
+ clearTimeout(timeout);
27
+ timeout = null;
28
+ }
29
+ previous = now;
30
+ result = func.apply(context, args);
31
+ if (!timeout) context = args = null;
32
+ } else if (!timeout && options.trailing !== false) {
33
+ timeout = setTimeout(later, remaining);
34
+ }
35
+ return result;
36
+ };
37
+ }
38
+ function assign(target: object, ..._args: any[]) {
39
+ const to = Object(target);
40
+ for (let index = 1; index < arguments.length; index++) {
41
+ // eslint-disable-next-line prefer-rest-params
42
+ const nextSource = arguments[index];
43
+ if (nextSource != null) {
44
+ // Skip over if undefined or null
45
+ for (const nextKey in nextSource) {
46
+ // Avoid bugs when hasOwnProperty is shadowed
47
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
48
+ to[nextKey] = nextSource[nextKey];
49
+ }
50
+ }
51
+ }
52
+ }
53
+ return to;
54
+ }
55
+ const camelCaseToKebabCase = (str?: string) => str ? str.replace(/([A-Z])/g, g => `-${g[0].toLowerCase()}`) : '';
56
+ export function bindAnimations(animations: BuilderAnimation[]) {
57
+ for (const animation of animations) {
58
+ switch (animation.trigger) {
59
+ case 'pageLoad':
60
+ triggerAnimation(animation);
61
+ break;
62
+ case 'hover':
63
+ bindHoverAnimation(animation);
64
+ break;
65
+ case 'scrollInView':
66
+ bindScrollInViewAnimation(animation);
67
+ break;
68
+ }
69
+ }
70
+ }
71
+ function warnElementNotPresent(id: string) {
72
+ console.warn(`Cannot animate element: element with ID ${id} not found!`);
73
+ }
74
+ function augmentAnimation(animation: BuilderAnimation, element: HTMLElement) {
75
+ const stylesUsed = getAllStylesUsed(animation);
76
+ const computedStyle: any = getComputedStyle(element);
77
+ // const computedStyle = getComputedStyle(element);
78
+ // // FIXME: this will break if original load is in one reponsive size then resize to another hmmm
79
+ // Need to use transform instead of left since left can change on screen sizes
80
+ const firstStyles = animation.steps[0].styles;
81
+ const lastStyles = animation.steps[animation.steps.length - 1]!.styles;
82
+ const bothStyles = [firstStyles, lastStyles];
83
+
84
+ // FIXME: this won't work as expected for augmented animations - may need the editor itself to manage this
85
+ for (const styles of bothStyles) {
86
+ for (const style of stylesUsed) {
87
+ if (!(style in styles)) {
88
+ styles[(style as any)] = computedStyle[style];
89
+ }
90
+ }
91
+ }
92
+ }
93
+ function getAllStylesUsed(animation: BuilderAnimation) {
94
+ const properties: (keyof CSSStyleDeclaration)[] = [];
95
+ for (const step of animation.steps) {
96
+ for (const key in step.styles) {
97
+ if (properties.indexOf((key as any)) === -1) {
98
+ properties.push((key as any));
99
+ }
100
+ }
101
+ }
102
+ return properties;
103
+ }
104
+ export function triggerAnimation(animation: BuilderAnimation) {
105
+ // TODO: do for ALL elements
106
+ const elements = (Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || '')) as HTMLElement[]);
107
+ if (!elements.length) {
108
+ warnElementNotPresent(animation.elementId || animation.id || '');
109
+ return;
110
+ }
111
+ Array.from(elements).forEach(element => {
112
+ augmentAnimation(animation, element);
113
+ // TODO: do this properly, may have other animations of different properties
114
+
115
+ // TODO: only override the properties
116
+ // TODO: if there is an entrance and hover animation, the transition duration will get effed
117
+ // element.setAttribute('style', '');
118
+
119
+ // const styledUsed = this.getAllStylesUsed(animation);
120
+ element.style.transition = 'none';
121
+ element.style.transitionDelay = '0';
122
+ assign(element.style, animation.steps[0].styles);
123
+ // TODO: queue/batch these timeouts
124
+ // TODO: only include properties explicitly set in the animation
125
+ // using Object.keys(styles)
126
+ setTimeout(() => {
127
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
128
+ if (animation.delay) {
129
+ element.style.transitionDelay = animation.delay + 's';
130
+ }
131
+ assign(element.style, animation.steps[1].styles);
132
+ // TODO: maybe remove/reset transitoin property after animation duration
133
+
134
+ // TODO: queue timers
135
+ setTimeout(() => {
136
+ // TODO: what if has other transition (reset back to what it was)
137
+ element.style.transition = '';
138
+ element.style.transitionDelay = '';
139
+ }, (animation.delay || 0) * 1000 + animation.duration * 1000 + 100);
140
+ });
141
+ });
142
+ }
143
+ export function bindHoverAnimation(animation: BuilderAnimation) {
144
+ // TODO: is it multiple binding when editing...?
145
+ // TODO: unbind on element remove
146
+ // TODO: apply to ALL elements
147
+ const elements = (Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || '')) as HTMLElement[]);
148
+ if (!elements.length) {
149
+ warnElementNotPresent(animation.elementId || animation.id || '');
150
+ return;
151
+ }
152
+ Array.from(elements).forEach(element => {
153
+ augmentAnimation(animation, element);
154
+ const defaultState = animation.steps[0].styles;
155
+ const hoverState = animation.steps[1].styles;
156
+ function attachDefaultState() {
157
+ assign(element!.style, defaultState);
158
+ }
159
+ function attachHoverState() {
160
+ assign(element!.style, hoverState);
161
+ }
162
+ attachDefaultState();
163
+ element.addEventListener('mouseenter', attachHoverState);
164
+ element.addEventListener('mouseleave', attachDefaultState);
165
+ // TODO: queue/batch these timeouts
166
+ setTimeout(() => {
167
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
168
+ if (animation.delay) {
169
+ element.style.transitionDelay = animation.delay + 's';
170
+ }
171
+ });
172
+ });
173
+ }
174
+
175
+ // TODO: unbind on element remove
176
+ export function bindScrollInViewAnimation(animation: BuilderAnimation) {
177
+ // TODO: apply to ALL matching elements
178
+ const elements = (Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || '')) as HTMLElement[]);
179
+ if (!elements.length) {
180
+ warnElementNotPresent(animation.elementId || animation.id || '');
181
+ return;
182
+ }
183
+
184
+ // TODO: if server side rendered and scrolled into view don't animate...
185
+ Array.from(elements).forEach(element => {
186
+ augmentAnimation(animation, element);
187
+ let triggered = false;
188
+ let pendingAnimation = false;
189
+ function immediateOnScroll() {
190
+ if (!triggered && isScrolledIntoView(element)) {
191
+ triggered = true;
192
+ pendingAnimation = true;
193
+ setTimeout(() => {
194
+ assign(element!.style, animation.steps[1].styles);
195
+ if (!animation.repeat) {
196
+ document.removeEventListener('scroll', onScroll);
197
+ }
198
+ setTimeout(() => {
199
+ pendingAnimation = false;
200
+ if (!animation.repeat) {
201
+ element.style.transition = '';
202
+ element.style.transitionDelay = '';
203
+ }
204
+ }, (animation.duration + (animation.delay || 0)) * 1000 + 100);
205
+ });
206
+ } else if (animation.repeat && triggered && !pendingAnimation && !isScrolledIntoView(element)) {
207
+ // we want to repeat the animation every time the the element is out of view and back again
208
+ triggered = false;
209
+ assign(element!.style, animation.steps[0].styles);
210
+ }
211
+ }
212
+
213
+ // TODO: roll all of these in one for more efficiency of checking all the rects
214
+ const onScroll = throttle(immediateOnScroll, 200, {
215
+ leading: false
216
+ });
217
+
218
+ // TODO: fully in view or partially
219
+ function isScrolledIntoView(elem: HTMLElement) {
220
+ const rect = elem.getBoundingClientRect();
221
+ const windowHeight = window.innerHeight;
222
+ const thresholdPercent = (animation.thresholdPercent || 0) / 100;
223
+ const threshold = thresholdPercent * windowHeight;
224
+
225
+ // TODO: partial in view? or what if element is larger than screen itself
226
+ return rect.bottom > threshold && rect.top < windowHeight - threshold // Element is peeking top or bottom
227
+ // (rect.top > 0 && rect.bottom < window.innerHeight) || // element fits within the screen and is fully on screen (not hanging off at all)
228
+ // (rect.top < 0 && rect.bottom > window.innerHeight) // element is larger than the screen and hangs over the top and bottom
229
+ ;
230
+ }
231
+ const defaultState = animation.steps[0].styles;
232
+ function attachDefaultState() {
233
+ assign(element!.style, defaultState);
234
+ }
235
+ attachDefaultState();
236
+
237
+ // TODO: queue/batch these timeouts!
238
+ setTimeout(() => {
239
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
240
+ if (animation.delay) {
241
+ element.style.transitionDelay = animation.delay + 's';
242
+ }
243
+ });
244
+
245
+ // TODO: one listener for everything
246
+ document.addEventListener('scroll', onScroll, ({
247
+ capture: true,
248
+ passive: true
249
+ } as any));
250
+
251
+ // Do an initial check
252
+ immediateOnScroll();
253
+ });
254
+ }
@@ -8,6 +8,7 @@
8
8
  </script>
9
9
 
10
10
  <script lang="ts">
11
+ import { onMount } from "svelte";
11
12
  import { writable } from "svelte/store";
12
13
 
13
14
  import type {
@@ -19,6 +20,7 @@
19
20
  import { getProcessedBlock } from "../../functions/get-processed-block.js";
20
21
  import { getStyle } from "../../functions/get-style.js";
21
22
  import type { BuilderBlock } from "../../types/builder-block.js";
23
+ import { bindAnimations } from "./animator.js";
22
24
  import { getComponent, getRepeatItemData } from "./block.helpers.js";
23
25
  import BlockStyles from "./components/block-styles.svelte";
24
26
  import BlockWrapper from "./components/block-wrapper.svelte";
@@ -122,6 +124,21 @@
122
124
  };
123
125
 
124
126
  let childrenContext = writable($context);
127
+
128
+ onMount(() => {
129
+ const blockId = processedBlock().id;
130
+ const animations = processedBlock().animations;
131
+ if (animations && blockId) {
132
+ bindAnimations(
133
+ animations
134
+ .filter((item) => item.trigger !== "hover")
135
+ .map((animation) => ({
136
+ ...animation,
137
+ elementId: blockId,
138
+ }))
139
+ );
140
+ }
141
+ });
125
142
  </script>
126
143
 
127
144
  {#if canShowBlock()}
@@ -24,7 +24,6 @@
24
24
  import { fetch } from "../../../functions/get-fetch.js";
25
25
  import { isBrowser } from "../../../functions/is-browser.js";
26
26
  import { isEditing } from "../../../functions/is-editing.js";
27
- import { isFromTrustedHost } from "../../../functions/is-from-trusted-host.js";
28
27
  import { isPreviewing } from "../../../functions/is-previewing.js";
29
28
  import { createRegisterComponentMessage } from "../../../functions/register-component.js";
30
29
  import { _track } from "../../../functions/track/index.js";
@@ -32,6 +31,7 @@
32
31
  import { getDefaultCanTrack } from "../../../helpers/canTrack.js";
33
32
  import { logger } from "../../../helpers/logger.js";
34
33
  import { postPreviewContent } from "../../../helpers/preview-lru-cache/set.js";
34
+ import { createEditorListener } from "../../../helpers/subscribe-to-editor.js";
35
35
  import {
36
36
  registerInsertMenu,
37
37
  setupBrowserForEditing,
@@ -39,6 +39,7 @@
39
39
  import type { BuilderContent } from "../../../types/builder-content.js";
40
40
  import type { ComponentInfo } from "../../../types/components.js";
41
41
  import type { Dictionary } from "../../../types/typescript.js";
42
+ import { triggerAnimation } from "../../block/animator.js";
42
43
  import type {
43
44
  BuilderComponentStateChange,
44
45
  ContentProps,
@@ -47,8 +48,8 @@
47
48
 
48
49
  export let builderContextSignal: BuilderEditorProps["builderContextSignal"];
49
50
  export let contentWrapper: BuilderEditorProps["contentWrapper"] = undefined;
50
- export let trustedHosts: BuilderEditorProps["trustedHosts"] = undefined;
51
51
  export let model: BuilderEditorProps["model"] = undefined;
52
+ export let trustedHosts: BuilderEditorProps["trustedHosts"] = undefined;
52
53
  export let context: BuilderEditorProps["context"] = undefined;
53
54
  export let canTrack: BuilderEditorProps["canTrack"] = undefined;
54
55
  export let apiKey: BuilderEditorProps["apiKey"];
@@ -92,14 +93,11 @@
92
93
  $builderContextSignal.content = newContentValue;
93
94
  }
94
95
  function processMessage(event: MessageEvent) {
95
- if (!isFromTrustedHost(trustedHosts, event)) {
96
- return;
97
- }
98
- const { data } = event;
99
- if (data) {
100
- switch (data.type) {
101
- case "builder.configureSdk": {
102
- const messageContent = data.data;
96
+ return createEditorListener({
97
+ model: model,
98
+ trustedHosts: trustedHosts,
99
+ callbacks: {
100
+ configureSdk: (messageContent) => {
103
101
  const { breakpoints, contentId } = messageContent;
104
102
  if (!contentId || contentId !== $builderContextSignal.content?.id) {
105
103
  return;
@@ -110,26 +108,18 @@
110
108
  breakpoints,
111
109
  },
112
110
  });
113
- }
114
- forceReRenderCount = forceReRenderCount + 1; // This is a hack to force Qwik to re-render.
115
- break;
116
- }
117
- case "builder.contentUpdate": {
118
- const messageContent = data.data;
119
- const key =
120
- messageContent.key ||
121
- messageContent.alias ||
122
- messageContent.entry ||
123
- messageContent.modelName;
124
- const contentData = messageContent.data;
125
- if (key === model) {
126
- mergeNewContent(contentData);
127
111
  forceReRenderCount = forceReRenderCount + 1; // This is a hack to force Qwik to re-render.
128
112
  }
129
- break;
130
- }
131
- }
132
- }
113
+ },
114
+ animation: (animation) => {
115
+ triggerAnimation(animation);
116
+ },
117
+ contentUpdate: (newContent) => {
118
+ mergeNewContent(newContent);
119
+ forceReRenderCount = forceReRenderCount + 1; // This is a hack to force Qwik to re-render.
120
+ },
121
+ },
122
+ })(event);
133
123
  }
134
124
  function evaluateJsCode() {
135
125
  // run any dynamic JS code attached to content
@@ -1 +1 @@
1
- export const SDK_VERSION = "0.12.6"
1
+ export const SDK_VERSION = "0.12.8"
@@ -0,0 +1,95 @@
1
+ import type { ContentProps } from '../components/content/content.types.js';
2
+ import { isBrowser } from '../functions/is-browser.js';
3
+ import { isFromTrustedHost } from '../functions/is-from-trusted-host.js';
4
+ import { setupBrowserForEditing } from '../scripts/init-editing.js';
5
+ import type { BuilderAnimation } from '../types/builder-block.js';
6
+ import type { BuilderContent } from '../types/builder-content.js';
7
+ import { logger } from './logger.js';
8
+ type ContentListener = Required<Pick<ContentProps, 'model' | 'trustedHosts'>> & {
9
+ callbacks: {
10
+ contentUpdate: (updatedContent: BuilderContent) => void;
11
+ animation: (updatedContent: BuilderAnimation) => void;
12
+ configureSdk: (updatedContent: any) => void;
13
+ };
14
+ };
15
+ export const createEditorListener = ({
16
+ model,
17
+ trustedHosts,
18
+ callbacks
19
+ }: ContentListener) => {
20
+ return (event: MessageEvent<any>): void => {
21
+ if (!isFromTrustedHost(trustedHosts, event)) {
22
+ return;
23
+ }
24
+ const {
25
+ data
26
+ } = event;
27
+ if (data) {
28
+ switch (data.type) {
29
+ case 'builder.configureSdk':
30
+ {
31
+ callbacks.configureSdk(data.data);
32
+ break;
33
+ }
34
+ case 'builder.triggerAnimation':
35
+ {
36
+ callbacks.animation(data.data);
37
+ break;
38
+ }
39
+ case 'builder.contentUpdate':
40
+ {
41
+ const messageContent = data.data;
42
+ const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
43
+ const contentData = messageContent.data;
44
+ if (key === model) {
45
+ callbacks.contentUpdate(contentData);
46
+ }
47
+ break;
48
+ }
49
+ }
50
+ }
51
+ };
52
+ };
53
+ type SubscribeToEditor = (
54
+ /**
55
+ * The Builder `model` to subscribe to
56
+ */
57
+ model: string,
58
+ /**
59
+ * The callback function to call when the content is updated.
60
+ */
61
+ callback: (updatedContent: BuilderContent) => void,
62
+ /**
63
+ * Extra options for the listener.
64
+ */
65
+ options?: {
66
+ /**
67
+ * List of hosts to allow editing content from.
68
+ */
69
+ trustedHosts?: string[] | undefined;
70
+ }) => () => void;
71
+
72
+ /**
73
+ * Subscribes to the Builder editor and listens to `content` updates of a certain `model`.
74
+ * Sends the updated `content` to the `callback` function.
75
+ */
76
+ export const subscribeToEditor: SubscribeToEditor = (model, callback, options) => {
77
+ if (!isBrowser) {
78
+ logger.warn('`subscribeToEditor` only works in the browser. It currently seems to be running on the server.');
79
+ return () => {};
80
+ }
81
+ setupBrowserForEditing();
82
+ const listener = createEditorListener({
83
+ callbacks: {
84
+ contentUpdate: callback,
85
+ animation: () => {},
86
+ configureSdk: () => {}
87
+ },
88
+ model,
89
+ trustedHosts: options?.trustedHosts
90
+ });
91
+ window.addEventListener('message', listener);
92
+ return () => {
93
+ window.removeEventListener('message', listener);
94
+ };
95
+ }
@@ -1,4 +1,8 @@
1
1
  export * from './index-helpers/top-of-file.js';
2
+
3
+ /**
4
+ * Component Prop types
5
+ */
2
6
  export type { ButtonProps } from './blocks/button/button.types.js';
3
7
  export type { ColumnProps } from './blocks/columns/columns.types.js';
4
8
  export type { FragmentProps } from './blocks/fragment/fragment.types.js';
@@ -9,6 +13,18 @@ export type { TextProps } from './blocks/text/text.types.js';
9
13
  export type { VideoProps } from './blocks/video/video.types.js';
10
14
  export type { BlocksProps } from './components/blocks/blocks.types.js';
11
15
  export type { ContentVariantsPrps as ContentProps } from './components/content-variants/content-variants.types.js';
16
+
17
+ /**
18
+ * General Builder types
19
+ */
20
+ export type { RegisteredComponent } from './context/types.js';
21
+ export type { BuilderBlock } from './types/builder-block.js';
22
+ export type { BuilderContent } from './types/builder-content.js';
23
+ export type { ComponentInfo } from './types/components.js';
24
+
25
+ /**
26
+ * Helper functions
27
+ */
12
28
  export { isEditing } from './functions/is-editing.js';
13
29
  export { isPreviewing } from './functions/is-previewing.js';
14
30
  export { createRegisterComponentMessage } from './functions/register-component.js';
@@ -16,9 +32,12 @@ export { register } from './functions/register.js';
16
32
  export type { InsertMenuConfig, InsertMenuItem } from './functions/register.js';
17
33
  export { setEditorSettings } from './functions/set-editor-settings.js';
18
34
  export type { Settings } from './functions/set-editor-settings.js';
19
- export { _processContentResult, fetchEntries, fetchOneEntry, getAllContent, getContent } from './functions/get-content/index.js';
20
35
  export { getBuilderSearchParams } from './functions/get-builder-search-params/index.js';
21
36
  export { track } from './functions/track/index.js';
22
- export type { RegisteredComponent } from './context/types.js';
23
- export type { ComponentInfo } from './types/components.js';
24
- export { fetchBuilderProps } from './functions/fetch-builder-props.js'
37
+ export { subscribeToEditor } from './helpers/subscribe-to-editor.js';
38
+
39
+ /**
40
+ * Content fetching
41
+ */
42
+ export { fetchBuilderProps } from './functions/fetch-builder-props.js';
43
+ export { _processContentResult, fetchEntries, fetchOneEntry, getAllContent, getContent } from './functions/get-content/index.js'
@@ -3,7 +3,28 @@ interface JSONObject {
3
3
  [x: string]: JSONValue;
4
4
  }
5
5
  interface JSONArray extends Array<JSONValue> {}
6
-
6
+ export interface AnimationStep {
7
+ // First one is always start state
8
+ // isStartState?: boolean;
9
+ styles: {
10
+ [key: string]: string;
11
+ };
12
+ delay?: number;
13
+ }
14
+ export interface BuilderAnimation {
15
+ elementId: string;
16
+ trigger: string;
17
+ steps: AnimationStep[];
18
+ duration: number;
19
+ delay?: number;
20
+ easing?: string;
21
+ // TODO: deprecate - only here because of an API bug
22
+ id?: string;
23
+ // only apply in scrollInView
24
+ repeat?: boolean;
25
+ // only apply in scrollInView, number from -1 to 1
26
+ thresholdPercent?: number;
27
+ }
7
28
  /** @todo typedoc this */
8
29
  export interface BuilderBlock {
9
30
  '@type': '@builder.io/sdk:Element';
@@ -52,7 +73,7 @@ export interface BuilderBlock {
52
73
  collection: string;
53
74
  itemName?: string;
54
75
  } | null;
55
- animations?: any[]; // TODO: type the animation spec
76
+ animations?: BuilderAnimation[];
56
77
  style?: Partial<CSSStyleDeclaration>;
57
78
  href?: string;
58
79