import type { getMembers, ApiItemJSON } from '@discordjs/api-extractor-utils'; import { Button } from 'ariakit/button'; import { Menu, MenuButton, MenuItem, useMenuState } from 'ariakit/menu'; import Image from 'next/future/image'; import Link from 'next/link'; import { useRouter } from 'next/router'; import type { MDXRemoteSerializeResult } from 'next-mdx-remote'; import { useTheme } from 'next-themes'; import { type PropsWithChildren, useState, useEffect, useMemo, Fragment } from 'react'; import { Scrollbars } from 'react-custom-scrollbars-2'; import { VscChevronDown, VscColorMode, VscGithubInverted, VscMenu, VscPackage, VscVersions } from 'react-icons/vsc'; import { useMedia /* useLockBodyScroll */ } from 'react-use'; import useSWR from 'swr'; import vercelLogo from '../assets/powered-by-vercel.svg'; import { SidebarItems } from './SidebarItems'; import { PACKAGES } from '~/util/constants'; import type { findMember } from '~/util/model.server'; const fetcher = async (url: string) => { const res = await fetch(url); return res.json(); }; export interface SidebarLayoutProps { branchName: string; data: { member: ReturnType; members: ReturnType; searchIndex: any[]; source: MDXRemoteSerializeResult; }; packageName: string; selectedMember?: ApiItemJSON | undefined; } export type Members = SidebarLayoutProps['data']['members']; export interface GroupedMembers { Classes: Members; Enums: Members; Functions: Members; Interfaces: Members; Types: Members; Variables: Members; } export function SidebarLayout({ packageName, branchName, data, children, }: PropsWithChildren>) { const router = useRouter(); const [asPathWithoutQueryAndAnchor, setAsPathWithoutQueryAndAnchor] = useState(''); const { data: versions } = useSWR(`https://docs.discordjs.dev/api/info?package=${packageName}`, fetcher); const { resolvedTheme, setTheme } = useTheme(); const toggleTheme = () => setTheme(resolvedTheme === 'light' ? 'dark' : 'light'); const matches = useMedia('(min-width: 992px)', false); const [opened, setOpened] = useState(false); const packageMenu = useMenuState({ gutter: 8, sameWidth: true, fitViewport: true }); const versionMenu = useMenuState({ gutter: 8, sameWidth: true, fitViewport: true }); // useLockBodyScroll(opened); useEffect(() => { if (matches) { setOpened(false); } }, [matches]); useEffect(() => { setAsPathWithoutQueryAndAnchor(router.asPath.split('?')[0]?.split('#')[0]?.split(':')[0] ?? ''); }, [router.asPath]); const packageMenuItems = useMemo( () => [ packageMenu.setOpen(false)} > discord.js , ...PACKAGES.map((pkg) => ( packageMenu.setOpen(false)} > {pkg} )), ], // eslint-disable-next-line react-hooks/exhaustive-deps [], ); const versionMenuItems = useMemo( () => versions ?.map((item) => ( versionMenu.setOpen(false)} > {item} )) .reverse() ?? [], // eslint-disable-next-line react-hooks/exhaustive-deps [versions, packageName], ); const pathElements = useMemo( () => asPathWithoutQueryAndAnchor.split('/').map((path, idx, original) => ( {path} )), [asPathWithoutQueryAndAnchor], ); const breadcrumbs = useMemo( () => pathElements.flatMap((el, idx, array) => { if (idx !== array.length - 1) { return ( {el}
/
); } return {el}; }), [pathElements], ); return ( <>
{breadcrumbs}
); }