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
|
@@ -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,
|
|
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: "
|
|
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, "
|
|
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 #
|
|
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
|
-
|
|
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: #
|
|
430
|
-
border-width:
|
|
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
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
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
|
|
601
|
-
selectedOutline
|
|
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
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
784
|
-
|
|
785
|
-
|
|
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
|
}
|