@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.js CHANGED
@@ -547,6 +547,212 @@ function getProcessedBlock({
547
547
  }
548
548
  }
549
549
 
550
+ // src/components/block/animator.ts
551
+ function throttle(func, wait, options = {}) {
552
+ let context;
553
+ let args;
554
+ let result;
555
+ let timeout = null;
556
+ let previous = 0;
557
+ const later = function() {
558
+ previous = options.leading === false ? 0 : Date.now();
559
+ timeout = null;
560
+ result = func.apply(context, args);
561
+ if (!timeout)
562
+ context = args = null;
563
+ };
564
+ return function() {
565
+ const now = Date.now();
566
+ if (!previous && options.leading === false)
567
+ previous = now;
568
+ const remaining = wait - (now - previous);
569
+ context = this;
570
+ args = arguments;
571
+ if (remaining <= 0 || remaining > wait) {
572
+ if (timeout) {
573
+ clearTimeout(timeout);
574
+ timeout = null;
575
+ }
576
+ previous = now;
577
+ result = func.apply(context, args);
578
+ if (!timeout)
579
+ context = args = null;
580
+ } else if (!timeout && options.trailing !== false) {
581
+ timeout = setTimeout(later, remaining);
582
+ }
583
+ return result;
584
+ };
585
+ }
586
+ function assign(target, ..._args) {
587
+ const to = Object(target);
588
+ for (let index = 1; index < arguments.length; index++) {
589
+ const nextSource = arguments[index];
590
+ if (nextSource != null) {
591
+ for (const nextKey in nextSource) {
592
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
593
+ to[nextKey] = nextSource[nextKey];
594
+ }
595
+ }
596
+ }
597
+ }
598
+ return to;
599
+ }
600
+ var camelCaseToKebabCase = (str) => str ? str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`) : "";
601
+ function bindAnimations(animations) {
602
+ for (const animation of animations) {
603
+ switch (animation.trigger) {
604
+ case "pageLoad":
605
+ triggerAnimation(animation);
606
+ break;
607
+ case "hover":
608
+ bindHoverAnimation(animation);
609
+ break;
610
+ case "scrollInView":
611
+ bindScrollInViewAnimation(animation);
612
+ break;
613
+ }
614
+ }
615
+ }
616
+ function warnElementNotPresent(id) {
617
+ console.warn(`Cannot animate element: element with ID ${id} not found!`);
618
+ }
619
+ function augmentAnimation(animation, element) {
620
+ const stylesUsed = getAllStylesUsed(animation);
621
+ const computedStyle = getComputedStyle(element);
622
+ const firstStyles = animation.steps[0].styles;
623
+ const lastStyles = animation.steps[animation.steps.length - 1].styles;
624
+ const bothStyles = [firstStyles, lastStyles];
625
+ for (const styles of bothStyles) {
626
+ for (const style of stylesUsed) {
627
+ if (!(style in styles)) {
628
+ styles[style] = computedStyle[style];
629
+ }
630
+ }
631
+ }
632
+ }
633
+ function getAllStylesUsed(animation) {
634
+ const properties = [];
635
+ for (const step of animation.steps) {
636
+ for (const key in step.styles) {
637
+ if (properties.indexOf(key) === -1) {
638
+ properties.push(key);
639
+ }
640
+ }
641
+ }
642
+ return properties;
643
+ }
644
+ function triggerAnimation(animation) {
645
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
646
+ if (!elements.length) {
647
+ warnElementNotPresent(animation.elementId || animation.id || "");
648
+ return;
649
+ }
650
+ Array.from(elements).forEach((element) => {
651
+ augmentAnimation(animation, element);
652
+ element.style.transition = "none";
653
+ element.style.transitionDelay = "0";
654
+ assign(element.style, animation.steps[0].styles);
655
+ setTimeout(() => {
656
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
657
+ if (animation.delay) {
658
+ element.style.transitionDelay = animation.delay + "s";
659
+ }
660
+ assign(element.style, animation.steps[1].styles);
661
+ setTimeout(() => {
662
+ element.style.transition = "";
663
+ element.style.transitionDelay = "";
664
+ }, (animation.delay || 0) * 1e3 + animation.duration * 1e3 + 100);
665
+ });
666
+ });
667
+ }
668
+ function bindHoverAnimation(animation) {
669
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
670
+ if (!elements.length) {
671
+ warnElementNotPresent(animation.elementId || animation.id || "");
672
+ return;
673
+ }
674
+ Array.from(elements).forEach((element) => {
675
+ augmentAnimation(animation, element);
676
+ const defaultState = animation.steps[0].styles;
677
+ const hoverState = animation.steps[1].styles;
678
+ function attachDefaultState() {
679
+ assign(element.style, defaultState);
680
+ }
681
+ function attachHoverState() {
682
+ assign(element.style, hoverState);
683
+ }
684
+ attachDefaultState();
685
+ element.addEventListener("mouseenter", attachHoverState);
686
+ element.addEventListener("mouseleave", attachDefaultState);
687
+ setTimeout(() => {
688
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
689
+ if (animation.delay) {
690
+ element.style.transitionDelay = animation.delay + "s";
691
+ }
692
+ });
693
+ });
694
+ }
695
+ function bindScrollInViewAnimation(animation) {
696
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
697
+ if (!elements.length) {
698
+ warnElementNotPresent(animation.elementId || animation.id || "");
699
+ return;
700
+ }
701
+ Array.from(elements).forEach((element) => {
702
+ augmentAnimation(animation, element);
703
+ let triggered = false;
704
+ let pendingAnimation = false;
705
+ function immediateOnScroll() {
706
+ if (!triggered && isScrolledIntoView(element)) {
707
+ triggered = true;
708
+ pendingAnimation = true;
709
+ setTimeout(() => {
710
+ assign(element.style, animation.steps[1].styles);
711
+ if (!animation.repeat) {
712
+ document.removeEventListener("scroll", onScroll);
713
+ }
714
+ setTimeout(() => {
715
+ pendingAnimation = false;
716
+ if (!animation.repeat) {
717
+ element.style.transition = "";
718
+ element.style.transitionDelay = "";
719
+ }
720
+ }, (animation.duration + (animation.delay || 0)) * 1e3 + 100);
721
+ });
722
+ } else if (animation.repeat && triggered && !pendingAnimation && !isScrolledIntoView(element)) {
723
+ triggered = false;
724
+ assign(element.style, animation.steps[0].styles);
725
+ }
726
+ }
727
+ const onScroll = throttle(immediateOnScroll, 200, {
728
+ leading: false
729
+ });
730
+ function isScrolledIntoView(elem) {
731
+ const rect = elem.getBoundingClientRect();
732
+ const windowHeight = window.innerHeight;
733
+ const thresholdPercent = (animation.thresholdPercent || 0) / 100;
734
+ const threshold = thresholdPercent * windowHeight;
735
+ return rect.bottom > threshold && rect.top < windowHeight - threshold;
736
+ }
737
+ const defaultState = animation.steps[0].styles;
738
+ function attachDefaultState() {
739
+ assign(element.style, defaultState);
740
+ }
741
+ attachDefaultState();
742
+ setTimeout(() => {
743
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
744
+ if (animation.delay) {
745
+ element.style.transitionDelay = animation.delay + "s";
746
+ }
747
+ });
748
+ document.addEventListener("scroll", onScroll, {
749
+ capture: true,
750
+ passive: true
751
+ });
752
+ immediateOnScroll();
753
+ });
754
+ }
755
+
550
756
  // src/components/block/block.helpers.ts
551
757
  var getComponent = ({
552
758
  block,
@@ -1122,6 +1328,16 @@ function Block(props) {
1122
1328
  isInteractive: !blockComponent()?.isRSC
1123
1329
  };
1124
1330
  }
1331
+ onMount(() => {
1332
+ const blockId = processedBlock().id;
1333
+ const animations = processedBlock().animations;
1334
+ if (animations && blockId) {
1335
+ bindAnimations(animations.filter((item) => item.trigger !== "hover").map((animation) => ({
1336
+ ...animation,
1337
+ elementId: blockId
1338
+ })));
1339
+ }
1340
+ });
1125
1341
  return createComponent(Show, {
1126
1342
  get when() {
1127
1343
  return canShowBlock();
@@ -3276,13 +3492,6 @@ async function fetchEntries(options) {
3276
3492
  }
3277
3493
  var getAllContent = fetchEntries;
3278
3494
 
3279
- // src/functions/is-from-trusted-host.ts
3280
- var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
3281
- function isFromTrustedHost(trustedHosts, e) {
3282
- const url = new URL(e.origin), hostname = url.hostname;
3283
- return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
3284
- }
3285
-
3286
3495
  // src/functions/is-previewing.ts
3287
3496
  function isPreviewing() {
3288
3497
  if (!isBrowser()) {
@@ -3533,8 +3742,15 @@ var getInteractionPropertiesForEvent = (event) => {
3533
3742
  };
3534
3743
  };
3535
3744
 
3745
+ // src/functions/is-from-trusted-host.ts
3746
+ var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
3747
+ function isFromTrustedHost(trustedHosts, e) {
3748
+ const url = new URL(e.origin), hostname = url.hostname;
3749
+ return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
3750
+ }
3751
+
3536
3752
  // src/constants/sdk-version.ts
3537
- var SDK_VERSION = "0.12.6";
3753
+ var SDK_VERSION = "0.12.8";
3538
3754
 
3539
3755
  // src/functions/register.ts
3540
3756
  var registry = {};
@@ -3671,6 +3887,66 @@ var setupBrowserForEditing = (options = {}) => {
3671
3887
  }
3672
3888
  };
3673
3889
 
3890
+ // src/helpers/subscribe-to-editor.ts
3891
+ var createEditorListener = ({
3892
+ model,
3893
+ trustedHosts,
3894
+ callbacks
3895
+ }) => {
3896
+ return (event) => {
3897
+ if (!isFromTrustedHost(trustedHosts, event)) {
3898
+ return;
3899
+ }
3900
+ const {
3901
+ data
3902
+ } = event;
3903
+ if (data) {
3904
+ switch (data.type) {
3905
+ case "builder.configureSdk": {
3906
+ callbacks.configureSdk(data.data);
3907
+ break;
3908
+ }
3909
+ case "builder.triggerAnimation": {
3910
+ callbacks.animation(data.data);
3911
+ break;
3912
+ }
3913
+ case "builder.contentUpdate": {
3914
+ const messageContent = data.data;
3915
+ const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3916
+ const contentData = messageContent.data;
3917
+ if (key === model) {
3918
+ callbacks.contentUpdate(contentData);
3919
+ }
3920
+ break;
3921
+ }
3922
+ }
3923
+ }
3924
+ };
3925
+ };
3926
+ var subscribeToEditor = (model, callback, options) => {
3927
+ if (!isBrowser) {
3928
+ logger.warn("`subscribeToEditor` only works in the browser. It currently seems to be running on the server.");
3929
+ return () => {
3930
+ };
3931
+ }
3932
+ setupBrowserForEditing();
3933
+ const listener = createEditorListener({
3934
+ callbacks: {
3935
+ contentUpdate: callback,
3936
+ animation: () => {
3937
+ },
3938
+ configureSdk: () => {
3939
+ }
3940
+ },
3941
+ model,
3942
+ trustedHosts: options?.trustedHosts
3943
+ });
3944
+ window.addEventListener("message", listener);
3945
+ return () => {
3946
+ window.removeEventListener("message", listener);
3947
+ };
3948
+ };
3949
+
3674
3950
  // src/components/content/components/enable-editor.tsx
3675
3951
  function EnableEditor(props) {
3676
3952
  const [forceReRenderCount, setForceReRenderCount] = createSignal(0);
@@ -3714,16 +3990,11 @@ function EnableEditor(props) {
3714
3990
  }));
3715
3991
  }
3716
3992
  function processMessage(event) {
3717
- if (!isFromTrustedHost(props.trustedHosts, event)) {
3718
- return;
3719
- }
3720
- const {
3721
- data
3722
- } = event;
3723
- if (data) {
3724
- switch (data.type) {
3725
- case "builder.configureSdk": {
3726
- const messageContent = data.data;
3993
+ return createEditorListener({
3994
+ model: props.model,
3995
+ trustedHosts: props.trustedHosts,
3996
+ callbacks: {
3997
+ configureSdk: (messageContent) => {
3727
3998
  const {
3728
3999
  breakpoints,
3729
4000
  contentId
@@ -3737,22 +4008,18 @@ function EnableEditor(props) {
3737
4008
  breakpoints
3738
4009
  }
3739
4010
  });
3740
- }
3741
- setForceReRenderCount(forceReRenderCount() + 1);
3742
- break;
3743
- }
3744
- case "builder.contentUpdate": {
3745
- const messageContent = data.data;
3746
- const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3747
- const contentData = messageContent.data;
3748
- if (key === props.model) {
3749
- mergeNewContent(contentData);
3750
4011
  setForceReRenderCount(forceReRenderCount() + 1);
3751
4012
  }
3752
- break;
4013
+ },
4014
+ animation: (animation) => {
4015
+ triggerAnimation(animation);
4016
+ },
4017
+ contentUpdate: (newContent) => {
4018
+ mergeNewContent(newContent);
4019
+ setForceReRenderCount(forceReRenderCount() + 1);
3753
4020
  }
3754
4021
  }
3755
- }
4022
+ })(event);
3756
4023
  }
3757
4024
  function evaluateJsCode() {
3758
4025
  const jsCode = props.builderContextSignal.content?.data?.jsCode;
@@ -4596,4 +4863,4 @@ var fetchBuilderProps = async (_args) => {
4596
4863
  };
4597
4864
  };
4598
4865
 
4599
- export { blocks_default as Blocks, button_default as Button, columns_default as Columns, content_variants_default as Content, fragment_default as Fragment, image_default as Image, RenderBlocks, RenderContent, section_default as Section, symbol_default as Symbol, text_default as Text, video_default as Video, _processContentResult, createRegisterComponentMessage, fetchBuilderProps, fetchEntries, fetchOneEntry, getAllContent, getBuilderSearchParams, getContent, isEditing, isPreviewing, register, setEditorSettings, track };
4866
+ export { blocks_default as Blocks, button_default as Button, columns_default as Columns, content_variants_default as Content, fragment_default as Fragment, image_default as Image, RenderBlocks, RenderContent, section_default as Section, symbol_default as Symbol, text_default as Text, video_default as Video, _processContentResult, createRegisterComponentMessage, fetchBuilderProps, fetchEntries, fetchOneEntry, getAllContent, getBuilderSearchParams, getContent, isEditing, isPreviewing, register, setEditorSettings, subscribeToEditor, track };