feat: readme if no member is selected

This commit is contained in:
iCrawl
2022-08-22 20:51:43 +02:00
parent 24c128d649
commit d297fb0b69
5 changed files with 1713 additions and 62 deletions

View File

@@ -60,10 +60,16 @@
"@microsoft/tsdoc-config": "0.16.1", "@microsoft/tsdoc-config": "0.16.1",
"@vscode/codicons": "^0.0.32", "@vscode/codicons": "^0.0.32",
"next": "^12.2.5", "next": "^12.2.5",
"next-mdx-remote": "^4.1.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-icons": "^4.4.0", "react-icons": "^4.4.0",
"react-syntax-highlighter": "^15.5.0", "react-syntax-highlighter": "^15.5.0",
"rehype-highlight": "^5.0.2",
"rehype-ignore": "^1.0.1",
"rehype-raw": "^6.1.1",
"rehype-slug": "^5.0.1",
"remark-gfm": "^3.0.1",
"sharp": "^0.30.7" "sharp": "^0.30.7"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -19,6 +19,7 @@ import {
useMantineColorScheme, useMantineColorScheme,
} from '@mantine/core'; } from '@mantine/core';
import { NextLink } from '@mantine/next'; import { NextLink } from '@mantine/next';
import type { MDXRemoteSerializeResult } from 'next-mdx-remote';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { type PropsWithChildren, useState } from 'react'; import { type PropsWithChildren, useState } from 'react';
@@ -34,6 +35,7 @@ export interface SidebarLayoutProps {
data: { data: {
members: ReturnType<typeof getMembers>; members: ReturnType<typeof getMembers>;
member: ReturnType<typeof findMember>; member: ReturnType<typeof findMember>;
source: MDXRemoteSerializeResult;
}; };
selectedMember?: ApiItemJSON | undefined; selectedMember?: ApiItemJSON | undefined;
@@ -161,7 +163,7 @@ export function SidebarLayout({ packageName, data, children }: PropsWithChildren
header={ header={
<Header height={70} p="md"> <Header height={70} p="md">
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', height: '100%' }}> <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', height: '100%' }}>
<div> <Box>
<MediaQuery largerThan="sm" styles={{ display: 'none' }}> <MediaQuery largerThan="sm" styles={{ display: 'none' }}>
<Burger <Burger
opened={opened} opened={opened}
@@ -175,7 +177,7 @@ export function SidebarLayout({ packageName, data, children }: PropsWithChildren
<MediaQuery smallerThan="sm" styles={{ display: 'none' }}> <MediaQuery smallerThan="sm" styles={{ display: 'none' }}>
<Breadcrumbs>{breadcrumbs}</Breadcrumbs> <Breadcrumbs>{breadcrumbs}</Breadcrumbs>
</MediaQuery> </MediaQuery>
</div> </Box>
<ActionIcon <ActionIcon
variant="outline" variant="outline"
color={dark ? 'yellow' : 'blurple'} color={dark ? 'yellow' : 'blurple'}

View File

@@ -2,13 +2,21 @@ import { readFile } from 'node:fs/promises';
import { join } from 'node:path'; import { join } from 'node:path';
import { Box } from '@mantine/core'; import { Box } from '@mantine/core';
import { ApiFunction, ApiPackage } from '@microsoft/api-extractor-model'; import { ApiFunction, ApiPackage } from '@microsoft/api-extractor-model';
import { MDXRemote } from 'next-mdx-remote';
import { serialize } from 'next-mdx-remote/serialize';
import Head from 'next/head'; import Head from 'next/head';
import type { GetStaticPaths, GetStaticProps } from 'next/types'; import type { GetStaticPaths, GetStaticProps } from 'next/types';
import rehypeHighlight from 'rehype-highlight';
import rehypeIgnore from 'rehype-ignore';
import rehypeRaw from 'rehype-raw';
import rehypeSlug from 'rehype-slug';
import remarkGfm from 'remark-gfm';
import type { import type {
ApiClassJSON, ApiClassJSON,
ApiEnumJSON, ApiEnumJSON,
ApiFunctionJSON, ApiFunctionJSON,
ApiInterfaceJSON, ApiInterfaceJSON,
ApiItemJSON,
ApiTypeAliasJSON, ApiTypeAliasJSON,
ApiVariableJSON, ApiVariableJSON,
} from '~/DocModel/ApiNodeJSONEncoder'; } from '~/DocModel/ApiNodeJSONEncoder';
@@ -121,6 +129,17 @@ export const getStaticProps: GetStaticProps = async ({ params }) => {
const [memberName, overloadIndex] = member.split(':') as [string, string | undefined]; const [memberName, overloadIndex] = member.split(':') as [string, string | undefined];
try { try {
const readme = await readFile(join(__dirname, '..', '..', '..', '..', '..', packageName, 'README.md'), 'utf-8');
const mdxSource = await serialize(readme, {
mdxOptions: {
remarkPlugins: [remarkGfm],
remarkRehypeOptions: { allowDangerousHtml: true },
rehypePlugins: [rehypeRaw, rehypeIgnore, rehypeSlug, [rehypeHighlight, { ignoreMissing: true }]],
format: 'md',
},
});
let data; let data;
if (process.env.NEXT_PUBLIC_LOCAL_DEV) { if (process.env.NEXT_PUBLIC_LOCAL_DEV) {
const res = await readFile( const res = await readFile(
@@ -150,6 +169,7 @@ export const getStaticProps: GetStaticProps = async ({ params }) => {
members: pkg ? getMembers(pkg, branchName) : [], members: pkg ? getMembers(pkg, branchName) : [],
member: member:
memberName && containerKey ? findMemberByKey(model, packageName, containerKey, branchName) ?? null : null, memberName && containerKey ? findMemberByKey(model, packageName, containerKey, branchName) ?? null : null,
source: mdxSource,
}, },
}, },
}; };
@@ -162,9 +182,8 @@ export const getStaticProps: GetStaticProps = async ({ params }) => {
} }
}; };
const member = (props: any) => { const member = (props?: ApiItemJSON | undefined) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access switch (props?.kind) {
switch (props.kind) {
case 'Class': case 'Class':
return <Class data={props as ApiClassJSON} />; return <Class data={props as ApiClassJSON} />;
case 'Function': case 'Function':
@@ -195,6 +214,10 @@ export default function Slug(props: Partial<SidebarLayoutProps & { error?: strin
</Head> </Head>
{member(props.data.member)} {member(props.data.member)}
</> </>
) : props.data?.source ? (
<Box px="xl">
<MDXRemote {...props.data.source} />
</Box>
) : null} ) : null}
</SidebarLayout> </SidebarLayout>
</MemberProvider> </MemberProvider>

View File

@@ -1,4 +1,4 @@
import { createStyles, Container, Title, Button, Group, Text, Center } from '@mantine/core'; import { createStyles, Container, Title, Button, Group, Text, Center, Box } from '@mantine/core';
import Image from 'next/future/image'; import Image from 'next/future/image';
import Link from 'next/link'; import Link from 'next/link';
import codeSample from '../assets/code-sample.png'; import codeSample from '../assets/code-sample.png';
@@ -67,50 +67,49 @@ const useStyles = createStyles((theme) => ({
export default function IndexRoute() { export default function IndexRoute() {
const { classes } = useStyles(); const { classes } = useStyles();
return (
<div>
<Container size="lg">
<div className={classes.inner}>
<div className={classes.content}>
<Title className={classes.title}>
The <span className={classes.highlight}>most popular</span> way to build Discord <br /> bots.
</Title>
<Text color="dimmed" mt="md">
discord.js is a powerful Node.js module that allows you to interact with the Discord API very easily. It
takes a much more object-oriented approach than most other JS Discord libraries, making your bot&apos;s
code significantly tidier and easier to comprehend.
</Text>
<Group mt={30}> return (
<Link href="/docs" passHref> <Container size="lg">
<Button component="a" radius="xl" size="md" className={classes.control}> <Box className={classes.inner}>
Docs <Box className={classes.content}>
</Button> <Title className={classes.title}>
</Link> The <span className={classes.highlight}>most popular</span> way to build Discord <br /> bots.
<Link href="https://discordjs.guide" passHref> </Title>
<Button component="a" variant="default" radius="xl" size="md" className={classes.control}> <Text color="dimmed" mt="md">
Guide discord.js is a powerful Node.js module that allows you to interact with the Discord API very easily. It
</Button> takes a much more object-oriented approach than most other JS Discord libraries, making your bot&apos;s code
</Link> significantly tidier and easier to comprehend.
</Group> </Text>
</div>
<Image src={codeSample} className={classes.image} /> <Group mt={30}>
</div> <Link href="/docs" passHref>
<Center> <Button component="a" radius="xl" size="md" className={classes.control}>
<Link href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss" passHref> Docs
<a title="Vercel"> </Button>
<Image </Link>
src="/powered-by-vercel.svg" <Link href="https://discordjs.guide" passHref>
alt="Vercel" <Button component="a" variant="default" radius="xl" size="md" className={classes.control}>
width={0} Guide
height={0} </Button>
style={{ height: '100%', width: '100%', maxWidth: 250 }} </Link>
className={classes.vercel} </Group>
/> </Box>
</a> <Image src={codeSample} className={classes.image} />
</Link> </Box>
</Center> <Center>
</Container> <Link href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss" passHref>
</div> <a title="Vercel">
<Image
src="/powered-by-vercel.svg"
alt="Vercel"
width={0}
height={0}
style={{ height: '100%', width: '100%', maxWidth: 250 }}
className={classes.vercel}
/>
</a>
</Link>
</Center>
</Container>
); );
} }

1645
yarn.lock

File diff suppressed because it is too large Load Diff