diff --git a/packages/api-extractor-utils/src/ApiNodeJSONEncoder.ts b/packages/api-extractor-utils/src/ApiNodeJSONEncoder.ts index 4f485fded9b3..ca1c64f0ac37 100644 --- a/packages/api-extractor-utils/src/ApiNodeJSONEncoder.ts +++ b/packages/api-extractor-utils/src/ApiNodeJSONEncoder.ts @@ -82,12 +82,14 @@ export interface ApiMethodSignatureJSON ApiTypeParameterListJSON, ApiParameterListJSON, ApiInheritableJSON { + mergedSiblings: ApiMethodSignatureJSON[]; optional: boolean; overloadIndex: number; returnTypeTokens: TokenDocumentation[]; } export interface ApiMethodJSON extends ApiMethodSignatureJSON { + mergedSiblings: ApiMethodJSON[]; protected: boolean; static: boolean; } @@ -133,6 +135,7 @@ export interface ApiVariableJSON extends ApiItemJSON { } export interface ApiFunctionJSON extends ApiItemJSON, ApiTypeParameterListJSON, ApiParameterListJSON { + mergedSiblings: ApiFunctionJSON[]; overloadIndex: number; returnTypeTokens: TokenDocumentation[]; } @@ -255,7 +258,7 @@ export class ApiNodeJSONEncoder { }; } - public static encodeFunction(model: ApiModel, item: FunctionLike, version: string): ApiFunctionJSON { + public static encodeFunctionLike(model: ApiModel, item: FunctionLike, version: string) { return { ...this.encodeItem(model, item, version), ...this.encodeParameterList(model, item, version), @@ -265,16 +268,31 @@ export class ApiNodeJSONEncoder { }; } + public static encodeFunction(model: ApiModel, item: FunctionLike, version: string, nested = false): ApiFunctionJSON { + return { + ...this.encodeFunctionLike(model, item, version), + mergedSiblings: nested + ? [] + : item.getMergedSiblings().map((item) => this.encodeFunction(model, item as ApiFunction, version, true)), + }; + } + public static encodeMethodSignature( model: ApiModel, item: ApiMethodSignature, parent: ApiItemContainerMixin, version: string, + nested = false, ): ApiMethodSignatureJSON { return { - ...this.encodeFunction(model, item, version), + ...this.encodeFunctionLike(model, item, version), ...this.encodeInheritanceData(item, parent, version), optional: item.isOptional, + mergedSiblings: nested + ? [] + : item + .getMergedSiblings() + .map((item) => this.encodeMethodSignature(model, item as ApiMethodSignature, parent, version, true)), }; } @@ -283,11 +301,15 @@ export class ApiNodeJSONEncoder { item: ApiMethod, parent: ApiItemContainerMixin, version: string, + nested = false, ): ApiMethodJSON { return { ...this.encodeMethodSignature(model, item, parent, version), static: item.isStatic, protected: item.isProtected, + mergedSiblings: nested + ? [] + : item.getMergedSiblings().map((item) => this.encodeMethod(model, item as ApiMethod, parent, version, true)), }; } diff --git a/packages/website/src/components/DocContainer.tsx b/packages/website/src/components/DocContainer.tsx index 92d18b8fa7d5..8335873a326e 100644 --- a/packages/website/src/components/DocContainer.tsx +++ b/packages/website/src/components/DocContainer.tsx @@ -5,6 +5,7 @@ import type { ApiClassJSON, ApiInterfaceJSON, } from '@discordjs/api-extractor-utils'; +import type { ReactNode } from 'react'; import { Fragment, type PropsWithChildren } from 'react'; import { Scrollbars } from 'react-custom-scrollbars-2'; import { @@ -32,6 +33,7 @@ type DocContainerProps = PropsWithChildren<{ methods?: ApiClassJSON['methods'] | ApiInterfaceJSON['methods'] | null; name: string; properties?: ApiClassJSON['properties'] | ApiInterfaceJSON['properties'] | null; + subHeading?: ReactNode; summary?: ApiItemJSON['summary']; typeParams?: TypeParameterData[]; }>; @@ -60,6 +62,7 @@ export function DocContainer({ implementsTokens, methods, properties, + subHeading, }: DocContainerProps) { const matches = useMedia('(max-width: 768px)', true); @@ -71,6 +74,8 @@ export function DocContainer({ {name} + {subHeading} +
} padded dense={matches}> {summary ? : No summary provided.}
diff --git a/packages/website/src/components/MethodItem.tsx b/packages/website/src/components/MethodItem.tsx index 6cdb6f1c04d8..2ce66e55a6cb 100644 --- a/packages/website/src/components/MethodItem.tsx +++ b/packages/website/src/components/MethodItem.tsx @@ -1,6 +1,8 @@ import type { ApiMethodJSON, ApiMethodSignatureJSON } from '@discordjs/api-extractor-utils'; -import { useCallback, useMemo } from 'react'; +import { Menu, MenuButton, MenuItem, useMenuState } from 'ariakit'; +import { useCallback, useMemo, useState } from 'react'; import { FiLink } from 'react-icons/fi'; +import { VscChevronDown, VscVersions } from 'react-icons/vsc'; import { HyperlinkedText } from './HyperlinkedText'; import { InheritanceText } from './InheritanceText'; import { ParameterTable } from './ParameterTable'; @@ -8,6 +10,10 @@ import { TSDoc } from './tsdoc/TSDoc'; export function MethodItem({ data }: { data: ApiMethodJSON | ApiMethodSignatureJSON }) { const method = data as ApiMethodJSON; + const [overloadIndex, setOverloadIndex] = useState(1); + const overloadedData = method.mergedSiblings[overloadIndex - 1]!; + const menu = useMenuState({ gutter: 8, sameWidth: true, fitViewport: true }); + const key = useMemo( () => `${data.name}${data.overloadIndex && data.overloadIndex > 1 ? `:${data.overloadIndex}` : ''}`, [data.name, data.overloadIndex], @@ -54,7 +60,7 @@ export function MethodItem({ data }: { data: ApiMethodJSON | ApiMethodSignatureJ
) : null}
-

{getShorthandName(data)}

+

{getShorthandName(overloadedData)}

:

@@ -62,13 +68,45 @@ export function MethodItem({ data }: { data: ApiMethodJSON | ApiMethodSignatureJ

+ {data.mergedSiblings.length > 1 ? ( +
+ +
+ +
+ {`Overload ${overloadIndex}`} + {` of ${data.mergedSiblings.length}`} +
+ +
+
+ + {data.mergedSiblings.map((_, idx) => ( + setOverloadIndex(idx + 1)} + >{`Overload ${idx + 1}`} + ))} + +
+ ) : null} {data.summary || data.parameters.length ? (
- {data.deprecated ? : null} - {data.summary ? : null} - {data.remarks ? : null} - {data.comment ? : null} - {data.parameters.length ? : null} + {overloadedData.deprecated ? : null} + {overloadedData.summary ?? data.summary ? : null} + {overloadedData.remarks ? : null} + {overloadedData.comment ? : null} + {overloadedData.parameters.length ? : null} {data.inheritanceData ? : null}
) : null} diff --git a/packages/website/src/components/MethodList.tsx b/packages/website/src/components/MethodList.tsx index 56b4a45f3624..478554bf700a 100644 --- a/packages/website/src/components/MethodList.tsx +++ b/packages/website/src/components/MethodList.tsx @@ -5,14 +5,16 @@ import { MethodItem } from './MethodItem'; export function MethodList({ data }: { data: (ApiMethodJSON | ApiMethodSignatureJSON)[] }) { const methodItems = useMemo( () => - data.map((method) => ( - 1 ? `:${method.overloadIndex}` : ''}`} - > - -
- - )), + data + .filter((method) => method.overloadIndex <= 1) + .map((method) => ( + 1 ? `:${method.overloadIndex}` : ''}`} + > + +
+ + )), [data], ); diff --git a/packages/website/src/components/SidebarLayout.tsx b/packages/website/src/components/SidebarLayout.tsx index 5f2127259e4a..a45e04fd6e4f 100644 --- a/packages/website/src/components/SidebarLayout.tsx +++ b/packages/website/src/components/SidebarLayout.tsx @@ -1,4 +1,4 @@ -import type { getMembers, ApiItemJSON } from '@discordjs/api-extractor-utils'; +import type { getMembers, ApiItemJSON, ApiClassJSON, ApiInterfaceJSON } from '@discordjs/api-extractor-utils'; import { Button } from 'ariakit/button'; import { Menu, MenuButton, MenuItem, useMenuState } from 'ariakit/menu'; import Image from 'next/future/image'; @@ -248,7 +248,11 @@ export function SidebarLayout({
@@ -258,7 +262,11 @@ export function SidebarLayout({