Skip to content
Merged
89 changes: 62 additions & 27 deletions src/components/Comment.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,37 @@
// https://github.com/TypeStrong/typedoc-default-themes/blob/master/src/default/partials/comment.hbs
import { Fragment } from 'react';
import type { JSONOutput } from 'typedoc';
import { Markdown } from './Markdown';

// Tags that carry meaning even without a user-supplied message get a sensible
// default so the section is never empty.
const TAG_DEFAULT_MESSAGES: Record<string, string> = {
'@deprecated': 'This API is deprecated and may be removed in a future version.',
'@see': 'See the related documentation.',
};

const TAG_PREFIX: Record<string, string> = {
'@deprecated': 'Deprecated - ',
'@see': 'See more at ',
};

const ALWAYS_HIDDEN = new Set(['@reference', '@since']);
const EMPTY_TAGS: string[] = [];

function filterBlockTags(
blockTags: JSONOutput.CommentTag[],
hideTags: string[],
): JSONOutput.CommentTag[] {
const hidden =
hideTags.length === 0 ? ALWAYS_HIDDEN : new Set([...ALWAYS_HIDDEN, ...hideTags]);

return blockTags.filter((tag) => !hidden.has(tag.tag) && tag.tag !== '@default');
}

export interface CommentProps {
comment?: JSONOutput.Comment;
root?: boolean;
hideTags?: string[];
noBlockTags?: boolean;
}

export function hasComment(comment?: JSONOutput.Comment): boolean {
Expand Down Expand Up @@ -78,22 +103,45 @@ export function displayPartsToMarkdown(parts: JSONOutput.CommentDisplayPart[]):
.join('');
}

export function Comment({ comment, root, hideTags = [] }: CommentProps) {
if (!comment || !hasComment(comment)) {
return null;
function resolveTagContent(tag: JSONOutput.CommentTag): string {
const raw = displayPartsToMarkdown(tag.content).trim();

if (raw) {
return TAG_PREFIX[tag.tag] ? `${TAG_PREFIX[tag.tag]}${raw}` : raw;
}

// Hide custom tags.
hideTags.push('@reference', '@since');
return TAG_DEFAULT_MESSAGES[tag.tag] || '';
}

const blockTags =
comment.blockTags?.filter((tag) => {
if (hideTags.includes(tag.tag)) {
return false;
}
export interface CommentTagsProps {
comment?: JSONOutput.Comment;
hideTags?: string[];
}

return tag.tag !== '@default';
}) ?? [];
export function CommentTags({ comment, hideTags = EMPTY_TAGS }: CommentTagsProps) {
const blockTags = filterBlockTags(comment?.blockTags ?? [], hideTags);

return (
<>
{blockTags.map((tag) => {
const content = resolveTagContent(tag);

if (!content) return null;

return (
<div key={`${tag.tag}-${content}`} className="tsd-comment-since">
<Markdown content={content} />
</div>
);
})}
</>
);
}

export function Comment({ comment, root, hideTags = EMPTY_TAGS, noBlockTags = false }: CommentProps) {
if (!comment || !hasComment(comment)) {
return null;
}

return (
<div className={`tsd-comment tsd-typography ${root ? 'tsd-comment-root' : ''}`}>
Expand All @@ -103,20 +151,7 @@ export function Comment({ comment, root, hideTags = [] }: CommentProps) {
</div>
)}

{blockTags.length > 0 && (
<dl className="tsd-comment-tags">
{blockTags.map((tag) => (
<Fragment key={tag.tag}>
<dt>
<strong>{tag.tag}</strong>
</dt>
<dd>
<Markdown content={displayPartsToMarkdown(tag.content)} />
</dd>
</Fragment>
))}
</dl>
)}
{!noBlockTags && <CommentTags comment={comment} hideTags={hideTags} />}
</div>
);
}
8 changes: 5 additions & 3 deletions src/components/MemberDeclaration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { useMinimalLayout } from '../hooks/useMinimalLayout';
import { useRequiredReflection } from '../hooks/useReflection';
import { escapeMdx } from '../utils/helpers';
import { Comment, displayPartsToMarkdown, getSinceContent, hasComment } from './Comment';
import { Comment, CommentTags, displayPartsToMarkdown, getSinceContent, hasComment } from './Comment';
import { DefaultValue } from './DefaultValue';
import { Icon } from './Icon';
import { Markdown } from './Markdown';
Expand Down Expand Up @@ -44,7 +44,7 @@ export function MemberDeclaration({ id }: MemberDeclarationProps) {
<div className="tsd-panel-content">
<MemberSources reflection={reflection} />

<Comment comment={reflection.comment} />
<Comment noBlockTags comment={reflection.comment} />

{hasComment(reflection.comment) && (showTypes || showDeclaration) && (
<hr className="tsd-divider" />
Expand All @@ -64,8 +64,10 @@ export function MemberDeclaration({ id }: MemberDeclarationProps) {
</div>
)}

<CommentTags comment={reflection.comment} />

{sinceContent && (
<div className="tsd-comment-since">
<div className="tsd-comment-since">
<Markdown content={displayPartsToMarkdown(sinceContent)} />
</div>
)}
Expand Down
20 changes: 9 additions & 11 deletions src/components/MemberSignatureBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { usePluginData } from '@docusaurus/useGlobalData';
import { useMinimalLayout } from '../hooks/useMinimalLayout';
import type { TSDSignatureReflection } from '../types';
import { ApiDataContext } from './ApiDataContext';
import { Comment, displayPartsToMarkdown, getSinceContent, hasComment } from './Comment';
import { Comment, CommentTags, displayPartsToMarkdown, getSinceContent, hasComment } from './Comment';
import { CommentBadges, isCommentWithModifiers } from './CommentBadges';
import { DefaultValue } from './DefaultValue';
import { Flags } from './Flags';
Expand Down Expand Up @@ -109,7 +109,7 @@ export function MemberSignatureBody({ hideSources, sig }: MemberSignatureBodyPro

{isCommentWithModifiers(sig.comment) && <CommentBadges comment={sig.comment} />}

<Comment comment={sig.comment} hideTags={HIDE_TAGS} />
<Comment noBlockTags comment={sig.comment} hideTags={HIDE_TAGS} />

{hasComment(sig.comment) && (showTypes || showParams || showReturn) && (
<hr className="tsd-divider" />
Expand Down Expand Up @@ -217,15 +217,13 @@ export function MemberSignatureBody({ hideSources, sig }: MemberSignatureBodyPro
</>
)}

{
sinceContent && (
<>
<div className="tsd-comment-since">
<Markdown content={displayPartsToMarkdown(sinceContent)} />
</div>
</>
)
}
<CommentTags comment={sig.comment} hideTags={HIDE_TAGS} />

{sinceContent && (
<div className="tsd-comment-since">
<Markdown content={displayPartsToMarkdown(sinceContent)} />
</div>
)}
</>
);
}
20 changes: 12 additions & 8 deletions src/components/Reflection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { useMemo } from 'react';
import type { TSDDeclarationReflection, TSDReflection, TSDSignatureReflection } from '../types';
import { createHierarchy } from '../utils/hierarchy';
import { Comment, displayPartsToMarkdown, getSinceContent, hasComment } from './Comment';
import { Comment, CommentTags, displayPartsToMarkdown, getSinceContent, hasComment } from './Comment';
import { CommentBadges, isCommentWithModifiers } from './CommentBadges';
import { Hierarchy } from './Hierarchy';
import { Icon } from './Icon';
Expand Down Expand Up @@ -31,13 +31,7 @@ export function Reflection({ reflection }: ReflectionProps) {
return (
<>
{isCommentWithModifiers(reflection.comment) && <CommentBadges comment={reflection.comment} />}
{hasComment(reflection.comment) && <Comment root comment={reflection.comment} />}

{sinceContent && (
<div className="tsd-comment-since tsd-comment-since-root">
<Markdown content={displayPartsToMarkdown(sinceContent)} />
</div>
)}
{hasComment(reflection.comment) && <Comment noBlockTags root comment={reflection.comment} />}

{'typeParameter' in reflection &&
reflection.typeParameter &&
Expand Down Expand Up @@ -138,6 +132,16 @@ export function Reflection({ reflection }: ReflectionProps) {
</section>
)}

<div className="tsd-tags-root">
<CommentTags comment={reflection.comment} />

{sinceContent && (
<div className="tsd-comment-since">
<Markdown content={displayPartsToMarkdown(sinceContent)} />
</div>
)}
</div>

<Index reflection={reflection as TSDDeclarationReflection} />

<Members reflection={reflection as TSDDeclarationReflection} />
Expand Down
5 changes: 2 additions & 3 deletions src/components/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,8 @@ html[data-theme='light'] .tsd-panel-content {
border-top: 1px solid rgba(0, 0, 0, 0.05);
}

/* Top-level symbols render the tag inline above other sections, so it needs a
bottom margin to sit evenly; member tags close out a panel and don't. */
.tsd-comment-since-root {

.tsd-tags-root > .tsd-comment-since:last-child {
margin-bottom: 1em;
}

Expand Down
Loading