@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.
@@ -421,6 +421,211 @@ function getProcessedBlock({
421
421
  }
422
422
  }
423
423
 
424
+ // src/components/block/animator.ts
425
+ function throttle(func, wait, options = {}) {
426
+ let context;
427
+ let args;
428
+ let result;
429
+ let timeout = null;
430
+ let previous = 0;
431
+ const later = function() {
432
+ previous = options.leading === false ? 0 : Date.now();
433
+ timeout = null;
434
+ result = func.apply(context, args);
435
+ if (!timeout)
436
+ context = args = null;
437
+ };
438
+ return function() {
439
+ const now = Date.now();
440
+ if (!previous && options.leading === false)
441
+ previous = now;
442
+ const remaining = wait - (now - previous);
443
+ context = this;
444
+ args = arguments;
445
+ if (remaining <= 0 || remaining > wait) {
446
+ if (timeout) {
447
+ clearTimeout(timeout);
448
+ timeout = null;
449
+ }
450
+ previous = now;
451
+ result = func.apply(context, args);
452
+ if (!timeout)
453
+ context = args = null;
454
+ } else if (!timeout && options.trailing !== false) {
455
+ timeout = setTimeout(later, remaining);
456
+ }
457
+ return result;
458
+ };
459
+ }
460
+ function assign(target, ..._args) {
461
+ const to = Object(target);
462
+ for (let index = 1; index < arguments.length; index++) {
463
+ const nextSource = arguments[index];
464
+ if (nextSource != null) {
465
+ for (const nextKey in nextSource) {
466
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
467
+ to[nextKey] = nextSource[nextKey];
468
+ }
469
+ }
470
+ }
471
+ }
472
+ return to;
473
+ }
474
+ var camelCaseToKebabCase = (str) => str ? str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`) : "";
475
+ function bindAnimations(animations) {
476
+ for (const animation of animations) {
477
+ switch (animation.trigger) {
478
+ case "pageLoad":
479
+ triggerAnimation(animation);
480
+ break;
481
+ case "hover":
482
+ bindHoverAnimation(animation);
483
+ break;
484
+ case "scrollInView":
485
+ bindScrollInViewAnimation(animation);
486
+ break;
487
+ }
488
+ }
489
+ }
490
+ function warnElementNotPresent(id) {
491
+ }
492
+ function augmentAnimation(animation, element) {
493
+ const stylesUsed = getAllStylesUsed(animation);
494
+ const computedStyle = getComputedStyle(element);
495
+ const firstStyles = animation.steps[0].styles;
496
+ const lastStyles = animation.steps[animation.steps.length - 1].styles;
497
+ const bothStyles = [firstStyles, lastStyles];
498
+ for (const styles of bothStyles) {
499
+ for (const style of stylesUsed) {
500
+ if (!(style in styles)) {
501
+ styles[style] = computedStyle[style];
502
+ }
503
+ }
504
+ }
505
+ }
506
+ function getAllStylesUsed(animation) {
507
+ const properties = [];
508
+ for (const step of animation.steps) {
509
+ for (const key in step.styles) {
510
+ if (properties.indexOf(key) === -1) {
511
+ properties.push(key);
512
+ }
513
+ }
514
+ }
515
+ return properties;
516
+ }
517
+ function triggerAnimation(animation) {
518
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
519
+ if (!elements.length) {
520
+ warnElementNotPresent(animation.elementId || animation.id || "");
521
+ return;
522
+ }
523
+ Array.from(elements).forEach((element) => {
524
+ augmentAnimation(animation, element);
525
+ element.style.transition = "none";
526
+ element.style.transitionDelay = "0";
527
+ assign(element.style, animation.steps[0].styles);
528
+ setTimeout(() => {
529
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
530
+ if (animation.delay) {
531
+ element.style.transitionDelay = animation.delay + "s";
532
+ }
533
+ assign(element.style, animation.steps[1].styles);
534
+ setTimeout(() => {
535
+ element.style.transition = "";
536
+ element.style.transitionDelay = "";
537
+ }, (animation.delay || 0) * 1e3 + animation.duration * 1e3 + 100);
538
+ });
539
+ });
540
+ }
541
+ function bindHoverAnimation(animation) {
542
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
543
+ if (!elements.length) {
544
+ warnElementNotPresent(animation.elementId || animation.id || "");
545
+ return;
546
+ }
547
+ Array.from(elements).forEach((element) => {
548
+ augmentAnimation(animation, element);
549
+ const defaultState = animation.steps[0].styles;
550
+ const hoverState = animation.steps[1].styles;
551
+ function attachDefaultState() {
552
+ assign(element.style, defaultState);
553
+ }
554
+ function attachHoverState() {
555
+ assign(element.style, hoverState);
556
+ }
557
+ attachDefaultState();
558
+ element.addEventListener("mouseenter", attachHoverState);
559
+ element.addEventListener("mouseleave", attachDefaultState);
560
+ setTimeout(() => {
561
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
562
+ if (animation.delay) {
563
+ element.style.transitionDelay = animation.delay + "s";
564
+ }
565
+ });
566
+ });
567
+ }
568
+ function bindScrollInViewAnimation(animation) {
569
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
570
+ if (!elements.length) {
571
+ warnElementNotPresent(animation.elementId || animation.id || "");
572
+ return;
573
+ }
574
+ Array.from(elements).forEach((element) => {
575
+ augmentAnimation(animation, element);
576
+ let triggered = false;
577
+ let pendingAnimation = false;
578
+ function immediateOnScroll() {
579
+ if (!triggered && isScrolledIntoView(element)) {
580
+ triggered = true;
581
+ pendingAnimation = true;
582
+ setTimeout(() => {
583
+ assign(element.style, animation.steps[1].styles);
584
+ if (!animation.repeat) {
585
+ document.removeEventListener("scroll", onScroll);
586
+ }
587
+ setTimeout(() => {
588
+ pendingAnimation = false;
589
+ if (!animation.repeat) {
590
+ element.style.transition = "";
591
+ element.style.transitionDelay = "";
592
+ }
593
+ }, (animation.duration + (animation.delay || 0)) * 1e3 + 100);
594
+ });
595
+ } else if (animation.repeat && triggered && !pendingAnimation && !isScrolledIntoView(element)) {
596
+ triggered = false;
597
+ assign(element.style, animation.steps[0].styles);
598
+ }
599
+ }
600
+ const onScroll = throttle(immediateOnScroll, 200, {
601
+ leading: false
602
+ });
603
+ function isScrolledIntoView(elem) {
604
+ const rect = elem.getBoundingClientRect();
605
+ const windowHeight = window.innerHeight;
606
+ const thresholdPercent = (animation.thresholdPercent || 0) / 100;
607
+ const threshold = thresholdPercent * windowHeight;
608
+ return rect.bottom > threshold && rect.top < windowHeight - threshold;
609
+ }
610
+ const defaultState = animation.steps[0].styles;
611
+ function attachDefaultState() {
612
+ assign(element.style, defaultState);
613
+ }
614
+ attachDefaultState();
615
+ setTimeout(() => {
616
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
617
+ if (animation.delay) {
618
+ element.style.transitionDelay = animation.delay + "s";
619
+ }
620
+ });
621
+ document.addEventListener("scroll", onScroll, {
622
+ capture: true,
623
+ passive: true
624
+ });
625
+ immediateOnScroll();
626
+ });
627
+ }
628
+
424
629
  // src/components/block/block.helpers.ts
425
630
  var getComponent = ({
426
631
  block,
@@ -993,6 +1198,16 @@ function Block(props) {
993
1198
  isInteractive: !blockComponent()?.isRSC
994
1199
  };
995
1200
  }
1201
+ onMount(() => {
1202
+ const blockId = processedBlock().id;
1203
+ const animations = processedBlock().animations;
1204
+ if (animations && blockId) {
1205
+ bindAnimations(animations.filter((item) => item.trigger !== "hover").map((animation) => ({
1206
+ ...animation,
1207
+ elementId: blockId
1208
+ })));
1209
+ }
1210
+ });
996
1211
  return createComponent(Show, {
997
1212
  get when() {
998
1213
  return canShowBlock();
@@ -3141,13 +3356,6 @@ async function fetchEntries(options) {
3141
3356
  }
3142
3357
  var getAllContent = fetchEntries;
3143
3358
 
3144
- // src/functions/is-from-trusted-host.ts
3145
- var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
3146
- function isFromTrustedHost(trustedHosts, e) {
3147
- const url = new URL(e.origin), hostname = url.hostname;
3148
- return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
3149
- }
3150
-
3151
3359
  // src/functions/is-previewing.ts
3152
3360
  function isPreviewing() {
3153
3361
  if (!isBrowser()) {
@@ -3395,8 +3603,15 @@ var getInteractionPropertiesForEvent = (event) => {
3395
3603
  };
3396
3604
  };
3397
3605
 
3606
+ // src/functions/is-from-trusted-host.ts
3607
+ var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
3608
+ function isFromTrustedHost(trustedHosts, e) {
3609
+ const url = new URL(e.origin), hostname = url.hostname;
3610
+ return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
3611
+ }
3612
+
3398
3613
  // src/constants/sdk-version.ts
3399
- var SDK_VERSION = "0.12.6";
3614
+ var SDK_VERSION = "0.12.8";
3400
3615
 
3401
3616
  // src/functions/register.ts
3402
3617
  var registry = {};
@@ -3532,6 +3747,66 @@ var setupBrowserForEditing = (options = {}) => {
3532
3747
  }
3533
3748
  };
3534
3749
 
3750
+ // src/helpers/subscribe-to-editor.ts
3751
+ var createEditorListener = ({
3752
+ model,
3753
+ trustedHosts,
3754
+ callbacks
3755
+ }) => {
3756
+ return (event) => {
3757
+ if (!isFromTrustedHost(trustedHosts, event)) {
3758
+ return;
3759
+ }
3760
+ const {
3761
+ data
3762
+ } = event;
3763
+ if (data) {
3764
+ switch (data.type) {
3765
+ case "builder.configureSdk": {
3766
+ callbacks.configureSdk(data.data);
3767
+ break;
3768
+ }
3769
+ case "builder.triggerAnimation": {
3770
+ callbacks.animation(data.data);
3771
+ break;
3772
+ }
3773
+ case "builder.contentUpdate": {
3774
+ const messageContent = data.data;
3775
+ const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3776
+ const contentData = messageContent.data;
3777
+ if (key === model) {
3778
+ callbacks.contentUpdate(contentData);
3779
+ }
3780
+ break;
3781
+ }
3782
+ }
3783
+ }
3784
+ };
3785
+ };
3786
+ var subscribeToEditor = (model, callback, options) => {
3787
+ if (!isBrowser) {
3788
+ logger.warn("`subscribeToEditor` only works in the browser. It currently seems to be running on the server.");
3789
+ return () => {
3790
+ };
3791
+ }
3792
+ setupBrowserForEditing();
3793
+ const listener = createEditorListener({
3794
+ callbacks: {
3795
+ contentUpdate: callback,
3796
+ animation: () => {
3797
+ },
3798
+ configureSdk: () => {
3799
+ }
3800
+ },
3801
+ model,
3802
+ trustedHosts: options?.trustedHosts
3803
+ });
3804
+ window.addEventListener("message", listener);
3805
+ return () => {
3806
+ window.removeEventListener("message", listener);
3807
+ };
3808
+ };
3809
+
3535
3810
  // src/components/content/components/enable-editor.tsx
3536
3811
  function EnableEditor(props) {
3537
3812
  const [forceReRenderCount, setForceReRenderCount] = createSignal(0);
@@ -3575,16 +3850,11 @@ function EnableEditor(props) {
3575
3850
  }));
3576
3851
  }
3577
3852
  function processMessage(event) {
3578
- if (!isFromTrustedHost(props.trustedHosts, event)) {
3579
- return;
3580
- }
3581
- const {
3582
- data
3583
- } = event;
3584
- if (data) {
3585
- switch (data.type) {
3586
- case "builder.configureSdk": {
3587
- const messageContent = data.data;
3853
+ return createEditorListener({
3854
+ model: props.model,
3855
+ trustedHosts: props.trustedHosts,
3856
+ callbacks: {
3857
+ configureSdk: (messageContent) => {
3588
3858
  const {
3589
3859
  breakpoints,
3590
3860
  contentId
@@ -3598,22 +3868,18 @@ function EnableEditor(props) {
3598
3868
  breakpoints
3599
3869
  }
3600
3870
  });
3601
- }
3602
- setForceReRenderCount(forceReRenderCount() + 1);
3603
- break;
3604
- }
3605
- case "builder.contentUpdate": {
3606
- const messageContent = data.data;
3607
- const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3608
- const contentData = messageContent.data;
3609
- if (key === props.model) {
3610
- mergeNewContent(contentData);
3611
3871
  setForceReRenderCount(forceReRenderCount() + 1);
3612
3872
  }
3613
- break;
3873
+ },
3874
+ animation: (animation) => {
3875
+ triggerAnimation(animation);
3876
+ },
3877
+ contentUpdate: (newContent) => {
3878
+ mergeNewContent(newContent);
3879
+ setForceReRenderCount(forceReRenderCount() + 1);
3614
3880
  }
3615
3881
  }
3616
- }
3882
+ })(event);
3617
3883
  }
3618
3884
  function evaluateJsCode() {
3619
3885
  const jsCode = props.builderContextSignal.content?.data?.jsCode;
@@ -4456,4 +4722,4 @@ var fetchBuilderProps = async (_args) => {
4456
4722
  };
4457
4723
  };
4458
4724
 
4459
- 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 };
4725
+ 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 };