cms-renderer 0.6.13 → 0.8.0

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.
@@ -104,12 +104,12 @@ function isArticlePublished(article) {
104
104
  var BLOCK_METADATA = {
105
105
  "hero-block": {
106
106
  name: "Hero",
107
- description: "Full-width hero section with headline, subheadline, and CTA",
107
+ description: "Full-width hero section with headline, description, and CTA",
108
108
  category: "Marketing",
109
109
  icon: "image",
110
110
  fields: [
111
111
  { name: "headline", label: "Headline", type: "Text" },
112
- { name: "subheadline", label: "Subheadline", type: "Text" },
112
+ { name: "subheadline", label: "Description", type: "Text" },
113
113
  { name: "ctaText", label: "CTA Label", type: "Text" },
114
114
  { name: "ctaUrl", label: "CTA URL", type: "URL" },
115
115
  { name: "backgroundImage", label: "Background Image", type: "Image" }
@@ -320,7 +320,7 @@ var fileSchema = z5.object({
320
320
  var HeroAlignment = ["left", "center", "right"];
321
321
  var HeroBlockContentSchema = z6.object({
322
322
  headline: z6.string().min(1, "Headline is required").max(100, "Headline too long"),
323
- subheadline: z6.string().max(200, "Subheadline too long").optional(),
323
+ subheadline: z6.string().max(200, "Description too long").optional(),
324
324
  ctaText: z6.string().max(50, "CTA text too long").optional(),
325
325
  ctaUrl: z6.string().refine(
326
326
  (val) => {
@@ -474,7 +474,7 @@ function generateCmsOverlayScript(cmsParentOrigin) {
474
474
  border-radius: 2px;
475
475
  }
476
476
  [data-cms-editable]:not([data-cms-block]):hover {
477
- outline: 2px solid #3b82f6;
477
+ outline: 2px solid var(--component-accent, #A78BFA);
478
478
  outline-offset: 2px;
479
479
  }
480
480
  #cms-overlay-root {
@@ -491,15 +491,38 @@ function generateCmsOverlayScript(cmsParentOrigin) {
491
491
  }
492
492
  .cms-block-outline {
493
493
  position: fixed;
494
- border: 2px solid #3b82f6;
494
+ box-sizing: border-box;
495
+ border: 4px solid var(--component-accent, #A78BFA);
495
496
  border-radius: 4px;
496
497
  pointer-events: none;
497
498
  z-index: 99997;
498
499
  transition: all 0.15s ease;
499
500
  }
500
501
  .cms-block-outline.cms-outline-selected {
501
- border-color: #2563eb;
502
- border-width: 3px;
502
+ border-color: var(--component-accent, #A78BFA);
503
+ border-width: 4px;
504
+ }
505
+ .cms-block-label {
506
+ position: absolute;
507
+ top: 0;
508
+ left: 0;
509
+ display: none;
510
+ max-width: 240px;
511
+ padding: 2px 8px;
512
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
513
+ font-size: 12px;
514
+ font-weight: 600;
515
+ line-height: 1.4;
516
+ color: #fff;
517
+ background: var(--component-accent, #A78BFA);
518
+ border-radius: 4px 4px 4px 0;
519
+ white-space: nowrap;
520
+ overflow: hidden;
521
+ text-overflow: ellipsis;
522
+ pointer-events: none;
523
+ }
524
+ .cms-block-label.cms-label-visible {
525
+ display: block;
503
526
  }
504
527
  .cms-block-cursor {
505
528
  position: fixed;
@@ -664,15 +687,19 @@ function generateCmsOverlayScript(cmsParentOrigin) {
664
687
  cursor.className = 'cms-block-cursor';
665
688
  overlayRoot.appendChild(cursor);
666
689
 
667
- var outline = document.createElement('div');
668
- outline.className = 'cms-block-outline';
669
- outline.style.display = 'none';
670
- overlayRoot.appendChild(outline);
690
+ function createOutline(extraClass) {
691
+ var el = document.createElement('div');
692
+ el.className = 'cms-block-outline' + (extraClass ? ' ' + extraClass : '');
693
+ el.style.display = 'none';
694
+ var label = document.createElement('span');
695
+ label.className = 'cms-block-label';
696
+ el.appendChild(label);
697
+ overlayRoot.appendChild(el);
698
+ return el;
699
+ }
671
700
 
672
- var selectedOutline = document.createElement('div');
673
- selectedOutline.className = 'cms-block-outline cms-outline-selected';
674
- selectedOutline.style.display = 'none';
675
- overlayRoot.appendChild(selectedOutline);
701
+ var outline = createOutline();
702
+ var selectedOutline = createOutline('cms-outline-selected');
676
703
 
677
704
  var toolbar = document.createElement('div');
678
705
  toolbar.className = 'cms-block-toolbar';
@@ -700,35 +727,19 @@ function generateCmsOverlayScript(cmsParentOrigin) {
700
727
  var toolbarVisible = false;
701
728
  var selectedBlockId = null;
702
729
 
703
- function decoratePreviewUrl(rawHref) {
704
- if (!rawHref) return rawHref;
705
- try {
706
- var url = new URL(rawHref, window.location.href);
707
- if (url.origin !== window.location.origin) return rawHref;
708
- url.searchParams.set('edit_mode', 'true');
709
- if (CMS_PARENT_ORIGIN) {
710
- url.searchParams.set('cms_parent_origin', CMS_PARENT_ORIGIN);
711
- }
712
- return url.toString();
713
- } catch (_) {
714
- return rawHref;
715
- }
716
- }
717
-
718
- function preserveEditParamsOnNavigation(e) {
719
- if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
720
- return;
721
- }
722
-
723
- var anchor = e.target.closest('a[href]');
724
- if (!anchor || (anchor.target && anchor.target !== '_self') || anchor.hasAttribute('download')) {
725
- return;
726
- }
727
-
728
- var href = anchor.getAttribute('href');
729
- var decorated = decoratePreviewUrl(href);
730
- if (decorated && decorated !== href) {
731
- anchor.setAttribute('href', decorated);
730
+ // In edit mode we hijack every link/button activation. Following a link or
731
+ // firing a button's own handler makes inline editing on that element
732
+ // impossible (the click navigates away or triggers an action instead of
733
+ // placing the caret). We block the default action and stop the event from
734
+ // reaching the element's own listeners, while still letting our selection /
735
+ // edit routing run below.
736
+ function blockInteractiveActivation(e) {
737
+ var interactive = e.target.closest(
738
+ 'a[href], button, [role="button"], input[type="submit"], input[type="button"], input[type="reset"]'
739
+ );
740
+ if (interactive) {
741
+ e.preventDefault();
742
+ e.stopPropagation();
732
743
  }
733
744
  }
734
745
 
@@ -748,7 +759,11 @@ function generateCmsOverlayScript(cmsParentOrigin) {
748
759
  setTimeout(sendReadySignal, 1500);
749
760
 
750
761
  function getBlockElement(blockId) {
751
- return document.querySelector('[data-block-id="' + blockId + '"]');
762
+ // Match the real block element, not the hidden sentinel <span> that shares
763
+ // the same data-block-id and precedes it in the DOM. The sentinel is
764
+ // display:none (a 0x0 rect), so selecting it would paint the outline at the
765
+ // top-left corner. Only the stamped block carries data-cms-block.
766
+ return document.querySelector('[data-cms-block][data-block-id="' + blockId + '"]');
752
767
  }
753
768
 
754
769
  function getAllBlocks() {
@@ -763,17 +778,38 @@ function generateCmsOverlayScript(cmsParentOrigin) {
763
778
  return -1;
764
779
  }
765
780
 
781
+ function formatBlockType(type) {
782
+ if (!type) return 'Block';
783
+ return type
784
+ .replace(/[-_]+/g, ' ')
785
+ .replace(/\\b\\w/g, function(c) { return c.toUpperCase(); });
786
+ }
787
+
766
788
  function updateOutline(el, outlineEl) {
789
+ var label = outlineEl.querySelector('.cms-block-label');
767
790
  if (!el) {
768
791
  outlineEl.style.display = 'none';
792
+ if (label) label.classList.remove('cms-label-visible');
769
793
  return;
770
794
  }
771
795
  var rect = el.getBoundingClientRect();
796
+ // A 0x0 rect means the element isn't laid out yet (or is hidden). Hide the
797
+ // outline instead of drawing a zero-size box with a floating label at the
798
+ // top-left corner.
799
+ if (rect.width === 0 && rect.height === 0) {
800
+ outlineEl.style.display = 'none';
801
+ if (label) label.classList.remove('cms-label-visible');
802
+ return;
803
+ }
772
804
  outlineEl.style.display = 'block';
773
805
  outlineEl.style.top = rect.top + 'px';
774
806
  outlineEl.style.left = rect.left + 'px';
775
807
  outlineEl.style.width = rect.width + 'px';
776
808
  outlineEl.style.height = rect.height + 'px';
809
+ if (label) {
810
+ label.textContent = formatBlockType(el.getAttribute('data-block-type'));
811
+ label.classList.add('cms-label-visible');
812
+ }
777
813
  }
778
814
 
779
815
  function positionToolbar(x, y) {
@@ -850,17 +886,19 @@ function generateCmsOverlayScript(cmsParentOrigin) {
850
886
  });
851
887
 
852
888
  document.addEventListener('click', function(e) {
853
- preserveEditParamsOnNavigation(e);
889
+ // The floating toolbar is interactive (and its buttons are real <button>s);
890
+ // bail out before any blocking so its own handlers run.
891
+ if (e.target.closest('[data-cms-toolbar]')) return;
854
892
 
855
- if (toolbarVisible && !e.target.closest('[data-cms-toolbar]')) {
856
- var block = e.target.closest('[data-cms-block]');
857
- if (!block || block.getAttribute('data-block-id') !== currentBlockId) {
893
+ blockInteractiveActivation(e);
894
+
895
+ if (toolbarVisible) {
896
+ var activeBlock = e.target.closest('[data-cms-block]');
897
+ if (!activeBlock || activeBlock.getAttribute('data-block-id') !== currentBlockId) {
858
898
  hideToolbar();
859
899
  }
860
900
  }
861
901
 
862
- if (e.target.closest('[data-cms-toolbar]')) return;
863
-
864
902
  var editable = e.target.closest('[data-cms-editable]');
865
903
  if (editable) {
866
904
  postToParent({
@@ -1072,7 +1110,7 @@ function BlockRenderer({
1072
1110
  return null;
1073
1111
  }
1074
1112
  const language = routeParams ? Object.values(routeParams).find((p) => p.schemaName === "language")?.value : void 0;
1075
- const component = /* @__PURE__ */ jsx(Component, { content: block.content, routeParams, language });
1113
+ const component = /* @__PURE__ */ jsx(Component, { content: block.content, routeParams, language, path });
1076
1114
  if (disableEditable) {
1077
1115
  return component;
1078
1116
  }