import { defaultJSXConverters, RichText } from '@payloadcms/richtext-lexical/react';
import type { JSXConverters } from '@payloadcms/richtext-lexical/react';
import Image from 'next/image';
// Import all custom React components that were previously mapped via MDX
import StickyNarrative from '@/components/blog/StickyNarrative';
import ComparisonGrid from '@/components/blog/ComparisonGrid';
import VisualLinkPreview from '@/components/blog/VisualLinkPreview';
import TechnicalGrid from '@/components/blog/TechnicalGrid';
import HighlightBox from '@/components/blog/HighlightBox';
import AnimatedImage from '@/components/blog/AnimatedImage';
import ChatBubble from '@/components/blog/ChatBubble';
import PowerCTA from '@/components/blog/PowerCTA';
import { Callout } from '@/components/ui/Callout';
import Stats from '@/components/blog/Stats';
import SplitHeading from '@/components/blog/SplitHeading';
import ProductTabs from '@/components/ProductTabs';
import ProductTechnicalData from '@/components/ProductTechnicalData';
const jsxConverters: JSXConverters = {
...defaultJSXConverters,
// Let the default converters handle text nodes to preserve valid formatting
// If the text node contains raw HTML (from messy migrations), render it as HTML instead of escaping it
text: ({ node }: any) => {
const text = node.text;
if (text && (text.includes('<') || text.includes('data-start'))) {
return ;
}
// Handle markdown-style lists embedded in text nodes from MDX migration
if (text && text.includes('\n- ')) {
const parts = text.split('\n- ').filter(Boolean);
// If first part doesn't start with "- ", it's a prefix paragraph
const startsWithDash = text.trimStart().startsWith('- ');
const prefix = startsWithDash ? null : parts.shift();
return (
<>
{prefix && {prefix}}
{parts.map((item: string, i: number) => (
{item.trim()}
))}
>
);
}
// Handle markdown-style links [text](url) from MDX migration
if (text && /\[([^\]]+)\]\(([^)]+)\)/.test(text)) {
const parts: React.ReactNode[] = [];
const remaining = text;
let key = 0;
const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
let match;
let lastIndex = 0;
while ((match = linkRegex.exec(remaining)) !== null) {
if (match.index > lastIndex) {
parts.push({remaining.slice(lastIndex, match.index)});
}
parts.push(
{match[1]}
,
);
lastIndex = match.index + match[0].length;
}
if (lastIndex < remaining.length) {
parts.push({remaining.slice(lastIndex)});
}
return <>{parts}>;
}
// Handle newlines in text nodes — convert to for proper line breaks
if (text && text.includes('\n')) {
const lines = text.split('\n');
return (
<>
{lines.map((line: string, i: number) => (
{line}
{i < lines.length - 1 && }
))}
>
);
}
if (node.format === 1) return {text};
if (node.format === 2) return {text};
return {text};
},
// Scale headings to prevent multiple H1s (H1 -> H2, etc)
h1: ({ children }: any) =>