diff --git a/packages/__docs__/buildScripts/DataTypes.mts b/packages/__docs__/buildScripts/DataTypes.mts index 92acf088bd..6ee798a842 100644 --- a/packages/__docs__/buildScripts/DataTypes.mts +++ b/packages/__docs__/buildScripts/DataTypes.mts @@ -28,7 +28,7 @@ import { Documentation } from 'react-docgen' type ProcessedFile = Documentation & YamlMetaInfo & - ParsedJSDoc & + JsDocResult & PackagePathData & { title: string, id:string } @@ -60,12 +60,16 @@ type YamlMetaInfo = { tags?: string } -type ParsedJSDoc = { +type JsDocResult = { + // the comment section above the function comment?: string, + // metadata about the parsed file like filename meta?: any, + // the comment without the comment characters ("/*" etc) description?: string, kind?: string, name?: string, + // function params. undefined if the comment is e.g. above imports params?: { description?: string defaultValue?: string | number | boolean @@ -73,10 +77,13 @@ type ParsedJSDoc = { type?: { names: string[] } optional?: boolean }[], + // function return value. undefined if the comment is e.g. above imports returns?: JSDocFunctionReturns[], - longName?: string, - sections?: any[], - undocumented?: boolean + //e.g. "module:debounce", "module:FocusRegion" + longname: string, + access?: string, + undocumented?: boolean, + title?: string } type JSDocFunctionReturns = { @@ -85,77 +92,61 @@ type JSDocFunctionReturns = { names: string[] } } -// TODO remove these types, now we can get them directly from react-docgen +// TODO these are from React-docgen Documentation.d.ts, +// remove when react-docgen exports them interface MethodParameter { - name: string - type?: TypeDescriptor | null - optional?: boolean + name: string; + description?: string; + optional: boolean; + type?: TypeDescriptor | null; } interface MethodReturn { - type: TypeDescriptor | undefined + description?: string; + type: TypeDescriptor | undefined; } interface PropDescriptor { - type?: PropTypeDescriptor - flowType?: TypeDescriptor - tsType?: TypeDescriptor - required?: boolean - defaultValue?: any - description?: string + type?: PropTypeDescriptor; + flowType?: TypeDescriptor; + tsType?: TypeDescriptor; + required?: boolean; + defaultValue?: DefaultValueDescriptor; + description?: string; } interface PropTypeDescriptor { - name: - | 'arrayOf' - | 'custom' - | 'enum' - | 'array' - | 'bool' - | 'func' - | 'number' - | 'object' - | 'string' - | 'any' - | 'element' - | 'node' - | 'symbol' - | 'objectOf' - | 'shape' - | 'exact' - | 'union' - | 'elementType' - | 'instanceOf' - value?: any - raw?: string - computed?: boolean - // These are only needed for shape/exact types. - // Consider consolidating PropTypeDescriptor and PropDescriptor - description?: string - required?: boolean + name: 'any' | 'array' | 'arrayOf' | 'bool' | 'custom' | 'element' | 'elementType' | 'enum' | 'exact' | 'func' | 'instanceOf' | 'node' | 'number' | 'object' | 'objectOf' | 'shape' | 'string' | 'symbol' | 'union'; + value?: unknown; + raw?: string; + computed?: boolean; + description?: string; + required?: boolean; } -type TypeDescriptor = - | SimpleType - | LiteralType - | ElementsType - | ObjectSignatureType - | T +type TypeDescriptor = ElementsType | LiteralType | ObjectSignatureType | SimpleType | T; +interface DefaultValueDescriptor { + value: unknown; + computed: boolean; +} +interface BaseType { + required?: boolean; + nullable?: boolean; + alias?: string; +} interface SimpleType extends BaseType { - name: string - raw?: string + name: string; + raw?: string; } - interface LiteralType extends BaseType { - name: 'literal' - value: string + name: 'literal'; + value: string; } - interface ElementsType extends BaseType { - name: string - raw: string - elements: Array> + name: string; + raw: string; + elements: Array>; } interface FunctionArgumentType { @@ -165,40 +156,33 @@ interface FunctionArgumentType { } interface FunctionSignatureType extends BaseType { - name: 'signature' - type: 'function' - raw: string + name: 'signature'; + type: 'function'; + raw: string; signature: { - arguments: Array> - return: TypeDescriptor - } + arguments: Array>; + return?: TypeDescriptor; + }; } - interface TSFunctionSignatureType extends FunctionSignatureType { signature: { - arguments: Array> - return: TypeDescriptor - this?: TypeDescriptor - } + arguments: Array>; + return?: TypeDescriptor; + this?: TypeDescriptor; + }; } - interface ObjectSignatureType extends BaseType { - name: 'signature' - type: 'object' - raw: string + name: 'signature'; + type: 'object'; + raw: string; signature: { properties: Array<{ - key: string | TypeDescriptor - value: TypeDescriptor - }> - constructor?: TypeDescriptor - } -} - -interface BaseType { - required?: boolean - nullable?: boolean - alias?: string + key: TypeDescriptor | string; + value: TypeDescriptor; + description?: string; + }>; + constructor?: TypeDescriptor; + }; } // end react-docgen part @@ -285,5 +269,5 @@ export type { IconGlyph, MainDocsData, MainIconsData, - ParsedJSDoc + JsDocResult } diff --git a/packages/__docs__/buildScripts/build-docs.mts b/packages/__docs__/buildScripts/build-docs.mts index 7002461fdb..983778bbc5 100644 --- a/packages/__docs__/buildScripts/build-docs.mts +++ b/packages/__docs__/buildScripts/build-docs.mts @@ -86,6 +86,7 @@ const pathsToIgnore = [ '**/__fixtures__/**', '**/__testfixtures__/**', '**/__tests__/**', + '**/__new-tests__/**', '**/locales/**', '**/styles.{js,ts}', '**/theme.{js,ts}', @@ -179,13 +180,15 @@ function buildDocs() { } // This function is also called by Webpack if a file changes +// TODO this parses some files twice, its needed for the Webpack watcher but not +// for the full build. function processSingleFile(fullPath: string) { let docObject const dirName = path.dirname(fullPath) const fileName = path.parse(fullPath).name if (fileName === 'index') { docObject = processFile(fullPath, projectRoot, library) - // Components (e.g. Alert) store their descriptions in README.md files. + // Some Components (e.g. Alert) store their descriptions in README.md files. // Add this to the final JSON if it's edited const readmeDesc = tryParseReadme(dirName) docObject.description = readmeDesc @@ -208,6 +211,7 @@ function processSingleFile(fullPath: string) { docObject = processFile(fullPath, projectRoot, library) } } else { + // documentation .md files, utils ts and tsx files docObject = processFile(fullPath, projectRoot, library) } const docJSON = JSON.stringify(docObject!) diff --git a/packages/__docs__/buildScripts/utils/getJSDoc.mts b/packages/__docs__/buildScripts/utils/getJSDoc.mts index 379393617e..5e1c5762e3 100644 --- a/packages/__docs__/buildScripts/utils/getJSDoc.mts +++ b/packages/__docs__/buildScripts/utils/getJSDoc.mts @@ -25,18 +25,21 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore no typing :( import jsdoc from 'jsdoc-api' -import type { ParsedJSDoc } from '../DataTypes.mjs' +import type { JsDocResult } from '../DataTypes.mts' export function getJSDoc(source: Buffer, error: (err: Error) => void) { - let doc: ParsedJSDoc = {} + // note: JSDoc seems to be abandoned, we should use TypeScript: + // https://stackoverflow.com/questions/47429792/is-it-possible-to-get-comments-as-nodes-in-the-ast-using-the-typescript-compiler + let doc: Partial = {} try { - const sections = jsdoc + // JSDoc only creates these sections if the file has a @module or @namespace annotation + let sections: JsDocResult[] = jsdoc .explainSync({ // note: Do not use cache:true here, its buggy configure: './jsdoc.config.json', source }) - .filter((section: Record) => { + sections = sections.filter((section) => { return ( section.undocumented !== true && section.access !== 'private' && @@ -44,9 +47,7 @@ export function getJSDoc(source: Buffer, error: (err: Error) => void) { ) }) const module = - sections.filter( - (section: Record) => section.kind === 'module' - )[0] || + sections.filter((section) => section.kind === 'module')[0] || sections[0] || {} if (process.platform === 'win32' && module.description) { @@ -55,18 +56,6 @@ export function getJSDoc(source: Buffer, error: (err: Error) => void) { } doc = { ...module, - sections: sections - .filter( - (section: Record) => section.longname !== module.longname - ) - .map((section: Record) => { - const name = section.longname.replace(`${module.longname}.`, '') - return { - ...section, - id: name, - title: name - } - }), undocumented: sections.length <= 0 } } catch (err: any) { diff --git a/packages/__docs__/buildScripts/utils/parseDoc.mts b/packages/__docs__/buildScripts/utils/parseDoc.mts index 27e0e25d78..73c71861c0 100644 --- a/packages/__docs__/buildScripts/utils/parseDoc.mts +++ b/packages/__docs__/buildScripts/utils/parseDoc.mts @@ -26,14 +26,14 @@ import { getJSDoc } from './getJSDoc.mjs' import { getReactDoc } from './getReactDoc.mjs' import { getFrontMatter } from './getFrontMatter.mjs' import path from 'path' -import type { ParsedJSDoc, YamlMetaInfo } from '../DataTypes.mjs' +import type { JsDocResult, YamlMetaInfo } from '../DataTypes.mjs' import type { Documentation } from 'react-docgen' export function parseDoc( resourcePath: string, source: Buffer, errorHandler: (err: Error) => void -): Documentation & YamlMetaInfo & ParsedJSDoc { +): Documentation & YamlMetaInfo & Partial { const extension = path.extname(resourcePath) const allowedExtensions = ['.js', '.ts', '.tsx'] let doc: Documentation | undefined diff --git a/packages/__docs__/package.json b/packages/__docs__/package.json index 7cec1f037f..02601d528c 100644 --- a/packages/__docs__/package.json +++ b/packages/__docs__/package.json @@ -18,6 +18,7 @@ "lint": "ui-scripts lint", "lint:fix": "ui-scripts lint --fix", "build:scripts:ts": "tsc -b tsconfig.node.build.json", + "ts:check": "tsc -p tsconfig.build.json --noEmit --emitDeclarationOnly false", "clean": "ui-scripts clean", "createStatsFile": "mkdirp ./__build__ && webpack --profile --json > __build__/bundleStats.json", "analyseStatsFile": "webpack-bundle-analyzer __build__/bundleStats.json" diff --git a/packages/__docs__/src/App/index.tsx b/packages/__docs__/src/App/index.tsx index 1b40308d79..d7d059637e 100644 --- a/packages/__docs__/src/App/index.tsx +++ b/packages/__docs__/src/App/index.tsx @@ -101,7 +101,7 @@ class App extends Component { static defaultProps = { trayWidth: 300 } - _content?: HTMLDivElement + _content?: HTMLDivElement | null _menuTrigger?: HTMLButtonElement _mediaQueryListener?: ReturnType _defaultDocumentTitle?: string diff --git a/packages/__docs__/src/App/props.ts b/packages/__docs__/src/App/props.ts index 41c5213577..be96cacdc6 100644 --- a/packages/__docs__/src/App/props.ts +++ b/packages/__docs__/src/App/props.ts @@ -28,7 +28,7 @@ import type { MainIconsData, MainDocsData, ProcessedFile -} from '../../buildScripts/DataTypes' +} from '../../buildScripts/DataTypes.mts' type AppOwnProps = { trayWidth: number diff --git a/packages/__docs__/src/Document/index.tsx b/packages/__docs__/src/Document/index.tsx index 0e46b8b07d..463487050d 100644 --- a/packages/__docs__/src/Document/index.tsx +++ b/packages/__docs__/src/Document/index.tsx @@ -86,19 +86,13 @@ class Document extends Component { } renderProps(doc: DocDataType) { - const { id, props, description } = doc - const hasTsProps = - typeof description === 'string' && description.includes('@tsProps') + const { id, props } = doc return props ? ( Properties - + ) : null } @@ -178,7 +172,6 @@ class Document extends Component { renderDescription(doc: DocDataType, description: string) { const { id, title } = doc const filteredDescription = description - .replace('@tsProps', '') .replace('@isWIP', '') .replace(/@module [a-zA-Z]+/g, '') return this.props.description ? ( @@ -352,7 +345,7 @@ import { ${importName} } from '${esPath}' > {this.renderDetails(doc)} - {children.map((child, index) => ( + {children.map((child: any, index: any) => ( ( - - - {section.kind && {section.kind}} - {section.title} - - {this.renderDescription(section, section.description)} - {this.renderDetails(section)} - - )) - } - return (
{ @@ -403,7 +371,6 @@ import { ${importName} } from '${esPath}' {pageRef && } {this.renderDescription(doc, this.props.description)} {details} - {sections} {['.js', '.ts', '.tsx'].includes(doc.extension) && this.renderUsage()} {this.renderEditOnGithub()} {repository && layout !== 'small' && ( diff --git a/packages/__docs__/src/Header/index.tsx b/packages/__docs__/src/Header/index.tsx index 32743b54cd..37413d55fe 100644 --- a/packages/__docs__/src/Header/index.tsx +++ b/packages/__docs__/src/Header/index.tsx @@ -48,7 +48,7 @@ class Header extends Component { } handleSelect = ( - _e: React.MouseEvent, + _e: React.MouseEvent, updated: (string | number | undefined)[] ) => { const [selectedVersion] = updated diff --git a/packages/__docs__/src/Hero/index.tsx b/packages/__docs__/src/Hero/index.tsx index b5fc7ae318..64b01e972d 100644 --- a/packages/__docs__/src/Hero/index.tsx +++ b/packages/__docs__/src/Hero/index.tsx @@ -467,7 +467,7 @@ class Hero extends Component {