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.
@@ -32,12 +32,12 @@ function isArticlePublished(article) {
32
32
  var BLOCK_METADATA = {
33
33
  "hero-block": {
34
34
  name: "Hero",
35
- description: "Full-width hero section with headline, subheadline, and CTA",
35
+ description: "Full-width hero section with headline, description, and CTA",
36
36
  category: "Marketing",
37
37
  icon: "image",
38
38
  fields: [
39
39
  { name: "headline", label: "Headline", type: "Text" },
40
- { name: "subheadline", label: "Subheadline", type: "Text" },
40
+ { name: "subheadline", label: "Description", type: "Text" },
41
41
  { name: "ctaText", label: "CTA Label", type: "Text" },
42
42
  { name: "ctaUrl", label: "CTA URL", type: "URL" },
43
43
  { name: "backgroundImage", label: "Background Image", type: "Image" }
@@ -248,7 +248,7 @@ var fileSchema = z5.object({
248
248
  var HeroAlignment = ["left", "center", "right"];
249
249
  var HeroBlockContentSchema = z6.object({
250
250
  headline: z6.string().min(1, "Headline is required").max(100, "Headline too long"),
251
- subheadline: z6.string().max(200, "Subheadline too long").optional(),
251
+ subheadline: z6.string().max(200, "Description too long").optional(),
252
252
  ctaText: z6.string().max(50, "CTA text too long").optional(),
253
253
  ctaUrl: z6.string().refine(
254
254
  (val) => {
@@ -402,7 +402,7 @@ function generateCmsOverlayScript(cmsParentOrigin) {
402
402
  border-radius: 2px;
403
403
  }
404
404
  [data-cms-editable]:not([data-cms-block]):hover {
405
- outline: 2px solid #3b82f6;
405
+ outline: 2px solid var(--component-accent, #A78BFA);
406
406
  outline-offset: 2px;
407
407
  }
408
408
  #cms-overlay-root {
@@ -419,15 +419,38 @@ function generateCmsOverlayScript(cmsParentOrigin) {
419
419
  }
420
420
  .cms-block-outline {
421
421
  position: fixed;
422
- border: 2px solid #3b82f6;
422
+ box-sizing: border-box;
423
+ border: 4px solid var(--component-accent, #A78BFA);
423
424
  border-radius: 4px;
424
425
  pointer-events: none;
425
426
  z-index: 99997;
426
427
  transition: all 0.15s ease;
427
428
  }
428
429
  .cms-block-outline.cms-outline-selected {
429
- border-color: #2563eb;
430
- border-width: 3px;
430
+ border-color: var(--component-accent, #A78BFA);
431
+ border-width: 4px;
432
+ }
433
+ .cms-block-label {
434
+ position: absolute;
435
+ top: 0;
436
+ left: 0;
437
+ display: none;
438
+ max-width: 240px;
439
+ padding: 2px 8px;
440
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
441
+ font-size: 12px;
442
+ font-weight: 600;
443
+ line-height: 1.4;
444
+ color: #fff;
445
+ background: var(--component-accent, #A78BFA);
446
+ border-radius: 4px 4px 4px 0;
447
+ white-space: nowrap;
448
+ overflow: hidden;
449
+ text-overflow: ellipsis;
450
+ pointer-events: none;
451
+ }
452
+ .cms-block-label.cms-label-visible {
453
+ display: block;
431
454
  }
432
455
  .cms-block-cursor {
433
456
  position: fixed;
@@ -592,15 +615,19 @@ function generateCmsOverlayScript(cmsParentOrigin) {
592
615
  cursor.className = 'cms-block-cursor';
593
616
  overlayRoot.appendChild(cursor);
594
617
 
595
- var outline = document.createElement('div');
596
- outline.className = 'cms-block-outline';
597
- outline.style.display = 'none';
598
- overlayRoot.appendChild(outline);
618
+ function createOutline(extraClass) {
619
+ var el = document.createElement('div');
620
+ el.className = 'cms-block-outline' + (extraClass ? ' ' + extraClass : '');
621
+ el.style.display = 'none';
622
+ var label = document.createElement('span');
623
+ label.className = 'cms-block-label';
624
+ el.appendChild(label);
625
+ overlayRoot.appendChild(el);
626
+ return el;
627
+ }
599
628
 
600
- var selectedOutline = document.createElement('div');
601
- selectedOutline.className = 'cms-block-outline cms-outline-selected';
602
- selectedOutline.style.display = 'none';
603
- overlayRoot.appendChild(selectedOutline);
629
+ var outline = createOutline();
630
+ var selectedOutline = createOutline('cms-outline-selected');
604
631
 
605
632
  var toolbar = document.createElement('div');
606
633
  toolbar.className = 'cms-block-toolbar';
@@ -628,35 +655,19 @@ function generateCmsOverlayScript(cmsParentOrigin) {
628
655
  var toolbarVisible = false;
629
656
  var selectedBlockId = null;
630
657
 
631
- function decoratePreviewUrl(rawHref) {
632
- if (!rawHref) return rawHref;
633
- try {
634
- var url = new URL(rawHref, window.location.href);
635
- if (url.origin !== window.location.origin) return rawHref;
636
- url.searchParams.set('edit_mode', 'true');
637
- if (CMS_PARENT_ORIGIN) {
638
- url.searchParams.set('cms_parent_origin', CMS_PARENT_ORIGIN);
639
- }
640
- return url.toString();
641
- } catch (_) {
642
- return rawHref;
643
- }
644
- }
645
-
646
- function preserveEditParamsOnNavigation(e) {
647
- if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
648
- return;
649
- }
650
-
651
- var anchor = e.target.closest('a[href]');
652
- if (!anchor || (anchor.target && anchor.target !== '_self') || anchor.hasAttribute('download')) {
653
- return;
654
- }
655
-
656
- var href = anchor.getAttribute('href');
657
- var decorated = decoratePreviewUrl(href);
658
- if (decorated && decorated !== href) {
659
- anchor.setAttribute('href', decorated);
658
+ // In edit mode we hijack every link/button activation. Following a link or
659
+ // firing a button's own handler makes inline editing on that element
660
+ // impossible (the click navigates away or triggers an action instead of
661
+ // placing the caret). We block the default action and stop the event from
662
+ // reaching the element's own listeners, while still letting our selection /
663
+ // edit routing run below.
664
+ function blockInteractiveActivation(e) {
665
+ var interactive = e.target.closest(
666
+ 'a[href], button, [role="button"], input[type="submit"], input[type="button"], input[type="reset"]'
667
+ );
668
+ if (interactive) {
669
+ e.preventDefault();
670
+ e.stopPropagation();
660
671
  }
661
672
  }
662
673
 
@@ -676,7 +687,11 @@ function generateCmsOverlayScript(cmsParentOrigin) {
676
687
  setTimeout(sendReadySignal, 1500);
677
688
 
678
689
  function getBlockElement(blockId) {
679
- return document.querySelector('[data-block-id="' + blockId + '"]');
690
+ // Match the real block element, not the hidden sentinel <span> that shares
691
+ // the same data-block-id and precedes it in the DOM. The sentinel is
692
+ // display:none (a 0x0 rect), so selecting it would paint the outline at the
693
+ // top-left corner. Only the stamped block carries data-cms-block.
694
+ return document.querySelector('[data-cms-block][data-block-id="' + blockId + '"]');
680
695
  }
681
696
 
682
697
  function getAllBlocks() {
@@ -691,17 +706,38 @@ function generateCmsOverlayScript(cmsParentOrigin) {
691
706
  return -1;
692
707
  }
693
708
 
709
+ function formatBlockType(type) {
710
+ if (!type) return 'Block';
711
+ return type
712
+ .replace(/[-_]+/g, ' ')
713
+ .replace(/\\b\\w/g, function(c) { return c.toUpperCase(); });
714
+ }
715
+
694
716
  function updateOutline(el, outlineEl) {
717
+ var label = outlineEl.querySelector('.cms-block-label');
695
718
  if (!el) {
696
719
  outlineEl.style.display = 'none';
720
+ if (label) label.classList.remove('cms-label-visible');
697
721
  return;
698
722
  }
699
723
  var rect = el.getBoundingClientRect();
724
+ // A 0x0 rect means the element isn't laid out yet (or is hidden). Hide the
725
+ // outline instead of drawing a zero-size box with a floating label at the
726
+ // top-left corner.
727
+ if (rect.width === 0 && rect.height === 0) {
728
+ outlineEl.style.display = 'none';
729
+ if (label) label.classList.remove('cms-label-visible');
730
+ return;
731
+ }
700
732
  outlineEl.style.display = 'block';
701
733
  outlineEl.style.top = rect.top + 'px';
702
734
  outlineEl.style.left = rect.left + 'px';
703
735
  outlineEl.style.width = rect.width + 'px';
704
736
  outlineEl.style.height = rect.height + 'px';
737
+ if (label) {
738
+ label.textContent = formatBlockType(el.getAttribute('data-block-type'));
739
+ label.classList.add('cms-label-visible');
740
+ }
705
741
  }
706
742
 
707
743
  function positionToolbar(x, y) {
@@ -778,17 +814,19 @@ function generateCmsOverlayScript(cmsParentOrigin) {
778
814
  });
779
815
 
780
816
  document.addEventListener('click', function(e) {
781
- preserveEditParamsOnNavigation(e);
817
+ // The floating toolbar is interactive (and its buttons are real <button>s);
818
+ // bail out before any blocking so its own handlers run.
819
+ if (e.target.closest('[data-cms-toolbar]')) return;
782
820
 
783
- if (toolbarVisible && !e.target.closest('[data-cms-toolbar]')) {
784
- var block = e.target.closest('[data-cms-block]');
785
- if (!block || block.getAttribute('data-block-id') !== currentBlockId) {
821
+ blockInteractiveActivation(e);
822
+
823
+ if (toolbarVisible) {
824
+ var activeBlock = e.target.closest('[data-cms-block]');
825
+ if (!activeBlock || activeBlock.getAttribute('data-block-id') !== currentBlockId) {
786
826
  hideToolbar();
787
827
  }
788
828
  }
789
829
 
790
- if (e.target.closest('[data-cms-toolbar]')) return;
791
-
792
830
  var editable = e.target.closest('[data-cms-editable]');
793
831
  if (editable) {
794
832
  postToParent({
@@ -1000,7 +1038,7 @@ function BlockRenderer({
1000
1038
  return null;
1001
1039
  }
1002
1040
  const language = routeParams ? Object.values(routeParams).find((p) => p.schemaName === "language")?.value : void 0;
1003
- const component = /* @__PURE__ */ jsx(Component, { content: block.content, routeParams, language });
1041
+ const component = /* @__PURE__ */ jsx(Component, { content: block.content, routeParams, language, path });
1004
1042
  if (disableEditable) {
1005
1043
  return component;
1006
1044
  }