diff --git a/src/components/Comment.tsx b/src/components/Comment.tsx index 3cb06157..80148def 100644 --- a/src/components/Comment.tsx +++ b/src/components/Comment.tsx @@ -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 = { + '@deprecated': 'This API is deprecated and may be removed in a future version.', + '@see': 'See the related documentation.', +}; + +const TAG_PREFIX: Record = { + '@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 { @@ -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 ( +
+ +
+ ); + })} + + ); +} + +export function Comment({ comment, root, hideTags = EMPTY_TAGS, noBlockTags = false }: CommentProps) { + if (!comment || !hasComment(comment)) { + return null; + } return (
@@ -103,20 +151,7 @@ export function Comment({ comment, root, hideTags = [] }: CommentProps) {
)} - {blockTags.length > 0 && ( -
- {blockTags.map((tag) => ( - -
- {tag.tag} -
-
- -
-
- ))} -
- )} + {!noBlockTags && } ); } diff --git a/src/components/MemberDeclaration.tsx b/src/components/MemberDeclaration.tsx index 4303c2a9..387ce0b2 100644 --- a/src/components/MemberDeclaration.tsx +++ b/src/components/MemberDeclaration.tsx @@ -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'; @@ -44,7 +44,7 @@ export function MemberDeclaration({ id }: MemberDeclarationProps) {
- + {hasComment(reflection.comment) && (showTypes || showDeclaration) && (
@@ -64,8 +64,10 @@ export function MemberDeclaration({ id }: MemberDeclarationProps) {
)} + + {sinceContent && ( -
+
)} diff --git a/src/components/MemberSignatureBody.tsx b/src/components/MemberSignatureBody.tsx index a41253d0..c581a6e4 100644 --- a/src/components/MemberSignatureBody.tsx +++ b/src/components/MemberSignatureBody.tsx @@ -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'; @@ -109,7 +109,7 @@ export function MemberSignatureBody({ hideSources, sig }: MemberSignatureBodyPro {isCommentWithModifiers(sig.comment) && } - + {hasComment(sig.comment) && (showTypes || showParams || showReturn) && (
@@ -217,15 +217,13 @@ export function MemberSignatureBody({ hideSources, sig }: MemberSignatureBodyPro )} - { - sinceContent && ( - <> -
- -
- - ) - } + + + {sinceContent && ( +
+ +
+ )} ); } diff --git a/src/components/Reflection.tsx b/src/components/Reflection.tsx index 40c2aca5..d97393dc 100644 --- a/src/components/Reflection.tsx +++ b/src/components/Reflection.tsx @@ -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'; @@ -31,13 +31,7 @@ export function Reflection({ reflection }: ReflectionProps) { return ( <> {isCommentWithModifiers(reflection.comment) && } - {hasComment(reflection.comment) && } - - {sinceContent && ( -
- -
- )} + {hasComment(reflection.comment) && } {'typeParameter' in reflection && reflection.typeParameter && @@ -138,6 +132,16 @@ export function Reflection({ reflection }: ReflectionProps) { )} +
+ + + {sinceContent && ( +
+ +
+ )} +
+ diff --git a/src/components/styles.css b/src/components/styles.css index 17987ab5..f9ff441d 100644 --- a/src/components/styles.css +++ b/src/components/styles.css @@ -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; }