mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-17 03:53:29 +01:00
feat(website): group items by symbol kind (#8360)
* feat(website): group items by symbol kind * chore: make requested changes * chore: fix darkmode colors * chore: make requested changes * Update packages/website/src/components/ListSidebar.tsx Co-authored-by: Almeida <almeidx@pm.me> Co-authored-by: Almeida <almeidx@pm.me>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import Link from 'next/link';
|
|
||||||
import { FiMenu } from 'react-icons/fi';
|
import { FiMenu } from 'react-icons/fi';
|
||||||
import { VscPackage } from 'react-icons/vsc';
|
import { VscPackage } from 'react-icons/vsc';
|
||||||
|
import { ListSidebar } from './ListSidebar';
|
||||||
import type { getMembers } from '~/util/parse.server';
|
import type { getMembers } from '~/util/parse.server';
|
||||||
|
|
||||||
export interface ItemListProps {
|
export interface ItemListProps {
|
||||||
@@ -19,7 +19,7 @@ function onMenuClick() {
|
|||||||
|
|
||||||
export function ItemSidebar({ packageName, data, selectedMember }: ItemListProps) {
|
export function ItemSidebar({ packageName, data, selectedMember }: ItemListProps) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col max-h-full min-w-[270px] lg:border-r-solid border-0.5 border-gray">
|
<div className="flex flex-col max-h-full grow min-w-[270px] lg:border-r-solid border-0.5 border-gray">
|
||||||
<div className="border-b-0.5 border-gray py-2">
|
<div className="border-b-0.5 border-gray py-2">
|
||||||
<h2 className="flex gap-2 items-center m-0 px-2 dark:text-white">
|
<h2 className="flex gap-2 items-center m-0 px-2 dark:text-white">
|
||||||
<VscPackage />
|
<VscPackage />
|
||||||
@@ -30,21 +30,7 @@ export function ItemSidebar({ packageName, data, selectedMember }: ItemListProps
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="hidden lg:block lg:min-h-full overflow-y-scroll overflow-x-clip p-7 space-y-2">
|
<div className="hidden lg:block lg:min-h-full overflow-y-scroll overflow-x-clip p-7 space-y-2">
|
||||||
{data.members.map((member, i) => (
|
<ListSidebar members={data.members} title="test" selectedMember={selectedMember} />
|
||||||
<div key={i} className="flex items-center no-underline break-all text-blue-500 dark:text-blue-300">
|
|
||||||
<Link href={member.path}>
|
|
||||||
<a
|
|
||||||
className={`no-underline m-0 ${
|
|
||||||
selectedMember === member.name
|
|
||||||
? 'text-blue-500 dark:text-blue-300 font-semibold'
|
|
||||||
: 'text-black dark:text-white hover:text-dark-100 dark:hover:text-gray-300 hover:font-semibold'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{member.name}
|
|
||||||
</a>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
132
packages/website/src/components/ListSidebar.tsx
Normal file
132
packages/website/src/components/ListSidebar.tsx
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { VscChevronDown, VscChevronRight } from 'react-icons/vsc';
|
||||||
|
import type { ItemListProps } from './ItemSidebar';
|
||||||
|
|
||||||
|
export type Members = ItemListProps['data']['members'];
|
||||||
|
|
||||||
|
export interface ListSidebarSectionProps {
|
||||||
|
members: Members;
|
||||||
|
selectedMember?: string | undefined;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GroupedMembers {
|
||||||
|
Classes: Members;
|
||||||
|
Functions: Members;
|
||||||
|
Enums: Members;
|
||||||
|
Interfaces: Members;
|
||||||
|
Types: Members;
|
||||||
|
Variables: Members;
|
||||||
|
}
|
||||||
|
|
||||||
|
function groupMembers(members: Members): GroupedMembers {
|
||||||
|
const Classes: Members = [];
|
||||||
|
const Enums: Members = [];
|
||||||
|
const Interfaces: Members = [];
|
||||||
|
const Types: Members = [];
|
||||||
|
const Variables: Members = [];
|
||||||
|
const Functions: Members = [];
|
||||||
|
|
||||||
|
for (const member of members) {
|
||||||
|
switch (member.kind) {
|
||||||
|
case 'Class':
|
||||||
|
Classes.push(member);
|
||||||
|
break;
|
||||||
|
case 'Enum':
|
||||||
|
Enums.push(member);
|
||||||
|
break;
|
||||||
|
case 'Interface':
|
||||||
|
Interfaces.push(member);
|
||||||
|
break;
|
||||||
|
case 'TypeAlias':
|
||||||
|
Types.push(member);
|
||||||
|
break;
|
||||||
|
case 'Variable':
|
||||||
|
Variables.push(member);
|
||||||
|
break;
|
||||||
|
case 'Function':
|
||||||
|
Functions.push(member);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { Classes, Functions, Enums, Interfaces, Types, Variables };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ListSidebarSection({ members, selectedMember, title }: ListSidebarSectionProps) {
|
||||||
|
const [showList, setShowList] = useState(true);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3
|
||||||
|
className="flex items-center dark:text-white m-0 text-sm font-semibold gap-2"
|
||||||
|
onClick={() => setShowList(!showList)}
|
||||||
|
>
|
||||||
|
{showList ? <VscChevronDown size={20} /> : <VscChevronRight size={20} />}
|
||||||
|
{title}
|
||||||
|
</h3>
|
||||||
|
<AnimatePresence exitBeforeEnter initial={false}>
|
||||||
|
{showList ? (
|
||||||
|
<motion.div
|
||||||
|
className="ml-7 mt-2 space-y-3"
|
||||||
|
transition={{ duration: 0.5, ease: [0.04, 0.62, 0.23, 0.98] }}
|
||||||
|
key="content"
|
||||||
|
initial="collapsed"
|
||||||
|
animate="open"
|
||||||
|
exit="collapsed"
|
||||||
|
variants={{
|
||||||
|
open: {
|
||||||
|
opacity: 1,
|
||||||
|
height: 'auto',
|
||||||
|
},
|
||||||
|
collapsed: {
|
||||||
|
opacity: 0,
|
||||||
|
height: 0,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{members.map((member, i) => (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
className="flex gap-2 whitespace-pre-wrap no-underline break-all text-blue-500 dark:text-blue-300"
|
||||||
|
>
|
||||||
|
<Link href={member.path}>
|
||||||
|
<a
|
||||||
|
className={`no-underline m-0 text-sm ${
|
||||||
|
selectedMember === member.name
|
||||||
|
? 'text-blue-500 dark:text-blue-300 font-semibold'
|
||||||
|
: 'text-gray-500 dark:text-gray-300 hover:text-dark-100 dark:hover:text-white'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{member.name}
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
) : null}
|
||||||
|
</AnimatePresence>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ListSidebar({ members, selectedMember }: ListSidebarSectionProps) {
|
||||||
|
const groupItems = groupMembers(members);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-2">
|
||||||
|
{Object.keys(groupItems).map((group, i) => (
|
||||||
|
<ListSidebarSection
|
||||||
|
key={i}
|
||||||
|
members={groupItems[group as keyof GroupedMembers]}
|
||||||
|
selectedMember={selectedMember}
|
||||||
|
title={group}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ export function SidebarLayout({
|
|||||||
}: PropsWithChildren<Partial<ItemListProps & { data: { member: ReturnType<typeof findMember> } }>>) {
|
}: PropsWithChildren<Partial<ItemListProps & { data: { member: ReturnType<typeof findMember> } }>>) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col lg:flex-row overflow-hidden max-w-full h-full max-h-full bg-white dark:bg-dark">
|
<div className="flex flex-col lg:flex-row overflow-hidden max-w-full h-full max-h-full bg-white dark:bg-dark">
|
||||||
<div className="w-full lg:max-w-1/4 lg:min-w-1/4">
|
<div className="w-full lg:max-w-[370px] lg:min-w-[370px]">
|
||||||
{packageName && data ? (
|
{packageName && data ? (
|
||||||
<ItemSidebar packageName={packageName} data={data} selectedMember={data.member?.name} />
|
<ItemSidebar packageName={packageName} data={data} selectedMember={data.member?.name} />
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export function generateIcon(kind: string, className?: string) {
|
|||||||
const icons = {
|
const icons = {
|
||||||
Class: <VscSymbolClass className={className} />,
|
Class: <VscSymbolClass className={className} />,
|
||||||
Method: <VscSymbolMethod className={className} />,
|
Method: <VscSymbolMethod className={className} />,
|
||||||
Function: <VscSymbolMethod color="purple" className={className} />,
|
Function: <VscSymbolMethod className={className} />,
|
||||||
Enum: <VscSymbolEnum className={className} />,
|
Enum: <VscSymbolEnum className={className} />,
|
||||||
Interface: <VscSymbolInterface className={className} />,
|
Interface: <VscSymbolInterface className={className} />,
|
||||||
TypeAlias: <VscSymbolVariable className={className} />,
|
TypeAlias: <VscSymbolVariable className={className} />,
|
||||||
|
|||||||
Reference in New Issue
Block a user