From 4492bf7c208650436159c051cf4f605d1a9f2e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aar=C3=B3n=20Garc=C3=ADa=20Herv=C3=A1s?= Date: Wed, 22 May 2024 11:08:57 +0200 Subject: [PATCH] Allow JSDoc tags in hooks --- .../use-menu-item-context-stabilizer.json | 2 +- .../use-option-context-stabilizer.json | 2 +- .../ApiBuilders/HookApiBuilder.ts | 18 ++++++++++++++++-- .../useMenuItemContextStabilizer.ts | 6 +++--- .../useOption/useOptionContextStabilizer.ts | 6 +++--- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/docs/translations/api-docs/use-menu-item-context-stabilizer/use-menu-item-context-stabilizer.json b/docs/translations/api-docs/use-menu-item-context-stabilizer/use-menu-item-context-stabilizer.json index d3762313773adb..e9fb6768d1a77f 100644 --- a/docs/translations/api-docs/use-menu-item-context-stabilizer/use-menu-item-context-stabilizer.json +++ b/docs/translations/api-docs/use-menu-item-context-stabilizer/use-menu-item-context-stabilizer.json @@ -1,5 +1,5 @@ { - "hookDescription": "Stabilizes the ListContext value for the MenuItem component, so it doesn't change when sibling items update.\n\n@param id The id of the MenuItem. If undefined, it will be generated with useId.\n@returns The stable ListContext value and the id of the MenuItem.", + "hookDescription": "Stabilizes the ListContext value for the MenuItem component, so it doesn't change when sibling items update.", "parametersDescriptions": {}, "returnValueDescriptions": {} } diff --git a/docs/translations/api-docs/use-option-context-stabilizer/use-option-context-stabilizer.json b/docs/translations/api-docs/use-option-context-stabilizer/use-option-context-stabilizer.json index 6c507c07107d7b..9a29af89977418 100644 --- a/docs/translations/api-docs/use-option-context-stabilizer/use-option-context-stabilizer.json +++ b/docs/translations/api-docs/use-option-context-stabilizer/use-option-context-stabilizer.json @@ -1,5 +1,5 @@ { - "hookDescription": "Stabilizes the ListContext value for the Option component, so it doesn't change when sibling Options update.\n\n@param value The value of the Option.\n@returns The stable ListContext value.", + "hookDescription": "Stabilizes the ListContext value for the Option component, so it doesn't change when sibling Options update.", "parametersDescriptions": {}, "returnValueDescriptions": {} } diff --git a/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts b/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts index f02e5e6d9de344..7a9c59bbf5d7f0 100644 --- a/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts +++ b/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts @@ -8,6 +8,7 @@ import traverse from '@babel/traverse'; import { defaultHandlers, parse as docgenParse, ReactDocgenApi } from 'react-docgen'; import kebabCase from 'lodash/kebabCase'; import upperFirst from 'lodash/upperFirst'; +import { parse as parseDoctrine, Annotation } from 'doctrine'; import { renderMarkdown } from '@mui/internal-markdown'; import { ProjectSettings } from '../ProjectSettings'; import { computeApiDescription } from './ComponentApiBuilder'; @@ -108,7 +109,7 @@ export interface ReactApi extends ReactDocgenApi { * * * * - [useButton API](https://mui.com/base-ui/api/use-button/) */ -async function annotateHookDefinition(api: ReactApi) { +async function annotateHookDefinition(api: ReactApi, hookJsdoc: Annotation) { const HOST = 'https://mui.com'; const typesFilename = api.filename.replace(/\.js$/, '.d.ts'); @@ -285,6 +286,14 @@ async function annotateHookDefinition(api: ReactApi) { })`, ); + if (hookJsdoc.tags.length > 0) { + markdownLines.push(''); + } + + hookJsdoc.tags.forEach((tag) => { + markdownLines.push(`@${tag.title}${tag.name ? ` ${tag.name} -` : ''} ${tag.description}`); + }); + const jsdoc = `/**\n${markdownLines .map((line) => (line.length > 0 ? ` * ${line}` : ` *`)) .join('\n')}\n */`; @@ -546,6 +555,11 @@ export default async function generateHookApi( const parameters = await extractInfoFromType(`${upperFirst(name)}Parameters`, project); const returnValue = await extractInfoFromType(`${upperFirst(name)}ReturnValue`, project); + const hookJsdoc = parseDoctrine(reactApi.description); + + // We override `reactApi.description` with `hookJsdoc.description` because + // the former can include JSDoc tags that we don't want to render in the docs. + reactApi.description = hookJsdoc.description; // Ignore what we might have generated in `annotateHookDefinition` const annotatedDescriptionMatch = reactApi.description.match(/(Demos|API):\r?\n\r?\n/); @@ -588,7 +602,7 @@ export default async function generateHookApi( await generateApiJson(apiPagesDirectory, reactApi); // Add comment about demo & api links to the component hook file - await annotateHookDefinition(reactApi); + await annotateHookDefinition(reactApi, hookJsdoc); } return reactApi; diff --git a/packages/mui-base/src/useMenuItem/useMenuItemContextStabilizer.ts b/packages/mui-base/src/useMenuItem/useMenuItemContextStabilizer.ts index fdcb643d437fd5..43e8719d5e0eac 100644 --- a/packages/mui-base/src/useMenuItem/useMenuItemContextStabilizer.ts +++ b/packages/mui-base/src/useMenuItem/useMenuItemContextStabilizer.ts @@ -6,9 +6,6 @@ import { ListContext, ListContextValue, ListItemState } from '../useList'; /** * Stabilizes the ListContext value for the MenuItem component, so it doesn't change when sibling items update. * - * @param id The id of the MenuItem. If undefined, it will be generated with useId. - * @returns The stable ListContext value and the id of the MenuItem. - * * Demos: * * - [Menu](https://mui.com/base-ui/react-menu/#hooks) @@ -16,6 +13,9 @@ import { ListContext, ListContextValue, ListItemState } from '../useList'; * API: * * - [useMenuItemContextStabilizer API](https://mui.com/base-ui/react-menu/hooks-api/#use-menu-item-context-stabilizer) + * + * @param id - The id of the MenuItem. If undefined, it will be generated with useId. + * @returns The stable ListContext value and the id of the MenuItem. */ export function useMenuItemContextStabilizer(id: string | undefined) { const listContext = React.useContext(ListContext as React.Context>); diff --git a/packages/mui-base/src/useOption/useOptionContextStabilizer.ts b/packages/mui-base/src/useOption/useOptionContextStabilizer.ts index 520cb1b8351a70..fe77b4e319f17a 100644 --- a/packages/mui-base/src/useOption/useOptionContextStabilizer.ts +++ b/packages/mui-base/src/useOption/useOptionContextStabilizer.ts @@ -5,9 +5,6 @@ import { ListContext, ListContextValue } from '../useList'; /** * Stabilizes the ListContext value for the Option component, so it doesn't change when sibling Options update. * - * @param value The value of the Option. - * @returns The stable ListContext value. - * * Demos: * * - [Select](https://mui.com/base-ui/react-select/#hooks) @@ -15,6 +12,9 @@ import { ListContext, ListContextValue } from '../useList'; * API: * * - [useOptionContextStabilizer API](https://mui.com/base-ui/react-select/hooks-api/#use-option-context-stabilizer) + * + * @param value - The value of the Option. + * @returns The stable ListContext value. */ export function useOptionContextStabilizer(value: OptionValue) { const listContext = React.useContext(ListContext as React.Context>);