mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat(website): add detailed property and method documentation (#8252)
Co-authored-by: Noel <buechler.noel@outlook.com>
This commit is contained in:
@@ -74,6 +74,7 @@
|
||||
"@typescript-eslint/eslint-plugin": "^5.30.5",
|
||||
"@typescript-eslint/parser": "^5.30.5",
|
||||
"@unocss/cli": "^0.43.2",
|
||||
"@unocss/reset": "^0.43.2",
|
||||
"@vitejs/plugin-react": "^1.3.2",
|
||||
"c8": "^7.11.3",
|
||||
"concurrently": "^7.2.2",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import { vs } from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
||||
import { Separator } from './Seperator';
|
||||
import { TypeParamTable } from './TypeParamTable';
|
||||
import { generateIcon } from '~/util/icon';
|
||||
import type { TypeParameterData } from '~/util/parse.server';
|
||||
@@ -9,38 +10,43 @@ export interface DocContainerProps {
|
||||
kind: string;
|
||||
excerpt: string;
|
||||
summary?: string | null;
|
||||
children?: JSX.Element;
|
||||
children?: JSX.Element | JSX.Element[];
|
||||
typeParams?: TypeParameterData[];
|
||||
}
|
||||
|
||||
export function DocContainer({ name, kind, excerpt, summary, typeParams, children }: DocContainerProps) {
|
||||
return (
|
||||
<div className="px-10">
|
||||
<h1 className="font-mono flex items-center content-center break-all">
|
||||
{generateIcon(kind, 'mr-2')}
|
||||
{name}
|
||||
</h1>
|
||||
<h3>Code declaration:</h3>
|
||||
<div>
|
||||
<SyntaxHighlighter
|
||||
wrapLines
|
||||
wrapLongLines
|
||||
language="typescript"
|
||||
style={vs}
|
||||
codeTagProps={{ style: { fontFamily: 'JetBrains Mono' } }}
|
||||
>
|
||||
{excerpt}
|
||||
</SyntaxHighlighter>
|
||||
<>
|
||||
<div className="bg-white border-b-solid border-gray border-width-0.5 sticky top-0 px-10 py-5">
|
||||
<h1 className="font-mono break-all m-0">
|
||||
{generateIcon(kind, 'mr-2')}
|
||||
{name}
|
||||
</h1>
|
||||
</div>
|
||||
{typeParams?.length ? (
|
||||
<>
|
||||
<h3>Type Parameters</h3>
|
||||
<TypeParamTable data={typeParams} />
|
||||
</>
|
||||
) : null}
|
||||
<h3>Summary</h3>
|
||||
<p>{summary ?? 'No summary provided.'}</p>
|
||||
{children}
|
||||
</div>
|
||||
<div className="p-10">
|
||||
<div>
|
||||
<SyntaxHighlighter
|
||||
wrapLines
|
||||
wrapLongLines
|
||||
language="typescript"
|
||||
style={vs}
|
||||
codeTagProps={{ style: { fontFamily: 'JetBrains Mono' } }}
|
||||
>
|
||||
{excerpt}
|
||||
</SyntaxHighlighter>
|
||||
</div>
|
||||
<h2>Summary</h2>
|
||||
<p className="color-slate-500">{summary ?? 'No summary provided.'}</p>
|
||||
<Separator />
|
||||
{typeParams?.length ? (
|
||||
<>
|
||||
<h2>Type Parameters</h2>
|
||||
<TypeParamTable data={typeParams} className="mb-5 p-3" />
|
||||
<Separator />
|
||||
</>
|
||||
) : null}
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AiOutlineMenu } from 'react-icons/ai';
|
||||
import { FiMenu } from 'react-icons/fi';
|
||||
import { VscPackage } from 'react-icons/vsc';
|
||||
import { generateIcon } from '~/util/icon';
|
||||
import type { getMembers } from '~/util/parse.server';
|
||||
@@ -17,14 +17,14 @@ function onMenuClick() {
|
||||
|
||||
export function ItemSidebar({ packageName, data }: ItemListProps) {
|
||||
return (
|
||||
<div className="flex flex-col max-h-full min-w-[270px] border-r-solid border-b-solid border-gray border-width-0.5">
|
||||
<div className="flex flex-col max-h-full min-w-[270px] lg:border-r-solid border-b-solid border-gray border-width-0.5">
|
||||
<div className="flex justify-between content-center items-center border-b-solid border-gray border-width-0.5">
|
||||
<h1 className="px-2 font-mono flex items-center content-center">
|
||||
<VscPackage className="px-1" />
|
||||
{`${packageName}`}
|
||||
</h1>
|
||||
<button className="lg:hidden mr-2 bg-transparent border-none" onClick={onMenuClick}>
|
||||
<AiOutlineMenu size={32} />
|
||||
<button className="lg:hidden mr-2 bg-transparent border-none cursor-pointer" onClick={onMenuClick}>
|
||||
<FiMenu size={32} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="hidden lg:block overflow-y-scroll overflow-x-clip p-7">
|
||||
|
||||
51
packages/website/src/components/MethodItem.tsx
Normal file
51
packages/website/src/components/MethodItem.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { FiLink } from 'react-icons/fi';
|
||||
import { ParameterTable } from './ParameterTable';
|
||||
import type { DocMethod } from '~/DocModel/DocMethod';
|
||||
import type { DocMethodSignature } from '~/DocModel/DocMethodSignature';
|
||||
import { constructHyperlinkedText } from '~/util/util';
|
||||
|
||||
type MethodResolvable = ReturnType<DocMethod['toJSON']> | ReturnType<DocMethodSignature['toJSON']>;
|
||||
|
||||
export interface MethodItemProps {
|
||||
data: MethodResolvable;
|
||||
}
|
||||
|
||||
function getShorthandName(data: MethodResolvable) {
|
||||
return `${data.name}(${data.parameters.reduce((prev, cur, index) => {
|
||||
if (index === 0) {
|
||||
return `${prev}${cur.name}`;
|
||||
}
|
||||
|
||||
return `${prev}, ${cur.name}`;
|
||||
}, '')})`;
|
||||
}
|
||||
|
||||
function onAnchorClick() {
|
||||
console.log('anchor clicked');
|
||||
// Todo implement jump-to links
|
||||
}
|
||||
|
||||
export function MethodItem({ data }: MethodItemProps) {
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<div className="flex content-center">
|
||||
<button className="bg-transparent border-none cursor-pointer" onClick={onAnchorClick}>
|
||||
<FiLink size={16} />
|
||||
</button>
|
||||
<div className="flex flex-col ml-3">
|
||||
<div className="w-full flex flex-row">
|
||||
<h4 className="font-mono my-0 break-all">{`${getShorthandName(data)}`}</h4>
|
||||
<h4 className="mx-3 my-0">:</h4>
|
||||
<h4 className="font-mono color-blue-800 my-0 break-all ">
|
||||
{constructHyperlinkedText(data.returnTypeTokens)}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx-10">
|
||||
{data.summary && <p className="color-slate-500 mt-2">{data.summary}</p>}
|
||||
{data.parameters.length ? <ParameterTable className="mb-10 mx-5" data={data.parameters} /> : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { MethodItem } from './MethodItem';
|
||||
import type { DocMethod } from '~/DocModel/DocMethod';
|
||||
import type { DocMethodSignature } from '~/DocModel/DocMethodSignature';
|
||||
|
||||
@@ -8,12 +9,12 @@ export interface MethodListProps {
|
||||
export function MethodList({ data }: MethodListProps) {
|
||||
return (
|
||||
<div>
|
||||
<h3>Methods</h3>
|
||||
<ul>
|
||||
<h2>Methods</h2>
|
||||
<div className="flex flex-col">
|
||||
{data.map((method) => (
|
||||
<li key={method.name}>{method.name}</li>
|
||||
<MethodItem key={method.name} data={method} />
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,35 +1,31 @@
|
||||
import { Table } from './Table';
|
||||
import { constructHyperlinkedText } from '../util/util';
|
||||
import type { ParameterDocumentation } from '~/util/parse.server';
|
||||
|
||||
interface ParameterDetailProps {
|
||||
data: ParameterDocumentation[];
|
||||
className?: string | undefined;
|
||||
}
|
||||
|
||||
export function ParameterTable({ data }: ParameterDetailProps) {
|
||||
export function ParameterTable({ data, className }: ParameterDetailProps) {
|
||||
const rows = data.map((param) => ({
|
||||
Name: param.name,
|
||||
Type: constructHyperlinkedText(param.tokens),
|
||||
Optional: param.isOptional ? 'Yes' : 'No',
|
||||
Description: 'None',
|
||||
}));
|
||||
|
||||
const columnStyles = {
|
||||
Name: 'font-mono',
|
||||
Type: 'font-mono',
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-10 border border-gray-200 solid rounded-md">
|
||||
<table className="w-full text-sm text-left text-black-500 dark:text-gray-400">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Optional</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.map((parameter) => (
|
||||
<tr key={parameter.name} className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
||||
<th className="py-4 font-normal text-gray-900 dark:text-white whitespace-nowrap">{parameter.name}</th>
|
||||
<th>
|
||||
<code>{constructHyperlinkedText(parameter.tokens)}</code>
|
||||
</th>
|
||||
<th>{parameter.isOptional ? 'Yes' : 'No'}</th>
|
||||
<th>None</th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<Table
|
||||
className={className}
|
||||
columns={['Name', 'Type', 'Optional', 'Description']}
|
||||
rows={rows}
|
||||
columnStyles={columnStyles}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
19
packages/website/src/components/PropertyItem.tsx
Normal file
19
packages/website/src/components/PropertyItem.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { DocProperty } from '~/DocModel/DocProperty';
|
||||
import { constructHyperlinkedText } from '~/util/util';
|
||||
|
||||
export interface PropertyItemProps {
|
||||
data: ReturnType<DocProperty['toJSON']>;
|
||||
}
|
||||
|
||||
export function PropertyItem({ data }: PropertyItemProps) {
|
||||
return (
|
||||
<div className="flex flex-col mb-2 ml-3">
|
||||
<div className="w-full flex flex-row">
|
||||
<h4 className="font-mono my-0">{`${data.name}`}</h4>
|
||||
<h4 className="mx-3 my-0">:</h4>
|
||||
<h4 className="font-mono color-blue-800 my-0">{constructHyperlinkedText(data.propertyTypeTokens)}</h4>
|
||||
</div>
|
||||
{data.summary && <p className="color-slate-500 mt-2">{data.summary}</p>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { PropertyItem } from './PropertyItem';
|
||||
import type { DocProperty } from '~/DocModel/DocProperty';
|
||||
|
||||
export interface PropertyListProps {
|
||||
@@ -6,13 +7,11 @@ export interface PropertyListProps {
|
||||
|
||||
export function PropertyList({ data }: PropertyListProps) {
|
||||
return (
|
||||
<div>
|
||||
<h3>Properties</h3>
|
||||
<ul>
|
||||
{data.map((prop) => (
|
||||
<li key={prop.name}>{prop.name}</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="flex flex-col">
|
||||
<h2>Properties</h2>
|
||||
{data.map((prop) => (
|
||||
<PropertyItem key={prop.name} data={prop} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
3
packages/website/src/components/Seperator.tsx
Normal file
3
packages/website/src/components/Seperator.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
export function Separator() {
|
||||
return <div className="h-[1px] w-full bg-gray-300 mb-3" />;
|
||||
}
|
||||
49
packages/website/src/components/Table.tsx
Normal file
49
packages/website/src/components/Table.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
export interface RowData {
|
||||
monospace?: boolean;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface TableProps {
|
||||
columns: string[];
|
||||
columnStyles?: Record<string, string>;
|
||||
rows: Record<string, string | (string | JSX.Element)[]>[];
|
||||
className?: string | undefined;
|
||||
}
|
||||
|
||||
export function Table({ rows, columns, columnStyles, className }: TableProps) {
|
||||
return (
|
||||
<div className={className}>
|
||||
<table className="table-fixed w-full pb-10 border-collapse">
|
||||
<thead>
|
||||
<tr>
|
||||
{columns.map((column) => (
|
||||
<th key={column} className="border-b z-10 text-left text-sm pl-2 border-slate-400">
|
||||
{column}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map((row, i) => (
|
||||
<tr key={i}>
|
||||
{Object.entries(row).map(([colName, val]) => {
|
||||
console.log(colName);
|
||||
console.log(columnStyles?.[colName]);
|
||||
return (
|
||||
<td
|
||||
key={colName}
|
||||
className={`p-2 text-sm border-b text-left border-slate-300 break-all ${
|
||||
columnStyles?.[colName] ?? ''
|
||||
}`}
|
||||
>
|
||||
{val}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,39 +1,33 @@
|
||||
import { Table } from './Table';
|
||||
import type { TypeParameterData } from '~/util/parse.server';
|
||||
import { constructHyperlinkedText } from '~/util/util';
|
||||
|
||||
export interface TableProps {
|
||||
data: TypeParameterData[];
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function TypeParamTable({ data }: TableProps) {
|
||||
export function TypeParamTable({ data, className }: TableProps) {
|
||||
const rows = data.map((typeParam) => ({
|
||||
Name: typeParam.name,
|
||||
Constraints: constructHyperlinkedText(typeParam.constraintTokens),
|
||||
Optional: typeParam.optional ? 'Yes' : 'No',
|
||||
Default: constructHyperlinkedText(typeParam.defaultTokens),
|
||||
Description: 'None',
|
||||
}));
|
||||
|
||||
const rowElements = {
|
||||
Name: 'font-mono',
|
||||
Constraints: 'font-mono',
|
||||
Default: 'font-mono',
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-10 border border-gray-200 solid rounded-md">
|
||||
<table className="w-full text-sm text-left text-black-500 dark:text-gray-400">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Constraint</th>
|
||||
<th>Optional</th>
|
||||
<th>Default</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.map((parameter) => (
|
||||
<tr key={parameter.name} className="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
|
||||
<th className="py-4 font-normal text-gray-900 dark:text-white whitespace-nowrap">{parameter.name}</th>
|
||||
<th>
|
||||
<code>{constructHyperlinkedText(parameter.constraintTokens)}</code>
|
||||
</th>
|
||||
<th>{parameter.optional ? 'Yes' : 'No'}</th>
|
||||
<th>
|
||||
<code>{constructHyperlinkedText(parameter.defaultTokens)}</code>
|
||||
</th>
|
||||
<th>None</th>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<Table
|
||||
className={className}
|
||||
columns={['Name', 'Constraints', 'Optional', 'Default', 'Description']}
|
||||
rows={rows}
|
||||
columnStyles={rowElements}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { DocContainer } from '../DocContainer';
|
||||
import { MethodList } from '../MethodList';
|
||||
import { PropertyList } from '../PropertyList';
|
||||
import { Separator } from '../Seperator';
|
||||
import type { DocClass } from '~/DocModel/DocClass';
|
||||
|
||||
export interface ClassProps {
|
||||
@@ -17,8 +18,19 @@ export function Class({ data }: ClassProps) {
|
||||
typeParams={data.typeParameterData}
|
||||
>
|
||||
<>
|
||||
{data.properties.length ? <PropertyList data={data.properties} /> : null}
|
||||
{data.methods.length ? <MethodList data={data.methods} /> : null}
|
||||
{data.properties.length ? (
|
||||
<>
|
||||
<PropertyList data={data.properties} />
|
||||
<Separator />
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{data.methods.length ? (
|
||||
<>
|
||||
<MethodList data={data.methods} />
|
||||
<Separator />
|
||||
</>
|
||||
) : null}
|
||||
</>
|
||||
</DocContainer>
|
||||
);
|
||||
|
||||
@@ -15,6 +15,7 @@ export function Function({ data }: FunctionProps) {
|
||||
summary={data.summary}
|
||||
typeParams={data.typeParameterData}
|
||||
>
|
||||
<h2>Parameters</h2>
|
||||
<ParameterTable data={data.parameters} />
|
||||
</DocContainer>
|
||||
);
|
||||
|
||||
@@ -13,8 +13,6 @@ export function TypeAlias({ data }: TypeAliasProps) {
|
||||
excerpt={data.excerpt}
|
||||
summary={data.summary}
|
||||
typeParams={data.typeParameterData}
|
||||
>
|
||||
<div>WIP</div>
|
||||
</DocContainer>
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,11 +39,11 @@ export default function Package() {
|
||||
const { packageName } = useParams();
|
||||
|
||||
return (
|
||||
<div className="flex flex-col lg:flex-row overflow-none max-w-full h-full">
|
||||
<div className="flex flex-col lg:flex-row overflow-hidden max-w-full h-full">
|
||||
<div className="w-full lg:min-w-1/4 lg:max-w-1/4">
|
||||
<ItemSidebar packageName={packageName!} data={data} />
|
||||
</div>
|
||||
<div>
|
||||
<div className="max-h-full grow overflow-auto">
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@import '@unocss/reset/tailwind.css';
|
||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800&display=swap');
|
||||
|
||||
html,
|
||||
|
||||
@@ -143,6 +143,11 @@ export function genReference(item: ApiItem) {
|
||||
}
|
||||
|
||||
export function genToken(model: ApiModel, token: ExcerptToken) {
|
||||
if (token.canonicalReference) {
|
||||
// @ts-expect-error
|
||||
token.canonicalReference._navigation = '.';
|
||||
}
|
||||
|
||||
const item = token.canonicalReference
|
||||
? model.resolveDeclarationReference(token.canonicalReference, undefined).resolvedApiItem ?? null
|
||||
: null;
|
||||
|
||||
@@ -3079,6 +3079,7 @@ __metadata:
|
||||
"@typescript-eslint/eslint-plugin": ^5.30.5
|
||||
"@typescript-eslint/parser": ^5.30.5
|
||||
"@unocss/cli": ^0.43.2
|
||||
"@unocss/reset": ^0.43.2
|
||||
"@vitejs/plugin-react": ^1.3.2
|
||||
"@vscode/codicons": ^0.0.31
|
||||
c8: ^7.11.3
|
||||
@@ -5089,7 +5090,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@unocss/reset@npm:0.43.2":
|
||||
"@unocss/reset@npm:0.43.2, @unocss/reset@npm:^0.43.2":
|
||||
version: 0.43.2
|
||||
resolution: "@unocss/reset@npm:0.43.2"
|
||||
checksum: ea9a47d09b179f9b0ee2ff96e5f1617b8f6f3e790f809f9c8e2824e2bb048f0c5b0f653f50f2501f2b1e46e604f344981c94054e70deb1728b34cd440b119be3
|
||||
|
||||
Reference in New Issue
Block a user