@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.
package/lib/node/dev.jsx CHANGED
@@ -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) {
@@ -536,6 +536,212 @@ function getProcessedBlock({
536
536
  }
537
537
  }
538
538
 
539
+ // src/components/block/animator.ts
540
+ function throttle(func, wait, options = {}) {
541
+ let context;
542
+ let args;
543
+ let result;
544
+ let timeout = null;
545
+ let previous = 0;
546
+ const later = function() {
547
+ previous = options.leading === false ? 0 : Date.now();
548
+ timeout = null;
549
+ result = func.apply(context, args);
550
+ if (!timeout)
551
+ context = args = null;
552
+ };
553
+ return function() {
554
+ const now = Date.now();
555
+ if (!previous && options.leading === false)
556
+ previous = now;
557
+ const remaining = wait - (now - previous);
558
+ context = this;
559
+ args = arguments;
560
+ if (remaining <= 0 || remaining > wait) {
561
+ if (timeout) {
562
+ clearTimeout(timeout);
563
+ timeout = null;
564
+ }
565
+ previous = now;
566
+ result = func.apply(context, args);
567
+ if (!timeout)
568
+ context = args = null;
569
+ } else if (!timeout && options.trailing !== false) {
570
+ timeout = setTimeout(later, remaining);
571
+ }
572
+ return result;
573
+ };
574
+ }
575
+ function assign(target, ..._args) {
576
+ const to = Object(target);
577
+ for (let index = 1; index < arguments.length; index++) {
578
+ const nextSource = arguments[index];
579
+ if (nextSource != null) {
580
+ for (const nextKey in nextSource) {
581
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
582
+ to[nextKey] = nextSource[nextKey];
583
+ }
584
+ }
585
+ }
586
+ }
587
+ return to;
588
+ }
589
+ var camelCaseToKebabCase = (str) => str ? str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`) : "";
590
+ function bindAnimations(animations) {
591
+ for (const animation of animations) {
592
+ switch (animation.trigger) {
593
+ case "pageLoad":
594
+ triggerAnimation(animation);
595
+ break;
596
+ case "hover":
597
+ bindHoverAnimation(animation);
598
+ break;
599
+ case "scrollInView":
600
+ bindScrollInViewAnimation(animation);
601
+ break;
602
+ }
603
+ }
604
+ }
605
+ function warnElementNotPresent(id) {
606
+ console.warn(`Cannot animate element: element with ID ${id} not found!`);
607
+ }
608
+ function augmentAnimation(animation, element) {
609
+ const stylesUsed = getAllStylesUsed(animation);
610
+ const computedStyle = getComputedStyle(element);
611
+ const firstStyles = animation.steps[0].styles;
612
+ const lastStyles = animation.steps[animation.steps.length - 1].styles;
613
+ const bothStyles = [firstStyles, lastStyles];
614
+ for (const styles of bothStyles) {
615
+ for (const style of stylesUsed) {
616
+ if (!(style in styles)) {
617
+ styles[style] = computedStyle[style];
618
+ }
619
+ }
620
+ }
621
+ }
622
+ function getAllStylesUsed(animation) {
623
+ const properties = [];
624
+ for (const step of animation.steps) {
625
+ for (const key in step.styles) {
626
+ if (properties.indexOf(key) === -1) {
627
+ properties.push(key);
628
+ }
629
+ }
630
+ }
631
+ return properties;
632
+ }
633
+ function triggerAnimation(animation) {
634
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
635
+ if (!elements.length) {
636
+ warnElementNotPresent(animation.elementId || animation.id || "");
637
+ return;
638
+ }
639
+ Array.from(elements).forEach((element) => {
640
+ augmentAnimation(animation, element);
641
+ element.style.transition = "none";
642
+ element.style.transitionDelay = "0";
643
+ assign(element.style, animation.steps[0].styles);
644
+ setTimeout(() => {
645
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
646
+ if (animation.delay) {
647
+ element.style.transitionDelay = animation.delay + "s";
648
+ }
649
+ assign(element.style, animation.steps[1].styles);
650
+ setTimeout(() => {
651
+ element.style.transition = "";
652
+ element.style.transitionDelay = "";
653
+ }, (animation.delay || 0) * 1e3 + animation.duration * 1e3 + 100);
654
+ });
655
+ });
656
+ }
657
+ function bindHoverAnimation(animation) {
658
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
659
+ if (!elements.length) {
660
+ warnElementNotPresent(animation.elementId || animation.id || "");
661
+ return;
662
+ }
663
+ Array.from(elements).forEach((element) => {
664
+ augmentAnimation(animation, element);
665
+ const defaultState = animation.steps[0].styles;
666
+ const hoverState = animation.steps[1].styles;
667
+ function attachDefaultState() {
668
+ assign(element.style, defaultState);
669
+ }
670
+ function attachHoverState() {
671
+ assign(element.style, hoverState);
672
+ }
673
+ attachDefaultState();
674
+ element.addEventListener("mouseenter", attachHoverState);
675
+ element.addEventListener("mouseleave", attachDefaultState);
676
+ setTimeout(() => {
677
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
678
+ if (animation.delay) {
679
+ element.style.transitionDelay = animation.delay + "s";
680
+ }
681
+ });
682
+ });
683
+ }
684
+ function bindScrollInViewAnimation(animation) {
685
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
686
+ if (!elements.length) {
687
+ warnElementNotPresent(animation.elementId || animation.id || "");
688
+ return;
689
+ }
690
+ Array.from(elements).forEach((element) => {
691
+ augmentAnimation(animation, element);
692
+ let triggered = false;
693
+ let pendingAnimation = false;
694
+ function immediateOnScroll() {
695
+ if (!triggered && isScrolledIntoView(element)) {
696
+ triggered = true;
697
+ pendingAnimation = true;
698
+ setTimeout(() => {
699
+ assign(element.style, animation.steps[1].styles);
700
+ if (!animation.repeat) {
701
+ document.removeEventListener("scroll", onScroll);
702
+ }
703
+ setTimeout(() => {
704
+ pendingAnimation = false;
705
+ if (!animation.repeat) {
706
+ element.style.transition = "";
707
+ element.style.transitionDelay = "";
708
+ }
709
+ }, (animation.duration + (animation.delay || 0)) * 1e3 + 100);
710
+ });
711
+ } else if (animation.repeat && triggered && !pendingAnimation && !isScrolledIntoView(element)) {
712
+ triggered = false;
713
+ assign(element.style, animation.steps[0].styles);
714
+ }
715
+ }
716
+ const onScroll = throttle(immediateOnScroll, 200, {
717
+ leading: false
718
+ });
719
+ function isScrolledIntoView(elem) {
720
+ const rect = elem.getBoundingClientRect();
721
+ const windowHeight = window.innerHeight;
722
+ const thresholdPercent = (animation.thresholdPercent || 0) / 100;
723
+ const threshold = thresholdPercent * windowHeight;
724
+ return rect.bottom > threshold && rect.top < windowHeight - threshold;
725
+ }
726
+ const defaultState = animation.steps[0].styles;
727
+ function attachDefaultState() {
728
+ assign(element.style, defaultState);
729
+ }
730
+ attachDefaultState();
731
+ setTimeout(() => {
732
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
733
+ if (animation.delay) {
734
+ element.style.transitionDelay = animation.delay + "s";
735
+ }
736
+ });
737
+ document.addEventListener("scroll", onScroll, {
738
+ capture: true,
739
+ passive: true
740
+ });
741
+ immediateOnScroll();
742
+ });
743
+ }
744
+
539
745
  // src/components/block/block.helpers.ts
540
746
  var getComponent = ({
541
747
  block,
@@ -1058,6 +1264,18 @@ function Block(props) {
1058
1264
  isInteractive: !blockComponent()?.isRSC
1059
1265
  };
1060
1266
  }
1267
+ onMount(() => {
1268
+ const blockId = processedBlock().id;
1269
+ const animations = processedBlock().animations;
1270
+ if (animations && blockId) {
1271
+ bindAnimations(
1272
+ animations.filter((item) => item.trigger !== "hover").map((animation) => ({
1273
+ ...animation,
1274
+ elementId: blockId
1275
+ }))
1276
+ );
1277
+ }
1278
+ });
1061
1279
  return <Show4 when={canShowBlock()}>
1062
1280
  <Block_styles_default block={props.block} context={props.context} />
1063
1281
  <Show4
@@ -1506,10 +1724,10 @@ function SectionComponent(props) {
1506
1724
  var section_default = SectionComponent;
1507
1725
 
1508
1726
  // src/blocks/symbol/symbol.tsx
1509
- import { onMount as onMount4, on as on3, createEffect as createEffect3, createSignal as createSignal14 } from "solid-js";
1727
+ import { onMount as onMount5, on as on3, createEffect as createEffect3, createSignal as createSignal14 } from "solid-js";
1510
1728
 
1511
1729
  // src/components/content-variants/content-variants.tsx
1512
- import { Show as Show11, For as For5, onMount as onMount3, createSignal as createSignal13 } from "solid-js";
1730
+ import { Show as Show11, For as For5, onMount as onMount4, createSignal as createSignal13 } from "solid-js";
1513
1731
 
1514
1732
  // src/helpers/url.ts
1515
1733
  var getTopLevelDomain = (host) => {
@@ -1987,12 +2205,12 @@ var componentInfo3 = {
1987
2205
  };
1988
2206
 
1989
2207
  // src/blocks/custom-code/custom-code.tsx
1990
- import { onMount, createSignal as createSignal7 } from "solid-js";
2208
+ import { onMount as onMount2, createSignal as createSignal7 } from "solid-js";
1991
2209
  function CustomCode(props) {
1992
2210
  const [scriptsInserted, setScriptsInserted] = createSignal7([]);
1993
2211
  const [scriptsRun, setScriptsRun] = createSignal7([]);
1994
2212
  let elementRef;
1995
- onMount(() => {
2213
+ onMount2(() => {
1996
2214
  if (!elementRef?.getElementsByTagName || typeof window === "undefined") {
1997
2215
  return;
1998
2216
  }
@@ -2713,7 +2931,7 @@ function InlinedScript(props) {
2713
2931
  var Inlined_script_default = InlinedScript;
2714
2932
 
2715
2933
  // src/components/content/components/enable-editor.tsx
2716
- import { Show as Show9, onMount as onMount2, on as on2, createEffect as createEffect2, createSignal as createSignal10 } from "solid-js";
2934
+ import { Show as Show9, onMount as onMount3, on as on2, createEffect as createEffect2, createSignal as createSignal10 } from "solid-js";
2717
2935
  import { Dynamic as Dynamic5 } from "solid-js/web";
2718
2936
 
2719
2937
  // src/helpers/preview-lru-cache/get.ts
@@ -2950,13 +3168,6 @@ async function fetchEntries(options) {
2950
3168
  }
2951
3169
  var getAllContent = fetchEntries;
2952
3170
 
2953
- // src/functions/is-from-trusted-host.ts
2954
- var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
2955
- function isFromTrustedHost(trustedHosts, e) {
2956
- const url = new URL(e.origin), hostname = url.hostname;
2957
- return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
2958
- }
2959
-
2960
3171
  // src/functions/is-previewing.ts
2961
3172
  function isPreviewing() {
2962
3173
  if (!isBrowser()) {
@@ -3207,8 +3418,15 @@ var getInteractionPropertiesForEvent = (event) => {
3207
3418
  };
3208
3419
  };
3209
3420
 
3421
+ // src/functions/is-from-trusted-host.ts
3422
+ var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
3423
+ function isFromTrustedHost(trustedHosts, e) {
3424
+ const url = new URL(e.origin), hostname = url.hostname;
3425
+ return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
3426
+ }
3427
+
3210
3428
  // src/constants/sdk-version.ts
3211
- var SDK_VERSION = "0.12.6";
3429
+ var SDK_VERSION = "0.12.8";
3212
3430
 
3213
3431
  // src/functions/register.ts
3214
3432
  var registry = {};
@@ -3345,6 +3563,66 @@ var setupBrowserForEditing = (options = {}) => {
3345
3563
  }
3346
3564
  };
3347
3565
 
3566
+ // src/helpers/subscribe-to-editor.ts
3567
+ var createEditorListener = ({
3568
+ model,
3569
+ trustedHosts,
3570
+ callbacks
3571
+ }) => {
3572
+ return (event) => {
3573
+ if (!isFromTrustedHost(trustedHosts, event)) {
3574
+ return;
3575
+ }
3576
+ const {
3577
+ data
3578
+ } = event;
3579
+ if (data) {
3580
+ switch (data.type) {
3581
+ case "builder.configureSdk": {
3582
+ callbacks.configureSdk(data.data);
3583
+ break;
3584
+ }
3585
+ case "builder.triggerAnimation": {
3586
+ callbacks.animation(data.data);
3587
+ break;
3588
+ }
3589
+ case "builder.contentUpdate": {
3590
+ const messageContent = data.data;
3591
+ const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3592
+ const contentData = messageContent.data;
3593
+ if (key === model) {
3594
+ callbacks.contentUpdate(contentData);
3595
+ }
3596
+ break;
3597
+ }
3598
+ }
3599
+ }
3600
+ };
3601
+ };
3602
+ var subscribeToEditor = (model, callback, options) => {
3603
+ if (!isBrowser) {
3604
+ logger.warn("`subscribeToEditor` only works in the browser. It currently seems to be running on the server.");
3605
+ return () => {
3606
+ };
3607
+ }
3608
+ setupBrowserForEditing();
3609
+ const listener = createEditorListener({
3610
+ callbacks: {
3611
+ contentUpdate: callback,
3612
+ animation: () => {
3613
+ },
3614
+ configureSdk: () => {
3615
+ }
3616
+ },
3617
+ model,
3618
+ trustedHosts: options?.trustedHosts
3619
+ });
3620
+ window.addEventListener("message", listener);
3621
+ return () => {
3622
+ window.removeEventListener("message", listener);
3623
+ };
3624
+ };
3625
+
3348
3626
  // src/components/content/components/enable-editor.tsx
3349
3627
  function EnableEditor(props) {
3350
3628
  const [forceReRenderCount, setForceReRenderCount] = createSignal10(0);
@@ -3390,14 +3668,11 @@ function EnableEditor(props) {
3390
3668
  }));
3391
3669
  }
3392
3670
  function processMessage(event) {
3393
- if (!isFromTrustedHost(props.trustedHosts, event)) {
3394
- return;
3395
- }
3396
- const { data } = event;
3397
- if (data) {
3398
- switch (data.type) {
3399
- case "builder.configureSdk": {
3400
- const messageContent = data.data;
3671
+ return createEditorListener({
3672
+ model: props.model,
3673
+ trustedHosts: props.trustedHosts,
3674
+ callbacks: {
3675
+ configureSdk: (messageContent) => {
3401
3676
  const { breakpoints, contentId } = messageContent;
3402
3677
  if (!contentId || contentId !== props.builderContextSignal.content?.id) {
3403
3678
  return;
@@ -3408,22 +3683,18 @@ function EnableEditor(props) {
3408
3683
  breakpoints
3409
3684
  }
3410
3685
  });
3411
- }
3412
- setForceReRenderCount(forceReRenderCount() + 1);
3413
- break;
3414
- }
3415
- case "builder.contentUpdate": {
3416
- const messageContent = data.data;
3417
- const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3418
- const contentData = messageContent.data;
3419
- if (key === props.model) {
3420
- mergeNewContent(contentData);
3421
3686
  setForceReRenderCount(forceReRenderCount() + 1);
3422
3687
  }
3423
- break;
3688
+ },
3689
+ animation: (animation) => {
3690
+ triggerAnimation(animation);
3691
+ },
3692
+ contentUpdate: (newContent) => {
3693
+ mergeNewContent(newContent);
3694
+ setForceReRenderCount(forceReRenderCount() + 1);
3424
3695
  }
3425
3696
  }
3426
- }
3697
+ })(event);
3427
3698
  }
3428
3699
  function evaluateJsCode() {
3429
3700
  const jsCode = props.builderContextSignal.content?.data?.jsCode;
@@ -3509,7 +3780,7 @@ function EnableEditor(props) {
3509
3780
  }
3510
3781
  }
3511
3782
  let elementRef;
3512
- onMount2(() => {
3783
+ onMount3(() => {
3513
3784
  if (isBrowser()) {
3514
3785
  if (isEditing() && true) {
3515
3786
  setForceReRenderCount(forceReRenderCount() + 1);
@@ -3574,7 +3845,7 @@ function EnableEditor(props) {
3574
3845
  }
3575
3846
  }
3576
3847
  });
3577
- onMount2(() => {
3848
+ onMount3(() => {
3578
3849
  if (!props.apiKey) {
3579
3850
  logger.error(
3580
3851
  "No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop."
@@ -3914,7 +4185,7 @@ function ContentVariants(props) {
3914
4185
  canTrack: getDefaultCanTrack(props.canTrack)
3915
4186
  });
3916
4187
  }
3917
- onMount3(() => {
4188
+ onMount4(() => {
3918
4189
  setShouldRenderVariants(false);
3919
4190
  });
3920
4191
  return <>
@@ -4026,7 +4297,7 @@ function Symbol(props) {
4026
4297
  }
4027
4298
  });
4028
4299
  }
4029
- onMount4(() => {
4300
+ onMount5(() => {
4030
4301
  setContent();
4031
4302
  });
4032
4303
  function onUpdateFn_0() {
@@ -4117,5 +4388,6 @@ export {
4117
4388
  isPreviewing,
4118
4389
  register,
4119
4390
  setEditorSettings,
4391
+ subscribeToEditor,
4120
4392
  track
4121
4393
  };