@builder.io/sdk-solid 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.
@@ -99,7 +99,7 @@ import { createContext as createContext2 } from "solid-js";
99
99
  var components_context_default = createContext2({ registeredComponents: {} });
100
100
 
101
101
  // src/components/block/block.tsx
102
- import { Show as Show4, For as For2, createSignal as createSignal4 } from "solid-js";
102
+ import { Show as Show4, For as For2, onMount, createSignal as createSignal4 } from "solid-js";
103
103
 
104
104
  // src/functions/get-block-component-options.ts
105
105
  function getBlockComponentOptions(block) {
@@ -410,6 +410,212 @@ function getProcessedBlock({
410
410
  }
411
411
  }
412
412
 
413
+ // src/components/block/animator.ts
414
+ function throttle(func, wait, options = {}) {
415
+ let context;
416
+ let args;
417
+ let result;
418
+ let timeout = null;
419
+ let previous = 0;
420
+ const later = function() {
421
+ previous = options.leading === false ? 0 : Date.now();
422
+ timeout = null;
423
+ result = func.apply(context, args);
424
+ if (!timeout)
425
+ context = args = null;
426
+ };
427
+ return function() {
428
+ const now = Date.now();
429
+ if (!previous && options.leading === false)
430
+ previous = now;
431
+ const remaining = wait - (now - previous);
432
+ context = this;
433
+ args = arguments;
434
+ if (remaining <= 0 || remaining > wait) {
435
+ if (timeout) {
436
+ clearTimeout(timeout);
437
+ timeout = null;
438
+ }
439
+ previous = now;
440
+ result = func.apply(context, args);
441
+ if (!timeout)
442
+ context = args = null;
443
+ } else if (!timeout && options.trailing !== false) {
444
+ timeout = setTimeout(later, remaining);
445
+ }
446
+ return result;
447
+ };
448
+ }
449
+ function assign(target, ..._args) {
450
+ const to = Object(target);
451
+ for (let index = 1; index < arguments.length; index++) {
452
+ const nextSource = arguments[index];
453
+ if (nextSource != null) {
454
+ for (const nextKey in nextSource) {
455
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
456
+ to[nextKey] = nextSource[nextKey];
457
+ }
458
+ }
459
+ }
460
+ }
461
+ return to;
462
+ }
463
+ var camelCaseToKebabCase = (str) => str ? str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`) : "";
464
+ function bindAnimations(animations) {
465
+ for (const animation of animations) {
466
+ switch (animation.trigger) {
467
+ case "pageLoad":
468
+ triggerAnimation(animation);
469
+ break;
470
+ case "hover":
471
+ bindHoverAnimation(animation);
472
+ break;
473
+ case "scrollInView":
474
+ bindScrollInViewAnimation(animation);
475
+ break;
476
+ }
477
+ }
478
+ }
479
+ function warnElementNotPresent(id) {
480
+ console.warn(`Cannot animate element: element with ID ${id} not found!`);
481
+ }
482
+ function augmentAnimation(animation, element) {
483
+ const stylesUsed = getAllStylesUsed(animation);
484
+ const computedStyle = getComputedStyle(element);
485
+ const firstStyles = animation.steps[0].styles;
486
+ const lastStyles = animation.steps[animation.steps.length - 1].styles;
487
+ const bothStyles = [firstStyles, lastStyles];
488
+ for (const styles of bothStyles) {
489
+ for (const style of stylesUsed) {
490
+ if (!(style in styles)) {
491
+ styles[style] = computedStyle[style];
492
+ }
493
+ }
494
+ }
495
+ }
496
+ function getAllStylesUsed(animation) {
497
+ const properties = [];
498
+ for (const step of animation.steps) {
499
+ for (const key in step.styles) {
500
+ if (properties.indexOf(key) === -1) {
501
+ properties.push(key);
502
+ }
503
+ }
504
+ }
505
+ return properties;
506
+ }
507
+ function triggerAnimation(animation) {
508
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
509
+ if (!elements.length) {
510
+ warnElementNotPresent(animation.elementId || animation.id || "");
511
+ return;
512
+ }
513
+ Array.from(elements).forEach((element) => {
514
+ augmentAnimation(animation, element);
515
+ element.style.transition = "none";
516
+ element.style.transitionDelay = "0";
517
+ assign(element.style, animation.steps[0].styles);
518
+ setTimeout(() => {
519
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
520
+ if (animation.delay) {
521
+ element.style.transitionDelay = animation.delay + "s";
522
+ }
523
+ assign(element.style, animation.steps[1].styles);
524
+ setTimeout(() => {
525
+ element.style.transition = "";
526
+ element.style.transitionDelay = "";
527
+ }, (animation.delay || 0) * 1e3 + animation.duration * 1e3 + 100);
528
+ });
529
+ });
530
+ }
531
+ function bindHoverAnimation(animation) {
532
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
533
+ if (!elements.length) {
534
+ warnElementNotPresent(animation.elementId || animation.id || "");
535
+ return;
536
+ }
537
+ Array.from(elements).forEach((element) => {
538
+ augmentAnimation(animation, element);
539
+ const defaultState = animation.steps[0].styles;
540
+ const hoverState = animation.steps[1].styles;
541
+ function attachDefaultState() {
542
+ assign(element.style, defaultState);
543
+ }
544
+ function attachHoverState() {
545
+ assign(element.style, hoverState);
546
+ }
547
+ attachDefaultState();
548
+ element.addEventListener("mouseenter", attachHoverState);
549
+ element.addEventListener("mouseleave", attachDefaultState);
550
+ setTimeout(() => {
551
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
552
+ if (animation.delay) {
553
+ element.style.transitionDelay = animation.delay + "s";
554
+ }
555
+ });
556
+ });
557
+ }
558
+ function bindScrollInViewAnimation(animation) {
559
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
560
+ if (!elements.length) {
561
+ warnElementNotPresent(animation.elementId || animation.id || "");
562
+ return;
563
+ }
564
+ Array.from(elements).forEach((element) => {
565
+ augmentAnimation(animation, element);
566
+ let triggered = false;
567
+ let pendingAnimation = false;
568
+ function immediateOnScroll() {
569
+ if (!triggered && isScrolledIntoView(element)) {
570
+ triggered = true;
571
+ pendingAnimation = true;
572
+ setTimeout(() => {
573
+ assign(element.style, animation.steps[1].styles);
574
+ if (!animation.repeat) {
575
+ document.removeEventListener("scroll", onScroll);
576
+ }
577
+ setTimeout(() => {
578
+ pendingAnimation = false;
579
+ if (!animation.repeat) {
580
+ element.style.transition = "";
581
+ element.style.transitionDelay = "";
582
+ }
583
+ }, (animation.duration + (animation.delay || 0)) * 1e3 + 100);
584
+ });
585
+ } else if (animation.repeat && triggered && !pendingAnimation && !isScrolledIntoView(element)) {
586
+ triggered = false;
587
+ assign(element.style, animation.steps[0].styles);
588
+ }
589
+ }
590
+ const onScroll = throttle(immediateOnScroll, 200, {
591
+ leading: false
592
+ });
593
+ function isScrolledIntoView(elem) {
594
+ const rect = elem.getBoundingClientRect();
595
+ const windowHeight = window.innerHeight;
596
+ const thresholdPercent = (animation.thresholdPercent || 0) / 100;
597
+ const threshold = thresholdPercent * windowHeight;
598
+ return rect.bottom > threshold && rect.top < windowHeight - threshold;
599
+ }
600
+ const defaultState = animation.steps[0].styles;
601
+ function attachDefaultState() {
602
+ assign(element.style, defaultState);
603
+ }
604
+ attachDefaultState();
605
+ setTimeout(() => {
606
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
607
+ if (animation.delay) {
608
+ element.style.transitionDelay = animation.delay + "s";
609
+ }
610
+ });
611
+ document.addEventListener("scroll", onScroll, {
612
+ capture: true,
613
+ passive: true
614
+ });
615
+ immediateOnScroll();
616
+ });
617
+ }
618
+
413
619
  // src/components/block/block.helpers.ts
414
620
  var getComponent = ({
415
621
  block,
@@ -932,6 +1138,18 @@ function Block(props) {
932
1138
  isInteractive: !blockComponent()?.isRSC
933
1139
  };
934
1140
  }
1141
+ onMount(() => {
1142
+ const blockId = processedBlock().id;
1143
+ const animations = processedBlock().animations;
1144
+ if (animations && blockId) {
1145
+ bindAnimations(
1146
+ animations.filter((item) => item.trigger !== "hover").map((animation) => ({
1147
+ ...animation,
1148
+ elementId: blockId
1149
+ }))
1150
+ );
1151
+ }
1152
+ });
935
1153
  return <Show4 when={canShowBlock()}>
936
1154
  <Block_styles_default block={props.block} context={props.context} />
937
1155
  <Show4
@@ -1380,10 +1598,10 @@ function SectionComponent(props) {
1380
1598
  var section_default = SectionComponent;
1381
1599
 
1382
1600
  // src/blocks/symbol/symbol.tsx
1383
- import { onMount as onMount4, on as on3, createEffect as createEffect3, createSignal as createSignal14 } from "solid-js";
1601
+ import { onMount as onMount5, on as on3, createEffect as createEffect3, createSignal as createSignal14 } from "solid-js";
1384
1602
 
1385
1603
  // src/components/content-variants/content-variants.tsx
1386
- import { Show as Show11, For as For5, onMount as onMount3, createSignal as createSignal13 } from "solid-js";
1604
+ import { Show as Show11, For as For5, onMount as onMount4, createSignal as createSignal13 } from "solid-js";
1387
1605
 
1388
1606
  // src/helpers/url.ts
1389
1607
  var getTopLevelDomain = (host) => {
@@ -1861,12 +2079,12 @@ var componentInfo3 = {
1861
2079
  };
1862
2080
 
1863
2081
  // src/blocks/custom-code/custom-code.tsx
1864
- import { onMount, createSignal as createSignal7 } from "solid-js";
2082
+ import { onMount as onMount2, createSignal as createSignal7 } from "solid-js";
1865
2083
  function CustomCode(props) {
1866
2084
  const [scriptsInserted, setScriptsInserted] = createSignal7([]);
1867
2085
  const [scriptsRun, setScriptsRun] = createSignal7([]);
1868
2086
  let elementRef;
1869
- onMount(() => {
2087
+ onMount2(() => {
1870
2088
  if (!elementRef?.getElementsByTagName || typeof window === "undefined") {
1871
2089
  return;
1872
2090
  }
@@ -2587,7 +2805,7 @@ function InlinedScript(props) {
2587
2805
  var Inlined_script_default = InlinedScript;
2588
2806
 
2589
2807
  // src/components/content/components/enable-editor.tsx
2590
- import { Show as Show9, onMount as onMount2, on as on2, createEffect as createEffect2, createSignal as createSignal10 } from "solid-js";
2808
+ import { Show as Show9, onMount as onMount3, on as on2, createEffect as createEffect2, createSignal as createSignal10 } from "solid-js";
2591
2809
  import { Dynamic as Dynamic5 } from "solid-js/web";
2592
2810
 
2593
2811
  // src/helpers/preview-lru-cache/get.ts
@@ -2824,13 +3042,6 @@ async function fetchEntries(options) {
2824
3042
  }
2825
3043
  var getAllContent = fetchEntries;
2826
3044
 
2827
- // src/functions/is-from-trusted-host.ts
2828
- var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
2829
- function isFromTrustedHost(trustedHosts, e) {
2830
- const url = new URL(e.origin), hostname = url.hostname;
2831
- return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
2832
- }
2833
-
2834
3045
  // src/functions/is-previewing.ts
2835
3046
  function isPreviewing() {
2836
3047
  if (!isBrowser()) {
@@ -3081,8 +3292,15 @@ var getInteractionPropertiesForEvent = (event) => {
3081
3292
  };
3082
3293
  };
3083
3294
 
3295
+ // src/functions/is-from-trusted-host.ts
3296
+ var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
3297
+ function isFromTrustedHost(trustedHosts, e) {
3298
+ const url = new URL(e.origin), hostname = url.hostname;
3299
+ return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
3300
+ }
3301
+
3084
3302
  // src/constants/sdk-version.ts
3085
- var SDK_VERSION = "0.12.6";
3303
+ var SDK_VERSION = "0.12.8";
3086
3304
 
3087
3305
  // src/functions/register.ts
3088
3306
  var registry = {};
@@ -3219,6 +3437,66 @@ var setupBrowserForEditing = (options = {}) => {
3219
3437
  }
3220
3438
  };
3221
3439
 
3440
+ // src/helpers/subscribe-to-editor.ts
3441
+ var createEditorListener = ({
3442
+ model,
3443
+ trustedHosts,
3444
+ callbacks
3445
+ }) => {
3446
+ return (event) => {
3447
+ if (!isFromTrustedHost(trustedHosts, event)) {
3448
+ return;
3449
+ }
3450
+ const {
3451
+ data
3452
+ } = event;
3453
+ if (data) {
3454
+ switch (data.type) {
3455
+ case "builder.configureSdk": {
3456
+ callbacks.configureSdk(data.data);
3457
+ break;
3458
+ }
3459
+ case "builder.triggerAnimation": {
3460
+ callbacks.animation(data.data);
3461
+ break;
3462
+ }
3463
+ case "builder.contentUpdate": {
3464
+ const messageContent = data.data;
3465
+ const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3466
+ const contentData = messageContent.data;
3467
+ if (key === model) {
3468
+ callbacks.contentUpdate(contentData);
3469
+ }
3470
+ break;
3471
+ }
3472
+ }
3473
+ }
3474
+ };
3475
+ };
3476
+ var subscribeToEditor = (model, callback, options) => {
3477
+ if (!isBrowser) {
3478
+ logger.warn("`subscribeToEditor` only works in the browser. It currently seems to be running on the server.");
3479
+ return () => {
3480
+ };
3481
+ }
3482
+ setupBrowserForEditing();
3483
+ const listener = createEditorListener({
3484
+ callbacks: {
3485
+ contentUpdate: callback,
3486
+ animation: () => {
3487
+ },
3488
+ configureSdk: () => {
3489
+ }
3490
+ },
3491
+ model,
3492
+ trustedHosts: options?.trustedHosts
3493
+ });
3494
+ window.addEventListener("message", listener);
3495
+ return () => {
3496
+ window.removeEventListener("message", listener);
3497
+ };
3498
+ };
3499
+
3222
3500
  // src/components/content/components/enable-editor.tsx
3223
3501
  function EnableEditor(props) {
3224
3502
  const [forceReRenderCount, setForceReRenderCount] = createSignal10(0);
@@ -3264,14 +3542,11 @@ function EnableEditor(props) {
3264
3542
  }));
3265
3543
  }
3266
3544
  function processMessage(event) {
3267
- if (!isFromTrustedHost(props.trustedHosts, event)) {
3268
- return;
3269
- }
3270
- const { data } = event;
3271
- if (data) {
3272
- switch (data.type) {
3273
- case "builder.configureSdk": {
3274
- const messageContent = data.data;
3545
+ return createEditorListener({
3546
+ model: props.model,
3547
+ trustedHosts: props.trustedHosts,
3548
+ callbacks: {
3549
+ configureSdk: (messageContent) => {
3275
3550
  const { breakpoints, contentId } = messageContent;
3276
3551
  if (!contentId || contentId !== props.builderContextSignal.content?.id) {
3277
3552
  return;
@@ -3282,22 +3557,18 @@ function EnableEditor(props) {
3282
3557
  breakpoints
3283
3558
  }
3284
3559
  });
3285
- }
3286
- setForceReRenderCount(forceReRenderCount() + 1);
3287
- break;
3288
- }
3289
- case "builder.contentUpdate": {
3290
- const messageContent = data.data;
3291
- const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3292
- const contentData = messageContent.data;
3293
- if (key === props.model) {
3294
- mergeNewContent(contentData);
3295
3560
  setForceReRenderCount(forceReRenderCount() + 1);
3296
3561
  }
3297
- break;
3562
+ },
3563
+ animation: (animation) => {
3564
+ triggerAnimation(animation);
3565
+ },
3566
+ contentUpdate: (newContent) => {
3567
+ mergeNewContent(newContent);
3568
+ setForceReRenderCount(forceReRenderCount() + 1);
3298
3569
  }
3299
3570
  }
3300
- }
3571
+ })(event);
3301
3572
  }
3302
3573
  function evaluateJsCode() {
3303
3574
  const jsCode = props.builderContextSignal.content?.data?.jsCode;
@@ -3383,7 +3654,7 @@ function EnableEditor(props) {
3383
3654
  }
3384
3655
  }
3385
3656
  let elementRef;
3386
- onMount2(() => {
3657
+ onMount3(() => {
3387
3658
  if (isBrowser()) {
3388
3659
  if (isEditing() && true) {
3389
3660
  setForceReRenderCount(forceReRenderCount() + 1);
@@ -3448,7 +3719,7 @@ function EnableEditor(props) {
3448
3719
  }
3449
3720
  }
3450
3721
  });
3451
- onMount2(() => {
3722
+ onMount3(() => {
3452
3723
  if (!props.apiKey) {
3453
3724
  logger.error(
3454
3725
  "No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop."
@@ -3788,7 +4059,7 @@ function ContentVariants(props) {
3788
4059
  canTrack: getDefaultCanTrack(props.canTrack)
3789
4060
  });
3790
4061
  }
3791
- onMount3(() => {
4062
+ onMount4(() => {
3792
4063
  setShouldRenderVariants(false);
3793
4064
  });
3794
4065
  return <>
@@ -3900,7 +4171,7 @@ function Symbol(props) {
3900
4171
  }
3901
4172
  });
3902
4173
  }
3903
- onMount4(() => {
4174
+ onMount5(() => {
3904
4175
  setContent();
3905
4176
  });
3906
4177
  function onUpdateFn_0() {
@@ -3991,5 +4262,6 @@ export {
3991
4262
  isPreviewing,
3992
4263
  register,
3993
4264
  setEditorSettings,
4265
+ subscribeToEditor,
3994
4266
  track
3995
4267
  };