mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
refactor: inline table of contents
This commit is contained in:
@@ -42,7 +42,7 @@ export function CodeListing({
|
||||
{optional ? '?' : ''}
|
||||
</Title>
|
||||
<Title order={4}>{separator}</Title>
|
||||
<Title order={4} className="font-mono break-all">
|
||||
<Title sx={{ wordBreak: 'break-all' }} order={4} className="font-mono">
|
||||
<HyperlinkedText tokens={typeTokens} />
|
||||
</Title>
|
||||
</Group>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Group, Stack, Title, Text, Box } from '@mantine/core';
|
||||
import { Group, Stack, Title, Text, Box, MediaQuery, Aside, ScrollArea } from '@mantine/core';
|
||||
import { useMediaQuery } from '@mantine/hooks';
|
||||
import type { ReactNode } from 'react';
|
||||
import { VscListSelection, VscSymbolParameter } from 'react-icons/vsc';
|
||||
@@ -6,8 +6,10 @@ import { PrismAsyncLight as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
||||
import { HyperlinkedText } from './HyperlinkedText';
|
||||
import { Section } from './Section';
|
||||
import { TableOfContentsItems } from './TableOfContentsItems';
|
||||
import { TypeParamTable } from './TypeParamTable';
|
||||
import { TSDoc } from './tsdoc/TSDoc';
|
||||
import type { DocClass } from '~/DocModel/DocClass';
|
||||
import type { DocItem } from '~/DocModel/DocItem';
|
||||
import type { AnyDocNodeJSON } from '~/DocModel/comment/CommentNode';
|
||||
import { generateIcon } from '~/util/icon';
|
||||
@@ -23,6 +25,7 @@ export interface DocContainerProps {
|
||||
implementsTokens?: TokenDocumentation[][];
|
||||
typeParams?: TypeParameterData[];
|
||||
comment?: AnyDocNodeJSON | null;
|
||||
methods?: ReturnType<DocClass['toJSON']>['methods'] | null;
|
||||
}
|
||||
|
||||
export function DocContainer({
|
||||
@@ -34,68 +37,85 @@ export function DocContainer({
|
||||
children,
|
||||
extendsTokens,
|
||||
implementsTokens,
|
||||
methods,
|
||||
}: DocContainerProps) {
|
||||
const matches = useMediaQuery('(max-width: 768px)', true, { getInitialValueInEffect: false });
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Title order={2} ml="xs" className="break-all">
|
||||
<Group>
|
||||
{generateIcon(kind)}
|
||||
{name}
|
||||
</Group>
|
||||
</Title>
|
||||
<Group>
|
||||
<Stack sx={{ flexGrow: 1 }}>
|
||||
<Title sx={{ wordBreak: 'break-all' }} order={2} ml="xs">
|
||||
<Group>
|
||||
{generateIcon(kind)}
|
||||
{name}
|
||||
</Group>
|
||||
</Title>
|
||||
|
||||
<Section title="Summary" icon={<VscListSelection />} padded dense={matches}>
|
||||
{summary ? <TSDoc node={summary} /> : <Text>No summary provided.</Text>}
|
||||
</Section>
|
||||
<Section title="Summary" icon={<VscListSelection />} padded dense={matches}>
|
||||
{summary ? <TSDoc node={summary} /> : <Text>No summary provided.</Text>}
|
||||
</Section>
|
||||
|
||||
<Box px="xs" pb="xs">
|
||||
<SyntaxHighlighter
|
||||
wrapLongLines
|
||||
language="typescript"
|
||||
style={vscDarkPlus}
|
||||
codeTagProps={{ style: { fontFamily: 'JetBrains Mono' } }}
|
||||
>
|
||||
{excerpt}
|
||||
</SyntaxHighlighter>
|
||||
</Box>
|
||||
<Box px="xs" pb="xs">
|
||||
<SyntaxHighlighter
|
||||
wrapLongLines
|
||||
language="typescript"
|
||||
style={vscDarkPlus}
|
||||
codeTagProps={{ style: { fontFamily: 'JetBrains Mono' } }}
|
||||
>
|
||||
{excerpt}
|
||||
</SyntaxHighlighter>
|
||||
</Box>
|
||||
|
||||
{extendsTokens?.length ? (
|
||||
<Group noWrap>
|
||||
<Title order={3} ml="xs">
|
||||
Extends
|
||||
</Title>
|
||||
<Text className="font-mono break-all">
|
||||
<HyperlinkedText tokens={extendsTokens} />
|
||||
</Text>
|
||||
</Group>
|
||||
) : null}
|
||||
|
||||
{implementsTokens?.length ? (
|
||||
<Group noWrap>
|
||||
<Title order={3} ml="xs">
|
||||
Implements
|
||||
</Title>
|
||||
<Text className="font-mono break-all">
|
||||
{implementsTokens.map((token, idx) => (
|
||||
<>
|
||||
<HyperlinkedText tokens={token} />
|
||||
{idx < implementsTokens.length - 1 ? ', ' : ''}
|
||||
</>
|
||||
))}
|
||||
</Text>
|
||||
</Group>
|
||||
) : null}
|
||||
|
||||
<Stack>
|
||||
{typeParams?.length ? (
|
||||
<Section title="Type Parameters" icon={<VscSymbolParameter />} padded dense={matches} defaultClosed>
|
||||
<TypeParamTable data={typeParams} />
|
||||
</Section>
|
||||
{extendsTokens?.length ? (
|
||||
<Group noWrap>
|
||||
<Title order={3} ml="xs">
|
||||
Extends
|
||||
</Title>
|
||||
<Text sx={{ wordBreak: 'break-all' }} className="font-mono">
|
||||
<HyperlinkedText tokens={extendsTokens} />
|
||||
</Text>
|
||||
</Group>
|
||||
) : null}
|
||||
<Stack>{children}</Stack>
|
||||
|
||||
{implementsTokens?.length ? (
|
||||
<Group noWrap>
|
||||
<Title order={3} ml="xs">
|
||||
Implements
|
||||
</Title>
|
||||
<Text sx={{ wordBreak: 'break-all' }} className="font-mono">
|
||||
{implementsTokens.map((token, idx) => (
|
||||
<>
|
||||
<HyperlinkedText tokens={token} />
|
||||
{idx < implementsTokens.length - 1 ? ', ' : ''}
|
||||
</>
|
||||
))}
|
||||
</Text>
|
||||
</Group>
|
||||
) : null}
|
||||
|
||||
<Stack>
|
||||
{typeParams?.length ? (
|
||||
<Section title="Type Parameters" icon={<VscSymbolParameter />} padded dense={matches} defaultClosed>
|
||||
<TypeParamTable data={typeParams} />
|
||||
</Section>
|
||||
) : null}
|
||||
<Stack>{children}</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
{kind === 'Class' && methods ? (
|
||||
<MediaQuery smallerThan="md" styles={{ display: 'none' }}>
|
||||
<Aside
|
||||
sx={{ backgroundColor: 'transparent' }}
|
||||
hiddenBreakpoint="md"
|
||||
width={{ md: 200, lg: 300 }}
|
||||
withBorder={false}
|
||||
>
|
||||
<ScrollArea p="xs">
|
||||
<TableOfContentsItems members={methods}></TableOfContentsItems>
|
||||
</ScrollArea>
|
||||
</Aside>
|
||||
</MediaQuery>
|
||||
) : null}
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,9 +34,9 @@ export function MethodItem({ data }: { data: MethodResolvable }) {
|
||||
<Badge variant="filled">Protected</Badge>
|
||||
) : null}
|
||||
{data.kind === 'Method' && method.static ? <Badge variant="filled">Static</Badge> : null}
|
||||
<Title order={4} className="font-mono break-all">{`${getShorthandName(data)}`}</Title>
|
||||
<Title sx={{ wordBreak: 'break-all' }} order={4} className="font-mono">{`${getShorthandName(data)}`}</Title>
|
||||
<Title order={4}>:</Title>
|
||||
<Title order={4} className="font-mono break-all">
|
||||
<Title sx={{ wordBreak: 'break-all' }} order={4} className="font-mono">
|
||||
<HyperlinkedText tokens={data.returnTypeTokens} />
|
||||
</Title>
|
||||
</Group>
|
||||
|
||||
@@ -17,7 +17,7 @@ export function ParameterTable({ data }: { data: ParameterDocumentation[] }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<Box className="overflow-x-auto">
|
||||
<Box sx={{ overflowX: 'auto' }}>
|
||||
<Table columns={['Name', 'Type', 'Optional', 'Description']} rows={rows} columnStyles={columnStyles} />
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -41,7 +41,7 @@ export function Section({
|
||||
const { classes } = useStyles({ opened });
|
||||
|
||||
return (
|
||||
<Box className="break-all">
|
||||
<Box sx={{ wordBreak: 'break-all' }}>
|
||||
<UnstyledButton className={classes.control} onClick={() => setOpened((o) => !o)}>
|
||||
<Group position="apart">
|
||||
<Group>
|
||||
|
||||
@@ -103,7 +103,9 @@ export function SidebarItems({
|
||||
<Link key={i} href={member.path} passHref>
|
||||
<UnstyledButton className={classes.link} component="a" onClick={() => setOpened((o) => !o)}>
|
||||
<Group>
|
||||
<Text className="line-clamp-1 text-ellipsis overflow-hidden">{member.name}</Text>
|
||||
<Text sx={{ textOverflow: 'ellipsis', overflow: 'hidden' }} className="line-clamp-1">
|
||||
{member.name}
|
||||
</Text>
|
||||
{member.overloadIndex && member.overloadIndex > 1 ? (
|
||||
<Text size="xs" color="dimmed">
|
||||
{member.overloadIndex}
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
AppShell,
|
||||
Navbar,
|
||||
MediaQuery,
|
||||
Aside,
|
||||
Header,
|
||||
Burger,
|
||||
Anchor,
|
||||
@@ -26,8 +25,6 @@ import { type PropsWithChildren, useState } from 'react';
|
||||
import { VscChevronDown, VscPackage } from 'react-icons/vsc';
|
||||
import { WiDaySunny, WiNightClear } from 'react-icons/wi';
|
||||
import { SidebarItems } from './SidebarItems';
|
||||
import { TableOfContentsItems } from './TableOfContentsItems';
|
||||
import type { DocClass } from '~/DocModel/DocClass';
|
||||
import type { DocItem } from '~/DocModel/DocItem';
|
||||
import type { findMember } from '~/util/model.server';
|
||||
import type { getMembers } from '~/util/parse.server';
|
||||
@@ -155,21 +152,6 @@ export function SidebarLayout({ packageName, data, children }: PropsWithChildren
|
||||
) : null}
|
||||
</Navbar>
|
||||
}
|
||||
aside={
|
||||
packageName && data?.member && data.member.kind === 'Class' ? (
|
||||
<MediaQuery smallerThan="sm" styles={{ display: 'none' }}>
|
||||
<Aside hiddenBreakpoint="sm" width={{ sm: 200, lg: 300 }}>
|
||||
<ScrollArea p="xs">
|
||||
<TableOfContentsItems
|
||||
members={(data.member as unknown as ReturnType<DocClass['toJSON']>).methods}
|
||||
></TableOfContentsItems>
|
||||
</ScrollArea>
|
||||
</Aside>
|
||||
</MediaQuery>
|
||||
) : (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
// footer={
|
||||
// <Footer height={60} p="md">
|
||||
// Application footer
|
||||
|
||||
@@ -38,7 +38,9 @@ export function TableOfContentsItems({
|
||||
return (
|
||||
<Box<'a'> key={key} href={`#${key}`} component="a" className={classes.link}>
|
||||
<Group>
|
||||
<Text className="line-clamp-1 text-ellipsis overflow-hidden">{member.name}</Text>
|
||||
<Text sx={{ textOverflow: 'ellipsis', overflow: 'hidden' }} className="line-clamp-1">
|
||||
{member.name}
|
||||
</Text>
|
||||
{member.overloadIndex && member.overloadIndex > 1 ? (
|
||||
<Text size="xs" color="dimmed">
|
||||
{member.overloadIndex}
|
||||
|
||||
@@ -19,7 +19,7 @@ export function TypeParamTable({ data }: { data: TypeParameterData[] }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<Box className="overflow-x-auto">
|
||||
<Box sx={{ overflowX: 'auto' }}>
|
||||
<Table
|
||||
columns={['Name', 'Constraints', 'Optional', 'Default', 'Description']}
|
||||
rows={rows}
|
||||
|
||||
@@ -13,6 +13,7 @@ export function Class({ data }: { data: ReturnType<DocClass['toJSON']> }) {
|
||||
extendsTokens={data.extendsTokens}
|
||||
implementsTokens={data.implementsTokens}
|
||||
comment={data.comment}
|
||||
methods={data.methods}
|
||||
>
|
||||
<PropertiesSection data={data.properties} />
|
||||
<MethodsSection data={data.methods} />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Alert } from '@mantine/core';
|
||||
import { Alert, Box, Title } from '@mantine/core';
|
||||
import { StandardTags } from '@microsoft/tsdoc';
|
||||
import type { ReactNode } from 'react';
|
||||
import { VscWarning } from 'react-icons/vsc';
|
||||
@@ -10,10 +10,10 @@ export interface BlockProps {
|
||||
|
||||
export function Block({ children, title }: BlockProps) {
|
||||
return (
|
||||
<div>
|
||||
<h3 className="m-0">{title}</h3>
|
||||
<Box>
|
||||
<Title order={3}>{title}</Title>
|
||||
{children}
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Anchor, Box, Text } from '@mantine/core';
|
||||
import { Anchor, Box, Code, Text } from '@mantine/core';
|
||||
import { DocNodeKind, StandardTags } from '@microsoft/tsdoc';
|
||||
import Link from 'next/link';
|
||||
import type { ReactNode } from 'react';
|
||||
@@ -61,9 +61,9 @@ export function TSDoc({ node }: { node: AnyDocNodeJSON }): JSX.Element {
|
||||
case DocNodeKind.CodeSpan: {
|
||||
const { code } = node as DocFencedCodeJSON;
|
||||
return (
|
||||
<pre key={idx} className="inline">
|
||||
<Code key={idx} sx={{ display: 'inline' }} className="text-sm font-mono">
|
||||
{code}
|
||||
</pre>
|
||||
</Code>
|
||||
);
|
||||
}
|
||||
case DocNodeKind.FencedCode: {
|
||||
|
||||
@@ -146,7 +146,7 @@ const member = (props: any) => {
|
||||
|
||||
export default function Slug(props: Partial<SidebarLayoutProps & { error?: string }>) {
|
||||
return props.error ? (
|
||||
<div className="flex max-w-full h-full bg-white dark:bg-dark">{props.error}</div>
|
||||
<Box sx={{ display: 'flex', maxWidth: '100%', height: '100%' }}>{props.error}</Box>
|
||||
) : (
|
||||
<MemberProvider member={props.data?.member}>
|
||||
<SidebarLayout {...props}>{props.data?.member ? member(props.data.member) : null}</SidebarLayout>
|
||||
|
||||
@@ -38,7 +38,7 @@ export function generatePath(items: readonly ApiItem[]) {
|
||||
const functionItem = item as ApiFunction;
|
||||
path += `${functionItem.displayName}${
|
||||
functionItem.overloadIndex && functionItem.overloadIndex > 1 ? `:${functionItem.overloadIndex}` : ''
|
||||
}:/`;
|
||||
}/`;
|
||||
break;
|
||||
default:
|
||||
path += `${item.displayName}/`;
|
||||
|
||||
Reference in New Issue
Block a user