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.
- package/README.md +31 -0
- package/dist/lib/ai-preview.d.ts +62 -0
- package/dist/lib/ai-preview.js +114 -0
- package/dist/lib/ai-preview.js.map +1 -0
- package/dist/lib/block-renderer.js +87 -49
- package/dist/lib/block-renderer.js.map +1 -1
- package/dist/lib/custom-schemas.js +126 -42
- package/dist/lib/custom-schemas.js.map +1 -1
- package/dist/lib/docs-markdown.js +49 -1
- package/dist/lib/docs-markdown.js.map +1 -1
- package/dist/lib/markdown-utils.js +46 -1
- package/dist/lib/markdown-utils.js.map +1 -1
- package/dist/lib/parametric-route.js +90 -52
- package/dist/lib/parametric-route.js.map +1 -1
- package/dist/lib/renderer.js +90 -52
- package/dist/lib/renderer.js.map +1 -1
- package/dist/lib/types.d.ts +2 -0
- package/dist/lib/types.js.map +1 -1
- package/package.json +8 -4
package/dist/lib/renderer.js
CHANGED
|
@@ -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,
|
|
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: "
|
|
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, "
|
|
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 #
|
|
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
|
-
|
|
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: #
|
|
502
|
-
border-width:
|
|
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
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
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
|
|
673
|
-
selectedOutline
|
|
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
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
856
|
-
|
|
857
|
-
|
|
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
|
}
|