import type { getMembers, ApiClassJSON, ApiInterfaceJSON } from '@discordjs/api-extractor-utils'; import { Button } from 'ariakit/button'; import { Menu, MenuButton, MenuItem, useMenuState } from 'ariakit/menu'; import Image from 'next/image'; import Link from 'next/link'; 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 { FiCommand } from 'react-icons/fi'; import { VscChevronDown, VscColorMode, VscGithubInverted, VscMenu, VscPackage, VscSearch, VscVersions, } from 'react-icons/vsc'; import { useMedia /* useLockBodyScroll */ } from 'react-use'; import useSWR from 'swr'; import vercelLogo from '../assets/powered-by-vercel.svg'; import { CmdKDialog } from './CmdK'; import { SidebarItems } from './SidebarItems'; import { useCmdK } from '~/contexts/cmdK'; import { PACKAGES } from '~/util/constants'; import { fetcher } from '~/util/fetcher'; import type { findMember } from '~/util/model.server'; export interface SidebarLayoutProps { asPath: string; branchName: string; data: { description: string; member?: ReturnType; members: ReturnType; source: MDXRemoteSerializeResult; }; packageName: string; } 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, asPath, children, }: PropsWithChildren) { const dialog = useCmdK(); 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]); const asPathWithoutContainerKey = useMemo(() => asPath?.split(':')[0] ?? '', [asPath]); const packageMenuItems = useMemo( () => [ packageMenu.setOpen(false)} state={packageMenu} > discord.js , ...PACKAGES.map((pkg) => ( packageMenu.setOpen(false)} state={packageMenu} > {pkg} )), ], // eslint-disable-next-line react-hooks/exhaustive-deps [], ); const versionMenuItems = useMemo( () => versions ?.map((item) => ( versionMenu.setOpen(false)} state={versionMenu} > {item} )) .reverse() ?? [], // eslint-disable-next-line react-hooks/exhaustive-deps [versions, packageName], ); const pathElements = useMemo( () => asPathWithoutContainerKey .split('/') .slice(1) .map((path, idx, original) => ( {path} )), [asPathWithoutContainerKey], ); const breadcrumbs = useMemo( () => pathElements.flatMap((el, idx, array) => { if (idx === 0) { return (
/
{el}
/
); } if (idx !== array.length - 1) { return ( {el}
/
); } return {el}; }), [pathElements], ); return ( <>
{breadcrumbs}
); }