@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/index.js CHANGED
@@ -544,6 +544,211 @@ function getProcessedBlock({
544
544
  }
545
545
  }
546
546
 
547
+ // src/components/block/animator.ts
548
+ function throttle(func, wait, options = {}) {
549
+ let context;
550
+ let args;
551
+ let result;
552
+ let timeout = null;
553
+ let previous = 0;
554
+ const later = function() {
555
+ previous = options.leading === false ? 0 : Date.now();
556
+ timeout = null;
557
+ result = func.apply(context, args);
558
+ if (!timeout)
559
+ context = args = null;
560
+ };
561
+ return function() {
562
+ const now = Date.now();
563
+ if (!previous && options.leading === false)
564
+ previous = now;
565
+ const remaining = wait - (now - previous);
566
+ context = this;
567
+ args = arguments;
568
+ if (remaining <= 0 || remaining > wait) {
569
+ if (timeout) {
570
+ clearTimeout(timeout);
571
+ timeout = null;
572
+ }
573
+ previous = now;
574
+ result = func.apply(context, args);
575
+ if (!timeout)
576
+ context = args = null;
577
+ } else if (!timeout && options.trailing !== false) {
578
+ timeout = setTimeout(later, remaining);
579
+ }
580
+ return result;
581
+ };
582
+ }
583
+ function assign(target, ..._args) {
584
+ const to = Object(target);
585
+ for (let index = 1; index < arguments.length; index++) {
586
+ const nextSource = arguments[index];
587
+ if (nextSource != null) {
588
+ for (const nextKey in nextSource) {
589
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
590
+ to[nextKey] = nextSource[nextKey];
591
+ }
592
+ }
593
+ }
594
+ }
595
+ return to;
596
+ }
597
+ var camelCaseToKebabCase = (str) => str ? str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`) : "";
598
+ function bindAnimations(animations) {
599
+ for (const animation of animations) {
600
+ switch (animation.trigger) {
601
+ case "pageLoad":
602
+ triggerAnimation(animation);
603
+ break;
604
+ case "hover":
605
+ bindHoverAnimation(animation);
606
+ break;
607
+ case "scrollInView":
608
+ bindScrollInViewAnimation(animation);
609
+ break;
610
+ }
611
+ }
612
+ }
613
+ function warnElementNotPresent(id) {
614
+ }
615
+ function augmentAnimation(animation, element) {
616
+ const stylesUsed = getAllStylesUsed(animation);
617
+ const computedStyle = getComputedStyle(element);
618
+ const firstStyles = animation.steps[0].styles;
619
+ const lastStyles = animation.steps[animation.steps.length - 1].styles;
620
+ const bothStyles = [firstStyles, lastStyles];
621
+ for (const styles of bothStyles) {
622
+ for (const style of stylesUsed) {
623
+ if (!(style in styles)) {
624
+ styles[style] = computedStyle[style];
625
+ }
626
+ }
627
+ }
628
+ }
629
+ function getAllStylesUsed(animation) {
630
+ const properties = [];
631
+ for (const step of animation.steps) {
632
+ for (const key in step.styles) {
633
+ if (properties.indexOf(key) === -1) {
634
+ properties.push(key);
635
+ }
636
+ }
637
+ }
638
+ return properties;
639
+ }
640
+ function triggerAnimation(animation) {
641
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
642
+ if (!elements.length) {
643
+ warnElementNotPresent(animation.elementId || animation.id || "");
644
+ return;
645
+ }
646
+ Array.from(elements).forEach((element) => {
647
+ augmentAnimation(animation, element);
648
+ element.style.transition = "none";
649
+ element.style.transitionDelay = "0";
650
+ assign(element.style, animation.steps[0].styles);
651
+ setTimeout(() => {
652
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
653
+ if (animation.delay) {
654
+ element.style.transitionDelay = animation.delay + "s";
655
+ }
656
+ assign(element.style, animation.steps[1].styles);
657
+ setTimeout(() => {
658
+ element.style.transition = "";
659
+ element.style.transitionDelay = "";
660
+ }, (animation.delay || 0) * 1e3 + animation.duration * 1e3 + 100);
661
+ });
662
+ });
663
+ }
664
+ function bindHoverAnimation(animation) {
665
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
666
+ if (!elements.length) {
667
+ warnElementNotPresent(animation.elementId || animation.id || "");
668
+ return;
669
+ }
670
+ Array.from(elements).forEach((element) => {
671
+ augmentAnimation(animation, element);
672
+ const defaultState = animation.steps[0].styles;
673
+ const hoverState = animation.steps[1].styles;
674
+ function attachDefaultState() {
675
+ assign(element.style, defaultState);
676
+ }
677
+ function attachHoverState() {
678
+ assign(element.style, hoverState);
679
+ }
680
+ attachDefaultState();
681
+ element.addEventListener("mouseenter", attachHoverState);
682
+ element.addEventListener("mouseleave", attachDefaultState);
683
+ setTimeout(() => {
684
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
685
+ if (animation.delay) {
686
+ element.style.transitionDelay = animation.delay + "s";
687
+ }
688
+ });
689
+ });
690
+ }
691
+ function bindScrollInViewAnimation(animation) {
692
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
693
+ if (!elements.length) {
694
+ warnElementNotPresent(animation.elementId || animation.id || "");
695
+ return;
696
+ }
697
+ Array.from(elements).forEach((element) => {
698
+ augmentAnimation(animation, element);
699
+ let triggered = false;
700
+ let pendingAnimation = false;
701
+ function immediateOnScroll() {
702
+ if (!triggered && isScrolledIntoView(element)) {
703
+ triggered = true;
704
+ pendingAnimation = true;
705
+ setTimeout(() => {
706
+ assign(element.style, animation.steps[1].styles);
707
+ if (!animation.repeat) {
708
+ document.removeEventListener("scroll", onScroll);
709
+ }
710
+ setTimeout(() => {
711
+ pendingAnimation = false;
712
+ if (!animation.repeat) {
713
+ element.style.transition = "";
714
+ element.style.transitionDelay = "";
715
+ }
716
+ }, (animation.duration + (animation.delay || 0)) * 1e3 + 100);
717
+ });
718
+ } else if (animation.repeat && triggered && !pendingAnimation && !isScrolledIntoView(element)) {
719
+ triggered = false;
720
+ assign(element.style, animation.steps[0].styles);
721
+ }
722
+ }
723
+ const onScroll = throttle(immediateOnScroll, 200, {
724
+ leading: false
725
+ });
726
+ function isScrolledIntoView(elem) {
727
+ const rect = elem.getBoundingClientRect();
728
+ const windowHeight = window.innerHeight;
729
+ const thresholdPercent = (animation.thresholdPercent || 0) / 100;
730
+ const threshold = thresholdPercent * windowHeight;
731
+ return rect.bottom > threshold && rect.top < windowHeight - threshold;
732
+ }
733
+ const defaultState = animation.steps[0].styles;
734
+ function attachDefaultState() {
735
+ assign(element.style, defaultState);
736
+ }
737
+ attachDefaultState();
738
+ setTimeout(() => {
739
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
740
+ if (animation.delay) {
741
+ element.style.transitionDelay = animation.delay + "s";
742
+ }
743
+ });
744
+ document.addEventListener("scroll", onScroll, {
745
+ capture: true,
746
+ passive: true
747
+ });
748
+ immediateOnScroll();
749
+ });
750
+ }
751
+
547
752
  // src/components/block/block.helpers.ts
548
753
  var getComponent = ({
549
754
  block,
@@ -1116,6 +1321,16 @@ function Block(props) {
1116
1321
  isInteractive: !blockComponent()?.isRSC
1117
1322
  };
1118
1323
  }
1324
+ onMount(() => {
1325
+ const blockId = processedBlock().id;
1326
+ const animations = processedBlock().animations;
1327
+ if (animations && blockId) {
1328
+ bindAnimations(animations.filter((item) => item.trigger !== "hover").map((animation) => ({
1329
+ ...animation,
1330
+ elementId: blockId
1331
+ })));
1332
+ }
1333
+ });
1119
1334
  return createComponent(Show, {
1120
1335
  get when() {
1121
1336
  return canShowBlock();
@@ -3264,13 +3479,6 @@ async function fetchEntries(options) {
3264
3479
  }
3265
3480
  var getAllContent = fetchEntries;
3266
3481
 
3267
- // src/functions/is-from-trusted-host.ts
3268
- var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
3269
- function isFromTrustedHost(trustedHosts, e) {
3270
- const url = new URL(e.origin), hostname = url.hostname;
3271
- return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
3272
- }
3273
-
3274
3482
  // src/functions/is-previewing.ts
3275
3483
  function isPreviewing() {
3276
3484
  if (!isBrowser()) {
@@ -3518,8 +3726,15 @@ var getInteractionPropertiesForEvent = (event) => {
3518
3726
  };
3519
3727
  };
3520
3728
 
3729
+ // src/functions/is-from-trusted-host.ts
3730
+ var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
3731
+ function isFromTrustedHost(trustedHosts, e) {
3732
+ const url = new URL(e.origin), hostname = url.hostname;
3733
+ return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
3734
+ }
3735
+
3521
3736
  // src/constants/sdk-version.ts
3522
- var SDK_VERSION = "0.12.6";
3737
+ var SDK_VERSION = "0.12.8";
3523
3738
 
3524
3739
  // src/functions/register.ts
3525
3740
  var registry = {};
@@ -3655,6 +3870,66 @@ var setupBrowserForEditing = (options = {}) => {
3655
3870
  }
3656
3871
  };
3657
3872
 
3873
+ // src/helpers/subscribe-to-editor.ts
3874
+ var createEditorListener = ({
3875
+ model,
3876
+ trustedHosts,
3877
+ callbacks
3878
+ }) => {
3879
+ return (event) => {
3880
+ if (!isFromTrustedHost(trustedHosts, event)) {
3881
+ return;
3882
+ }
3883
+ const {
3884
+ data
3885
+ } = event;
3886
+ if (data) {
3887
+ switch (data.type) {
3888
+ case "builder.configureSdk": {
3889
+ callbacks.configureSdk(data.data);
3890
+ break;
3891
+ }
3892
+ case "builder.triggerAnimation": {
3893
+ callbacks.animation(data.data);
3894
+ break;
3895
+ }
3896
+ case "builder.contentUpdate": {
3897
+ const messageContent = data.data;
3898
+ const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3899
+ const contentData = messageContent.data;
3900
+ if (key === model) {
3901
+ callbacks.contentUpdate(contentData);
3902
+ }
3903
+ break;
3904
+ }
3905
+ }
3906
+ }
3907
+ };
3908
+ };
3909
+ var subscribeToEditor = (model, callback, options) => {
3910
+ if (!isBrowser) {
3911
+ logger.warn("`subscribeToEditor` only works in the browser. It currently seems to be running on the server.");
3912
+ return () => {
3913
+ };
3914
+ }
3915
+ setupBrowserForEditing();
3916
+ const listener = createEditorListener({
3917
+ callbacks: {
3918
+ contentUpdate: callback,
3919
+ animation: () => {
3920
+ },
3921
+ configureSdk: () => {
3922
+ }
3923
+ },
3924
+ model,
3925
+ trustedHosts: options?.trustedHosts
3926
+ });
3927
+ window.addEventListener("message", listener);
3928
+ return () => {
3929
+ window.removeEventListener("message", listener);
3930
+ };
3931
+ };
3932
+
3658
3933
  // src/components/content/components/enable-editor.tsx
3659
3934
  function EnableEditor(props) {
3660
3935
  const [forceReRenderCount, setForceReRenderCount] = createSignal(0);
@@ -3698,16 +3973,11 @@ function EnableEditor(props) {
3698
3973
  }));
3699
3974
  }
3700
3975
  function processMessage(event) {
3701
- if (!isFromTrustedHost(props.trustedHosts, event)) {
3702
- return;
3703
- }
3704
- const {
3705
- data
3706
- } = event;
3707
- if (data) {
3708
- switch (data.type) {
3709
- case "builder.configureSdk": {
3710
- const messageContent = data.data;
3976
+ return createEditorListener({
3977
+ model: props.model,
3978
+ trustedHosts: props.trustedHosts,
3979
+ callbacks: {
3980
+ configureSdk: (messageContent) => {
3711
3981
  const {
3712
3982
  breakpoints,
3713
3983
  contentId
@@ -3721,22 +3991,18 @@ function EnableEditor(props) {
3721
3991
  breakpoints
3722
3992
  }
3723
3993
  });
3724
- }
3725
- setForceReRenderCount(forceReRenderCount() + 1);
3726
- break;
3727
- }
3728
- case "builder.contentUpdate": {
3729
- const messageContent = data.data;
3730
- const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3731
- const contentData = messageContent.data;
3732
- if (key === props.model) {
3733
- mergeNewContent(contentData);
3734
3994
  setForceReRenderCount(forceReRenderCount() + 1);
3735
3995
  }
3736
- break;
3996
+ },
3997
+ animation: (animation) => {
3998
+ triggerAnimation(animation);
3999
+ },
4000
+ contentUpdate: (newContent) => {
4001
+ mergeNewContent(newContent);
4002
+ setForceReRenderCount(forceReRenderCount() + 1);
3737
4003
  }
3738
4004
  }
3739
- }
4005
+ })(event);
3740
4006
  }
3741
4007
  function evaluateJsCode() {
3742
4008
  const jsCode = props.builderContextSignal.content?.data?.jsCode;
@@ -4579,4 +4845,4 @@ var fetchBuilderProps = async (_args) => {
4579
4845
  };
4580
4846
  };
4581
4847
 
4582
- 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 };
4848
+ 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 };