import type {
BlockEditProps,
BlockReadProps,
BlockSpec,
} from "@agent-native/core/blocks";
import {
builderCodeBlockConfig,
builderCodeSnippetsV2BlockConfig,
builderRawBlockConfig,
builderSymbolBlockConfig,
builderTabbedContentBlockConfig,
builderTextBlockConfig,
type BuilderCodeBlockData,
type BuilderCodeSnippetsV2Data,
type BuilderRawBlockData,
type BuilderSymbolData,
type BuilderTabbedContentData,
type BuilderTextData,
} from "@shared/builder-docs-blocks";
import {
IconBox,
IconCode,
IconFileText,
IconLayout,
IconPuzzle,
} from "@tabler/icons-react";
import { useState } from "react";
import { ContentReferencePreview } from "@/components/editor/ContentReferencePreview";
function SidecarBadge({ rawRef }: { rawRef: string }) {
return (
{rawRef}
);
}
export function BuilderTextRead({
data,
blockId,
ctx,
}: BlockReadProps) {
return (
{ctx.renderMarkdown?.(data.body) ?? (
{data.body}
)}
);
}
export function BuilderTextEdit({
data,
onChange,
editable,
blockId,
ctx,
}: BlockEditProps) {
return (
{ctx.renderMarkdownEditor?.({
value: data.body,
onChange: (body) => onChange({ ...data, body }),
editable,
blockId,
}) ?? (
);
}
export function BuilderCodeBlockRead({
data,
blockId,
}: BlockReadProps) {
return (
{data.filename || data.language || data.componentName || "Code block"}
{data.code}
);
}
export function BuilderCodeSnippetsV2Read({
data,
blockId,
}: BlockReadProps) {
const tabCount = Object.values(data.customTabContent ?? {}).filter((value) =>
Array.isArray(value) ? value.length > 0 : Boolean(value),
).length;
return (
CodeSnippetsV2
{data.modelName || "No model name"} / {data.modelType || "page"} /{" "}
{tabCount} custom tabs
);
}
export function BuilderTabbedContentRead({
data,
blockId,
ctx,
}: BlockReadProps) {
const [active, setActive] = useState(0);
const current =
data.tabs[Math.min(active, Math.max(data.tabs.length - 1, 0))];
return (
{data.title ? (
{data.title}
) : null}
{data.tabs.map((tab, index) => (
setActive(index)}
>
{tab.label}
))}
{current
? (ctx.renderMarkdown?.(current.body) ?? (
{current.body}
))
: null}
);
}
export function BuilderSymbolRead({
data,
blockId,
}: BlockReadProps) {
return (
Builder Symbol
{data.model || "model unknown"} / {data.entry || "entry unknown"}
{data.dynamic ? " / dynamic" : ""}
{data.source ? (
) : null}
);
}
export function BuilderRawBlockRead({
data,
blockId,
}: BlockReadProps) {
return (
{data.componentName || "Raw Builder block"}
{data.summary ? {data.summary}
: null}
);
}
export const builderTextBlock: BlockSpec = {
...builderTextBlockConfig,
Read: BuilderTextRead,
Edit: BuilderTextEdit,
icon: IconFileText,
};
export const builderCodeBlock: BlockSpec = {
...builderCodeBlockConfig,
Read: BuilderCodeBlockRead,
icon: IconCode,
};
export const builderCodeSnippetsV2Block: BlockSpec =
{
...builderCodeSnippetsV2BlockConfig,
Read: BuilderCodeSnippetsV2Read,
icon: IconCode,
};
export const builderTabbedContentBlock: BlockSpec = {
...builderTabbedContentBlockConfig,
Read: BuilderTabbedContentRead,
icon: IconLayout,
};
export const builderSymbolBlock: BlockSpec = {
...builderSymbolBlockConfig,
Read: BuilderSymbolRead,
icon: IconPuzzle,
};
export const builderRawBlock: BlockSpec = {
...builderRawBlockConfig,
Read: BuilderRawBlockRead,
icon: IconBox,
};
export const builderDocsBlocks: BlockSpec[] = [
builderTextBlock,
builderCodeBlock,
builderCodeSnippetsV2Block,
builderTabbedContentBlock,
builderSymbolBlock,
builderRawBlock,
];