feat(website): show inherited members (#8526)

* feat(website): show inherited members

* fix: use passHref
This commit is contained in:
Suneet Tipirneni
2022-08-19 12:22:22 -04:00
committed by GitHub
parent e475b63f25
commit 47f2990b89
9 changed files with 104 additions and 15 deletions

View File

@@ -29,14 +29,29 @@ export class DocClass extends TypeParameterMixin(DocItem<ApiClass>) {
excerpt.excerpt.spannedTokens.map((token) => genToken(this.model, token)), excerpt.excerpt.spannedTokens.map((token) => genToken(this.model, token)),
); );
for (const member of item.members) { for (const member of item.findMembersWithInheritance().items) {
switch (member.kind) { switch (member.kind) {
case ApiItemKind.Method: case ApiItemKind.Method: {
this.methods.push(new DocMethod(this.model, member as ApiMethod)); const method = member as ApiMethod;
if (method.parent?.containerKey !== this.containerKey) {
this.methods.push(new DocMethod(this.model, method, true));
break;
}
this.methods.push(new DocMethod(this.model, method));
break; break;
case ApiItemKind.Property: }
this.properties.push(new DocProperty(this.model, member as ApiPropertyItem)); case ApiItemKind.Property: {
const property = member as ApiPropertyItem;
if (property.parent?.containerKey !== this.containerKey) {
this.properties.push(new DocProperty(this.model, property, true));
break;
}
this.properties.push(new DocProperty(this.model, property));
break; break;
}
default: default:
break; break;
} }

View File

@@ -23,14 +23,29 @@ export class DocInterface extends TypeParameterMixin(DocItem<ApiInterface>) {
excerpt.excerpt.spannedTokens.map((token) => genToken(this.model, token)), excerpt.excerpt.spannedTokens.map((token) => genToken(this.model, token)),
); );
for (const member of item.members) { for (const member of item.findMembersWithInheritance().items) {
switch (member.kind) { switch (member.kind) {
case ApiItemKind.MethodSignature: case ApiItemKind.MethodSignature: {
this.methods.push(new DocMethodSignature(this.model, member as ApiMethodSignature)); const method = member as ApiMethodSignature;
if (method.parent?.containerKey !== this.containerKey) {
this.methods.push(new DocMethodSignature(this.model, method, true));
break;
}
this.methods.push(new DocMethodSignature(this.model, method));
break; break;
case ApiItemKind.PropertySignature: }
this.properties.push(new DocProperty(this.model, member as ApiPropertySignature)); case ApiItemKind.PropertySignature: {
const property = member as ApiPropertySignature;
if (property.parent?.containerKey !== this.containerKey) {
this.properties.push(new DocProperty(this.model, property, true));
break;
}
this.properties.push(new DocProperty(this.model, property));
break; break;
}
default: default:
break; break;
} }

View File

@@ -1,17 +1,31 @@
import type { ApiMethod, ApiModel } from '@microsoft/api-extractor-model'; import type { ApiMethod, ApiModel } from '@microsoft/api-extractor-model';
import { DocFunction } from './DocFunction'; import { DocFunction } from './DocFunction';
import { Visibility } from './Visibility'; import { Visibility } from './Visibility';
import { generatePath } from '~/util/parse.server';
export interface InheritanceData {
parentName: string;
path: string;
}
export class DocMethod extends DocFunction { export class DocMethod extends DocFunction {
public readonly static: boolean; public readonly static: boolean;
public readonly optional: boolean; public readonly optional: boolean;
public readonly visibility: Visibility; public readonly visibility: Visibility;
public readonly inheritanceData: InheritanceData | null;
public constructor(model: ApiModel, item: ApiMethod) { public constructor(model: ApiModel, item: ApiMethod, inherited = false) {
super(model, item); super(model, item);
this.static = item.isStatic; this.static = item.isStatic;
this.optional = item.isOptional; this.optional = item.isOptional;
this.visibility = item.isProtected ? Visibility.Protected : Visibility.Public; this.visibility = item.isProtected ? Visibility.Protected : Visibility.Public;
this.inheritanceData =
inherited && item.parent
? {
parentName: item.parent.displayName,
path: generatePath(item.parent.getHierarchy()),
}
: null;
} }
public override toJSON() { public override toJSON() {
@@ -20,6 +34,7 @@ export class DocMethod extends DocFunction {
static: this.static, static: this.static,
optional: this.optional, optional: this.optional,
visibility: this.visibility, visibility: this.visibility,
inheritanceData: this.inheritanceData,
}; };
} }
} }

View File

@@ -1,18 +1,29 @@
import type { ApiMethodSignature, ApiModel } from '@microsoft/api-extractor-model'; import type { ApiMethodSignature, ApiModel } from '@microsoft/api-extractor-model';
import { DocFunction } from './DocFunction'; import { DocFunction } from './DocFunction';
import type { InheritanceData } from './DocMethod';
import { generatePath } from '~/util/parse.server';
export class DocMethodSignature extends DocFunction { export class DocMethodSignature extends DocFunction {
public readonly optional: boolean; public readonly optional: boolean;
public readonly inheritanceData: InheritanceData | null;
public constructor(model: ApiModel, item: ApiMethodSignature) { public constructor(model: ApiModel, item: ApiMethodSignature, inherited = false) {
super(model, item); super(model, item);
this.optional = item.isOptional; this.optional = item.isOptional;
this.inheritanceData =
inherited && item.parent
? {
parentName: item.parent.displayName,
path: generatePath(item.parent.getHierarchy()),
}
: null;
} }
public override toJSON() { public override toJSON() {
return { return {
...super.toJSON(), ...super.toJSON(),
optional: this.optional, optional: this.optional,
inheritanceData: this.inheritanceData,
}; };
} }
} }

View File

@@ -1,17 +1,26 @@
import type { ApiPropertyItem, ApiModel, ApiPropertySignature } from '@microsoft/api-extractor-model'; import type { ApiPropertyItem, ApiModel, ApiPropertySignature } from '@microsoft/api-extractor-model';
import { DocItem } from './DocItem'; import { DocItem } from './DocItem';
import { type TokenDocumentation, genToken } from '~/util/parse.server'; import type { InheritanceData } from './DocMethod';
import { type TokenDocumentation, genToken, generatePath } from '~/util/parse.server';
export class DocProperty extends DocItem<ApiPropertyItem> { export class DocProperty extends DocItem<ApiPropertyItem> {
public readonly propertyTypeTokens: TokenDocumentation[]; public readonly propertyTypeTokens: TokenDocumentation[];
public readonly readonly: boolean; public readonly readonly: boolean;
public readonly optional: boolean; public readonly optional: boolean;
public readonly inheritanceData: InheritanceData | null;
public constructor(model: ApiModel, item: ApiPropertyItem | ApiPropertySignature) { public constructor(model: ApiModel, item: ApiPropertyItem | ApiPropertySignature, inherited = false) {
super(model, item); super(model, item);
this.propertyTypeTokens = item.propertyTypeExcerpt.spannedTokens.map((token) => genToken(this.model, token)); this.propertyTypeTokens = item.propertyTypeExcerpt.spannedTokens.map((token) => genToken(this.model, token));
this.readonly = item.isReadonly; this.readonly = item.isReadonly;
this.optional = item.isOptional; this.optional = item.isOptional;
this.inheritanceData =
inherited && item.parent
? {
parentName: item.parent.displayName,
path: generatePath(item.parent.getHierarchy()),
}
: null;
} }
public override toJSON() { public override toJSON() {
@@ -20,6 +29,7 @@ export class DocProperty extends DocItem<ApiPropertyItem> {
propertyTypeTokens: this.propertyTypeTokens, propertyTypeTokens: this.propertyTypeTokens,
readonly: this.readonly, readonly: this.readonly,
optional: this.optional, optional: this.optional,
inheritanceData: this.inheritanceData,
}; };
} }
} }

View File

@@ -1,8 +1,10 @@
import { Badge, Group, Stack, Title } from '@mantine/core'; import { Badge, Group, Stack, Title } from '@mantine/core';
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import { HyperlinkedText } from './HyperlinkedText'; import { HyperlinkedText } from './HyperlinkedText';
import { InheritanceText } from './InheritanceText';
import { TSDoc } from './tsdoc/TSDoc'; import { TSDoc } from './tsdoc/TSDoc';
import type { DocItem } from '~/DocModel/DocItem'; import type { DocItem } from '~/DocModel/DocItem';
import type { InheritanceData } from '~/DocModel/DocMethod';
import type { AnyDocNodeJSON } from '~/DocModel/comment/CommentNode'; import type { AnyDocNodeJSON } from '~/DocModel/comment/CommentNode';
import type { TokenDocumentation } from '~/util/parse.server'; import type { TokenDocumentation } from '~/util/parse.server';
@@ -21,6 +23,7 @@ export function CodeListing({
children, children,
comment, comment,
deprecation, deprecation,
inheritanceData,
}: { }: {
name: string; name: string;
separator?: CodeListingSeparatorType; separator?: CodeListingSeparatorType;
@@ -31,6 +34,7 @@ export function CodeListing({
comment?: AnyDocNodeJSON | null; comment?: AnyDocNodeJSON | null;
children?: ReactNode; children?: ReactNode;
deprecation?: AnyDocNodeJSON | null; deprecation?: AnyDocNodeJSON | null;
inheritanceData?: InheritanceData | null;
}) { }) {
return ( return (
<Stack spacing="xs" key={name}> <Stack spacing="xs" key={name}>
@@ -56,6 +60,7 @@ export function CodeListing({
{deprecation ? <TSDoc node={deprecation} /> : null} {deprecation ? <TSDoc node={deprecation} /> : null}
{summary && <TSDoc node={summary} />} {summary && <TSDoc node={summary} />}
{comment && <TSDoc node={comment} />} {comment && <TSDoc node={comment} />}
{inheritanceData ? <InheritanceText data={inheritanceData} /> : null}
{children} {children}
</Stack> </Stack>
</Group> </Group>

View File

@@ -0,0 +1,16 @@
import { Anchor, Text } from '@mantine/core';
import Link from 'next/link';
import type { InheritanceData } from '~/DocModel/DocMethod';
export function InheritanceText({ data }: { data: InheritanceData }) {
return (
<Text className="font-semibold">
{'Inherited from '}
<Link href={data.path} passHref>
<Anchor component="a" className="font-mono">
{data.parentName}
</Anchor>
</Link>
</Text>
);
}

View File

@@ -1,5 +1,6 @@
import { Badge, Group, Stack, Title } from '@mantine/core'; import { Badge, Group, Stack, Title } from '@mantine/core';
import { HyperlinkedText } from './HyperlinkedText'; import { HyperlinkedText } from './HyperlinkedText';
import { InheritanceText } from './InheritanceText';
import { ParameterTable } from './ParameterTable'; import { ParameterTable } from './ParameterTable';
import { TSDoc } from './tsdoc/TSDoc'; import { TSDoc } from './tsdoc/TSDoc';
import type { DocMethod } from '~/DocModel/DocMethod'; import type { DocMethod } from '~/DocModel/DocMethod';
@@ -20,7 +21,6 @@ function getShorthandName(data: MethodResolvable) {
export function MethodItem({ data }: { data: MethodResolvable }) { export function MethodItem({ data }: { data: MethodResolvable }) {
const method = data as ReturnType<DocMethod['toJSON']>; const method = data as ReturnType<DocMethod['toJSON']>;
return ( return (
<Stack <Stack
id={`${data.name}${data.overloadIndex && data.overloadIndex > 1 ? `:${data.overloadIndex}` : ''}`} id={`${data.name}${data.overloadIndex && data.overloadIndex > 1 ? `:${data.overloadIndex}` : ''}`}
@@ -54,6 +54,7 @@ export function MethodItem({ data }: { data: MethodResolvable }) {
{data.remarks ? <TSDoc node={data.remarks} /> : null} {data.remarks ? <TSDoc node={data.remarks} /> : null}
{data.comment ? <TSDoc node={data.comment} /> : null} {data.comment ? <TSDoc node={data.comment} /> : null}
{data.parameters.length ? <ParameterTable data={data.parameters} /> : null} {data.parameters.length ? <ParameterTable data={data.parameters} /> : null}
{data.inheritanceData ? <InheritanceText data={data.inheritanceData} /> : null}
</Stack> </Stack>
</Group> </Group>
</Stack> </Stack>

View File

@@ -15,6 +15,7 @@ export function PropertyList({ data }: { data: ReturnType<DocProperty['toJSON']>
summary={prop.summary} summary={prop.summary}
comment={prop.comment} comment={prop.comment}
deprecation={prop.deprecated} deprecation={prop.deprecated}
inheritanceData={prop.inheritanceData}
/> />
))} ))}
</Stack> </Stack>