import { Anchor, Box, Text } from '@mantine/core';
import { DocNodeKind, StandardTags } from '@microsoft/tsdoc';
import Link from 'next/link';
import type { ReactNode } from 'react';
import { PrismAsyncLight as SyntaxHighlighter } from 'react-syntax-highlighter';
import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import { BlockComment } from './BlockComment';
import type { DocBlockJSON } from '~/DocModel/comment/CommentBlock';
import type { AnyDocNodeJSON } from '~/DocModel/comment/CommentNode';
import type { DocNodeContainerJSON } from '~/DocModel/comment/CommentNodeContainer';
import type { DocFencedCodeJSON } from '~/DocModel/comment/FencedCodeCommentNode';
import type { DocLinkTagJSON } from '~/DocModel/comment/LinkTagCommentNode';
import type { DocPlainTextJSON } from '~/DocModel/comment/PlainTextCommentNode';
import type { DocCommentJSON } from '~/DocModel/comment/RootComment';
export function TSDoc({ node }: { node: AnyDocNodeJSON }): JSX.Element {
let numberOfExamples = 0;
let exampleIndex = 0;
const createNode = (node: AnyDocNodeJSON, idx?: number): ReactNode => {
switch (node.kind) {
case DocNodeKind.PlainText:
return (
{(node as DocPlainTextJSON).text}
);
case DocNodeKind.Paragraph:
return (
{(node as DocNodeContainerJSON).nodes.map((node, idx) => createNode(node, idx))}
);
case DocNodeKind.SoftBreak:
return <>>;
case DocNodeKind.LinkTag: {
const { codeDestination, urlDestination, text } = node as DocLinkTagJSON;
if (codeDestination) {
return (
{text ?? codeDestination.name}
);
}
if (urlDestination) {
return (
{text ?? urlDestination}
);
}
return null;
}
case DocNodeKind.CodeSpan: {
const { code } = node as DocFencedCodeJSON;
return (
{code}
);
}
case DocNodeKind.FencedCode: {
const { language, code } = node as DocFencedCodeJSON;
return (
{code}
);
}
case DocNodeKind.Block: {
const { tag } = node as DocBlockJSON;
if (tag.tagName.toUpperCase() === StandardTags.example.tagNameWithUpperCase) {
exampleIndex++;
}
const index = numberOfExamples > 1 ? exampleIndex : undefined;
return (
{(node as DocBlockJSON).content.map((node, idx) => createNode(node, idx))}
);
}
case DocNodeKind.Comment: {
const comment = node as DocCommentJSON;
// Cheat a bit by finding out how many comments we have beforehand...
numberOfExamples = comment.customBlocks.filter(
(block) => block.tag.tagName.toUpperCase() === StandardTags.example.tagNameWithUpperCase,
).length;
return