@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) {
@@ -408,6 +408,211 @@ function getProcessedBlock({
408
408
  }
409
409
  }
410
410
 
411
+ // src/components/block/animator.ts
412
+ function throttle(func, wait, options = {}) {
413
+ let context;
414
+ let args;
415
+ let result;
416
+ let timeout = null;
417
+ let previous = 0;
418
+ const later = function() {
419
+ previous = options.leading === false ? 0 : Date.now();
420
+ timeout = null;
421
+ result = func.apply(context, args);
422
+ if (!timeout)
423
+ context = args = null;
424
+ };
425
+ return function() {
426
+ const now = Date.now();
427
+ if (!previous && options.leading === false)
428
+ previous = now;
429
+ const remaining = wait - (now - previous);
430
+ context = this;
431
+ args = arguments;
432
+ if (remaining <= 0 || remaining > wait) {
433
+ if (timeout) {
434
+ clearTimeout(timeout);
435
+ timeout = null;
436
+ }
437
+ previous = now;
438
+ result = func.apply(context, args);
439
+ if (!timeout)
440
+ context = args = null;
441
+ } else if (!timeout && options.trailing !== false) {
442
+ timeout = setTimeout(later, remaining);
443
+ }
444
+ return result;
445
+ };
446
+ }
447
+ function assign(target, ..._args) {
448
+ const to = Object(target);
449
+ for (let index = 1; index < arguments.length; index++) {
450
+ const nextSource = arguments[index];
451
+ if (nextSource != null) {
452
+ for (const nextKey in nextSource) {
453
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
454
+ to[nextKey] = nextSource[nextKey];
455
+ }
456
+ }
457
+ }
458
+ }
459
+ return to;
460
+ }
461
+ var camelCaseToKebabCase = (str) => str ? str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`) : "";
462
+ function bindAnimations(animations) {
463
+ for (const animation of animations) {
464
+ switch (animation.trigger) {
465
+ case "pageLoad":
466
+ triggerAnimation(animation);
467
+ break;
468
+ case "hover":
469
+ bindHoverAnimation(animation);
470
+ break;
471
+ case "scrollInView":
472
+ bindScrollInViewAnimation(animation);
473
+ break;
474
+ }
475
+ }
476
+ }
477
+ function warnElementNotPresent(id) {
478
+ }
479
+ function augmentAnimation(animation, element) {
480
+ const stylesUsed = getAllStylesUsed(animation);
481
+ const computedStyle = getComputedStyle(element);
482
+ const firstStyles = animation.steps[0].styles;
483
+ const lastStyles = animation.steps[animation.steps.length - 1].styles;
484
+ const bothStyles = [firstStyles, lastStyles];
485
+ for (const styles of bothStyles) {
486
+ for (const style of stylesUsed) {
487
+ if (!(style in styles)) {
488
+ styles[style] = computedStyle[style];
489
+ }
490
+ }
491
+ }
492
+ }
493
+ function getAllStylesUsed(animation) {
494
+ const properties = [];
495
+ for (const step of animation.steps) {
496
+ for (const key in step.styles) {
497
+ if (properties.indexOf(key) === -1) {
498
+ properties.push(key);
499
+ }
500
+ }
501
+ }
502
+ return properties;
503
+ }
504
+ function triggerAnimation(animation) {
505
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
506
+ if (!elements.length) {
507
+ warnElementNotPresent(animation.elementId || animation.id || "");
508
+ return;
509
+ }
510
+ Array.from(elements).forEach((element) => {
511
+ augmentAnimation(animation, element);
512
+ element.style.transition = "none";
513
+ element.style.transitionDelay = "0";
514
+ assign(element.style, animation.steps[0].styles);
515
+ setTimeout(() => {
516
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
517
+ if (animation.delay) {
518
+ element.style.transitionDelay = animation.delay + "s";
519
+ }
520
+ assign(element.style, animation.steps[1].styles);
521
+ setTimeout(() => {
522
+ element.style.transition = "";
523
+ element.style.transitionDelay = "";
524
+ }, (animation.delay || 0) * 1e3 + animation.duration * 1e3 + 100);
525
+ });
526
+ });
527
+ }
528
+ function bindHoverAnimation(animation) {
529
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
530
+ if (!elements.length) {
531
+ warnElementNotPresent(animation.elementId || animation.id || "");
532
+ return;
533
+ }
534
+ Array.from(elements).forEach((element) => {
535
+ augmentAnimation(animation, element);
536
+ const defaultState = animation.steps[0].styles;
537
+ const hoverState = animation.steps[1].styles;
538
+ function attachDefaultState() {
539
+ assign(element.style, defaultState);
540
+ }
541
+ function attachHoverState() {
542
+ assign(element.style, hoverState);
543
+ }
544
+ attachDefaultState();
545
+ element.addEventListener("mouseenter", attachHoverState);
546
+ element.addEventListener("mouseleave", attachDefaultState);
547
+ setTimeout(() => {
548
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
549
+ if (animation.delay) {
550
+ element.style.transitionDelay = animation.delay + "s";
551
+ }
552
+ });
553
+ });
554
+ }
555
+ function bindScrollInViewAnimation(animation) {
556
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
557
+ if (!elements.length) {
558
+ warnElementNotPresent(animation.elementId || animation.id || "");
559
+ return;
560
+ }
561
+ Array.from(elements).forEach((element) => {
562
+ augmentAnimation(animation, element);
563
+ let triggered = false;
564
+ let pendingAnimation = false;
565
+ function immediateOnScroll() {
566
+ if (!triggered && isScrolledIntoView(element)) {
567
+ triggered = true;
568
+ pendingAnimation = true;
569
+ setTimeout(() => {
570
+ assign(element.style, animation.steps[1].styles);
571
+ if (!animation.repeat) {
572
+ document.removeEventListener("scroll", onScroll);
573
+ }
574
+ setTimeout(() => {
575
+ pendingAnimation = false;
576
+ if (!animation.repeat) {
577
+ element.style.transition = "";
578
+ element.style.transitionDelay = "";
579
+ }
580
+ }, (animation.duration + (animation.delay || 0)) * 1e3 + 100);
581
+ });
582
+ } else if (animation.repeat && triggered && !pendingAnimation && !isScrolledIntoView(element)) {
583
+ triggered = false;
584
+ assign(element.style, animation.steps[0].styles);
585
+ }
586
+ }
587
+ const onScroll = throttle(immediateOnScroll, 200, {
588
+ leading: false
589
+ });
590
+ function isScrolledIntoView(elem) {
591
+ const rect = elem.getBoundingClientRect();
592
+ const windowHeight = window.innerHeight;
593
+ const thresholdPercent = (animation.thresholdPercent || 0) / 100;
594
+ const threshold = thresholdPercent * windowHeight;
595
+ return rect.bottom > threshold && rect.top < windowHeight - threshold;
596
+ }
597
+ const defaultState = animation.steps[0].styles;
598
+ function attachDefaultState() {
599
+ assign(element.style, defaultState);
600
+ }
601
+ attachDefaultState();
602
+ setTimeout(() => {
603
+ element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
604
+ if (animation.delay) {
605
+ element.style.transitionDelay = animation.delay + "s";
606
+ }
607
+ });
608
+ document.addEventListener("scroll", onScroll, {
609
+ capture: true,
610
+ passive: true
611
+ });
612
+ immediateOnScroll();
613
+ });
614
+ }
615
+
411
616
  // src/components/block/block.helpers.ts
412
617
  var getComponent = ({
413
618
  block,
@@ -927,6 +1132,18 @@ function Block(props) {
927
1132
  isInteractive: !blockComponent()?.isRSC
928
1133
  };
929
1134
  }
1135
+ onMount(() => {
1136
+ const blockId = processedBlock().id;
1137
+ const animations = processedBlock().animations;
1138
+ if (animations && blockId) {
1139
+ bindAnimations(
1140
+ animations.filter((item) => item.trigger !== "hover").map((animation) => ({
1141
+ ...animation,
1142
+ elementId: blockId
1143
+ }))
1144
+ );
1145
+ }
1146
+ });
930
1147
  return <Show4 when={canShowBlock()}>
931
1148
  <Block_styles_default block={props.block} context={props.context} />
932
1149
  <Show4
@@ -1374,10 +1591,10 @@ function SectionComponent(props) {
1374
1591
  var section_default = SectionComponent;
1375
1592
 
1376
1593
  // src/blocks/symbol/symbol.tsx
1377
- import { onMount as onMount4, on as on3, createEffect as createEffect3, createSignal as createSignal14 } from "solid-js";
1594
+ import { onMount as onMount5, on as on3, createEffect as createEffect3, createSignal as createSignal14 } from "solid-js";
1378
1595
 
1379
1596
  // src/components/content-variants/content-variants.tsx
1380
- import { Show as Show11, For as For5, onMount as onMount3, createSignal as createSignal13 } from "solid-js";
1597
+ import { Show as Show11, For as For5, onMount as onMount4, createSignal as createSignal13 } from "solid-js";
1381
1598
 
1382
1599
  // src/helpers/url.ts
1383
1600
  var getTopLevelDomain = (host) => {
@@ -1855,12 +2072,12 @@ var componentInfo3 = {
1855
2072
  };
1856
2073
 
1857
2074
  // src/blocks/custom-code/custom-code.tsx
1858
- import { onMount, createSignal as createSignal7 } from "solid-js";
2075
+ import { onMount as onMount2, createSignal as createSignal7 } from "solid-js";
1859
2076
  function CustomCode(props) {
1860
2077
  const [scriptsInserted, setScriptsInserted] = createSignal7([]);
1861
2078
  const [scriptsRun, setScriptsRun] = createSignal7([]);
1862
2079
  let elementRef;
1863
- onMount(() => {
2080
+ onMount2(() => {
1864
2081
  if (!elementRef?.getElementsByTagName || typeof window === "undefined") {
1865
2082
  return;
1866
2083
  }
@@ -2578,7 +2795,7 @@ function InlinedScript(props) {
2578
2795
  var Inlined_script_default = InlinedScript;
2579
2796
 
2580
2797
  // src/components/content/components/enable-editor.tsx
2581
- import { Show as Show9, onMount as onMount2, on as on2, createEffect as createEffect2, createSignal as createSignal10 } from "solid-js";
2798
+ import { Show as Show9, onMount as onMount3, on as on2, createEffect as createEffect2, createSignal as createSignal10 } from "solid-js";
2582
2799
  import { Dynamic as Dynamic5 } from "solid-js/web";
2583
2800
 
2584
2801
  // src/helpers/preview-lru-cache/get.ts
@@ -2813,13 +3030,6 @@ async function fetchEntries(options) {
2813
3030
  }
2814
3031
  var getAllContent = fetchEntries;
2815
3032
 
2816
- // src/functions/is-from-trusted-host.ts
2817
- var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
2818
- function isFromTrustedHost(trustedHosts, e) {
2819
- const url = new URL(e.origin), hostname = url.hostname;
2820
- return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
2821
- }
2822
-
2823
3033
  // src/functions/is-previewing.ts
2824
3034
  function isPreviewing() {
2825
3035
  if (!isBrowser()) {
@@ -3067,8 +3277,15 @@ var getInteractionPropertiesForEvent = (event) => {
3067
3277
  };
3068
3278
  };
3069
3279
 
3280
+ // src/functions/is-from-trusted-host.ts
3281
+ var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
3282
+ function isFromTrustedHost(trustedHosts, e) {
3283
+ const url = new URL(e.origin), hostname = url.hostname;
3284
+ return (trustedHosts || DEFAULT_TRUSTED_HOSTS).findIndex((trustedHost) => trustedHost.startsWith("*.") ? hostname.endsWith(trustedHost.slice(1)) : trustedHost === hostname) > -1;
3285
+ }
3286
+
3070
3287
  // src/constants/sdk-version.ts
3071
- var SDK_VERSION = "0.12.6";
3288
+ var SDK_VERSION = "0.12.8";
3072
3289
 
3073
3290
  // src/functions/register.ts
3074
3291
  var registry = {};
@@ -3204,6 +3421,66 @@ var setupBrowserForEditing = (options = {}) => {
3204
3421
  }
3205
3422
  };
3206
3423
 
3424
+ // src/helpers/subscribe-to-editor.ts
3425
+ var createEditorListener = ({
3426
+ model,
3427
+ trustedHosts,
3428
+ callbacks
3429
+ }) => {
3430
+ return (event) => {
3431
+ if (!isFromTrustedHost(trustedHosts, event)) {
3432
+ return;
3433
+ }
3434
+ const {
3435
+ data
3436
+ } = event;
3437
+ if (data) {
3438
+ switch (data.type) {
3439
+ case "builder.configureSdk": {
3440
+ callbacks.configureSdk(data.data);
3441
+ break;
3442
+ }
3443
+ case "builder.triggerAnimation": {
3444
+ callbacks.animation(data.data);
3445
+ break;
3446
+ }
3447
+ case "builder.contentUpdate": {
3448
+ const messageContent = data.data;
3449
+ const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3450
+ const contentData = messageContent.data;
3451
+ if (key === model) {
3452
+ callbacks.contentUpdate(contentData);
3453
+ }
3454
+ break;
3455
+ }
3456
+ }
3457
+ }
3458
+ };
3459
+ };
3460
+ var subscribeToEditor = (model, callback, options) => {
3461
+ if (!isBrowser) {
3462
+ logger.warn("`subscribeToEditor` only works in the browser. It currently seems to be running on the server.");
3463
+ return () => {
3464
+ };
3465
+ }
3466
+ setupBrowserForEditing();
3467
+ const listener = createEditorListener({
3468
+ callbacks: {
3469
+ contentUpdate: callback,
3470
+ animation: () => {
3471
+ },
3472
+ configureSdk: () => {
3473
+ }
3474
+ },
3475
+ model,
3476
+ trustedHosts: options?.trustedHosts
3477
+ });
3478
+ window.addEventListener("message", listener);
3479
+ return () => {
3480
+ window.removeEventListener("message", listener);
3481
+ };
3482
+ };
3483
+
3207
3484
  // src/components/content/components/enable-editor.tsx
3208
3485
  function EnableEditor(props) {
3209
3486
  const [forceReRenderCount, setForceReRenderCount] = createSignal10(0);
@@ -3249,14 +3526,11 @@ function EnableEditor(props) {
3249
3526
  }));
3250
3527
  }
3251
3528
  function processMessage(event) {
3252
- if (!isFromTrustedHost(props.trustedHosts, event)) {
3253
- return;
3254
- }
3255
- const { data } = event;
3256
- if (data) {
3257
- switch (data.type) {
3258
- case "builder.configureSdk": {
3259
- const messageContent = data.data;
3529
+ return createEditorListener({
3530
+ model: props.model,
3531
+ trustedHosts: props.trustedHosts,
3532
+ callbacks: {
3533
+ configureSdk: (messageContent) => {
3260
3534
  const { breakpoints, contentId } = messageContent;
3261
3535
  if (!contentId || contentId !== props.builderContextSignal.content?.id) {
3262
3536
  return;
@@ -3267,22 +3541,18 @@ function EnableEditor(props) {
3267
3541
  breakpoints
3268
3542
  }
3269
3543
  });
3270
- }
3271
- setForceReRenderCount(forceReRenderCount() + 1);
3272
- break;
3273
- }
3274
- case "builder.contentUpdate": {
3275
- const messageContent = data.data;
3276
- const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
3277
- const contentData = messageContent.data;
3278
- if (key === props.model) {
3279
- mergeNewContent(contentData);
3280
3544
  setForceReRenderCount(forceReRenderCount() + 1);
3281
3545
  }
3282
- break;
3546
+ },
3547
+ animation: (animation) => {
3548
+ triggerAnimation(animation);
3549
+ },
3550
+ contentUpdate: (newContent) => {
3551
+ mergeNewContent(newContent);
3552
+ setForceReRenderCount(forceReRenderCount() + 1);
3283
3553
  }
3284
3554
  }
3285
- }
3555
+ })(event);
3286
3556
  }
3287
3557
  function evaluateJsCode() {
3288
3558
  const jsCode = props.builderContextSignal.content?.data?.jsCode;
@@ -3367,7 +3637,7 @@ function EnableEditor(props) {
3367
3637
  }
3368
3638
  }
3369
3639
  let elementRef;
3370
- onMount2(() => {
3640
+ onMount3(() => {
3371
3641
  if (isBrowser()) {
3372
3642
  if (isEditing() && true) {
3373
3643
  setForceReRenderCount(forceReRenderCount() + 1);
@@ -3432,7 +3702,7 @@ function EnableEditor(props) {
3432
3702
  }
3433
3703
  }
3434
3704
  });
3435
- onMount2(() => {
3705
+ onMount3(() => {
3436
3706
  if (!props.apiKey) {
3437
3707
  logger.error(
3438
3708
  "No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop."
@@ -3772,7 +4042,7 @@ function ContentVariants(props) {
3772
4042
  canTrack: getDefaultCanTrack(props.canTrack)
3773
4043
  });
3774
4044
  }
3775
- onMount3(() => {
4045
+ onMount4(() => {
3776
4046
  setShouldRenderVariants(false);
3777
4047
  });
3778
4048
  return <>
@@ -3884,7 +4154,7 @@ function Symbol(props) {
3884
4154
  }
3885
4155
  });
3886
4156
  }
3887
- onMount4(() => {
4157
+ onMount5(() => {
3888
4158
  setContent();
3889
4159
  });
3890
4160
  function onUpdateFn_0() {
@@ -3975,5 +4245,6 @@ export {
3975
4245
  isPreviewing,
3976
4246
  register,
3977
4247
  setEditorSettings,
4248
+ subscribeToEditor,
3978
4249
  track
3979
4250
  };