refactor(website): extract layouts and use more server components (#9027)

Closes https://github.com/discordjs/discord.js/issues/8920
Closes https://github.com/discordjs/discord.js/issues/8997
This commit is contained in:
Suneet Tipirneni
2023-01-10 12:25:14 -05:00
committed by GitHub
parent 158db474b7
commit 39c4de2dbc
73 changed files with 1831 additions and 1476 deletions

View File

@@ -0,0 +1,38 @@
import { Alert } from '@discordjs/ui';
import type { PropsWithChildren } from 'react';
export function Block({ children, title }: PropsWithChildren<{ title: string }>) {
return (
<div className="flex flex-col gap-2">
<h5 className="font-bold">{title}</h5>
{children}
</div>
);
}
export function ExampleBlock({
children,
exampleIndex,
}: PropsWithChildren<{ exampleIndex?: number | undefined }>): JSX.Element {
return <Block title={`Example ${exampleIndex ? exampleIndex : ''}`}>{children}</Block>;
}
export function DefaultValueBlock({ children }: PropsWithChildren): JSX.Element {
return <Block title="Default value">{children}</Block>;
}
export function RemarksBlock({ children }: PropsWithChildren): JSX.Element {
return <Block title="Remarks">{children}</Block>;
}
export function DeprecatedBlock({ children }: PropsWithChildren): JSX.Element {
return (
<Alert title="Deprecated" type="danger">
{children}
</Alert>
);
}
export function SeeBlock({ children }: PropsWithChildren): JSX.Element {
return <Block title="See Also">{children}</Block>;
}

View File

@@ -0,0 +1,121 @@
import type { ApiItem } from '@microsoft/api-extractor-model';
import type { DocComment, DocFencedCode, DocLinkTag, DocNode, DocNodeContainer, DocPlainText } from '@microsoft/tsdoc';
import { DocNodeKind, StandardTags } from '@microsoft/tsdoc';
import Link from 'next/link';
import { Fragment, useCallback, type ReactNode } from 'react';
import { SyntaxHighlighter } from '../../SyntaxHighlighter';
import { resolveItemURI } from '../util';
import { DeprecatedBlock, ExampleBlock, RemarksBlock, SeeBlock } from './BlockComment';
import { ItemLink } from '~/components/ItemLink';
export function TSDoc({ item, tsdoc }: { item: ApiItem; tsdoc: DocNode }): JSX.Element {
const createNode = useCallback(
(tsdoc: DocNode, idx?: number): ReactNode => {
switch (tsdoc.kind) {
case DocNodeKind.PlainText:
return (
<span className="break-words" key={idx}>
{(tsdoc as DocPlainText).text}
</span>
);
case DocNodeKind.Section:
case DocNodeKind.Paragraph:
return (
<span className="break-words leading-relaxed" key={idx}>
{(tsdoc as DocNodeContainer).nodes.map((node, idx) => createNode(node, idx))}
</span>
);
case DocNodeKind.SoftBreak:
return <Fragment key={idx} />;
case DocNodeKind.LinkTag: {
const { codeDestination, urlDestination, linkText } = tsdoc as DocLinkTag;
if (codeDestination) {
const foundItem = item
.getAssociatedModel()
?.resolveDeclarationReference(codeDestination, item).resolvedApiItem;
if (!foundItem) return null;
return (
<ItemLink
className="text-blurple focus:ring-width-2 focus:ring-blurple rounded font-mono outline-0 focus:ring"
itemURI={resolveItemURI(foundItem)}
key={idx}
>
{linkText ?? foundItem.displayName}
</ItemLink>
);
}
if (urlDestination) {
return (
<Link
className="text-blurple focus:ring-width-2 focus:ring-blurple rounded font-mono outline-0 focus:ring"
href={urlDestination}
key={idx}
>
{linkText ?? urlDestination}
</Link>
);
}
return null;
}
case DocNodeKind.CodeSpan: {
const { code } = tsdoc as DocFencedCode;
return (
<code className="font-mono text-sm" key={idx}>
{code}
</code>
);
}
case DocNodeKind.FencedCode: {
const { language, code } = tsdoc as DocFencedCode;
return <SyntaxHighlighter code={code} key={idx} language={language} />;
}
case DocNodeKind.Comment: {
const comment = tsdoc as DocComment;
const exampleBlocks = comment.customBlocks.filter(
(block) => block.blockTag.tagName.toUpperCase() === StandardTags.example.tagNameWithUpperCase,
);
return (
<div className="flex flex-col space-y-2">
{comment.deprecatedBlock ? (
<DeprecatedBlock>{createNode(comment.deprecatedBlock.content)}</DeprecatedBlock>
) : null}
{comment.summarySection ? createNode(comment.summarySection) : null}
{comment.remarksBlock ? <RemarksBlock>{createNode(comment.remarksBlock.content)}</RemarksBlock> : null}
{exampleBlocks.length
? exampleBlocks.map((block, idx) => <ExampleBlock key={idx}>{createNode(block.content)}</ExampleBlock>)
: null}
{comment.seeBlocks.length ? (
<SeeBlock>{comment.seeBlocks.map((seeBlock, idx) => createNode(seeBlock.content, idx))}</SeeBlock>
) : null}
</div>
);
}
default:
// console.log(`Captured unknown node kind: ${node.kind}`);
return null;
}
},
[item],
);
return (
<>
{tsdoc.kind === 'Paragraph' || tsdoc.kind === 'Section' ? (
<>{(tsdoc as DocNodeContainer).nodes.map((node, idx) => createNode(node, idx))}</>
) : (
createNode(tsdoc)
)}
</>
);
}