diff --git a/.changeset/brown-taxis-appear.md b/.changeset/brown-taxis-appear.md new file mode 100644 index 000000000..2eb1bad23 --- /dev/null +++ b/.changeset/brown-taxis-appear.md @@ -0,0 +1,7 @@ +--- +"@livekit/components-core": patch +"@livekit/components-react": patch +"@livekit/api-documenter": patch +--- + +Include useKrispNoiseFilter in generated docs diff --git a/packages/core/etc/components-core.api.md b/packages/core/etc/components-core.api.md index 869248941..4ed33af59 100644 --- a/packages/core/etc/components-core.api.md +++ b/packages/core/etc/components-core.api.md @@ -221,7 +221,7 @@ export type GridLayoutInfo = { export function isEqualTrackRef(a?: TrackReferenceOrPlaceholder, b?: TrackReferenceOrPlaceholder): boolean; // @public (undocumented) -export function isLocal(p: Participant): p is LocalParticipant; +export function isLocal(p: Participant): boolean; // @public export function isMobileBrowser(): boolean; @@ -235,7 +235,7 @@ export function isParticipantTrackReferencePinned(trackRef: TrackReference, pinS export function isPlaceholderReplacement(currentTrackRef: TrackReferenceOrPlaceholder, nextTrackRef: TrackReferenceOrPlaceholder): boolean; // @public (undocumented) -export function isRemote(p: Participant): p is RemoteParticipant; +export function isRemote(p: Participant): boolean; // @public (undocumented) export function isSourcesWithOptions(sources: SourcesArray): sources is TrackSourceWithOptions[]; diff --git a/packages/core/tsdoc.json b/packages/core/tsdoc.json new file mode 100644 index 000000000..ab7d7f2f1 --- /dev/null +++ b/packages/core/tsdoc.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": [ "../../tsdoc.json" ] +} diff --git a/packages/react/api-extractor.json b/packages/react/api-extractor.json index 1f75e0708..beeee4a02 100644 --- a/packages/react/api-extractor.json +++ b/packages/react/api-extractor.json @@ -16,5 +16,5 @@ * DEFAULT VALUE: "" */ "extends": "../../api-extractor-shared.json", - "mainEntryPointFilePath": "./dist/index.d.ts" + "mainEntryPointFilePath": "./dist/index.docs.d.ts" } diff --git a/packages/react/etc/components-react.api.md b/packages/react/etc/components-react.api.md index c27495bea..7371a27c2 100644 --- a/packages/react/etc/components-react.api.md +++ b/packages/react/etc/components-react.api.md @@ -13,12 +13,14 @@ import { CreateLocalTracksOptions } from 'livekit-client'; import { DataPublishOptions } from 'livekit-client'; import { DisconnectReason } from 'livekit-client'; import { HTMLAttributes } from 'react'; +import { KrispNoiseFilterProcessor } from '@livekit/krisp-noise-filter'; import { LocalAudioTrack } from 'livekit-client'; import { LocalParticipant } from 'livekit-client'; import { LocalTrack } from 'livekit-client'; import { LocalTrackPublication } from 'livekit-client'; import { LocalVideoTrack } from 'livekit-client'; import { MediaDeviceFailure } from 'livekit-client'; +import { NoiseFilterOptions } from '@livekit/krisp-noise-filter'; import { Participant } from 'livekit-client'; import { ParticipantEvent } from 'livekit-client'; import type { ParticipantKind } from 'livekit-client'; @@ -162,7 +164,7 @@ export const ChatIcon: (props: SVGProps) => React_2.JSX.Element; export { ChatMessage } -// Warning: (ae-forgotten-export) The symbol "ChatOptions" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "ChatOptions" needs to be exported by the entry point index.docs.d.ts // // @public (undocumented) export interface ChatProps extends React_2.HTMLAttributes, ChatOptions { @@ -445,12 +447,12 @@ export interface MediaDeviceSelectProps extends Omit LegacyReceivedChatMessage; -// Warning: (ae-forgotten-export) The symbol "LegacyChatMessage" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "LegacyChatMessage" needs to be exported by the entry point index.docs.d.ts // // @public @deprecated (undocumented) export type MessageEncoder = (message: LegacyChatMessage) => Uint8Array; @@ -500,7 +502,7 @@ export function ParticipantContextIfNeeded(props: React_2.PropsWithChildren<{ participant?: Participant; }>): React_2.JSX.Element; -// Warning: (ae-forgotten-export) The symbol "RequireAtLeastOne" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "RequireAtLeastOne" needs to be exported by the entry point index.docs.d.ts // // @beta (undocumented) export type ParticipantIdentifier = RequireAtLeastOne<{ @@ -629,14 +631,14 @@ export const ScreenShareIcon: (props: SVGProps) => React_2.JSX.El // @internal (undocumented) export const ScreenShareStopIcon: (props: SVGProps) => React_2.JSX.Element; -// Warning: (ae-forgotten-export) The symbol "LogExtension" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "SetLogExtensionOptions" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "LogExtension" needs to be exported by the entry point index.docs.d.ts +// Warning: (ae-forgotten-export) The symbol "SetLogExtensionOptions" needs to be exported by the entry point index.docs.d.ts // // @public export function setLogExtension(extension: LogExtension, options?: SetLogExtensionOptions): void; -// Warning: (ae-forgotten-export) The symbol "LogLevel" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "SetLogLevelOptions" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "LogLevel" needs to be exported by the entry point index.docs.d.ts +// Warning: (ae-forgotten-export) The symbol "SetLogLevelOptions" needs to be exported by the entry point index.docs.d.ts // // @public export function setLogLevel(level: LogLevel, options?: SetLogLevelOptions): void; @@ -692,19 +694,19 @@ export type TrackReference = { source: Track.Source; }; -// Warning: (ae-forgotten-export) The symbol "TrackReferencePlaceholder" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "TrackReferencePlaceholder" needs to be exported by the entry point index.docs.d.ts // // @public (undocumented) export type TrackReferenceOrPlaceholder = TrackReference | TrackReferencePlaceholder; -// Warning: (ae-forgotten-export) The symbol "ToggleSource" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "ToggleSource" needs to be exported by the entry point index.docs.d.ts // // @public export const TrackToggle: (props: TrackToggleProps & React_2.RefAttributes) => React_2.ReactNode; // @public (undocumented) export interface TrackToggleProps extends Omit, 'onChange'> { - // Warning: (ae-forgotten-export) The symbol "CaptureOptionsBySource" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "CaptureOptionsBySource" needs to be exported by the entry point index.docs.d.ts // // (undocumented) captureOptions?: CaptureOptionsBySource; @@ -793,8 +795,8 @@ export function useConnectionState(room?: Room): ConnectionState_2; // @public (undocumented) export function useCreateLayoutContext(): LayoutContextType; -// Warning: (ae-forgotten-export) The symbol "ReceivedDataMessage" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "UseDataChannelReturnType" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "ReceivedDataMessage" needs to be exported by the entry point index.docs.d.ts +// Warning: (ae-forgotten-export) The symbol "UseDataChannelReturnType" needs to be exported by the entry point index.docs.d.ts // // @public export function useDataChannel(topic: T, onMessage?: (msg: ReceivedDataMessage) => void): UseDataChannelReturnType; @@ -829,7 +831,7 @@ export function useEnsureTrackRef(trackRef?: TrackReferenceOrPlaceholder): Track // @alpha export function useFacingMode(trackReference: TrackReferenceOrPlaceholder): 'user' | 'environment' | 'left' | 'right' | 'undefined'; -// Warning: (ae-forgotten-export) The symbol "FeatureContext" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "FeatureContext" needs to be exported by the entry point index.docs.d.ts // Warning: (ae-internal-missing-underscore) The name "useFeatureContext" should be prefixed with an underscore because the declaration is marked as @internal // // @internal (undocumented) @@ -887,6 +889,21 @@ export function useIsRecording(room?: Room): boolean; // @public export function useIsSpeaking(participant?: Participant): boolean; +// @beta +export function useKrispNoiseFilter(options?: useKrispNoiseFilterOptions): { + setNoiseFilterEnabled: (enable: boolean) => Promise; + isNoiseFilterEnabled: boolean; + isNoiseFilterPending: boolean; + processor: KrispNoiseFilterProcessor | undefined; +}; + +// @beta (undocumented) +export interface useKrispNoiseFilterOptions { + // @internal (undocumented) + filterOptions?: NoiseFilterOptions; + trackRef?: TrackReferenceOrPlaceholder; +} + // @public export function useLayoutContext(): LayoutContextType; @@ -1183,7 +1200,7 @@ export interface UseTokenOptions { // @public export function useTrackByName(name: string, participant?: Participant): TrackReferenceOrPlaceholder; -// Warning: (ae-forgotten-export) The symbol "TrackMutedIndicatorReturnType" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "TrackMutedIndicatorReturnType" needs to be exported by the entry point index.docs.d.ts // // @public export function useTrackMutedIndicator(trackRef?: TrackReferenceOrPlaceholder): TrackMutedIndicatorReturnType; @@ -1191,12 +1208,12 @@ export function useTrackMutedIndicator(trackRef?: TrackReferenceOrPlaceholder): // @public export function useTrackRefContext(): TrackReferenceOrPlaceholder; -// Warning: (ae-forgotten-export) The symbol "SourcesArray" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "SourcesArray" needs to be exported by the entry point index.docs.d.ts // // @public export function useTracks(sources?: T, options?: UseTracksOptions): UseTracksHookReturnType; -// Warning: (ae-forgotten-export) The symbol "TrackSourceWithOptions" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "TrackSourceWithOptions" needs to be exported by the entry point index.docs.d.ts // // @public (undocumented) export type UseTracksHookReturnType = T extends Track.Source[] ? TrackReference[] : T extends TrackSourceWithOptions[] ? TrackReferenceOrPlaceholder[] : never; @@ -1316,11 +1333,11 @@ export type WidgetState = { // Warnings were encountered during analysis: // -// src/context/layout-context.ts:10:3 - (ae-forgotten-export) The symbol "PinContextType" needs to be exported by the entry point index.d.ts -// src/context/layout-context.ts:11:3 - (ae-forgotten-export) The symbol "WidgetContextType" needs to be exported by the entry point index.d.ts -// src/hooks/useGridLayout.ts:27:6 - (ae-forgotten-export) The symbol "GridLayoutInfo" needs to be exported by the entry point index.d.ts -// src/hooks/useMediaDeviceSelect.ts:47:29 - (ae-forgotten-export) The symbol "SetMediaDeviceOptions" needs to be exported by the entry point index.d.ts -// src/hooks/useTrackTranscription.ts:43:38 - (ae-forgotten-export) The symbol "ReceivedTranscriptionSegment" needs to be exported by the entry point index.d.ts +// src/context/layout-context.ts:10:3 - (ae-forgotten-export) The symbol "PinContextType" needs to be exported by the entry point index.docs.d.ts +// src/context/layout-context.ts:11:3 - (ae-forgotten-export) The symbol "WidgetContextType" needs to be exported by the entry point index.docs.d.ts +// src/hooks/useGridLayout.ts:27:6 - (ae-forgotten-export) The symbol "GridLayoutInfo" needs to be exported by the entry point index.docs.d.ts +// src/hooks/useMediaDeviceSelect.ts:47:29 - (ae-forgotten-export) The symbol "SetMediaDeviceOptions" needs to be exported by the entry point index.docs.d.ts +// src/hooks/useTrackTranscription.ts:43:38 - (ae-forgotten-export) The symbol "ReceivedTranscriptionSegment" needs to be exported by the entry point index.docs.d.ts // (No @packageDocumentation comment for this package) diff --git a/packages/react/src/hooks/cloud/krisp/useKrispNoiseFilter.ts b/packages/react/src/hooks/cloud/krisp/useKrispNoiseFilter.ts index e80c62717..df7c958bd 100644 --- a/packages/react/src/hooks/cloud/krisp/useKrispNoiseFilter.ts +++ b/packages/react/src/hooks/cloud/krisp/useKrispNoiseFilter.ts @@ -6,33 +6,38 @@ import type { TrackReferenceOrPlaceholder } from '@livekit/components-core'; import { useLocalParticipant } from '../../..'; /** - * @alpha + * @beta */ export interface useKrispNoiseFilterOptions { /** - * by default the hook will use the localParticipant's microphone track publication. - * You can override this behavior by passing in a target TrackReference here + * The track reference to use for the noise filter (defaults: local microphone track) */ trackRef?: TrackReferenceOrPlaceholder; + /** + * @internal + */ filterOptions?: NoiseFilterOptions; } /** - * This hook is a convenience helper for enabling Krisp Enhanced Audio Noise Cancellation on LiveKit audio tracks. - * It returns a `setNoiseFilterEnabled` method to conveniently toggle between enabled and disabled states. + * Enable the Krisp enhanced noise cancellation feature for local audio tracks. + * + * Defaults to the localParticipant's microphone track publication, but you can override this behavior by passing in a different track reference. * - * @remarks Krisp noise filter is a feature that's only supported on LiveKit cloud plans - * @alpha + * @package \@livekit/components-react/krisp + * @remarks This filter requires that you install the `@livekit/krisp-noise-filter` package and is supported only on {@link https://cloud.livekit.io | LiveKit Cloud}. + * @beta * @example * ```tsx - * const krisp = useKrispNoiseFilter(); - * return krisp.setNoiseFilterEnabled(ev.target.checked)} - checked={krisp.isNoiseFilterEnabled} - disabled={krisp.isNoiseFilterPending} - /> + * const krisp = useKrispNoiseFilter(); + * return krisp.setNoiseFilterEnabled(ev.target.checked)} + * checked={krisp.isNoiseFilterEnabled} + * disabled={krisp.isNoiseFilterPending} + * /> * ``` + * @returns Use `setIsNoiseFilterEnabled` to enable/disable the noise filter. */ export function useKrispNoiseFilter(options: useKrispNoiseFilterOptions = {}) { const [shouldEnable, setShouldEnable] = React.useState(false); diff --git a/packages/react/src/hooks/useIsMuted.ts b/packages/react/src/hooks/useIsMuted.ts index 6389ae8b7..fd3f1884c 100644 --- a/packages/react/src/hooks/useIsMuted.ts +++ b/packages/react/src/hooks/useIsMuted.ts @@ -16,10 +16,20 @@ export interface UseIsMutedOptions { * The `useIsMuted` hook is used to implement the `TrackMutedIndicator` or your custom implementation of it. * It returns a `boolean` that indicates if the track is muted or not. * - * @example + * @example With a track reference * ```tsx * const isMuted = useIsMuted(track); * ``` + * + * @example With a track source / participant + * ```tsx + * const isMuted = useIsMuted('camera', { participant }); + * ``` + * + * @param sourceOrTrackRef - Either a `TrackReference` or a `Track.Source` (see usage examples) + * @param options - Additional options when using a `Track.Source` + * @returns boolean indicating if the track is muted + * * @public */ export function useIsMuted(trackRef: TrackReferenceOrPlaceholder): boolean; diff --git a/packages/react/src/index.docs.ts b/packages/react/src/index.docs.ts new file mode 100644 index 000000000..4319180c6 --- /dev/null +++ b/packages/react/src/index.docs.ts @@ -0,0 +1,12 @@ +/** + * Used to merge the exports from the main index.ts file with the exports from the cloud/krisp/useKrispNoiseFilter.ts file for docs generation. + */ + +// Regular exports +export * from './index'; + +// Cloud/Krisp exports +export { + useKrispNoiseFilter, + type useKrispNoiseFilterOptions, +} from './hooks/cloud/krisp/useKrispNoiseFilter'; diff --git a/packages/react/tsdoc.json b/packages/react/tsdoc.json new file mode 100644 index 000000000..ab7d7f2f1 --- /dev/null +++ b/packages/react/tsdoc.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": [ "../../tsdoc.json" ] +} diff --git a/tooling/api-documenter/src/documenters/MarkdownDocumenter.ts b/tooling/api-documenter/src/documenters/MarkdownDocumenter.ts index d98fe4715..01ec5772c 100644 --- a/tooling/api-documenter/src/documenters/MarkdownDocumenter.ts +++ b/tooling/api-documenter/src/documenters/MarkdownDocumenter.ts @@ -18,6 +18,7 @@ import { DocComment, DocNodeContainer, DocNode, + DocEscapedText, } from '@microsoft/tsdoc'; import { ApiModel, @@ -49,7 +50,6 @@ import { IFindApiItemsResult, Parameter, ApiPropertySignature, - ApiVariable, } from '@microsoft/api-extractor-model'; import { CustomDocNodes } from '../nodes/CustomDocNodeKind'; @@ -58,7 +58,6 @@ import { DocTable } from '../nodes/DocTable'; import { DocEmphasisSpan } from '../nodes/DocEmphasisSpan'; import { DocTableRow } from '../nodes/DocTableRow'; import { DocTableCell } from '../nodes/DocTableCell'; -import { DocNoteBox } from '../nodes/DocNoteBox'; import { Utilities } from '../utils/Utilities'; import { CustomMarkdownEmitter } from '../markdown/CustomMarkdownEmitter'; import { PluginLoader } from '../plugin/PluginLoader'; @@ -209,6 +208,9 @@ export class MarkdownDocumenter { if (apiItem.releaseTag === ReleaseTag.Beta) { this._writeBetaWarning(output); } + if (apiItem.releaseTag === ReleaseTag.Alpha) { + this._writeAlphaWarning(output); + } } const decoratorBlocks: DocBlock[] = []; @@ -269,8 +271,7 @@ export class MarkdownDocumenter { if (category !== undefined) { let importPath: string = ''; try { - // @ts-ignore - importPath = apiItem.canonicalReference.source.escapedPath; + importPath = this._getImportPath(apiItem); } catch (error) { console.error(error); } @@ -508,30 +509,82 @@ export class MarkdownDocumenter { (x) => x.blockTag.tagNameWithUpperCase === StandardTags.example.tagNameWithUpperCase, ); - let exampleNumber: number = 1; - for (const exampleBlock of exampleBlocks) { - const heading: string = - exampleBlocks.length > 1 ? `Usage Example ${exampleNumber}` : 'Usage'; + if (exampleBlocks.length > 0) { + output.appendNode(new DocHeading({ configuration, title: 'Usage', level: 2 })); + } - output.appendNode(new DocHeading({ configuration, title: heading, level: 2 })); + const findFirstPlainText = ( + node: DocNode, + ): { text: string | undefined; node: DocPlainText | undefined } => { + if (node.kind === DocNodeKind.PlainText) { + const plainTextNode = node as DocPlainText; + return { + text: plainTextNode.text.split('\n')[0].trim(), + node: plainTextNode, + }; + } - this._appendSection(output, exampleBlock.content); + if (node instanceof DocNodeContainer) { + for (const childNode of node.getChildNodes()) { + const result = findFirstPlainText(childNode); + if (result.text) { + return result; + } + } + } - ++exampleNumber; - } + return { text: undefined, node: undefined }; + }; + + for (const [index, exampleBlock] of exampleBlocks.entries()) { + if (exampleBlocks.length > 1) { + let firstNode: DocNode | undefined = exampleBlock.content.nodes[0]; + let title: string = `Example ${index + 1}`; + + if (firstNode) { + const { text, node: plainTextNode } = findFirstPlainText(firstNode); + if (text) { + title = text; + if (plainTextNode) { + const remainingText: string | undefined = plainTextNode.text + .split('\n') + .slice(1) + .join('\n') + .trim(); + const parent: DocNodeContainer = firstNode as DocNodeContainer; + + const newChildNodes: DocNode[] = parent + .getChildNodes() + .map((childNode) => { + if (childNode === plainTextNode) { + return remainingText + ? new DocPlainText({ configuration, text: remainingText }) + : undefined; + } + return childNode; + }) + .filter((node): node is DocNode => node !== undefined); - output.appendNode( - new MarkDocTag({ - configuration, - name: 'partial', - attributes: { - file: 'p_usage.md', - }, - variables: { - exampleCount: exampleNumber - 1, - }, - }), - ); + firstNode = new DocParagraph({ configuration }, newChildNodes); + } + } + } + + output.appendNode(new DocHeading({ configuration, title, level: 3 })); + + const newContent: DocSection = new DocSection({ configuration }); + if (firstNode && firstNode.getChildNodes().length > 0) { + newContent.appendNode(firstNode); + } + for (let i: number = 1; i < exampleBlock.content.nodes.length; i++) { + newContent.appendNode(exampleBlock.content.nodes[i]); + } + + this._appendSection(output, newContent); + } else { + this._appendSection(output, exampleBlock.content); + } + } } } } @@ -1104,7 +1157,7 @@ export class MarkdownDocumenter { //@ts-ignore // apiParameter?._parent?.displayName === 'useParticipantTile' && firstParameter.kind === ExcerptTokenKind.Reference && - firstParameter.text.endsWith('Props') && + (firstParameter.text.endsWith('Props') || firstParameter.text.endsWith('Options')) && firstParameter.canonicalReference ) { // First parameter is a props object. @@ -1118,7 +1171,7 @@ export class MarkdownDocumenter { new ParameterItem({ configuration, attributes: { - name: member.displayName, + name: `${apiParameter.name}.${member.displayName}`, type: member.propertyTypeExcerpt.text, optional: member.isOptional, description: member.tsdocComment?.summarySection?.nodes ?? [], @@ -1153,6 +1206,12 @@ export class MarkdownDocumenter { const returnTypeExcerpt: Excerpt = apiParameterListMixin.returnTypeExcerpt; output.appendNode(new DocHeading({ configuration, title: 'Returns', level: 2 })); + if (apiParameterListMixin instanceof ApiDocumentedItem) { + if (apiParameterListMixin.tsdocComment?.returnsBlock) { + this._appendSection(output, apiParameterListMixin.tsdocComment.returnsBlock.content); + } + } + const fencedCode: DocFencedCode = new DocFencedCode({ configuration, code: returnTypeExcerpt.text, @@ -1501,10 +1560,9 @@ export class MarkdownDocumenter { private _writeBetaWarning(output: DocSection): void { const configuration: TSDocConfiguration = this._tsdocConfiguration; const betaWarning: string = - 'This API is provided as a preview for developers and may change' + - ' based on feedback that we receive. Do not use this API in a production environment.'; + 'This feature is under active development and may change based on developer feedback and real-world usage.'; output.appendNode( - new DocNoteBox({ configuration }, [ + new Callout({ configuration }, [ new DocParagraph({ configuration }, [ new DocPlainText({ configuration, text: betaWarning }), ]), @@ -1512,6 +1570,19 @@ export class MarkdownDocumenter { ); } + private _writeAlphaWarning(output: DocSection): void { + const configuration: TSDocConfiguration = this._tsdocConfiguration; + const alphaWarning: string = + 'This feature is experimental and may change or be removed based on developer feedback and real-world usage.'; + output.appendNode( + new Callout({ configuration }, [ + new DocParagraph({ configuration }, [ + new DocPlainText({ configuration, text: alphaWarning }), + ]), + ]), + ); + } + private _appendSection(output: DocSection, docSection: DocSection): void { for (const node of docSection.nodes) { output.appendNode(node); @@ -1616,4 +1687,39 @@ export class MarkdownDocumenter { console.log('Deleting old output from ' + this._outputFolder); FileSystem.ensureEmptyFolder(this._outputFolder); } + + private _getImportPath(apiItem: ApiDeclaredItem): string { + // Check for custom import path from TSDoc first + if (apiItem instanceof ApiDocumentedItem && apiItem.tsdocComment) { + const packageTag: DocBlock | undefined = apiItem.tsdocComment.customBlocks.find( + (block) => block.blockTag.tagName === '@package', + ); + + if (packageTag) { + return packageTag.content.nodes + .map((node) => { + if (node.kind === DocNodeKind.Paragraph) { + return node + .getChildNodes() + .map((child) => { + if (child.kind === DocNodeKind.PlainText) { + return (child as DocPlainText).text; + } else if (child.kind === DocNodeKind.EscapedText) { + return (child as DocEscapedText).decodedText; + } + return ''; + }) + .join(''); + } + return ''; + }) + .join('') + .trim(); + } + } + + // Fallback to canonical reference + // @ts-ignore + return apiItem.canonicalReference.source.escapedPath; + } } diff --git a/tooling/api-documenter/src/nodes/Callout.ts b/tooling/api-documenter/src/nodes/Callout.ts index 37afd27e0..00f19155f 100644 --- a/tooling/api-documenter/src/nodes/Callout.ts +++ b/tooling/api-documenter/src/nodes/Callout.ts @@ -4,7 +4,7 @@ import { IDocNodeParameters, DocNode, DocSection } from '@microsoft/tsdoc'; import { CustomDocNodeKind } from './CustomDocNodeKind'; -type CalloutType = 'info' | 'tip' | 'important' | 'caution' | 'warning'; +type CalloutType = 'note' | 'tip' | 'important' | 'caution' | 'warning'; type CalloutVariant = 'normal' | 'compact'; /** @@ -26,7 +26,7 @@ export class Callout extends DocNode { public constructor(parameters: ICalloutParameters, sectionChildNodes?: ReadonlyArray) { super(parameters); this.content = new DocSection({ configuration: this.configuration }, sectionChildNodes); - this.type = parameters.type ?? 'info'; + this.type = parameters.type ?? 'note'; this.variant = parameters.variant ?? 'normal'; } diff --git a/tsdoc.json b/tsdoc.json new file mode 100644 index 000000000..bf943edec --- /dev/null +++ b/tsdoc.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "tagDefinitions": [ + { + "tagName": "@package", + "syntaxKind": "block" + } + ] +} \ No newline at end of file