From 7a04d9380e3b3c22a2125966de8244b1470d7bb5 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 31 Jul 2024 15:09:57 +0200 Subject: [PATCH 01/19] Move API pages to TS --- docs/package.json | 1 + .../components/{ApiPage.js => ApiPage.tsx} | 76 ++++--- .../ApiPage/list/PropertiesList.tsx | 2 +- .../components/ApiPage/list/SlotsList.tsx | 16 +- .../ApiPage/sections/ClassesSection.tsx | 18 +- .../ApiPage/sections/PropertiesSection.js | 155 -------------- .../ApiPage/sections/PropertiesSection.tsx | 195 ++++++++++++++++++ .../ApiPage/sections/SlotsSection.tsx | 9 +- .../components/ApiPage/table/SlotsTable.tsx | 6 +- .../ApiBuilders/ComponentApiBuilder.ts | 8 +- packages/api-docs-builder/index.ts | 7 +- .../types/ApiBuilder.types.ts | 119 ++++++----- .../utils/generateApiTranslation.ts | 3 +- .../src/MarkdownElement/MarkdownElement.tsx | 1 + .../src/SectionTitle/SectionTitle.tsx | 4 +- packages/mui-docs/src/i18n/i18n.tsx | 25 ++- pnpm-lock.yaml | 3 + 17 files changed, 388 insertions(+), 260 deletions(-) rename docs/src/modules/components/{ApiPage.js => ApiPage.tsx} (86%) delete mode 100644 docs/src/modules/components/ApiPage/sections/PropertiesSection.js create mode 100644 docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx diff --git a/docs/package.json b/docs/package.json index 0edc8bc33b826f..0b82a81dc10633 100644 --- a/docs/package.json +++ b/docs/package.json @@ -117,6 +117,7 @@ "@mui/internal-docs-utils": "workspace:^", "@mui/internal-scripts": "workspace:^", "@mui/internal-test-utils": "workspace:^", + "@mui-internal/api-docs-builder": "workspace:^", "@types/autosuggest-highlight": "^3.2.3", "@types/chai": "^4.3.16", "@types/css-mediaquery": "^0.1.4", diff --git a/docs/src/modules/components/ApiPage.js b/docs/src/modules/components/ApiPage.tsx similarity index 86% rename from docs/src/modules/components/ApiPage.js rename to docs/src/modules/components/ApiPage.tsx index d0515266588688..a5d000cf98b885 100644 --- a/docs/src/modules/components/ApiPage.js +++ b/docs/src/modules/components/ApiPage.tsx @@ -1,16 +1,16 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; import PropTypes from 'prop-types'; -import { exactProp } from '@mui/utils'; +import { ComponentApiContent } from '@mui-internal/api-docs-builder'; import Typography from '@mui/material/Typography'; import Alert from '@mui/material/Alert'; import { Ad, AdGuest } from '@mui/docs/Ad'; import VerifiedRoundedIcon from '@mui/icons-material/VerifiedRounded'; import WarningRoundedIcon from '@mui/icons-material/WarningRounded'; -import { useTranslate, useUserLanguage } from '@mui/docs/i18n'; +import { Translator, useTranslate, useUserLanguage } from '@mui/docs/i18n'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { BrandingProvider } from '@mui/docs/branding'; -import { SectionTitle } from '@mui/docs/SectionTitle'; +import { SectionTitle, SectionTitleProps } from '@mui/docs/SectionTitle'; import { MarkdownElement } from '@mui/docs/MarkdownElement'; import AppLayoutDocs from 'docs/src/modules/components/AppLayoutDocs'; import PropertiesSection, { @@ -20,9 +20,24 @@ import ClassesSection, { getClassesToC, } from 'docs/src/modules/components/ApiPage/sections/ClassesSection'; import SlotsSection from 'docs/src/modules/components/ApiPage/sections/SlotsSection'; -import { DEFAULT_API_LAYOUT_STORAGE_KEYS } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; +import { + ApiDisplayOptions, + DEFAULT_API_LAYOUT_STORAGE_KEYS, +} from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; +import { PropsTranslations } from 'packages/api-docs-builder/types/ApiBuilder.types'; +import { TableOfContentsEntry } from '@mui/internal-markdown'; -export function getTranslatedHeader(t, header) { +type ApiHeaderKeys = + | 'demos' + | 'import' + | 'props' + | 'theme-default-props' + | 'inheritance' + | 'slots' + | 'classes' + | 'css'; + +export function getTranslatedHeader(t: Translator, header: ApiHeaderKeys) { const translations = { demos: t('api-docs.demos'), import: t('api-docs.import'), @@ -46,7 +61,7 @@ export function getTranslatedHeader(t, header) { return translations[header] || header; } -function Heading(props) { +function Heading(props: Pick, 'hash' | 'level'>) { const { hash, level = 'h2' } = props; const t = useTranslate(); return ; @@ -57,7 +72,30 @@ Heading.propTypes = { level: PropTypes.string, }; -export default function ApiPage(props) { +export interface LayoutStorageKeys { + slots: string; + props: string; + classes: string; +} + +interface ApiPageProps { + descriptions: { + [lang: string]: PropsTranslations & { + // Table of Content added by the mapApiPageTranslations function + componentDescriptionToc: TableOfContentsEntry[]; + }; + }; + disableAd?: boolean; + pageContent: ComponentApiContent; + defaultLayout?: ApiDisplayOptions; + /** + * The localStorage key used to save the user layout for each section. + * It's useful to dave different preferences on different pages. + * For example, the data grid has a different key that the core. + */ + layoutStorageKey?: LayoutStorageKeys; +} +export default function ApiPage(props: ApiPageProps) { const { descriptions, disableAd = false, @@ -77,7 +115,7 @@ export default function ApiPage(props) { inheritance, props: componentProps, spread, - slots: componentSlots, + slots: componentSlots = [], classes, } = pageContent; @@ -106,14 +144,14 @@ export default function ApiPage(props) { classDescriptions, deprecationInfo, propDescriptions, - slotDescriptions, + slotDescriptions = {}, } = descriptions[userLanguage]; const description = t('api-docs.pageDescription').replace(/{{name}}/, pageContent.name); // Prefer linking the .tsx or .d.ts for the "Edit this page" link. const apiSourceLocation = filename.replace('.js', '.d.ts'); - function createTocEntry(sectionName) { + function createTocEntry(sectionName: ApiHeaderKeys) { return { text: getTranslatedHeader(t, sectionName), hash: sectionName, @@ -288,6 +326,7 @@ export default function ApiPage(props) { /> )} + ( + ) ); } - -ApiPage.propTypes = { - defaultLayout: PropTypes.oneOf(['collapsed', 'expanded', 'table']), - descriptions: PropTypes.object.isRequired, - disableAd: PropTypes.bool, - layoutStorageKey: PropTypes.shape({ - classes: PropTypes.string, - props: PropTypes.string, - slots: PropTypes.string, - }), - pageContent: PropTypes.object.isRequired, -}; - -if (process.env.NODE_ENV !== 'production') { - ApiPage.propTypes = exactProp(ApiPage.propTypes); -} diff --git a/docs/src/modules/components/ApiPage/list/PropertiesList.tsx b/docs/src/modules/components/ApiPage/list/PropertiesList.tsx index 9bd1ed3d69e756..9a431389c10c98 100644 --- a/docs/src/modules/components/ApiPage/list/PropertiesList.tsx +++ b/docs/src/modules/components/ApiPage/list/PropertiesList.tsx @@ -145,7 +145,7 @@ export interface Properties { isPremiumPlan?: boolean; propDefault?: string; propName: string; - requiresRef?: string; + requiresRef?: boolean; seeMoreDescription?: string; signature?: string; signatureArgs?: { argName: string; argDescription?: string }[]; diff --git a/docs/src/modules/components/ApiPage/list/SlotsList.tsx b/docs/src/modules/components/ApiPage/list/SlotsList.tsx index d05c5a859fa45e..d743843db6a701 100644 --- a/docs/src/modules/components/ApiPage/list/SlotsList.tsx +++ b/docs/src/modules/components/ApiPage/list/SlotsList.tsx @@ -43,14 +43,14 @@ const StyledApiItem = styled(ExpandableApiItem)( }), ); -type HashParams = { componentName: string; className: string }; +type HashParams = { componentName: string; className: string | null; name: string }; -export function getHash({ componentName, className }: HashParams) { - return `${componentName}-css-${className}`; +export function getHash({ componentName, className, name }: HashParams) { + return `${componentName}-css-${className ?? name}`; } -export type SlotsFormatedParams = { - className: string; +export type SlotsFormattedParams = { + className: string | null; componentName: string; description?: string; name: string; @@ -58,7 +58,7 @@ export type SlotsFormatedParams = { }; interface SlotsListProps { - slots: SlotsFormatedParams[]; + slots: SlotsFormattedParams[]; displayOption: 'collapsed' | 'expanded'; } @@ -75,8 +75,8 @@ export default function SlotsList(props: SlotsListProps) { return ( any; + t: Translator; hash?: string; }; @@ -47,8 +47,18 @@ export type ClassesSectionProps = { classDescriptions: ClassDescription; componentName: string; spreadHint?: string; - title: string; - titleHash: string; + /** + * The translation key of the section title. + * @default 'api-docs.classes' + */ + title?: string; + /** + * @default 'classes' + */ + titleHash?: string; + /** + * @default 'h2' + */ level?: 'h2' | 'h3' | 'h4'; defaultLayout: ApiDisplayOptions; layoutStorageKey: string; diff --git a/docs/src/modules/components/ApiPage/sections/PropertiesSection.js b/docs/src/modules/components/ApiPage/sections/PropertiesSection.js deleted file mode 100644 index 27de98b4755c15..00000000000000 --- a/docs/src/modules/components/ApiPage/sections/PropertiesSection.js +++ /dev/null @@ -1,155 +0,0 @@ -/* eslint-disable react/no-danger */ -import * as React from 'react'; -import PropTypes from 'prop-types'; -import Box from '@mui/material/Box'; -import { useTranslate } from '@mui/docs/i18n'; -import { SectionTitle } from '@mui/docs/SectionTitle'; -import ToggleDisplayOption, { - useApiPageOption, -} from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; -import PropertiesList, { getHash } from 'docs/src/modules/components/ApiPage/list/PropertiesList'; -import PropertiesTable from 'docs/src/modules/components/ApiPage/table/PropertiesTable'; - -export function getPropsToC({ - componentName, - componentProps, - inheritance, - themeDefaultProps, - t, - hash, -}) { - return { - text: t('api-docs.props'), - hash: hash ?? 'props', - children: [ - ...Object.entries(componentProps) - .filter(([, propData]) => propData.description !== '@ignore') - .map(([propName]) => ({ - text: propName, - hash: getHash({ propName, componentName }), - children: [], - })), - ...(inheritance - ? [{ text: t('api-docs.inheritance'), hash: 'inheritance', children: [] }] - : []), - ...(themeDefaultProps - ? [{ text: t('api-docs.themeDefaultProps'), hash: 'theme-default-props', children: [] }] - : []), - ], - }; -} - -export default function PropertiesSection(props) { - const { - properties, - propertiesDescriptions, - componentName = '', - showOptionalAbbr = false, - title = 'api-docs.props', - titleHash = 'props', - level = 'h2', - spreadHint, - hooksParameters = false, - hooksReturnValue = false, - defaultLayout, - layoutStorageKey, - } = props; - const t = useTranslate(); - - const [displayOption, setDisplayOption] = useApiPageOption(layoutStorageKey, defaultLayout); - const formatedProperties = Object.entries(properties) - .filter(([, propData]) => propData.description !== '@ignore') - .map(([propName, propData]) => { - const isRequired = propData.required && !showOptionalAbbr; - const isOptional = !propData.required && showOptionalAbbr; - - const isDeprecated = propData.deprecated; - const deprecationInfo = propData.deprecationInfo; - - const typeName = propData.type?.description || propData.type.name; - const propDefault = propData.default; - const propDescription = propertiesDescriptions[propName]; - - const additionalInfo = [ - 'cssApi', - 'sx', - 'slotsApi', - 'joy-size', - 'joy-color', - 'joy-variant', - ].filter((key) => propData.additionalInfo?.[key]); - - const seeMoreDescription = - propDescription?.seeMoreText && - propData.seeMoreLink && - propDescription.seeMoreText.replace( - '{{link}}', - `${propData.seeMoreLink.text}`, - ); - - const signature = propData.signature?.type; - const signatureArgs = propData.signature?.describedArgs?.map((argName) => ({ - argName, - argDescription: propertiesDescriptions[propName].typeDescriptions[argName], - })); - const signatureReturnDescription = - propData.signature?.returned && - propertiesDescriptions[propName].typeDescriptions[propData.signature.returned]; - - return { - componentName, - propName, - seeMoreDescription, - description: propDescription?.description, - requiresRef: propDescription?.requiresRef, - isOptional, - isRequired, - isProPlan: propData.isProPlan, - isPremiumPlan: propData.isPremiumPlan, - isDeprecated, - hooksParameters, - hooksReturnValue, - deprecationInfo, - typeName, - propDefault, - additionalInfo, - signature, - signatureArgs, - signatureReturnDescription, - }; - }); - - return ( - - - - - - {spreadHint &&

} - {displayOption === 'table' ? ( - - ) : ( - - )} - - ); -} - -PropertiesSection.propTypes = { - componentName: PropTypes.string, - defaultLayout: PropTypes.oneOf(['collapsed', 'expanded', 'table']).isRequired, - hooksParameters: PropTypes.bool, - hooksReturnValue: PropTypes.bool, - layoutStorageKey: PropTypes.string.isRequired, - level: PropTypes.string, - properties: PropTypes.object.isRequired, - propertiesDescriptions: PropTypes.object.isRequired, - showOptionalAbbr: PropTypes.bool, - spreadHint: PropTypes.string, - title: PropTypes.string, - titleHash: PropTypes.string, -}; diff --git a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx new file mode 100644 index 00000000000000..25c29f19dfadcc --- /dev/null +++ b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx @@ -0,0 +1,195 @@ +/* eslint-disable react/no-danger */ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import Box from '@mui/material/Box'; +import { Translator, useTranslate } from '@mui/docs/i18n'; +import { SectionTitle, SectionTitleProps } from '@mui/docs/SectionTitle'; +import ToggleDisplayOption, { + ApiDisplayOptions, + useApiPageOption, +} from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; +import PropertiesList, { getHash } from 'docs/src/modules/components/ApiPage/list/PropertiesList'; +import PropertiesTable from 'docs/src/modules/components/ApiPage/table/PropertiesTable'; +import { ComponentApiContent } from '@mui-internal/api-docs-builder'; +import { + PropsTableItem, + PropsTranslations, +} from 'packages/api-docs-builder/types/ApiBuilder.types'; +import { LayoutStorageKeys } from '../../ApiPage'; + +interface GetPropsToCParams extends Pick { + componentProps: ComponentApiContent['props']; + componentName: ComponentApiContent['name']; + t: Translator; + /** + * @default 'props' + */ + hash?: string; +} + +export function getPropsToC({ + componentName, + componentProps, + inheritance, + themeDefaultProps, + t, + hash = 'props', +}: GetPropsToCParams) { + return { + text: t('api-docs.props'), + hash, + children: [ + ...Object.entries(componentProps).map(([propName]) => ({ + text: propName, + hash: getHash({ propName, componentName }), + children: [], + })), + ...(inheritance + ? [{ text: t('api-docs.inheritance'), hash: 'inheritance', children: [] }] + : []), + ...(themeDefaultProps + ? [{ text: t('api-docs.themeDefaultProps'), hash: 'theme-default-props', children: [] }] + : []), + ], + }; +} + +interface PropertiesSectionProps { + properties: { + // isProPlan and isPremiumPlan are added for the MUI X interface documentation. + [name: string]: PropsTableItem & { isProPlan?: true; isPremiumPlan?: true }; + }; + propertiesDescriptions: PropsTranslations['propDescriptions']; + componentName: string; + spreadHint: string; + defaultLayout: ApiDisplayOptions; + layoutStorageKey: LayoutStorageKeys['props']; + /** + * Add indicators that the properties is optional instead of showing it is required. + */ + showOptionalAbbr?: boolean; + /** + * The translation key of the section title. + * @default 'api-docs.props' + */ + title?: string; + /** + * The hash linking to the section title. + * @default 'props' + */ + titleHash?: SectionTitleProps['hash']; + /** + * The title level of the section. + * @default 'h2' + */ + level?: SectionTitleProps['level']; + hooksParameters?: true; + hooksReturnValue?: true; +} +export default function PropertiesSection(props: PropertiesSectionProps) { + const { + properties, + propertiesDescriptions, + componentName = '', + showOptionalAbbr = false, + title = 'api-docs.props', + titleHash = 'props', + level = 'h2', + spreadHint, + hooksParameters = false, + hooksReturnValue = false, + defaultLayout, + layoutStorageKey, + } = props; + const t = useTranslate(); + + const [displayOption, setDisplayOption] = useApiPageOption(layoutStorageKey, defaultLayout); + const formattedProperties = Object.entries(properties).map(([propName, propData]) => { + const isRequired = propData.required && !showOptionalAbbr; + const isOptional = !propData.required && showOptionalAbbr; + + const isDeprecated = propData.deprecated; + const deprecationInfo = propData.deprecationInfo; + + const typeName = propData.type?.description || propData.type.name; + const propDefault = propData.default; + const propDescription = propertiesDescriptions[propName]; + + const additionalInfo = ( + ['cssApi', 'sx', 'slotsApi', 'joy-size', 'joy-color', 'joy-variant'] as const + ).filter((key) => propData.additionalInfo?.[key]); + + const seeMoreDescription = + propDescription?.seeMoreText && + propData.seeMoreLink && + propDescription.seeMoreText.replace( + '{{link}}', + `${propData.seeMoreLink.text}`, + ); + + const signature = propData.signature?.type; + const signatureArgs = propData.signature?.describedArgs?.map((argName) => ({ + argName, + argDescription: propertiesDescriptions[propName].typeDescriptions?.[argName], + })); + const signatureReturnDescription = + propData.signature?.returned && + propertiesDescriptions[propName].typeDescriptions?.[propData.signature.returned]; + + return { + componentName, + propName, + seeMoreDescription, + description: propDescription?.description, + requiresRef: propDescription?.requiresRef, + isOptional, + isRequired, + isProPlan: propData.isProPlan, + isPremiumPlan: propData.isPremiumPlan, + isDeprecated, + hooksParameters, + hooksReturnValue, + deprecationInfo, + typeName, + propDefault, + additionalInfo, + signature, + signatureArgs, + signatureReturnDescription, + }; + }); + + return ( + + + + + + {spreadHint &&

} + {displayOption === 'table' ? ( + + ) : ( + + )} + + ); +} + +PropertiesSection.propTypes = { + componentName: PropTypes.string, + defaultLayout: PropTypes.oneOf(['collapsed', 'expanded', 'table']).isRequired, + hooksParameters: PropTypes.bool, + hooksReturnValue: PropTypes.bool, + layoutStorageKey: PropTypes.string.isRequired, + level: PropTypes.string, + properties: PropTypes.object.isRequired, + propertiesDescriptions: PropTypes.object.isRequired, + showOptionalAbbr: PropTypes.bool, + spreadHint: PropTypes.string, + title: PropTypes.string, + titleHash: PropTypes.string, +}; diff --git a/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx b/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx index 6b45e992905a02..82cc42d34e4a6e 100644 --- a/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx @@ -3,6 +3,7 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import { useTranslate } from '@mui/docs/i18n'; import { SectionTitle } from '@mui/docs/SectionTitle'; +import { ComponentApiContent } from '@mui-internal/api-docs-builder'; import ToggleDisplayOption, { ApiDisplayOptions, useApiPageOption, @@ -11,7 +12,7 @@ import SlotsList from 'docs/src/modules/components/ApiPage/list/SlotsList'; import SlotsTable from 'docs/src/modules/components/ApiPage/table/SlotsTable'; export type SlotsSectionProps = { - componentSlots: { class: string; name: string; default: string }[]; + componentSlots: ComponentApiContent['slots']; slotDescriptions: { [key: string]: string }; componentName: string; title?: string; @@ -42,7 +43,7 @@ export default function SlotsSection(props: SlotsSectionProps) { return null; } - const formatedSlots = componentSlots?.map(({ class: className, name, default: defaultValue }) => { + const formattedSlots = componentSlots?.map(({ class: className, name, default: defaultValue }) => { return { description: slotDescriptions[name], className, @@ -64,9 +65,9 @@ export default function SlotsSection(props: SlotsSectionProps) { {spreadHint &&

} {displayOption === 'table' ? ( - + ) : ( - + )} ); diff --git a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx index bdaaf23ef987fe..8aa43055b88224 100644 --- a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx +++ b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx @@ -6,7 +6,7 @@ import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, } from '@mui/docs/branding'; -import { SlotsFormatedParams, getHash } from 'docs/src/modules/components/ApiPage/list/SlotsList'; +import { SlotsFormattedParams, getHash } from 'docs/src/modules/components/ApiPage/list/SlotsList'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; const StyledTable = styled('table')( @@ -69,7 +69,7 @@ const StyledTable = styled('table')( ); interface SlotsTableProps { - slots: SlotsFormatedParams[]; + slots: SlotsFormattedParams[]; } export default function SlotsTable(props: SlotsTableProps) { @@ -92,7 +92,7 @@ export default function SlotsTable(props: SlotsTableProps) { const { description, className, name, defaultValue, componentName } = params; return ( - + {name} diff --git a/packages/api-docs-builder/ApiBuilders/ComponentApiBuilder.ts b/packages/api-docs-builder/ApiBuilders/ComponentApiBuilder.ts index c4279fd99407d8..386a90b0b0d2af 100644 --- a/packages/api-docs-builder/ApiBuilders/ComponentApiBuilder.ts +++ b/packages/api-docs-builder/ApiBuilders/ComponentApiBuilder.ts @@ -25,7 +25,11 @@ import { TypeScriptProject } from '../utils/createTypeScriptProject'; import parseSlotsAndClasses from '../utils/parseSlotsAndClasses'; import generateApiTranslations from '../utils/generateApiTranslation'; import { sortAlphabetical } from '../utils/sortObjects'; -import { AdditionalPropsInfo, ComponentReactApi } from '../types/ApiBuilder.types'; +import { + AdditionalPropsInfo, + ComponentApiContent, + ComponentReactApi, +} from '../types/ApiBuilder.types'; import { Slot, ComponentInfo } from '../types/utils.types'; const cssComponents = ['Box', 'Grid', 'Typography', 'Stack']; @@ -301,7 +305,7 @@ const generateApiPage = async ( /** * Gather the metadata needed for the component's API page. */ - const pageContent = { + const pageContent: ComponentApiContent = { // Sorted by required DESC, name ASC props: _.fromPairs( Object.entries(reactApi.propsTable).sort(([aName, aData], [bName, bData]) => { diff --git a/packages/api-docs-builder/index.ts b/packages/api-docs-builder/index.ts index cef8251e51f4bf..aa49317a644366 100644 --- a/packages/api-docs-builder/index.ts +++ b/packages/api-docs-builder/index.ts @@ -1,3 +1,8 @@ export { buildApi } from './buildApi'; export type { ProjectSettings } from './ProjectSettings'; -export type { ComponentReactApi, HookReactApi } from './types/ApiBuilder.types'; +export type { + ComponentReactApi, + ComponentApiContent, + HookReactApi, +} from './types/ApiBuilder.types'; +export type { Slot } from './types/utils.types'; diff --git a/packages/api-docs-builder/types/ApiBuilder.types.ts b/packages/api-docs-builder/types/ApiBuilder.types.ts index cd77289cde5777..e5445ae8ad01fd 100644 --- a/packages/api-docs-builder/types/ApiBuilder.types.ts +++ b/packages/api-docs-builder/types/ApiBuilder.types.ts @@ -36,6 +36,40 @@ interface CommonReactApi extends ReactDocgenApi { deprecated: true | undefined; } +export interface PropsTableItem { + default: string | undefined; + required: boolean | undefined; + type: { name: string; description: string | undefined }; + deprecated: true | undefined; + deprecationInfo: string | undefined; + signature: undefined | { type: string; describedArgs?: string[]; returned?: string }; + additionalInfo?: AdditionalPropsInfo; + seeMoreLink?: SeeMore['link']; +} + +export interface PropsTranslations { + componentDescription: string; + deprecationInfo: string | undefined; + propDescriptions: { + [key: string]: { + description: string; + requiresRef?: boolean; + deprecated?: string; + typeDescriptions?: { [t: string]: string }; + seeMoreText?: string; + }; + }; + classDescriptions: { + [key: string]: { + description: string; + conditions?: string; + nodeName?: string; + deprecationInfo?: string; + }; + }; + slotDescriptions?: { [key: string]: string }; +} + export interface ComponentReactApi extends CommonReactApi { forwardsRefTo: string | undefined; inheritance: ReturnType; @@ -54,38 +88,25 @@ export interface ComponentReactApi extends CommonReactApi { themeDefaultProps: boolean | undefined | null; classes: ComponentClassDefinition[]; slots: Slot[]; - propsTable: _.Dictionary<{ - default: string | undefined; - required: boolean | undefined; - type: { name: string | undefined; description: string | undefined }; - deprecated: true | undefined; - deprecationInfo: string | undefined; - signature: undefined | { type: string; describedArgs?: string[]; returned?: string }; - additionalInfo?: AdditionalPropsInfo; - seeMoreLink?: SeeMore['link']; - }>; - translations: { - componentDescription: string; - deprecationInfo: string | undefined; - propDescriptions: { - [key: string]: { - description: string; - requiresRef?: boolean; - deprecated?: string; - typeDescriptions?: { [t: string]: string }; - seeMoreText?: string; - }; - }; - classDescriptions: { - [key: string]: { - description: string; - conditions?: string; - nodeName?: string; - deprecationInfo?: string; - }; - }; - slotDescriptions?: { [key: string]: string }; - }; + propsTable: _.Dictionary; + translations: PropsTranslations; +} + +export interface ComponentApiContent { + props: { [name: string]: PropsTableItem }; + name: string; + imports: string[]; + slots?: Slot[]; + classes: ComponentClassDefinition[]; + spread: boolean | undefined; + themeDefaultProps: boolean | null | undefined; + muiName: string; + forwardsRefTo: string | undefined; + filename: string; + inheritance: null | { component: string; pathname: string }; + demos: string; + cssComponent: boolean; + deprecated: true | undefined; } export interface ParsedProperty { @@ -96,6 +117,23 @@ export interface ParsedProperty { typeStr: string; } +export interface HooksTranslations { + hookDescription: string; + deprecationInfo: string | undefined; + parametersDescriptions: { + [key: string]: { + description: string; + deprecated?: string; + }; + }; + returnValueDescriptions: { + [key: string]: { + description: string; + deprecated?: string; + }; + }; +} + export interface HookReactApi extends CommonReactApi { parameters?: ParsedProperty[]; returnValue?: ParsedProperty[]; @@ -119,20 +157,5 @@ export interface HookReactApi extends CommonReactApi { deprecated: true | undefined; deprecationInfo: string | undefined; }>; - translations: { - hookDescription: string; - deprecationInfo: string | undefined; - parametersDescriptions: { - [key: string]: { - description: string; - deprecated?: string; - }; - }; - returnValueDescriptions: { - [key: string]: { - description: string; - deprecated?: string; - }; - }; - }; + translations: HooksTranslations; } diff --git a/packages/api-docs-builder/utils/generateApiTranslation.ts b/packages/api-docs-builder/utils/generateApiTranslation.ts index 50b6aa0dbe9c9c..b1f61385e475ec 100644 --- a/packages/api-docs-builder/utils/generateApiTranslation.ts +++ b/packages/api-docs-builder/utils/generateApiTranslation.ts @@ -2,11 +2,12 @@ import { mkdirSync } from 'fs'; import path from 'path'; import kebabCase from 'lodash/kebabCase'; import { writePrettifiedFile } from '../buildApiUtils'; +import { HooksTranslations, PropsTranslations } from '../types/ApiBuilder.types'; interface MinimalReactAPI { name: string; apiDocsTranslationFolder?: string; - translations: object; + translations: PropsTranslations | HooksTranslations; } export default async function generateApiTranslations( diff --git a/packages/mui-docs/src/MarkdownElement/MarkdownElement.tsx b/packages/mui-docs/src/MarkdownElement/MarkdownElement.tsx index 039625ad4fa9a8..9849f07184d334 100644 --- a/packages/mui-docs/src/MarkdownElement/MarkdownElement.tsx +++ b/packages/mui-docs/src/MarkdownElement/MarkdownElement.tsx @@ -823,6 +823,7 @@ function handleHeaderClick(event: Event) { export interface MarkdownElementProps { className?: string; renderedMarkdown?: string; + children?: React.ReactNode; } export const MarkdownElement = React.forwardRef( diff --git a/packages/mui-docs/src/SectionTitle/SectionTitle.tsx b/packages/mui-docs/src/SectionTitle/SectionTitle.tsx index 3a12539f7b79fc..23892aa617748c 100644 --- a/packages/mui-docs/src/SectionTitle/SectionTitle.tsx +++ b/packages/mui-docs/src/SectionTitle/SectionTitle.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; -export interface SectionTitleProps { +export interface SectionTitleProps { title: string; - hash: string; + hash: Hash; level?: 'h2' | 'h3' | 'h4'; } export function SectionTitle(props: SectionTitleProps) { diff --git a/packages/mui-docs/src/i18n/i18n.tsx b/packages/mui-docs/src/i18n/i18n.tsx index 1ac68955c0e560..840fdf9419ee4d 100644 --- a/packages/mui-docs/src/i18n/i18n.tsx +++ b/packages/mui-docs/src/i18n/i18n.tsx @@ -6,7 +6,7 @@ import defaultTranslations from '../translations'; const TranslationsContext = React.createContext(defaultTranslations); interface TranslationsProviderProps { - translations?: Record; + translations?: Translations; children: React.ReactNode; } @@ -23,12 +23,23 @@ function TranslationsProvider({ translations = {}, children }: TranslationsProvi ); } -function getPath(obj: any, path: string): any { +function getPath(obj: Translations, path: string): string | null { if (!path || typeof path !== 'string') { return null; } - return path.split('.').reduce((acc, item) => (acc && acc[item] ? acc[item] : null), obj); + const translation = path + .split('.') + .reduce( + (acc: Translations | string | null, item) => + (acc && typeof acc === 'object' && acc[item]) || null, + obj, + ); + + if (typeof translation === 'object') { + return null; + } + return translation; } interface UserLanguageContextValue { @@ -96,7 +107,9 @@ export interface TranslateOptions { ignoreWarning?: boolean; } -export function useTranslate() { +export type Translator = (key: string, options?: TranslateOptions) => string; + +export function useTranslate(): Translator { const userLanguage = useUserLanguage(); const translations = React.useContext(TranslationsContext); @@ -116,7 +129,9 @@ export function useTranslate() { if (!translation) { warn(userLanguage, key, ignoreWarning); - return getPath(translations.en, key); + + const enTranslation = getPath(translations.en, key); + return enTranslation ?? key; } return translation; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 514cc2ea1299e4..1b3676f0144203 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -816,6 +816,9 @@ importers: '@babel/preset-typescript': specifier: ^7.24.7 version: 7.24.7(@babel/core@7.24.9) + '@mui-internal/api-docs-builder': + specifier: workspace:^ + version: link:../packages/api-docs-builder '@mui/internal-docs-utils': specifier: workspace:^ version: link:../packages-internal/docs-utils From 4a74e29d54e57f3b8ab48989a7f0cbff041bc7d8 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 31 Jul 2024 16:13:08 +0200 Subject: [PATCH 02/19] work --- .../components/ApiPage/common/classes.ts | 16 ++++ .../components/ApiPage/common/properties.ts | 88 +++++++++++++++++++ .../components/ApiPage/common/slots.ts | 15 ++++ .../components/ApiPage/list/ClassesList.tsx | 25 +++--- .../ApiPage/list/ExpandableApiItem.tsx | 2 +- .../ApiPage/list/PropertiesList.tsx | 57 ++---------- .../components/ApiPage/list/SlotsList.tsx | 25 ++---- .../ApiPage/sections/ClassesSection.tsx | 7 +- .../ApiPage/sections/PropertiesSection.tsx | 44 +--------- .../components/ApiPage/table/ClassesTable.tsx | 6 +- .../ApiPage/table/PropertiesTable.tsx | 14 ++- .../components/ApiPage/table/SlotsTable.tsx | 6 +- 12 files changed, 172 insertions(+), 133 deletions(-) create mode 100644 docs/src/modules/components/ApiPage/common/classes.ts create mode 100644 docs/src/modules/components/ApiPage/common/properties.ts create mode 100644 docs/src/modules/components/ApiPage/common/slots.ts diff --git a/docs/src/modules/components/ApiPage/common/classes.ts b/docs/src/modules/components/ApiPage/common/classes.ts new file mode 100644 index 00000000000000..c3dac732a13439 --- /dev/null +++ b/docs/src/modules/components/ApiPage/common/classes.ts @@ -0,0 +1,16 @@ +import kebabCase from 'lodash/kebabCase'; + +type HashParams = { componentName: string; className: string }; + +export function getClassesHash({ componentName, className }: HashParams) { + return `${kebabCase(componentName)}-classes-${className}`; +} + +export interface ClassDefinition { + className: string; + key: string; + description?: string; + isGlobal?: boolean; + isDeprecated?: boolean; + deprecationInfo?: string; +} diff --git a/docs/src/modules/components/ApiPage/common/properties.ts b/docs/src/modules/components/ApiPage/common/properties.ts new file mode 100644 index 00000000000000..b040c82e6b2fac --- /dev/null +++ b/docs/src/modules/components/ApiPage/common/properties.ts @@ -0,0 +1,88 @@ +import { Translator } from '@mui/docs/i18n'; +import kebabCase from 'lodash/kebabCase'; +import { ComponentApiContent } from 'packages/api-docs-builder'; + +export function getPropertiesHash({ + componentName, + propName, + hooksParameters, + hooksReturnValue, +}: { + componentName: string; + propName: string; + hooksParameters?: boolean; + hooksReturnValue?: boolean; +}) { + let sectionName = 'prop'; + if (hooksParameters) { + sectionName = 'parameters'; + } else if (hooksReturnValue) { + sectionName = 'return-value'; + } + return `${kebabCase(componentName)}-${sectionName}-${propName}`; +} + +export interface PropertyDefinition { + additionalInfo: string[]; + componentName: string; + deprecationInfo?: string; + description?: string; + hooksParameters?: boolean; + hooksReturnValue?: boolean; + isDeprecated?: boolean; + isOptional?: boolean; + isRequired?: boolean; + propDefault?: string; + propName: string; + requiresRef?: boolean; + seeMoreDescription?: string; + signature?: string; + signatureArgs?: { argName: string; argDescription?: string }[]; + signatureReturnDescription?: string; + typeName: string; + /** + * Used by MUI X interface documentation + */ + isProPlan?: boolean; + /** + * Used by MUI X interface documentation + */ + isPremiumPlan?: boolean; +} + +interface GetPropsToCParams extends Pick { + componentProps: ComponentApiContent['props']; + componentName: ComponentApiContent['name']; + t: Translator; + /** + * @default 'props' + */ + hash?: string; +} + +export function getPropsToC({ + componentName, + componentProps, + inheritance, + themeDefaultProps, + t, + hash = 'props', +}: GetPropsToCParams) { + return { + text: t('api-docs.props'), + hash, + children: [ + ...Object.entries(componentProps).map(([propName]) => ({ + text: propName, + hash: getPropertiesHash({ propName, componentName }), + children: [], + })), + ...(inheritance + ? [{ text: t('api-docs.inheritance'), hash: 'inheritance', children: [] }] + : []), + ...(themeDefaultProps + ? [{ text: t('api-docs.themeDefaultProps'), hash: 'theme-default-props', children: [] }] + : []), + ], + }; +} diff --git a/docs/src/modules/components/ApiPage/common/slots.ts b/docs/src/modules/components/ApiPage/common/slots.ts new file mode 100644 index 00000000000000..1a1fcfc47febc9 --- /dev/null +++ b/docs/src/modules/components/ApiPage/common/slots.ts @@ -0,0 +1,15 @@ +type HashParams = { componentName: string; className: string | null; name: string }; + +// eslint-disable-next-line import/prefer-default-export +export function getSlotsHash({ componentName, className, name }: HashParams) { + // We can use "-css-" linke in `getClassesHash` because slots with associated className should not be rendered in classes. + return `${componentName}-css-${className ?? name}`; +} + +export type SlotsDefinition = { + className: string | null; + componentName: string; + description?: string; + name: string; + defaultValue?: string; +}; diff --git a/docs/src/modules/components/ApiPage/list/ClassesList.tsx b/docs/src/modules/components/ApiPage/list/ClassesList.tsx index 4e20b6e72eab4a..c970c7f862f978 100644 --- a/docs/src/modules/components/ApiPage/list/ClassesList.tsx +++ b/docs/src/modules/components/ApiPage/list/ClassesList.tsx @@ -1,12 +1,14 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; import { styled } from '@mui/material/styles'; -import kebabCase from 'lodash/kebabCase'; -import { ComponentClassDefinition } from '@mui/internal-docs-utils'; import { useTranslate } from '@mui/docs/i18n'; import ExpandableApiItem, { - ApiItemContaier, + ApiItemContainer, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; +import { + ClassDefinition, + getClassesHash, +} from 'docs/src/modules/components/ApiPage/common/classes'; import { brandingLightTheme as lightTheme, brandingDarkTheme as darkTheme, @@ -49,16 +51,13 @@ const StyledApiItem = styled(ExpandableApiItem)( }), ); -type HashParams = { componentName: string; className: string }; - -export function getHash({ componentName, className }: HashParams) { - return `${kebabCase(componentName)}-classes-${className}`; -} - type ClassesListProps = { componentName: string; - classes: ComponentClassDefinition[]; + classes: ClassDefinition[]; displayOption: 'collapsed' | 'expanded'; + /** + * If `true` the the associated key in the classes object is visible. + */ displayClassKeys?: boolean; }; @@ -67,7 +66,7 @@ export default function ClassesList(props: ClassesListProps) { const t = useTranslate(); return ( - + {classes.map((classDefinition) => { const { className, key, description, isGlobal, isDeprecated, deprecationInfo } = classDefinition; @@ -80,7 +79,7 @@ export default function ClassesList(props: ClassesListProps) { return ( ); })} - + ); } diff --git a/docs/src/modules/components/ApiPage/list/ExpandableApiItem.tsx b/docs/src/modules/components/ApiPage/list/ExpandableApiItem.tsx index 0a2598466f3f69..fba0ccccdb1ee5 100644 --- a/docs/src/modules/components/ApiPage/list/ExpandableApiItem.tsx +++ b/docs/src/modules/components/ApiPage/list/ExpandableApiItem.tsx @@ -221,7 +221,7 @@ export default function ExpandableApiItem(props: ExpandableApiItemProps) { ); } -export const ApiItemContaier = styled('div')({ +export const ApiItemContainer = styled('div')({ width: '100%', display: 'flex', flexDirection: 'column', diff --git a/docs/src/modules/components/ApiPage/list/PropertiesList.tsx b/docs/src/modules/components/ApiPage/list/PropertiesList.tsx index 9a431389c10c98..7d0895b6b7040f 100644 --- a/docs/src/modules/components/ApiPage/list/PropertiesList.tsx +++ b/docs/src/modules/components/ApiPage/list/PropertiesList.tsx @@ -1,16 +1,19 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; import { styled } from '@mui/material/styles'; -import kebabCase from 'lodash/kebabCase'; import { useTranslate } from '@mui/docs/i18n'; import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, } from '@mui/docs/branding'; import ExpandableApiItem, { - ApiItemContaier, + ApiItemContainer, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; import ApiWarningAlert from 'docs/src/modules/components/ApiPage/ApiWarningAlert'; +import { + getPropertiesHash, + PropertyDefinition, +} from 'docs/src/modules/components/ApiPage/common/properties'; const StyledApiItem = styled(ExpandableApiItem)( ({ theme }) => ({ @@ -111,50 +114,8 @@ function PropDescription(props: { description: string }) { ); } -export function getHash({ - componentName, - propName, - hooksParameters, - hooksReturnValue, -}: { - componentName: string; - propName: string; - hooksParameters?: boolean; - hooksReturnValue?: boolean; -}) { - let sectionName = 'prop'; - if (hooksParameters) { - sectionName = 'parameters'; - } else if (hooksReturnValue) { - sectionName = 'return-value'; - } - return `${kebabCase(componentName)}-${sectionName}-${propName}`; -} - -export interface Properties { - additionalInfo: string[]; - componentName: string; - deprecationInfo?: string; - description?: string; - hooksParameters?: boolean; - hooksReturnValue?: boolean; - isDeprecated?: boolean; - isOptional?: boolean; - isRequired?: boolean; - isProPlan?: boolean; - isPremiumPlan?: boolean; - propDefault?: string; - propName: string; - requiresRef?: boolean; - seeMoreDescription?: string; - signature?: string; - signatureArgs?: { argName: string; argDescription?: string }[]; - signatureReturnDescription?: string; - typeName: string; -} - interface PropertiesListProps { - properties: Properties[]; + properties: PropertyDefinition[]; displayOption: 'collapsed' | 'expanded'; } @@ -162,7 +123,7 @@ export default function PropertiesList(props: PropertiesListProps) { const { properties, displayOption } = props; const t = useTranslate(); return ( - + {properties.map((params) => { const { componentName, @@ -196,7 +157,7 @@ export default function PropertiesList(props: PropertiesListProps) { return ( {propName} @@ -310,6 +271,6 @@ export default function PropertiesList(props: PropertiesListProps) { ); })} - + ); } diff --git a/docs/src/modules/components/ApiPage/list/SlotsList.tsx b/docs/src/modules/components/ApiPage/list/SlotsList.tsx index d743843db6a701..c2a59568293fa2 100644 --- a/docs/src/modules/components/ApiPage/list/SlotsList.tsx +++ b/docs/src/modules/components/ApiPage/list/SlotsList.tsx @@ -7,8 +7,9 @@ import { } from '@mui/docs/branding'; import { useTranslate } from '@mui/docs/i18n'; import ExpandableApiItem, { - ApiItemContaier, + ApiItemContainer, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; +import { getSlotsHash, SlotsDefinition } from 'docs/src/modules/components/ApiPage/common/slots'; const StyledApiItem = styled(ExpandableApiItem)( ({ theme }) => ({ @@ -43,22 +44,8 @@ const StyledApiItem = styled(ExpandableApiItem)( }), ); -type HashParams = { componentName: string; className: string | null; name: string }; - -export function getHash({ componentName, className, name }: HashParams) { - return `${componentName}-css-${className ?? name}`; -} - -export type SlotsFormattedParams = { - className: string | null; - componentName: string; - description?: string; - name: string; - defaultValue?: string; -}; - interface SlotsListProps { - slots: SlotsFormattedParams[]; + slots: SlotsDefinition[]; displayOption: 'collapsed' | 'expanded'; } @@ -67,7 +54,7 @@ export default function SlotsList(props: SlotsListProps) { const t = useTranslate(); return ( - + {slots.map((params) => { const { description, className, name, defaultValue, componentName } = params; @@ -75,7 +62,7 @@ export default function SlotsList(props: SlotsListProps) { return ( ); })} - + ); } diff --git a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx index 2faa6179a7115b..5cb5e1b61d1cea 100644 --- a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx @@ -8,8 +8,9 @@ import ToggleDisplayOption, { ApiDisplayOptions, useApiPageOption, } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; -import ClassesList, { getHash } from 'docs/src/modules/components/ApiPage/list/ClassesList'; +import ClassesList from 'docs/src/modules/components/ApiPage/list/ClassesList'; import ClassesTable from 'docs/src/modules/components/ApiPage/table/ClassesTable'; +import { getClassesHash } from '../common/classes'; export type GetCssToCParams = { componentName: string; @@ -28,12 +29,13 @@ export const getClassesToC = ({ componentName, componentClasses, t, hash }: GetC children: [ ...componentClasses.map((styles) => ({ text: styles.key, - hash: getHash({ componentName, className: styles.key }), + hash: getClassesHash({ componentName, className: styles.key }), children: [], })), ], }, ]; + type ClassDescription = { [classKey: string]: { description: string; @@ -42,6 +44,7 @@ type ClassDescription = { deprecationInfo?: string; }; }; + export type ClassesSectionProps = { componentClasses: ComponentClassDefinition[]; classDescriptions: ClassDescription; diff --git a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx index 25c29f19dfadcc..b3f50945eaeb75 100644 --- a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx @@ -2,57 +2,19 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import Box from '@mui/material/Box'; -import { Translator, useTranslate } from '@mui/docs/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import { SectionTitle, SectionTitleProps } from '@mui/docs/SectionTitle'; import ToggleDisplayOption, { ApiDisplayOptions, useApiPageOption, } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; -import PropertiesList, { getHash } from 'docs/src/modules/components/ApiPage/list/PropertiesList'; +import PropertiesList from 'docs/src/modules/components/ApiPage/list/PropertiesList'; import PropertiesTable from 'docs/src/modules/components/ApiPage/table/PropertiesTable'; -import { ComponentApiContent } from '@mui-internal/api-docs-builder'; import { PropsTableItem, PropsTranslations, } from 'packages/api-docs-builder/types/ApiBuilder.types'; -import { LayoutStorageKeys } from '../../ApiPage'; - -interface GetPropsToCParams extends Pick { - componentProps: ComponentApiContent['props']; - componentName: ComponentApiContent['name']; - t: Translator; - /** - * @default 'props' - */ - hash?: string; -} - -export function getPropsToC({ - componentName, - componentProps, - inheritance, - themeDefaultProps, - t, - hash = 'props', -}: GetPropsToCParams) { - return { - text: t('api-docs.props'), - hash, - children: [ - ...Object.entries(componentProps).map(([propName]) => ({ - text: propName, - hash: getHash({ propName, componentName }), - children: [], - })), - ...(inheritance - ? [{ text: t('api-docs.inheritance'), hash: 'inheritance', children: [] }] - : []), - ...(themeDefaultProps - ? [{ text: t('api-docs.themeDefaultProps'), hash: 'theme-default-props', children: [] }] - : []), - ], - }; -} +import { LayoutStorageKeys } from 'docs/src/modules/components/ApiPage'; interface PropertiesSectionProps { properties: { diff --git a/docs/src/modules/components/ApiPage/table/ClassesTable.tsx b/docs/src/modules/components/ApiPage/table/ClassesTable.tsx index 3eb163ec72727c..88addc50ff8501 100644 --- a/docs/src/modules/components/ApiPage/table/ClassesTable.tsx +++ b/docs/src/modules/components/ApiPage/table/ClassesTable.tsx @@ -7,7 +7,7 @@ import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, } from '@mui/docs/branding'; -import { getHash } from 'docs/src/modules/components/ApiPage/list/ClassesList'; +import { getClassesHash } from 'docs/src/modules/components/ApiPage/common/classes'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; import ApiWarningAlert from 'docs/src/modules/components/ApiPage/ApiWarningAlert'; @@ -54,7 +54,7 @@ const StyledTable = styled('table')( interface ClassesTableProps { componentName: string; - classes: ComponentClassDefinition[]; + classes: ClassDefinition[]; displayClassKeys?: boolean; } @@ -77,7 +77,7 @@ export default function ClassesTable(props: ClassesTableProps) { const { className, key, description, isGlobal, isDeprecated, deprecationInfo } = params; return ( - + .{className} diff --git a/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx b/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx index a0dede795e2271..9eecbe6316650b 100644 --- a/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx +++ b/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx @@ -6,7 +6,10 @@ import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, } from '@mui/docs/branding'; -import { Properties, getHash } from 'docs/src/modules/components/ApiPage/list/PropertiesList'; +import { + PropertyDefinition, + getPropertiesHash, +} from 'docs/src/modules/components/ApiPage/common/properties'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; import ApiWarningAlert from 'docs/src/modules/components/ApiPage/ApiWarningAlert'; @@ -119,7 +122,7 @@ function PropDescription({ description }: { description: string }) { } interface PropertiesTableProps { - properties: Properties[]; + properties: PropertyDefinition[]; } export default function PropertiesTable(props: PropertiesTableProps) { @@ -166,7 +169,12 @@ export default function PropertiesTable(props: PropertiesTableProps) { return ( {propName} diff --git a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx index 8aa43055b88224..811341b33d3b7c 100644 --- a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx +++ b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx @@ -6,8 +6,8 @@ import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, } from '@mui/docs/branding'; -import { SlotsFormattedParams, getHash } from 'docs/src/modules/components/ApiPage/list/SlotsList'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; +import { getSlotsHash, SlotsDefinition } from 'docs/src/modules/components/ApiPage/common/slots'; const StyledTable = styled('table')( ({ theme }) => ({ @@ -69,7 +69,7 @@ const StyledTable = styled('table')( ); interface SlotsTableProps { - slots: SlotsFormattedParams[]; + slots: SlotsDefinition[]; } export default function SlotsTable(props: SlotsTableProps) { @@ -92,7 +92,7 @@ export default function SlotsTable(props: SlotsTableProps) { const { description, className, name, defaultValue, componentName } = params; return ( - + {name} From 1ae9c7bc422c689b6b7ee36622f34dc1c9f2e514 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 1 Aug 2024 13:24:36 +0200 Subject: [PATCH 03/19] work --- docs/src/modules/components/ApiPage.tsx | 31 ++--- .../components/ApiPage/common/classes.ts | 9 +- .../components/ApiPage/common/properties.ts | 70 ++-------- .../components/ApiPage/list/ClassesList.tsx | 12 +- .../ApiPage/list/PropertiesList.tsx | 13 +- .../ApiPage/processors/properties.ts | 124 ++++++++++++++++++ .../ApiPage/sections/ClassesSection.tsx | 31 +---- .../ApiPage/sections/PropertiesSection.tsx | 98 +------------- .../components/ApiPage/table/ClassesTable.tsx | 11 +- .../ApiPage/table/PropertiesTable.tsx | 21 +-- .../components/ComponentsApiContent.js | 9 +- .../src/modules/components/HooksApiContent.js | 22 ++-- docs/src/modules/components/MarkdownDocsV2.js | 19 +-- .../ApiBuilders/HookApiBuilder.ts | 4 +- packages/api-docs-builder/index.ts | 2 + .../types/ApiBuilder.types.ts | 35 ++--- 16 files changed, 217 insertions(+), 294 deletions(-) create mode 100644 docs/src/modules/components/ApiPage/processors/properties.ts diff --git a/docs/src/modules/components/ApiPage.tsx b/docs/src/modules/components/ApiPage.tsx index a5d000cf98b885..0b297444d7e2dc 100644 --- a/docs/src/modules/components/ApiPage.tsx +++ b/docs/src/modules/components/ApiPage.tsx @@ -13,12 +13,8 @@ import { BrandingProvider } from '@mui/docs/branding'; import { SectionTitle, SectionTitleProps } from '@mui/docs/SectionTitle'; import { MarkdownElement } from '@mui/docs/MarkdownElement'; import AppLayoutDocs from 'docs/src/modules/components/AppLayoutDocs'; -import PropertiesSection, { - getPropsToC, -} from 'docs/src/modules/components/ApiPage/sections/PropertiesSection'; -import ClassesSection, { - getClassesToC, -} from 'docs/src/modules/components/ApiPage/sections/ClassesSection'; +import PropertiesSection from 'docs/src/modules/components/ApiPage/sections/PropertiesSection'; +import ClassesSection from 'docs/src/modules/components/ApiPage/sections/ClassesSection'; import SlotsSection from 'docs/src/modules/components/ApiPage/sections/SlotsSection'; import { ApiDisplayOptions, @@ -26,6 +22,7 @@ import { } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; import { PropsTranslations } from 'packages/api-docs-builder/types/ApiBuilder.types'; import { TableOfContentsEntry } from '@mui/internal-markdown'; +import { propsApiProcessor } from './ApiPage/processors/properties'; type ApiHeaderKeys = | 'demos' @@ -170,19 +167,9 @@ export default function ApiPage(props: ApiPageProps) { createTocEntry('demos'), createTocEntry('import'), ...componentDescriptionToc, - getPropsToC({ - t, - componentName: pageContent.name, - componentProps, - inheritance, - themeDefaultProps: pageContent.themeDefaultProps, - }), + createTocEntry('props'), componentSlots?.length > 0 && createTocEntry('slots'), - ...getClassesToC({ - t, - componentName: pageContent.name, - componentClasses, - }), + createTocEntry('classes'), ].filter(Boolean); // The `ref` is forwarded to the root element. @@ -273,9 +260,11 @@ export default function ApiPage(props: ApiPageProps) { ) : null} { - componentProps: ComponentApiContent['props']; - componentName: ComponentApiContent['name']; - t: Translator; - /** - * @default 'props' - */ - hash?: string; -} - -export function getPropsToC({ - componentName, - componentProps, - inheritance, - themeDefaultProps, - t, - hash = 'props', -}: GetPropsToCParams) { - return { - text: t('api-docs.props'), - hash, - children: [ - ...Object.entries(componentProps).map(([propName]) => ({ - text: propName, - hash: getPropertiesHash({ propName, componentName }), - children: [], - })), - ...(inheritance - ? [{ text: t('api-docs.inheritance'), hash: 'inheritance', children: [] }] - : []), - ...(themeDefaultProps - ? [{ text: t('api-docs.themeDefaultProps'), hash: 'theme-default-props', children: [] }] - : []), - ], - }; -} diff --git a/docs/src/modules/components/ApiPage/list/ClassesList.tsx b/docs/src/modules/components/ApiPage/list/ClassesList.tsx index c970c7f862f978..2c9092c8b95110 100644 --- a/docs/src/modules/components/ApiPage/list/ClassesList.tsx +++ b/docs/src/modules/components/ApiPage/list/ClassesList.tsx @@ -5,10 +5,7 @@ import { useTranslate } from '@mui/docs/i18n'; import ExpandableApiItem, { ApiItemContainer, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; -import { - ClassDefinition, - getClassesHash, -} from 'docs/src/modules/components/ApiPage/common/classes'; +import { ClassDefinition } from 'docs/src/modules/components/ApiPage/common/classes'; import { brandingLightTheme as lightTheme, brandingDarkTheme as darkTheme, @@ -52,7 +49,6 @@ const StyledApiItem = styled(ExpandableApiItem)( ); type ClassesListProps = { - componentName: string; classes: ClassDefinition[]; displayOption: 'collapsed' | 'expanded'; /** @@ -62,13 +58,13 @@ type ClassesListProps = { }; export default function ClassesList(props: ClassesListProps) { - const { classes, displayOption, componentName, displayClassKeys } = props; + const { classes, displayOption, displayClassKeys } = props; const t = useTranslate(); return ( {classes.map((classDefinition) => { - const { className, key, description, isGlobal, isDeprecated, deprecationInfo } = + const { hash, className, key, description, isGlobal, isDeprecated, deprecationInfo } = classDefinition; let note = isGlobal ? t('api-docs.state') : ''; @@ -79,7 +75,7 @@ export default function ClassesList(props: ClassesListProps) { return ( ({ @@ -126,7 +123,6 @@ export default function PropertiesList(props: PropertiesListProps) { {properties.map((params) => { const { - componentName, propName, seeMoreDescription, description, @@ -136,8 +132,6 @@ export default function PropertiesList(props: PropertiesListProps) { isDeprecated, isProPlan, isPremiumPlan, - hooksParameters, - hooksReturnValue, deprecationInfo, typeName, propDefault, @@ -145,6 +139,7 @@ export default function PropertiesList(props: PropertiesListProps) { signature, signatureArgs, signatureReturnDescription, + hash, } = params; let note = @@ -157,7 +152,7 @@ export default function PropertiesList(props: PropertiesListProps) { return ( {propName} @@ -189,7 +184,7 @@ export default function PropertiesList(props: PropertiesListProps) { /> )} - {additionalInfo.map((key) => ( + {additionalInfo?.map((key) => (

{ + const isRequired = propData.required && !showOptionalAbbr; + const isOptional = !propData.required && showOptionalAbbr; + + const isDeprecated = propData.deprecated; + const deprecationInfo = propData.deprecationInfo; + + const typeName = propData.type?.description || propData.type.name; + const propDefault = propData.default; + const propDescription = propertiesDescriptions[propName]; + + const additionalInfo = ( + ['cssApi', 'sx', 'slotsApi', 'joy-size', 'joy-color', 'joy-variant'] as const + ).filter((key) => propData.additionalInfo?.[key]); + + const seeMoreDescription = + propDescription?.seeMoreText && + propData.seeMoreLink && + propDescription.seeMoreText.replace( + '{{link}}', + `${propData.seeMoreLink.text}`, + ); + + const signature = propData.signature?.type; + const signatureArgs = propData.signature?.describedArgs?.map((argName) => ({ + argName, + argDescription: propertiesDescriptions[propName].typeDescriptions?.[argName], + })); + const signatureReturnDescription = + propData.signature?.returned && + propertiesDescriptions[propName].typeDescriptions?.[propData.signature.returned]; + + return { + hash: `${kebabCase(componentName)}-prop-${propName}`, + propName, + seeMoreDescription, + description: propDescription?.description, + requiresRef: propDescription?.requiresRef, + isOptional, + isRequired, + isDeprecated, + deprecationInfo, + typeName, + propDefault, + additionalInfo, + signature, + signatureArgs, + signatureReturnDescription, + }; + }); +} + +// interface InterfaceApiProcessorParams {} + +// export function InterfaceApiProcessor(params: InterfaceApiProcessorParams): PropertyDefinition[] { +// return []; +// } + +interface HookCommonApiParams { + hookName: string; +} + +interface HookReturnApiProcessorParams extends HookCommonApiParams { + kind: 'return'; + properties: HookApiContent['returnValue']; + translations: HooksTranslations['returnValueDescriptions']; +} + +interface HookParametersApiProcessorParams extends HookCommonApiParams { + kind: 'parameters'; + properties: HookApiContent['parameters']; + translations: HooksTranslations['parametersDescriptions']; +} + +export function hookApiProcessor( + params: HookReturnApiProcessorParams | HookParametersApiProcessorParams, +): PropertyDefinition[] { + const { properties, translations, hookName, kind } = params; + + return Object.entries(properties).map(([propName, propData]) => { + const isOptional = !propData.required; + + const isDeprecated = propData.deprecated; + const deprecationInfo = propData.deprecationInfo; + + const typeName = propData.type?.description || propData.type.name; + const propDefault = propData.default; + const propDescription = translations[propName]; + + return { + hash: `${kebabCase(hookName)}-${kind === 'parameters' ? 'parameters' : 'return-value'}-${propName}`, + propName, + description: propDescription?.description, + isOptional, + isDeprecated, + deprecationInfo, + typeName, + propDefault, + }; + }); +} diff --git a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx index 5cb5e1b61d1cea..b0dc20179e69f2 100644 --- a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx @@ -1,6 +1,6 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; -import { Translator, useTranslate } from '@mui/docs/i18n'; +import { useTranslate } from '@mui/docs/i18n'; import { SectionTitle } from '@mui/docs/SectionTitle'; import { ComponentClassDefinition } from '@mui/internal-docs-utils'; import Box from '@mui/material/Box'; @@ -10,31 +10,7 @@ import ToggleDisplayOption, { } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; import ClassesList from 'docs/src/modules/components/ApiPage/list/ClassesList'; import ClassesTable from 'docs/src/modules/components/ApiPage/table/ClassesTable'; -import { getClassesHash } from '../common/classes'; - -export type GetCssToCParams = { - componentName: string; - componentClasses: ComponentClassDefinition[]; - t: Translator; - hash?: string; -}; - -export const getClassesToC = ({ componentName, componentClasses, t, hash }: GetCssToCParams) => - !componentClasses || componentClasses.length === 0 - ? [] - : [ - { - text: t('api-docs.classes'), - hash: hash ?? 'classes', - children: [ - ...componentClasses.map((styles) => ({ - text: styles.key, - hash: getClassesHash({ componentName, className: styles.key }), - children: [], - })), - ], - }, - ]; +import kebabCase from 'lodash/kebabCase'; type ClassDescription = { [classKey: string]: { @@ -100,6 +76,7 @@ export default function ClassesSection(props: ClassesSectionProps) { ?.replace(/{{nodeName}}/, classDescriptions[classDefinition.key].nodeName!) ?? classDefinition.description, deprecationInfo: classDescriptions[classDefinition.key]?.deprecationInfo, + hash: `${kebabCase(componentName)}-classes-${classDefinition.className}`, }; }); @@ -117,13 +94,11 @@ export default function ClassesSection(props: ClassesSectionProps) { {displayOption === 'table' ? ( ) : ( diff --git a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx index b3f50945eaeb75..f158543859e35e 100644 --- a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx @@ -1,6 +1,5 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; -import PropTypes from 'prop-types'; import Box from '@mui/material/Box'; import { useTranslate } from '@mui/docs/i18n'; import { SectionTitle, SectionTitleProps } from '@mui/docs/SectionTitle'; @@ -10,26 +9,14 @@ import ToggleDisplayOption, { } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; import PropertiesList from 'docs/src/modules/components/ApiPage/list/PropertiesList'; import PropertiesTable from 'docs/src/modules/components/ApiPage/table/PropertiesTable'; -import { - PropsTableItem, - PropsTranslations, -} from 'packages/api-docs-builder/types/ApiBuilder.types'; +import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/common/properties'; import { LayoutStorageKeys } from 'docs/src/modules/components/ApiPage'; interface PropertiesSectionProps { - properties: { - // isProPlan and isPremiumPlan are added for the MUI X interface documentation. - [name: string]: PropsTableItem & { isProPlan?: true; isPremiumPlan?: true }; - }; - propertiesDescriptions: PropsTranslations['propDescriptions']; - componentName: string; + properties: PropertyDefinition[]; spreadHint: string; defaultLayout: ApiDisplayOptions; layoutStorageKey: LayoutStorageKeys['props']; - /** - * Add indicators that the properties is optional instead of showing it is required. - */ - showOptionalAbbr?: boolean; /** * The translation key of the section title. * @default 'api-docs.props' @@ -45,81 +32,21 @@ interface PropertiesSectionProps { * @default 'h2' */ level?: SectionTitleProps['level']; - hooksParameters?: true; - hooksReturnValue?: true; } + export default function PropertiesSection(props: PropertiesSectionProps) { const { properties, - propertiesDescriptions, - componentName = '', - showOptionalAbbr = false, title = 'api-docs.props', titleHash = 'props', level = 'h2', spreadHint, - hooksParameters = false, - hooksReturnValue = false, defaultLayout, layoutStorageKey, } = props; const t = useTranslate(); const [displayOption, setDisplayOption] = useApiPageOption(layoutStorageKey, defaultLayout); - const formattedProperties = Object.entries(properties).map(([propName, propData]) => { - const isRequired = propData.required && !showOptionalAbbr; - const isOptional = !propData.required && showOptionalAbbr; - - const isDeprecated = propData.deprecated; - const deprecationInfo = propData.deprecationInfo; - - const typeName = propData.type?.description || propData.type.name; - const propDefault = propData.default; - const propDescription = propertiesDescriptions[propName]; - - const additionalInfo = ( - ['cssApi', 'sx', 'slotsApi', 'joy-size', 'joy-color', 'joy-variant'] as const - ).filter((key) => propData.additionalInfo?.[key]); - - const seeMoreDescription = - propDescription?.seeMoreText && - propData.seeMoreLink && - propDescription.seeMoreText.replace( - '{{link}}', - `${propData.seeMoreLink.text}`, - ); - - const signature = propData.signature?.type; - const signatureArgs = propData.signature?.describedArgs?.map((argName) => ({ - argName, - argDescription: propertiesDescriptions[propName].typeDescriptions?.[argName], - })); - const signatureReturnDescription = - propData.signature?.returned && - propertiesDescriptions[propName].typeDescriptions?.[propData.signature.returned]; - - return { - componentName, - propName, - seeMoreDescription, - description: propDescription?.description, - requiresRef: propDescription?.requiresRef, - isOptional, - isRequired, - isProPlan: propData.isProPlan, - isPremiumPlan: propData.isPremiumPlan, - isDeprecated, - hooksParameters, - hooksReturnValue, - deprecationInfo, - typeName, - propDefault, - additionalInfo, - signature, - signatureArgs, - signatureReturnDescription, - }; - }); return ( @@ -133,25 +60,10 @@ export default function PropertiesSection(props: PropertiesSectionProps) { {spreadHint &&

} {displayOption === 'table' ? ( - + ) : ( - + )} ); } - -PropertiesSection.propTypes = { - componentName: PropTypes.string, - defaultLayout: PropTypes.oneOf(['collapsed', 'expanded', 'table']).isRequired, - hooksParameters: PropTypes.bool, - hooksReturnValue: PropTypes.bool, - layoutStorageKey: PropTypes.string.isRequired, - level: PropTypes.string, - properties: PropTypes.object.isRequired, - propertiesDescriptions: PropTypes.object.isRequired, - showOptionalAbbr: PropTypes.bool, - spreadHint: PropTypes.string, - title: PropTypes.string, - titleHash: PropTypes.string, -}; diff --git a/docs/src/modules/components/ApiPage/table/ClassesTable.tsx b/docs/src/modules/components/ApiPage/table/ClassesTable.tsx index 88addc50ff8501..e57deac2763f7e 100644 --- a/docs/src/modules/components/ApiPage/table/ClassesTable.tsx +++ b/docs/src/modules/components/ApiPage/table/ClassesTable.tsx @@ -1,13 +1,12 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; -import { ComponentClassDefinition } from '@mui/internal-docs-utils'; import { useTranslate } from '@mui/docs/i18n'; import { styled, alpha } from '@mui/material/styles'; import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, } from '@mui/docs/branding'; -import { getClassesHash } from 'docs/src/modules/components/ApiPage/common/classes'; +import { ClassDefinition } from 'docs/src/modules/components/ApiPage/common/classes'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; import ApiWarningAlert from 'docs/src/modules/components/ApiPage/ApiWarningAlert'; @@ -53,13 +52,12 @@ const StyledTable = styled('table')( ); interface ClassesTableProps { - componentName: string; classes: ClassDefinition[]; displayClassKeys?: boolean; } export default function ClassesTable(props: ClassesTableProps) { - const { classes, componentName, displayClassKeys } = props; + const { classes, displayClassKeys } = props; const t = useTranslate(); return ( @@ -74,10 +72,11 @@ export default function ClassesTable(props: ClassesTableProps) { {classes.map((params) => { - const { className, key, description, isGlobal, isDeprecated, deprecationInfo } = params; + const { className, hash, key, description, isGlobal, isDeprecated, deprecationInfo } = + params; return ( - + .{className} diff --git a/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx b/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx index 9eecbe6316650b..d3855817e55da5 100644 --- a/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx +++ b/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx @@ -6,10 +6,7 @@ import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, } from '@mui/docs/branding'; -import { - PropertyDefinition, - getPropertiesHash, -} from 'docs/src/modules/components/ApiPage/common/properties'; +import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/common/properties'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; import ApiWarningAlert from 'docs/src/modules/components/ApiPage/ApiWarningAlert'; @@ -145,7 +142,6 @@ export default function PropertiesTable(props: PropertiesTableProps) { {properties.map((params) => { const { - componentName, propName, description, seeMoreDescription, @@ -155,8 +151,6 @@ export default function PropertiesTable(props: PropertiesTableProps) { isProPlan, isPremiumPlan, isDeprecated, - hooksParameters, - hooksReturnValue, deprecationInfo, typeName, propDefault, @@ -164,18 +158,11 @@ export default function PropertiesTable(props: PropertiesTableProps) { signature, signatureArgs, signatureReturnDescription, + hash, } = params; return ( - + {propName} {isRequired ? '*' : ''} @@ -218,7 +205,7 @@ export default function PropertiesTable(props: PropertiesTableProps) { className="prop-table-additional-description" /> )} - {additionalInfo.map((key) => ( + {additionalInfo?.map((key) => (

)} 0 ? ( {t('api-docs.hooksNoParameters')} )} 0 && createComponentTocEntry(componentNameKebabCase, 'slots'), - ...getClassesToC({ - t, - componentName: componentNameKebabCase, - componentClasses: classes, - hash: `${componentNameKebabCase}-classes`, - }), + createComponentTocEntry(componentNameKebabCase, 'classes'), ].filter(Boolean); componentsApiToc.push({ diff --git a/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts b/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts index e2555d53cb8896..25681aa91b4529 100644 --- a/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts +++ b/packages/api-docs-builder/ApiBuilders/HookApiBuilder.ts @@ -21,7 +21,7 @@ import { } from '../buildApiUtils'; import { TypeScriptProject } from '../utils/createTypeScriptProject'; import generateApiTranslations from '../utils/generateApiTranslation'; -import { HookReactApi, ParsedProperty } from '../types/ApiBuilder.types'; +import { HookApiContent, HookReactApi, ParsedProperty } from '../types/ApiBuilder.types'; import { HookInfo } from '../types/utils.types'; const parseProperty = async ( @@ -352,7 +352,7 @@ const generateApiJson = async (outputDirectory: string, reactApi: HookReactApi) /** * Gather the metadata needed for the component's API page. */ - const pageContent = { + const pageContent: HookApiContent = { // Sorted by required DESC, name ASC parameters: _.fromPairs( Object.entries(reactApi.parametersTable).sort(([aName, aData], [bName, bData]) => { diff --git a/packages/api-docs-builder/index.ts b/packages/api-docs-builder/index.ts index aa49317a644366..8cd1dc70512997 100644 --- a/packages/api-docs-builder/index.ts +++ b/packages/api-docs-builder/index.ts @@ -4,5 +4,7 @@ export type { ComponentReactApi, ComponentApiContent, HookReactApi, + PropsTableItem, + PropsTranslations, } from './types/ApiBuilder.types'; export type { Slot } from './types/utils.types'; diff --git a/packages/api-docs-builder/types/ApiBuilder.types.ts b/packages/api-docs-builder/types/ApiBuilder.types.ts index e5445ae8ad01fd..f9426313095028 100644 --- a/packages/api-docs-builder/types/ApiBuilder.types.ts +++ b/packages/api-docs-builder/types/ApiBuilder.types.ts @@ -134,6 +134,14 @@ export interface HooksTranslations { }; } +interface AttributeDefinition { + default: string | undefined; + required: boolean | undefined; + type: { name: string; description: string | undefined }; + deprecated: true | undefined; + deprecationInfo: string | undefined; +} + export interface HookReactApi extends CommonReactApi { parameters?: ParsedProperty[]; returnValue?: ParsedProperty[]; @@ -142,20 +150,17 @@ export interface HookReactApi extends CommonReactApi { * @example 'useButton' */ name: string; - - parametersTable: _.Dictionary<{ - default: string | undefined; - required: boolean | undefined; - type: { name: string | undefined; description: string | undefined }; - deprecated: true | undefined; - deprecationInfo: string | undefined; - }>; - returnValueTable: _.Dictionary<{ - default: string | undefined; - required: boolean | undefined; - type: { name: string | undefined; description: string | undefined }; - deprecated: true | undefined; - deprecationInfo: string | undefined; - }>; + parametersTable: _.Dictionary; + returnValueTable: _.Dictionary; translations: HooksTranslations; } + +export interface HookApiContent { + parameters: Record; + returnValue: Record; + name: string; + filename: string; + imports: string[]; + demos: string; + deprecated: boolean | undefined; +} From d6476773d28e267a95320056588591d3d9fc4835 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 2 Aug 2024 17:23:24 +0200 Subject: [PATCH 04/19] migrate classes section to processors strategy --- docs/src/modules/components/ApiPage.tsx | 11 +++-- .../components/ApiPage/common/slots.ts | 3 +- .../components/ApiPage/processors/classes.ts | 26 ++++++++++++ .../ApiPage/sections/ClassesSection.tsx | 42 +++---------------- .../components/ComponentsApiContent.js | 9 ++-- packages/api-docs-builder/index.ts | 1 + .../types/ApiBuilder.types.ts | 30 +++++++------ 7 files changed, 64 insertions(+), 58 deletions(-) create mode 100644 docs/src/modules/components/ApiPage/processors/classes.ts diff --git a/docs/src/modules/components/ApiPage.tsx b/docs/src/modules/components/ApiPage.tsx index 313f4b3d05d473..198396e8671c26 100644 --- a/docs/src/modules/components/ApiPage.tsx +++ b/docs/src/modules/components/ApiPage.tsx @@ -21,7 +21,8 @@ import { ApiDisplayOptions, DEFAULT_API_LAYOUT_STORAGE_KEYS, } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; -import { propsApiProcessor } from './ApiPage/processors/properties'; +import { propsApiProcessor } from 'docs/src/modules/components/ApiPage/processors/properties'; +import { classesApiProcessor } from 'docs/src/modules/components/ApiPage/processors/classes'; type ApiHeaderKeys = | 'demos' @@ -328,9 +329,11 @@ export default function ApiPage(props: ApiPageProps) { /> ) { + return { + ...classDefinition, + description: + classDescriptions[classDefinition.key]?.description + ?.replace(/{{conditions}}/, classDescriptions[classDefinition.key].conditions!) + ?.replace(/{{nodeName}}/, classDescriptions[classDefinition.key].nodeName!) ?? + classDefinition.description, + deprecationInfo: classDescriptions[classDefinition.key]?.deprecationInfo, + hash: `${kebabCase(componentName)}-classes-${classDefinition.className}`, + }; + }); +} diff --git a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx index b0dc20179e69f2..9cd7afa794959a 100644 --- a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import { useTranslate } from '@mui/docs/i18n'; import { SectionTitle } from '@mui/docs/SectionTitle'; -import { ComponentClassDefinition } from '@mui/internal-docs-utils'; import Box from '@mui/material/Box'; import ToggleDisplayOption, { ApiDisplayOptions, @@ -10,21 +9,10 @@ import ToggleDisplayOption, { } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; import ClassesList from 'docs/src/modules/components/ApiPage/list/ClassesList'; import ClassesTable from 'docs/src/modules/components/ApiPage/table/ClassesTable'; -import kebabCase from 'lodash/kebabCase'; - -type ClassDescription = { - [classKey: string]: { - description: string; - nodeName?: string; - conditions?: string; - deprecationInfo?: string; - }; -}; +import { ClassDefinition } from '../common/classes'; export type ClassesSectionProps = { - componentClasses: ComponentClassDefinition[]; - classDescriptions: ClassDescription; - componentName: string; + classes: ClassDefinition[]; spreadHint?: string; /** * The translation key of the section title. @@ -47,9 +35,7 @@ export type ClassesSectionProps = { export default function ClassesSection(props: ClassesSectionProps) { const { - componentClasses, - classDescriptions, - componentName, + classes, spreadHint, title = 'api-docs.classes', titleHash = 'classes', @@ -63,23 +49,10 @@ export default function ClassesSection(props: ClassesSectionProps) { const [displayOption, setDisplayOption] = useApiPageOption(layoutStorageKey, defaultLayout); - if (!componentClasses || componentClasses.length === 0) { + if (!classes || classes.length === 0) { return null; } - const classesWithTranslatedDescriptions = componentClasses.map((classDefinition) => { - return { - ...classDefinition, - description: - classDescriptions[classDefinition.key]?.description - ?.replace(/{{conditions}}/, classDescriptions[classDefinition.key].conditions!) - ?.replace(/{{nodeName}}/, classDescriptions[classDefinition.key].nodeName!) ?? - classDefinition.description, - deprecationInfo: classDescriptions[classDefinition.key]?.deprecationInfo, - hash: `${kebabCase(componentName)}-classes-${classDefinition.className}`, - }; - }); - return ( @@ -92,13 +65,10 @@ export default function ClassesSection(props: ClassesSectionProps) { {spreadHint &&

} {displayOption === 'table' ? ( - + ) : ( diff --git a/docs/src/modules/components/ComponentsApiContent.js b/docs/src/modules/components/ComponentsApiContent.js index 37e4f4cc1aa71e..402f71e283fe04 100644 --- a/docs/src/modules/components/ComponentsApiContent.js +++ b/docs/src/modules/components/ComponentsApiContent.js @@ -12,6 +12,7 @@ import PropertiesSection from 'docs/src/modules/components/ApiPage/sections/Prop import ClassesSection from 'docs/src/modules/components/ApiPage/sections/ClassesSection'; import SlotsSection from 'docs/src/modules/components/ApiPage/sections/SlotsSection'; import { propsApiProcessor } from 'docs/src/modules/components/ApiPage/processors/properties'; +import { classesApiProcessor } from 'docs/src/modules/components/ApiPage/processors/classes'; import { DEFAULT_API_LAYOUT_STORAGE_KEYS } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; function getTranslatedHeader(t, header, text) { @@ -225,9 +226,11 @@ export default function ComponentsApiContent(props) { layoutStorageKey={layoutStorageKey.slots} /> Date: Mon, 5 Aug 2024 11:23:47 +0200 Subject: [PATCH 05/19] clean up --- .../components/ApiPage/common/classes.ts | 9 ---- .../components/ApiPage/common/properties.ts | 40 ----------------- .../components/ApiPage/common/slots.ts | 14 ------ .../components/ApiPage/processors/classes.ts | 11 ++++- .../ApiPage/processors/properties.ts | 27 ++++++++++- .../components/ApiPage/processors/slots.ts | 32 +++++++++++++ .../ApiPage/sections/ClassesSection.tsx | 39 +++++++++++++--- .../ApiPage/sections/PropertiesSection.tsx | 39 +++++++++++++--- .../ApiPage/sections/SlotsSection.tsx | 45 +++++++++++-------- 9 files changed, 161 insertions(+), 95 deletions(-) delete mode 100644 docs/src/modules/components/ApiPage/common/classes.ts delete mode 100644 docs/src/modules/components/ApiPage/common/properties.ts delete mode 100644 docs/src/modules/components/ApiPage/common/slots.ts create mode 100644 docs/src/modules/components/ApiPage/processors/slots.ts diff --git a/docs/src/modules/components/ApiPage/common/classes.ts b/docs/src/modules/components/ApiPage/common/classes.ts deleted file mode 100644 index 8cd3a5d9c2d972..00000000000000 --- a/docs/src/modules/components/ApiPage/common/classes.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface ClassDefinition { - className: string; - key: string; - hash: string; - description?: string; - isGlobal?: boolean; - isDeprecated?: boolean; - deprecationInfo?: string; -} diff --git a/docs/src/modules/components/ApiPage/common/properties.ts b/docs/src/modules/components/ApiPage/common/properties.ts deleted file mode 100644 index d3f4dd9294509d..00000000000000 --- a/docs/src/modules/components/ApiPage/common/properties.ts +++ /dev/null @@ -1,40 +0,0 @@ -import kebabCase from 'lodash/kebabCase'; - -export type GetHashParams = { - componentName: string; - propName: string; -}; - -export function getHookParamsHash({ componentName, propName }: GetHashParams) { - return `${kebabCase(componentName)}-parameters-${propName}`; -} - -export function getHookReturnHash({ componentName, propName }: GetHashParams) { - return `${kebabCase(componentName)}-return-value-${propName}`; -} - -export interface PropertyDefinition { - additionalInfo?: string[]; - hash: string; - deprecationInfo?: string; - description?: string; - isDeprecated?: boolean; - isOptional?: boolean; - isRequired?: boolean; - propDefault?: string; - propName: string; - requiresRef?: boolean; - seeMoreDescription?: string; - signature?: string; - signatureArgs?: { argName: string; argDescription?: string }[]; - signatureReturnDescription?: string; - typeName: string; - /** - * Used by MUI X interface documentation - */ - isProPlan?: boolean; - /** - * Used by MUI X interface documentation - */ - isPremiumPlan?: boolean; -} diff --git a/docs/src/modules/components/ApiPage/common/slots.ts b/docs/src/modules/components/ApiPage/common/slots.ts deleted file mode 100644 index 18887bc6d9c444..00000000000000 --- a/docs/src/modules/components/ApiPage/common/slots.ts +++ /dev/null @@ -1,14 +0,0 @@ -type HashParams = { componentName: string; className: string | null; name: string }; - -export function getSlotsHash({ componentName, className, name }: HashParams) { - // We can use "-css-" linke in `getClassesHash` because slots with associated className should not be rendered in classes. - return `${componentName}-css-${className ?? name}`; -} - -export type SlotsDefinition = { - className: string | null; - hash: string; - description?: string; - name: string; - defaultValue?: string; -}; diff --git a/docs/src/modules/components/ApiPage/processors/classes.ts b/docs/src/modules/components/ApiPage/processors/classes.ts index 1505c623d17e42..e1d59d81138068 100644 --- a/docs/src/modules/components/ApiPage/processors/classes.ts +++ b/docs/src/modules/components/ApiPage/processors/classes.ts @@ -1,7 +1,16 @@ import { PropsTranslations, ComponentApiContent } from '@mui-internal/api-docs-builder'; -import { ClassDefinition } from 'docs/src/modules/components/ApiPage/common/classes'; import kebabCase from 'lodash/kebabCase'; +export interface ClassDefinition { + className: string; + key: string; + hash: string; + description?: string; + isGlobal?: boolean; + isDeprecated?: boolean; + deprecationInfo?: string; +} + export interface ClassesApiProcessorParams { componentClasses: ComponentApiContent['classes']; classDescriptions: PropsTranslations['classDescriptions']; diff --git a/docs/src/modules/components/ApiPage/processors/properties.ts b/docs/src/modules/components/ApiPage/processors/properties.ts index 82a4ca7bfa8827..9541f32988a733 100644 --- a/docs/src/modules/components/ApiPage/processors/properties.ts +++ b/docs/src/modules/components/ApiPage/processors/properties.ts @@ -1,11 +1,36 @@ import { PropsTableItem, PropsTranslations } from '@mui-internal/api-docs-builder'; -import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/common/properties'; import kebabCase from 'lodash/kebabCase'; import { HookApiContent, HooksTranslations, } from 'packages/api-docs-builder/types/ApiBuilder.types'; +export interface PropertyDefinition { + additionalInfo?: string[]; + hash: string; + deprecationInfo?: string; + description?: string; + isDeprecated?: boolean; + isOptional?: boolean; + isRequired?: boolean; + propDefault?: string; + propName: string; + requiresRef?: boolean; + seeMoreDescription?: string; + signature?: string; + signatureArgs?: { argName: string; argDescription?: string }[]; + signatureReturnDescription?: string; + typeName: string; + /** + * Used by MUI X interface documentation + */ + isProPlan?: boolean; + /** + * Used by MUI X interface documentation + */ + isPremiumPlan?: boolean; +} + interface PropsApiProcessorParams { componentName: string; properties: { diff --git a/docs/src/modules/components/ApiPage/processors/slots.ts b/docs/src/modules/components/ApiPage/processors/slots.ts new file mode 100644 index 00000000000000..58de5376eb343d --- /dev/null +++ b/docs/src/modules/components/ApiPage/processors/slots.ts @@ -0,0 +1,32 @@ +import { PropsTranslations, ComponentApiContent } from '@mui-internal/api-docs-builder'; + +export type SlotDefinition = { + className: string | null; + hash: string; + description?: string; + name: string; + defaultValue?: string; +}; + +export interface SlotsApiProcessorParams { + componentSlots: ComponentApiContent['slots']; + slotDescriptions: PropsTranslations['slotDescriptions']; + componentName: string; +} + +export function slotsApiProcessor(params: SlotsApiProcessorParams): SlotDefinition[] { + const { componentSlots, slotDescriptions, componentName } = params; + + if (!componentSlots) { + return []; + } + return componentSlots.map(({ class: className, name, default: defaultValue }) => { + return { + description: slotDescriptions?.[name], + className, + name, + defaultValue, + hash: `${componentName}-css-${className ?? name}`, + }; + }); +} diff --git a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx index 9cd7afa794959a..6868160954b020 100644 --- a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx @@ -9,10 +9,27 @@ import ToggleDisplayOption, { } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; import ClassesList from 'docs/src/modules/components/ApiPage/list/ClassesList'; import ClassesTable from 'docs/src/modules/components/ApiPage/table/ClassesTable'; -import { ClassDefinition } from '../common/classes'; +import { + ClassDefinition, + classesApiProcessor, +} from 'docs/src/modules/components/ApiPage/processors/classes'; +import { ComponentClassDefinition } from '@mui/internal-docs-utils'; +import { PropsTranslations } from '@mui-internal/api-docs-builder'; -export type ClassesSectionProps = { - classes: ClassDefinition[]; +export type ClassesSectionProps = ( + | { + classes: ClassDefinition[]; + componentClasses: undefined; + classDescriptions: undefined; + componentName: undefined; + } + | { + classes: undefined; + componentClasses: ComponentClassDefinition[]; + classDescriptions: PropsTranslations['classDescriptions']; + componentName: string; + } +) & { spreadHint?: string; /** * The translation key of the section title. @@ -36,6 +53,9 @@ export type ClassesSectionProps = { export default function ClassesSection(props: ClassesSectionProps) { const { classes, + componentClasses, + classDescriptions, + componentName, spreadHint, title = 'api-docs.classes', titleHash = 'classes', @@ -49,7 +69,14 @@ export default function ClassesSection(props: ClassesSectionProps) { const [displayOption, setDisplayOption] = useApiPageOption(layoutStorageKey, defaultLayout); - if (!classes || classes.length === 0) { + const formattedClasses = + classes || + classesApiProcessor({ + componentClasses, + classDescriptions, + componentName, + }); + if (!formattedClasses || formattedClasses.length === 0) { return null; } @@ -65,10 +92,10 @@ export default function ClassesSection(props: ClassesSectionProps) { {spreadHint &&

} {displayOption === 'table' ? ( - + ) : ( diff --git a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx index f158543859e35e..027b8734d73c9a 100644 --- a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx @@ -9,11 +9,28 @@ import ToggleDisplayOption, { } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; import PropertiesList from 'docs/src/modules/components/ApiPage/list/PropertiesList'; import PropertiesTable from 'docs/src/modules/components/ApiPage/table/PropertiesTable'; -import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/common/properties'; +import { + PropertyDefinition, + propsApiProcessor, +} from 'docs/src/modules/components/ApiPage/processors/properties'; import { LayoutStorageKeys } from 'docs/src/modules/components/ApiPage'; +import { PropsTableItem, PropsTranslations } from 'packages/api-docs-builder'; -interface PropertiesSectionProps { - properties: PropertyDefinition[]; +type PropertiesSectionProps = ( + | { + properties: { + // isProPlan and isPremiumPlan are added for the MUI X interface documentation. + [name: string]: PropsTableItem & { isProPlan?: true; isPremiumPlan?: true }; + }; + propertiesDescriptions: PropsTranslations['propDescriptions']; + componentName: string; + } + | { + properties: PropertyDefinition[]; + propertiesDescriptions: undefined; + componentName: undefined; + } +) & { spreadHint: string; defaultLayout: ApiDisplayOptions; layoutStorageKey: LayoutStorageKeys['props']; @@ -32,11 +49,13 @@ interface PropertiesSectionProps { * @default 'h2' */ level?: SectionTitleProps['level']; -} +}; export default function PropertiesSection(props: PropertiesSectionProps) { const { properties, + propertiesDescriptions, + componentName, title = 'api-docs.props', titleHash = 'props', level = 'h2', @@ -48,6 +67,14 @@ export default function PropertiesSection(props: PropertiesSectionProps) { const [displayOption, setDisplayOption] = useApiPageOption(layoutStorageKey, defaultLayout); + const formattedProperties = Array.isArray(properties) + ? properties + : propsApiProcessor({ + properties, + propertiesDescriptions: propertiesDescriptions!, + componentName: componentName!, + }); + return ( @@ -60,9 +87,9 @@ export default function PropertiesSection(props: PropertiesSectionProps) { {spreadHint &&

} {displayOption === 'table' ? ( - + ) : ( - + )} ); diff --git a/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx b/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx index f2c42a85c545fc..2d2558dc25f0d0 100644 --- a/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx @@ -10,12 +10,25 @@ import ToggleDisplayOption, { } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; import SlotsList from 'docs/src/modules/components/ApiPage/list/SlotsList'; import SlotsTable from 'docs/src/modules/components/ApiPage/table/SlotsTable'; -import { getSlotsHash } from '../common/slots'; +import { + SlotDefinition, + slotsApiProcessor, +} from 'docs/src/modules/components/ApiPage/processors/slots'; -export type SlotsSectionProps = { - componentSlots: ComponentApiContent['slots']; - slotDescriptions: { [key: string]: string }; - componentName: string; +export type SlotsSectionProps = ( + | { + slots: SlotDefinition[]; + componentSlots: undefined; + slotDescriptions: undefined; + componentName: undefined; + } + | { + slots: undefined; + componentSlots: ComponentApiContent['slots']; + slotDescriptions: { [key: string]: string }; + componentName: string; + } +) & { title?: string; titleHash?: string; level?: 'h2' | 'h3' | 'h4'; @@ -26,6 +39,7 @@ export type SlotsSectionProps = { export default function SlotsSection(props: SlotsSectionProps) { const { + slots, componentSlots, slotDescriptions, componentName, @@ -40,22 +54,17 @@ export default function SlotsSection(props: SlotsSectionProps) { const [displayOption, setDisplayOption] = useApiPageOption(layoutStorageKey, defaultLayout); - if (!componentSlots || componentSlots.length === 0) { + const formattedSlots = + slots ?? + slotsApiProcessor({ + componentSlots, + slotDescriptions, + componentName, + }); + if (!formattedSlots || formattedSlots.length === 0) { return null; } - const formattedSlots = componentSlots?.map( - ({ class: className, name, default: defaultValue }) => { - return { - description: slotDescriptions[name], - className, - name, - defaultValue, - hash: getSlotsHash({ componentName, className, name }), - }; - }, - ); - return ( From a4ecdad3f0325acf44e70d3e474186306b8c39a0 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 5 Aug 2024 15:37:56 +0200 Subject: [PATCH 06/19] recreate the ToC generators --- docs/src/modules/components/ApiPage.tsx | 48 +++++++++++------- .../components/ApiPage/processors/classes.ts | 24 +++++++++ .../ApiPage/processors/properties.ts | 33 +++++++++++++ .../ApiPage/sections/ClassesSection.tsx | 36 ++++++++++++-- .../ApiPage/sections/PropertiesSection.tsx | 49 +++++++++++++++++-- .../ApiPage/sections/SlotsSection.tsx | 6 +-- .../components/ComponentsApiContent.js | 2 +- docs/src/modules/components/MarkdownDocsV2.js | 17 ++++++- 8 files changed, 184 insertions(+), 31 deletions(-) diff --git a/docs/src/modules/components/ApiPage.tsx b/docs/src/modules/components/ApiPage.tsx index 198396e8671c26..cd0372bf8e5e44 100644 --- a/docs/src/modules/components/ApiPage.tsx +++ b/docs/src/modules/components/ApiPage.tsx @@ -21,8 +21,15 @@ import { ApiDisplayOptions, DEFAULT_API_LAYOUT_STORAGE_KEYS, } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; -import { propsApiProcessor } from 'docs/src/modules/components/ApiPage/processors/properties'; -import { classesApiProcessor } from 'docs/src/modules/components/ApiPage/processors/classes'; +import { + getPropertiesToC, + propsApiProcessor, +} from 'docs/src/modules/components/ApiPage/processors/properties'; +import { + classesApiProcessor, + getClassesToC, +} from 'docs/src/modules/components/ApiPage/processors/classes'; +import { slotsApiProcessor } from './ApiPage/processors/slots'; type ApiHeaderKeys = | 'demos' @@ -148,6 +155,23 @@ export default function ApiPage(props: ApiPageProps) { // Prefer linking the .tsx or .d.ts for the "Edit this page" link. const apiSourceLocation = filename.replace('.js', '.d.ts'); + // Merge data and translation + const propertiesDef = propsApiProcessor({ + componentName: pageContent.name, + properties: componentProps, + propertiesDescriptions: propDescriptions, + }); + const classesDef = classesApiProcessor({ + componentClasses, + componentName: pageContent.name, + classDescriptions, + }); + const slotsDef = slotsApiProcessor({ + componentSlots, + componentName: pageContent.name, + slotDescriptions, + }); + function createTocEntry(sectionName: ApiHeaderKeys) { return { text: getTranslatedHeader(t, sectionName), @@ -167,9 +191,9 @@ export default function ApiPage(props: ApiPageProps) { createTocEntry('demos'), createTocEntry('import'), ...componentDescriptionToc, - createTocEntry('props'), + getPropertiesToC({ properties: propertiesDef, t }), componentSlots?.length > 0 && createTocEntry('slots'), - createTocEntry('classes'), + getClassesToC({ classes: classesDef, t }), ].filter(Boolean); // The `ref` is forwarded to the root element. @@ -260,11 +284,7 @@ export default function ApiPage(props: ApiPageProps) { ) : null} ) + !classes || classes.length === 0 + ? [] + : [ + { + text: t('api-docs.classes'), + hash: hash ?? 'classes', + children: [ + ...classes.map(({ key, hash: classeHash }) => ({ + text: key, + hash: classeHash, + children: [], + })), + ], + }, + ]; + export interface ClassesApiProcessorParams { componentClasses: ComponentApiContent['classes']; classDescriptions: PropsTranslations['classDescriptions']; diff --git a/docs/src/modules/components/ApiPage/processors/properties.ts b/docs/src/modules/components/ApiPage/processors/properties.ts index 9541f32988a733..51e809129ec076 100644 --- a/docs/src/modules/components/ApiPage/processors/properties.ts +++ b/docs/src/modules/components/ApiPage/processors/properties.ts @@ -1,4 +1,5 @@ import { PropsTableItem, PropsTranslations } from '@mui-internal/api-docs-builder'; +import { Translate } from '@mui/docs/i18n'; import kebabCase from 'lodash/kebabCase'; import { HookApiContent, @@ -31,6 +32,38 @@ export interface PropertyDefinition { isPremiumPlan?: boolean; } +export type GetCssToCParams = { + properties: PropertyDefinition[]; + inheritance?: boolean; + themeDefaultProps?: boolean; + t: Translate; + hash?: string; +}; + +export const getPropertiesToC = ({ + properties, + inheritance, + themeDefaultProps, + t, + hash, +}: GetCssToCParams) => ({ + text: t('api-docs.props'), + hash, + children: [ + ...properties.map(({ propName, hash: propertyHash }) => ({ + text: propName, + hash: propertyHash, + children: [], + })), + ...(inheritance + ? [{ text: t('api-docs.inheritance'), hash: 'inheritance', children: [] }] + : []), + ...(themeDefaultProps + ? [{ text: t('api-docs.themeDefaultProps'), hash: 'theme-default-props', children: [] }] + : []), + ], +}); + interface PropsApiProcessorParams { componentName: string; properties: { diff --git a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx index 6868160954b020..755b4484cfa435 100644 --- a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx @@ -1,6 +1,6 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; -import { useTranslate } from '@mui/docs/i18n'; +import { Translate, useTranslate } from '@mui/docs/i18n'; import { SectionTitle } from '@mui/docs/SectionTitle'; import Box from '@mui/material/Box'; import ToggleDisplayOption, { @@ -15,13 +15,41 @@ import { } from 'docs/src/modules/components/ApiPage/processors/classes'; import { ComponentClassDefinition } from '@mui/internal-docs-utils'; import { PropsTranslations } from '@mui-internal/api-docs-builder'; +import kebabCase from 'lodash/kebabCase'; + +export type GetCssToCParams = { + componentName: string; + componentClasses: ComponentClassDefinition[]; + t: Translate; + hash?: string; +}; + +/** + * @deprecated Use the function from ApiPage/processors + */ +export const getClassesToC = ({ componentName, componentClasses, t, hash }: GetCssToCParams) => + !componentClasses || componentClasses.length === 0 + ? [] + : [ + { + text: t('api-docs.classes'), + hash: hash ?? 'classes', + children: [ + ...componentClasses.map((styles) => ({ + text: styles.key, + hash: `${kebabCase(componentName)}-classes-${styles.key}`, + children: [], + })), + ], + }, + ]; export type ClassesSectionProps = ( | { classes: ClassDefinition[]; - componentClasses: undefined; - classDescriptions: undefined; - componentName: undefined; + componentClasses?: undefined; + classDescriptions?: undefined; + componentName?: undefined; } | { classes: undefined; diff --git a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx index 027b8734d73c9a..b639cf8c83ff78 100644 --- a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx @@ -1,7 +1,7 @@ /* eslint-disable react/no-danger */ import * as React from 'react'; import Box from '@mui/material/Box'; -import { useTranslate } from '@mui/docs/i18n'; +import { Translate, useTranslate } from '@mui/docs/i18n'; import { SectionTitle, SectionTitleProps } from '@mui/docs/SectionTitle'; import ToggleDisplayOption, { ApiDisplayOptions, @@ -14,7 +14,48 @@ import { propsApiProcessor, } from 'docs/src/modules/components/ApiPage/processors/properties'; import { LayoutStorageKeys } from 'docs/src/modules/components/ApiPage'; -import { PropsTableItem, PropsTranslations } from 'packages/api-docs-builder'; +import { ComponentApiContent, PropsTableItem, PropsTranslations } from 'packages/api-docs-builder'; +import kebabCase from 'lodash/kebabCase'; + +interface GetPropsToCParams extends Pick { + componentProps: ComponentApiContent['props']; + componentName: ComponentApiContent['name']; + t: Translate; + /** + * @default 'props' + */ + hash?: string; +} + +/** + * @deprecated Use the one from ApiPage/processors + */ +export function getPropsToC({ + componentName, + componentProps, + inheritance, + themeDefaultProps, + t, + hash = 'props', +}: GetPropsToCParams) { + return { + text: t('api-docs.props'), + hash, + children: [ + ...Object.entries(componentProps).map(([propName]) => ({ + text: propName, + hash: `${kebabCase(componentName)}-prop-${propName}`, + children: [], + })), + ...(inheritance + ? [{ text: t('api-docs.inheritance'), hash: 'inheritance', children: [] }] + : []), + ...(themeDefaultProps + ? [{ text: t('api-docs.themeDefaultProps'), hash: 'theme-default-props', children: [] }] + : []), + ], + }; +} type PropertiesSectionProps = ( | { @@ -27,8 +68,8 @@ type PropertiesSectionProps = ( } | { properties: PropertyDefinition[]; - propertiesDescriptions: undefined; - componentName: undefined; + propertiesDescriptions?: undefined; + componentName?: undefined; } ) & { spreadHint: string; diff --git a/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx b/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx index 2d2558dc25f0d0..60f0ba9c5261f5 100644 --- a/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx @@ -18,9 +18,9 @@ import { export type SlotsSectionProps = ( | { slots: SlotDefinition[]; - componentSlots: undefined; - slotDescriptions: undefined; - componentName: undefined; + componentSlots?: undefined; + slotDescriptions?: undefined; + componentName?: undefined; } | { slots: undefined; diff --git a/docs/src/modules/components/ComponentsApiContent.js b/docs/src/modules/components/ComponentsApiContent.js index 402f71e283fe04..1d922fabbfe235 100644 --- a/docs/src/modules/components/ComponentsApiContent.js +++ b/docs/src/modules/components/ComponentsApiContent.js @@ -55,7 +55,7 @@ export default function ComponentsApiContent(props) { const router = useRouter(); // There are legacy links where the the components had the Unstyled suffix - // This effects makes sure that the anchors will be correct wtih the renames + // This effects makes sure that the anchors will be correct with the renames React.useEffect(() => { const anchor = router.asPath.indexOf('#') >= 0 ? router.asPath.split('#')[1] : null; if (router.isReady && anchor && anchor.indexOf('-unstyled') >= 0) { diff --git a/docs/src/modules/components/MarkdownDocsV2.js b/docs/src/modules/components/MarkdownDocsV2.js index b5264cfe4fa610..37be334cf1543f 100644 --- a/docs/src/modules/components/MarkdownDocsV2.js +++ b/docs/src/modules/components/MarkdownDocsV2.js @@ -16,6 +16,8 @@ import { useTranslate, useUserLanguage } from '@mui/docs/i18n'; import { BrandingProvider } from '@mui/docs/branding'; import { HEIGHT as AppFrameHeight } from 'docs/src/modules/components/AppFrame'; import { HEIGHT as TabsHeight } from 'docs/src/modules/components/ComponentPageTabs'; +import { getPropsToC } from 'docs/src/modules/components/ApiPage/sections/PropertiesSection'; +import { getClassesToC } from 'docs/src/modules/components/ApiPage/sections/ClassesSection'; function JoyModeObserver({ mode }) { const { setMode } = useColorScheme(); @@ -147,18 +149,29 @@ export default function MarkdownDocsV2(props) { slots, inheritance, themeDefaultProps, + classes, + props: componentProps, } = componentsApiPageContents[key]; const componentNameKebabCase = kebabCase(componentName); const componentApiToc = [ createComponentTocEntry(componentNameKebabCase, 'import'), ...componentDescriptionToc, - createComponentTocEntry(componentNameKebabCase, 'props', { + getPropsToC({ + t, + componentName: componentNameKebabCase, + componentProps, inheritance, themeDefaultProps, + hash: `${componentNameKebabCase}-props`, }), slots?.length > 0 && createComponentTocEntry(componentNameKebabCase, 'slots'), - createComponentTocEntry(componentNameKebabCase, 'classes'), + ...getClassesToC({ + t, + componentName: componentNameKebabCase, + componentClasses: classes, + hash: `${componentNameKebabCase}-classes`, + }), ].filter(Boolean); componentsApiToc.push({ From 2ce4e3c1d346ae66c425a2ce30310a229176975c Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 5 Aug 2024 16:14:06 +0200 Subject: [PATCH 07/19] fixes --- docs/src/modules/components/ApiPage/list/ClassesList.tsx | 2 +- docs/src/modules/components/ApiPage/list/PropertiesList.tsx | 2 +- docs/src/modules/components/ApiPage/list/SlotsList.tsx | 2 +- docs/src/modules/components/ApiPage/table/ClassesTable.tsx | 2 +- docs/src/modules/components/ApiPage/table/PropertiesTable.tsx | 2 +- docs/src/modules/components/ApiPage/table/SlotsTable.tsx | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/src/modules/components/ApiPage/list/ClassesList.tsx b/docs/src/modules/components/ApiPage/list/ClassesList.tsx index 2c9092c8b95110..8d1bd56c744cfd 100644 --- a/docs/src/modules/components/ApiPage/list/ClassesList.tsx +++ b/docs/src/modules/components/ApiPage/list/ClassesList.tsx @@ -5,7 +5,7 @@ import { useTranslate } from '@mui/docs/i18n'; import ExpandableApiItem, { ApiItemContainer, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; -import { ClassDefinition } from 'docs/src/modules/components/ApiPage/common/classes'; +import { ClassDefinition } from 'docs/src/modules/components/ApiPage/processors/classes'; import { brandingLightTheme as lightTheme, brandingDarkTheme as darkTheme, diff --git a/docs/src/modules/components/ApiPage/list/PropertiesList.tsx b/docs/src/modules/components/ApiPage/list/PropertiesList.tsx index 9507653befea21..ee131bb8204184 100644 --- a/docs/src/modules/components/ApiPage/list/PropertiesList.tsx +++ b/docs/src/modules/components/ApiPage/list/PropertiesList.tsx @@ -10,7 +10,7 @@ import ExpandableApiItem, { ApiItemContainer, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; import ApiWarningAlert from 'docs/src/modules/components/ApiPage/ApiWarningAlert'; -import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/common/properties'; +import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/processors/properties'; const StyledApiItem = styled(ExpandableApiItem)( ({ theme }) => ({ diff --git a/docs/src/modules/components/ApiPage/list/SlotsList.tsx b/docs/src/modules/components/ApiPage/list/SlotsList.tsx index 5334b9bbeb277d..3f149392dd90ab 100644 --- a/docs/src/modules/components/ApiPage/list/SlotsList.tsx +++ b/docs/src/modules/components/ApiPage/list/SlotsList.tsx @@ -9,7 +9,7 @@ import { useTranslate } from '@mui/docs/i18n'; import ExpandableApiItem, { ApiItemContainer, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; -import { SlotsDefinition } from 'docs/src/modules/components/ApiPage/common/slots'; +import { SlotsDefinition } from 'docs/src/modules/components/ApiPage/processors/slots'; const StyledApiItem = styled(ExpandableApiItem)( ({ theme }) => ({ diff --git a/docs/src/modules/components/ApiPage/table/ClassesTable.tsx b/docs/src/modules/components/ApiPage/table/ClassesTable.tsx index e57deac2763f7e..fe7750ce1ee5d9 100644 --- a/docs/src/modules/components/ApiPage/table/ClassesTable.tsx +++ b/docs/src/modules/components/ApiPage/table/ClassesTable.tsx @@ -6,7 +6,7 @@ import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, } from '@mui/docs/branding'; -import { ClassDefinition } from 'docs/src/modules/components/ApiPage/common/classes'; +import { ClassDefinition } from 'docs/src/modules/components/ApiPage/processors/classes'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; import ApiWarningAlert from 'docs/src/modules/components/ApiPage/ApiWarningAlert'; diff --git a/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx b/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx index d3855817e55da5..480174aaec053a 100644 --- a/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx +++ b/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx @@ -6,7 +6,7 @@ import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, } from '@mui/docs/branding'; -import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/common/properties'; +import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/processors/properties'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; import ApiWarningAlert from 'docs/src/modules/components/ApiPage/ApiWarningAlert'; diff --git a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx index d6ba65e925c07e..e2ca72958512bf 100644 --- a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx +++ b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx @@ -7,7 +7,7 @@ import { brandingLightTheme as lightTheme, } from '@mui/docs/branding'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; -import { SlotsDefinition } from 'docs/src/modules/components/ApiPage/common/slots'; +import { SlotsDefinition } from 'docs/src/modules/components/ApiPage/processors/slots'; const StyledTable = styled('table')( ({ theme }) => ({ From 5c3031d1770a5193fb9da44dbd505e6cb3163dfc Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 6 Aug 2024 10:18:25 +0200 Subject: [PATCH 08/19] fix TS --- docs/src/modules/components/ApiPage/list/SlotsList.tsx | 4 ++-- docs/src/modules/components/ApiPage/table/SlotsTable.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/modules/components/ApiPage/list/SlotsList.tsx b/docs/src/modules/components/ApiPage/list/SlotsList.tsx index 3f149392dd90ab..dc7766d29dddb4 100644 --- a/docs/src/modules/components/ApiPage/list/SlotsList.tsx +++ b/docs/src/modules/components/ApiPage/list/SlotsList.tsx @@ -9,7 +9,7 @@ import { useTranslate } from '@mui/docs/i18n'; import ExpandableApiItem, { ApiItemContainer, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; -import { SlotsDefinition } from 'docs/src/modules/components/ApiPage/processors/slots'; +import { SlotDefinition } from 'docs/src/modules/components/ApiPage/processors/slots'; const StyledApiItem = styled(ExpandableApiItem)( ({ theme }) => ({ @@ -45,7 +45,7 @@ const StyledApiItem = styled(ExpandableApiItem)( ); interface SlotsListProps { - slots: SlotsDefinition[]; + slots: SlotDefinition[]; displayOption: 'collapsed' | 'expanded'; } diff --git a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx index e2ca72958512bf..298ddcc14b4ec5 100644 --- a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx +++ b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx @@ -7,7 +7,7 @@ import { brandingLightTheme as lightTheme, } from '@mui/docs/branding'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; -import { SlotsDefinition } from 'docs/src/modules/components/ApiPage/processors/slots'; +import { SlotDefinition } from 'docs/src/modules/components/ApiPage/processors/slots'; const StyledTable = styled('table')( ({ theme }) => ({ @@ -69,7 +69,7 @@ const StyledTable = styled('table')( ); interface SlotsTableProps { - slots: SlotsDefinition[]; + slots: SlotDefinition[]; } export default function SlotsTable(props: SlotsTableProps) { From ba5e578ea60328ee99463b88e31e295c7d426912 Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 6 Aug 2024 11:18:33 +0200 Subject: [PATCH 09/19] fix --- docs/src/modules/components/ApiPage.tsx | 30 ++++++++++++++++--- .../components/ApiPage/processors/classes.ts | 3 +- .../ApiPage/processors/properties.ts | 5 ++-- packages/markdown/index.d.ts | 2 +- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/docs/src/modules/components/ApiPage.tsx b/docs/src/modules/components/ApiPage.tsx index cd0372bf8e5e44..ac8118a0ef4f42 100644 --- a/docs/src/modules/components/ApiPage.tsx +++ b/docs/src/modules/components/ApiPage.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { ComponentApiContent, PropsTranslations } from '@mui-internal/api-docs-builder'; +import exactProp from '@mui/utils/exactProp'; import Typography from '@mui/material/Typography'; import Alert from '@mui/material/Alert'; import { TableOfContentsEntry } from '@mui/internal-markdown'; @@ -31,6 +32,13 @@ import { } from 'docs/src/modules/components/ApiPage/processors/classes'; import { slotsApiProcessor } from './ApiPage/processors/slots'; +// TODO Move this type definition to the AppLayoutDocs file when moved to TS +export interface TableOfContentsParams { + children: (TableOfContentsParams | TableOfContentsEntry)[]; + hash: string; + text: string; +} + type ApiHeaderKeys = | 'demos' | 'import' @@ -187,13 +195,13 @@ export default function ApiPage(props: ApiPageProps) { }; } - const toc = [ + const toc: TableOfContentsParams[] = [ createTocEntry('demos'), createTocEntry('import'), ...componentDescriptionToc, - getPropertiesToC({ properties: propertiesDef, t }), - componentSlots?.length > 0 && createTocEntry('slots'), - getClassesToC({ classes: classesDef, t }), + getPropertiesToC({ properties: propertiesDef, hash: 'props', t }), + ...(componentSlots?.length > 0 ? [createTocEntry('slots')] : []), + ...getClassesToC({ classes: classesDef, t }), ].filter(Boolean); // The `ref` is forwarded to the root element. @@ -363,3 +371,17 @@ export default function ApiPage(props: ApiPageProps) { ); } + +if (process.env.NODE_ENV !== 'production') { + ApiPage.propTypes = exactProp({ + defaultLayout: PropTypes.oneOf(['collapsed', 'expanded', 'table']), + descriptions: PropTypes.object.isRequired, + disableAd: PropTypes.bool, + layoutStorageKey: PropTypes.shape({ + classes: PropTypes.string, + props: PropTypes.string, + slots: PropTypes.string, + }), + pageContent: PropTypes.object.isRequired, + }); +} diff --git a/docs/src/modules/components/ApiPage/processors/classes.ts b/docs/src/modules/components/ApiPage/processors/classes.ts index 0309d3d9302680..64cc15b75bba68 100644 --- a/docs/src/modules/components/ApiPage/processors/classes.ts +++ b/docs/src/modules/components/ApiPage/processors/classes.ts @@ -1,6 +1,7 @@ import { PropsTranslations, ComponentApiContent } from '@mui-internal/api-docs-builder'; import { Translate } from '@mui/docs/i18n'; import kebabCase from 'lodash/kebabCase'; +import type { TableOfContentsParams } from 'docs/src/modules/components/ApiPage'; export interface ClassDefinition { className: string; @@ -18,7 +19,7 @@ export type GetCssToCParams = { hash?: string; }; -export const getClassesToC = ({ classes, t, hash }: GetCssToCParams) => +export const getClassesToC = ({ classes, t, hash }: GetCssToCParams): TableOfContentsParams[] => !classes || classes.length === 0 ? [] : [ diff --git a/docs/src/modules/components/ApiPage/processors/properties.ts b/docs/src/modules/components/ApiPage/processors/properties.ts index 51e809129ec076..2a528f07bce9f2 100644 --- a/docs/src/modules/components/ApiPage/processors/properties.ts +++ b/docs/src/modules/components/ApiPage/processors/properties.ts @@ -5,6 +5,7 @@ import { HookApiContent, HooksTranslations, } from 'packages/api-docs-builder/types/ApiBuilder.types'; +import type { TableOfContentsParams } from 'docs/src/modules/components/ApiPage'; export interface PropertyDefinition { additionalInfo?: string[]; @@ -37,7 +38,7 @@ export type GetCssToCParams = { inheritance?: boolean; themeDefaultProps?: boolean; t: Translate; - hash?: string; + hash: string; }; export const getPropertiesToC = ({ @@ -46,7 +47,7 @@ export const getPropertiesToC = ({ themeDefaultProps, t, hash, -}: GetCssToCParams) => ({ +}: GetCssToCParams): TableOfContentsParams => ({ text: t('api-docs.props'), hash, children: [ diff --git a/packages/markdown/index.d.ts b/packages/markdown/index.d.ts index dc73e31e7a0d53..1fcebbc23b6111 100644 --- a/packages/markdown/index.d.ts +++ b/packages/markdown/index.d.ts @@ -1,5 +1,5 @@ interface TableOfContentsEntry { - children: TableOfContentsEntry; + children: TableOfContentsEntry[]; hash: string; level: number; text: string; From 90aa5bf12dc35f0250541917116bc9fe6056aaf1 Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 6 Aug 2024 11:56:39 +0200 Subject: [PATCH 10/19] remove useless export --- packages/api-docs-builder/index.ts | 1 - .../types/ApiBuilder.types.ts | 28 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/packages/api-docs-builder/index.ts b/packages/api-docs-builder/index.ts index 53c8a27a25fd7a..45148e6d77c6e1 100644 --- a/packages/api-docs-builder/index.ts +++ b/packages/api-docs-builder/index.ts @@ -8,6 +8,5 @@ export type { PropsTranslations, HooksTranslations, HookApiContent, - ClassDescription, } from './types/ApiBuilder.types'; export type { Slot } from './types/utils.types'; diff --git a/packages/api-docs-builder/types/ApiBuilder.types.ts b/packages/api-docs-builder/types/ApiBuilder.types.ts index 1e683cf1e10aa2..4414a759358694 100644 --- a/packages/api-docs-builder/types/ApiBuilder.types.ts +++ b/packages/api-docs-builder/types/ApiBuilder.types.ts @@ -47,7 +47,19 @@ export interface PropsTableItem { seeMoreLink?: SeeMore['link']; } -export interface PropDescription { +export interface PropsTranslations { + componentDescription: string; + deprecationInfo: string | undefined; + propDescriptions: { + [key: string]: PropDescription; + }; + classDescriptions: { + [key: string]: ClassDescription; + }; + slotDescriptions?: { [key: string]: string }; +} + +interface PropDescription { description: string; requiresRef?: boolean; deprecated?: string; @@ -55,25 +67,13 @@ export interface PropDescription { seeMoreText?: string; } -export interface ClassDescription { +interface ClassDescription { description: string; conditions?: string; nodeName?: string; deprecationInfo?: string; } -export interface PropsTranslations { - componentDescription: string; - deprecationInfo: string | undefined; - propDescriptions: { - [key: string]: PropDescription; - }; - classDescriptions: { - [key: string]: ClassDescription; - }; - slotDescriptions?: { [key: string]: string }; -} - export interface ComponentReactApi extends CommonReactApi { forwardsRefTo: string | undefined; inheritance: ReturnType; From a66049eac9c4e7859e084605d9989fdde7f0adb6 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 7 Aug 2024 15:21:42 +0200 Subject: [PATCH 11/19] Add Error for class API --- .../components/ApiPage/processors/classes.ts | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/src/modules/components/ApiPage/processors/classes.ts b/docs/src/modules/components/ApiPage/processors/classes.ts index 64cc15b75bba68..104e5213533f82 100644 --- a/docs/src/modules/components/ApiPage/processors/classes.ts +++ b/docs/src/modules/components/ApiPage/processors/classes.ts @@ -46,14 +46,27 @@ export function classesApiProcessor(params: ClassesApiProcessorParams): ClassDef const { componentClasses, classDescriptions, componentName } = params; return componentClasses.map((classDefinition) => { + const { description, conditions, nodeName, deprecationInfo } = + classDescriptions[classDefinition.key]; + + if (!conditions && description.search(/{{conditions}}/) !== -1) { + throw Error( + `In ${componentName} the class "${classDefinition.className}" description with "{{conditions}}" but without \`conditions\` to replace it.`, + ); + } + + if (!conditions && description.search(/{{nodeName}}/) !== -1) { + throw Error( + `In ${componentName} the class "${classDefinition.className}" description with "{{nodeName}}" but without \`nodeName\` to replace it.`, + ); + } + return { ...classDefinition, - description: - classDescriptions[classDefinition.key]?.description - ?.replace(/{{conditions}}/, classDescriptions[classDefinition.key].conditions!) - ?.replace(/{{nodeName}}/, classDescriptions[classDefinition.key].nodeName!) ?? - classDefinition.description, - deprecationInfo: classDescriptions[classDefinition.key]?.deprecationInfo, + description: description + .replace(/{{conditions}}/, conditions!) + .replace(/{{nodeName}}/, nodeName!), + deprecationInfo, hash: `${kebabCase(componentName)}-classes-${classDefinition.className}`, }; }); From 712dd52f6a5be55385675142c385e01edb14a779 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 7 Aug 2024 15:26:59 +0200 Subject: [PATCH 12/19] renamings --- docs/src/modules/components/ApiPage.tsx | 16 ++++++++-------- .../{processors => definitions}/classes.ts | 4 ++-- .../{processors => definitions}/properties.ts | 12 ++++++------ .../ApiPage/{processors => definitions}/slots.ts | 4 ++-- .../components/ApiPage/list/ClassesList.tsx | 2 +- .../components/ApiPage/list/PropertiesList.tsx | 2 +- .../components/ApiPage/list/SlotsList.tsx | 2 +- .../ApiPage/sections/ClassesSection.tsx | 6 +++--- .../ApiPage/sections/PropertiesSection.tsx | 6 +++--- .../components/ApiPage/sections/SlotsSection.tsx | 6 +++--- .../components/ApiPage/table/ClassesTable.tsx | 2 +- .../components/ApiPage/table/PropertiesTable.tsx | 2 +- .../components/ApiPage/table/SlotsTable.tsx | 2 +- .../modules/components/ComponentsApiContent.js | 8 ++++---- docs/src/modules/components/HooksApiContent.js | 6 +++--- 15 files changed, 40 insertions(+), 40 deletions(-) rename docs/src/modules/components/ApiPage/{processors => definitions}/classes.ts (93%) rename docs/src/modules/components/ApiPage/{processors => definitions}/properties.ts (92%) rename docs/src/modules/components/ApiPage/{processors => definitions}/slots.ts (83%) diff --git a/docs/src/modules/components/ApiPage.tsx b/docs/src/modules/components/ApiPage.tsx index ac8118a0ef4f42..95c775ecb3a89d 100644 --- a/docs/src/modules/components/ApiPage.tsx +++ b/docs/src/modules/components/ApiPage.tsx @@ -24,13 +24,13 @@ import { } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; import { getPropertiesToC, - propsApiProcessor, -} from 'docs/src/modules/components/ApiPage/processors/properties'; + getPropsApiDefinitions, +} from 'docs/src/modules/components/ApiPage/definitions/properties'; import { - classesApiProcessor, + getClassApiDefinitions, getClassesToC, -} from 'docs/src/modules/components/ApiPage/processors/classes'; -import { slotsApiProcessor } from './ApiPage/processors/slots'; +} from 'docs/src/modules/components/ApiPage/definitions/classes'; +import { getSlotsApiDefinitions } from './ApiPage/definitions/slots'; // TODO Move this type definition to the AppLayoutDocs file when moved to TS export interface TableOfContentsParams { @@ -164,17 +164,17 @@ export default function ApiPage(props: ApiPageProps) { const apiSourceLocation = filename.replace('.js', '.d.ts'); // Merge data and translation - const propertiesDef = propsApiProcessor({ + const propertiesDef = getPropsApiDefinitions({ componentName: pageContent.name, properties: componentProps, propertiesDescriptions: propDescriptions, }); - const classesDef = classesApiProcessor({ + const classesDef = getClassApiDefinitions({ componentClasses, componentName: pageContent.name, classDescriptions, }); - const slotsDef = slotsApiProcessor({ + const slotsDef = getSlotsApiDefinitions({ componentSlots, componentName: pageContent.name, slotDescriptions, diff --git a/docs/src/modules/components/ApiPage/processors/classes.ts b/docs/src/modules/components/ApiPage/definitions/classes.ts similarity index 93% rename from docs/src/modules/components/ApiPage/processors/classes.ts rename to docs/src/modules/components/ApiPage/definitions/classes.ts index 104e5213533f82..f67956414a2999 100644 --- a/docs/src/modules/components/ApiPage/processors/classes.ts +++ b/docs/src/modules/components/ApiPage/definitions/classes.ts @@ -36,13 +36,13 @@ export const getClassesToC = ({ classes, t, hash }: GetCssToCParams): TableOfCon }, ]; -export interface ClassesApiProcessorParams { +export interface GetClassApiDefinitionsParams { componentClasses: ComponentApiContent['classes']; classDescriptions: PropsTranslations['classDescriptions']; componentName: string; } -export function classesApiProcessor(params: ClassesApiProcessorParams): ClassDefinition[] { +export function getClassApiDefinitions(params: GetClassApiDefinitionsParams): ClassDefinition[] { const { componentClasses, classDescriptions, componentName } = params; return componentClasses.map((classDefinition) => { diff --git a/docs/src/modules/components/ApiPage/processors/properties.ts b/docs/src/modules/components/ApiPage/definitions/properties.ts similarity index 92% rename from docs/src/modules/components/ApiPage/processors/properties.ts rename to docs/src/modules/components/ApiPage/definitions/properties.ts index 2a528f07bce9f2..6e81b2faee2bd3 100644 --- a/docs/src/modules/components/ApiPage/processors/properties.ts +++ b/docs/src/modules/components/ApiPage/definitions/properties.ts @@ -65,7 +65,7 @@ export const getPropertiesToC = ({ ], }); -interface PropsApiProcessorParams { +interface GetPropsApiDefinitionsParams { componentName: string; properties: { [name: string]: PropsTableItem; @@ -77,7 +77,7 @@ interface PropsApiProcessorParams { showOptionalAbbr?: boolean; } -export function propsApiProcessor(params: PropsApiProcessorParams): PropertyDefinition[] { +export function getPropsApiDefinitions(params: GetPropsApiDefinitionsParams): PropertyDefinition[] { const { properties, propertiesDescriptions, componentName, showOptionalAbbr = false } = params; return Object.entries(properties).map(([propName, propData]) => { @@ -142,20 +142,20 @@ interface HookCommonApiParams { hookName: string; } -interface HookReturnApiProcessorParams extends HookCommonApiParams { +interface GetHookReturnApiDefinitionsParams extends HookCommonApiParams { kind: 'return'; properties: HookApiContent['returnValue']; translations: HooksTranslations['returnValueDescriptions']; } -interface HookParametersApiProcessorParams extends HookCommonApiParams { +interface GetHookParametersApiDefinitions extends HookCommonApiParams { kind: 'parameters'; properties: HookApiContent['parameters']; translations: HooksTranslations['parametersDescriptions']; } -export function hookApiProcessor( - params: HookReturnApiProcessorParams | HookParametersApiProcessorParams, +export function getHookApiDefinitions( + params: GetHookReturnApiDefinitionsParams | GetHookParametersApiDefinitions, ): PropertyDefinition[] { const { properties, translations, hookName, kind } = params; diff --git a/docs/src/modules/components/ApiPage/processors/slots.ts b/docs/src/modules/components/ApiPage/definitions/slots.ts similarity index 83% rename from docs/src/modules/components/ApiPage/processors/slots.ts rename to docs/src/modules/components/ApiPage/definitions/slots.ts index 58de5376eb343d..0108dd1f6c2790 100644 --- a/docs/src/modules/components/ApiPage/processors/slots.ts +++ b/docs/src/modules/components/ApiPage/definitions/slots.ts @@ -8,13 +8,13 @@ export type SlotDefinition = { defaultValue?: string; }; -export interface SlotsApiProcessorParams { +export interface GetSlotsApiDefinitionsParams { componentSlots: ComponentApiContent['slots']; slotDescriptions: PropsTranslations['slotDescriptions']; componentName: string; } -export function slotsApiProcessor(params: SlotsApiProcessorParams): SlotDefinition[] { +export function getSlotsApiDefinitions(params: GetSlotsApiDefinitionsParams): SlotDefinition[] { const { componentSlots, slotDescriptions, componentName } = params; if (!componentSlots) { diff --git a/docs/src/modules/components/ApiPage/list/ClassesList.tsx b/docs/src/modules/components/ApiPage/list/ClassesList.tsx index 8d1bd56c744cfd..bce18f61354667 100644 --- a/docs/src/modules/components/ApiPage/list/ClassesList.tsx +++ b/docs/src/modules/components/ApiPage/list/ClassesList.tsx @@ -5,7 +5,7 @@ import { useTranslate } from '@mui/docs/i18n'; import ExpandableApiItem, { ApiItemContainer, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; -import { ClassDefinition } from 'docs/src/modules/components/ApiPage/processors/classes'; +import { ClassDefinition } from 'docs/src/modules/components/ApiPage/definitions/classes'; import { brandingLightTheme as lightTheme, brandingDarkTheme as darkTheme, diff --git a/docs/src/modules/components/ApiPage/list/PropertiesList.tsx b/docs/src/modules/components/ApiPage/list/PropertiesList.tsx index ee131bb8204184..52895d4d91373f 100644 --- a/docs/src/modules/components/ApiPage/list/PropertiesList.tsx +++ b/docs/src/modules/components/ApiPage/list/PropertiesList.tsx @@ -10,7 +10,7 @@ import ExpandableApiItem, { ApiItemContainer, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; import ApiWarningAlert from 'docs/src/modules/components/ApiPage/ApiWarningAlert'; -import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/processors/properties'; +import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/definitions/properties'; const StyledApiItem = styled(ExpandableApiItem)( ({ theme }) => ({ diff --git a/docs/src/modules/components/ApiPage/list/SlotsList.tsx b/docs/src/modules/components/ApiPage/list/SlotsList.tsx index dc7766d29dddb4..416cc2ff9ce4e3 100644 --- a/docs/src/modules/components/ApiPage/list/SlotsList.tsx +++ b/docs/src/modules/components/ApiPage/list/SlotsList.tsx @@ -9,7 +9,7 @@ import { useTranslate } from '@mui/docs/i18n'; import ExpandableApiItem, { ApiItemContainer, } from 'docs/src/modules/components/ApiPage/list/ExpandableApiItem'; -import { SlotDefinition } from 'docs/src/modules/components/ApiPage/processors/slots'; +import { SlotDefinition } from 'docs/src/modules/components/ApiPage/definitions/slots'; const StyledApiItem = styled(ExpandableApiItem)( ({ theme }) => ({ diff --git a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx index 755b4484cfa435..065466e1ac7f1f 100644 --- a/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/ClassesSection.tsx @@ -11,8 +11,8 @@ import ClassesList from 'docs/src/modules/components/ApiPage/list/ClassesList'; import ClassesTable from 'docs/src/modules/components/ApiPage/table/ClassesTable'; import { ClassDefinition, - classesApiProcessor, -} from 'docs/src/modules/components/ApiPage/processors/classes'; + getClassApiDefinitions, +} from 'docs/src/modules/components/ApiPage/definitions/classes'; import { ComponentClassDefinition } from '@mui/internal-docs-utils'; import { PropsTranslations } from '@mui-internal/api-docs-builder'; import kebabCase from 'lodash/kebabCase'; @@ -99,7 +99,7 @@ export default function ClassesSection(props: ClassesSectionProps) { const formattedClasses = classes || - classesApiProcessor({ + getClassApiDefinitions({ componentClasses, classDescriptions, componentName, diff --git a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx index b639cf8c83ff78..d4b938e81c0b96 100644 --- a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx @@ -11,8 +11,8 @@ import PropertiesList from 'docs/src/modules/components/ApiPage/list/PropertiesL import PropertiesTable from 'docs/src/modules/components/ApiPage/table/PropertiesTable'; import { PropertyDefinition, - propsApiProcessor, -} from 'docs/src/modules/components/ApiPage/processors/properties'; + getPropsApiDefinitions, +} from 'docs/src/modules/components/ApiPage/definitions/properties'; import { LayoutStorageKeys } from 'docs/src/modules/components/ApiPage'; import { ComponentApiContent, PropsTableItem, PropsTranslations } from 'packages/api-docs-builder'; import kebabCase from 'lodash/kebabCase'; @@ -110,7 +110,7 @@ export default function PropertiesSection(props: PropertiesSectionProps) { const formattedProperties = Array.isArray(properties) ? properties - : propsApiProcessor({ + : getPropsApiDefinitions({ properties, propertiesDescriptions: propertiesDescriptions!, componentName: componentName!, diff --git a/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx b/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx index 60f0ba9c5261f5..0dca67551af461 100644 --- a/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/SlotsSection.tsx @@ -12,8 +12,8 @@ import SlotsList from 'docs/src/modules/components/ApiPage/list/SlotsList'; import SlotsTable from 'docs/src/modules/components/ApiPage/table/SlotsTable'; import { SlotDefinition, - slotsApiProcessor, -} from 'docs/src/modules/components/ApiPage/processors/slots'; + getSlotsApiDefinitions, +} from 'docs/src/modules/components/ApiPage/definitions/slots'; export type SlotsSectionProps = ( | { @@ -56,7 +56,7 @@ export default function SlotsSection(props: SlotsSectionProps) { const formattedSlots = slots ?? - slotsApiProcessor({ + getSlotsApiDefinitions({ componentSlots, slotDescriptions, componentName, diff --git a/docs/src/modules/components/ApiPage/table/ClassesTable.tsx b/docs/src/modules/components/ApiPage/table/ClassesTable.tsx index fe7750ce1ee5d9..025c6e4b242682 100644 --- a/docs/src/modules/components/ApiPage/table/ClassesTable.tsx +++ b/docs/src/modules/components/ApiPage/table/ClassesTable.tsx @@ -6,7 +6,7 @@ import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, } from '@mui/docs/branding'; -import { ClassDefinition } from 'docs/src/modules/components/ApiPage/processors/classes'; +import { ClassDefinition } from 'docs/src/modules/components/ApiPage/definitions/classes'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; import ApiWarningAlert from 'docs/src/modules/components/ApiPage/ApiWarningAlert'; diff --git a/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx b/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx index 480174aaec053a..aab9a344bc96be 100644 --- a/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx +++ b/docs/src/modules/components/ApiPage/table/PropertiesTable.tsx @@ -6,7 +6,7 @@ import { brandingDarkTheme as darkTheme, brandingLightTheme as lightTheme, } from '@mui/docs/branding'; -import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/processors/properties'; +import { PropertyDefinition } from 'docs/src/modules/components/ApiPage/definitions/properties'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; import ApiWarningAlert from 'docs/src/modules/components/ApiPage/ApiWarningAlert'; diff --git a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx index 298ddcc14b4ec5..7e59379e46d8d2 100644 --- a/docs/src/modules/components/ApiPage/table/SlotsTable.tsx +++ b/docs/src/modules/components/ApiPage/table/SlotsTable.tsx @@ -7,7 +7,7 @@ import { brandingLightTheme as lightTheme, } from '@mui/docs/branding'; import StyledTableContainer from 'docs/src/modules/components/ApiPage/table/StyledTableContainer'; -import { SlotDefinition } from 'docs/src/modules/components/ApiPage/processors/slots'; +import { SlotDefinition } from 'docs/src/modules/components/ApiPage/definitions/slots'; const StyledTable = styled('table')( ({ theme }) => ({ diff --git a/docs/src/modules/components/ComponentsApiContent.js b/docs/src/modules/components/ComponentsApiContent.js index 1d922fabbfe235..e7b33051bac304 100644 --- a/docs/src/modules/components/ComponentsApiContent.js +++ b/docs/src/modules/components/ComponentsApiContent.js @@ -11,8 +11,8 @@ import { MarkdownElement } from '@mui/docs/MarkdownElement'; import PropertiesSection from 'docs/src/modules/components/ApiPage/sections/PropertiesSection'; import ClassesSection from 'docs/src/modules/components/ApiPage/sections/ClassesSection'; import SlotsSection from 'docs/src/modules/components/ApiPage/sections/SlotsSection'; -import { propsApiProcessor } from 'docs/src/modules/components/ApiPage/processors/properties'; -import { classesApiProcessor } from 'docs/src/modules/components/ApiPage/processors/classes'; +import { getPropsApiDefinitions } from 'docs/src/modules/components/ApiPage/definitions/properties'; +import { getClassApiDefinitions } from 'docs/src/modules/components/ApiPage/definitions/classes'; import { DEFAULT_API_LAYOUT_STORAGE_KEYS } from 'docs/src/modules/components/ApiPage/sections/ToggleDisplayOption'; function getTranslatedHeader(t, header, text) { @@ -146,7 +146,7 @@ export default function ComponentsApiContent(props) {

)} 0 ? ( {t('api-docs.hooksNoParameters')} )} Date: Wed, 7 Aug 2024 15:55:37 +0200 Subject: [PATCH 13/19] Update docs/src/modules/components/ApiPage/definitions/classes.ts Signed-off-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> --- docs/src/modules/components/ApiPage/definitions/classes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/modules/components/ApiPage/definitions/classes.ts b/docs/src/modules/components/ApiPage/definitions/classes.ts index f67956414a2999..a39f322c9bc11c 100644 --- a/docs/src/modules/components/ApiPage/definitions/classes.ts +++ b/docs/src/modules/components/ApiPage/definitions/classes.ts @@ -55,7 +55,7 @@ export function getClassApiDefinitions(params: GetClassApiDefinitionsParams): Cl ); } - if (!conditions && description.search(/{{nodeName}}/) !== -1) { + if (!nodeName && description.search(/{{nodeName}}/) !== -1) { throw Error( `In ${componentName} the class "${classDefinition.className}" description with "{{nodeName}}" but without \`nodeName\` to replace it.`, ); From 9d7d779c1a8a9a6d2001276e371ea29d6b197aee Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 7 Aug 2024 16:48:42 +0200 Subject: [PATCH 14/19] use invariant patern --- .../components/ApiPage/definitions/classes.ts | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/docs/src/modules/components/ApiPage/definitions/classes.ts b/docs/src/modules/components/ApiPage/definitions/classes.ts index a39f322c9bc11c..286e77456a668a 100644 --- a/docs/src/modules/components/ApiPage/definitions/classes.ts +++ b/docs/src/modules/components/ApiPage/definitions/classes.ts @@ -42,30 +42,34 @@ export interface GetClassApiDefinitionsParams { componentName: string; } +const errorMessage = (componentName: string, className: string, slotName: string): string => + `${className} description from component ${componentName} should include ${slotName} since its definition includes "{{${slotName}}}"`; + export function getClassApiDefinitions(params: GetClassApiDefinitionsParams): ClassDefinition[] { const { componentClasses, classDescriptions, componentName } = params; return componentClasses.map((classDefinition) => { - const { description, conditions, nodeName, deprecationInfo } = - classDescriptions[classDefinition.key]; + const { conditions, nodeName, deprecationInfo } = classDescriptions[classDefinition.key]; + + let description = classDescriptions[classDefinition.key].description; - if (!conditions && description.search(/{{conditions}}/) !== -1) { - throw Error( - `In ${componentName} the class "${classDefinition.className}" description with "{{conditions}}" but without \`conditions\` to replace it.`, - ); + if (description.includes('{{conditions}}')) { + if (!conditions) { + throw Error(errorMessage(componentName, classDefinition.className, 'conditions')); + } + description = description.replace(/{{conditions}}/, conditions); } - if (!nodeName && description.search(/{{nodeName}}/) !== -1) { - throw Error( - `In ${componentName} the class "${classDefinition.className}" description with "{{nodeName}}" but without \`nodeName\` to replace it.`, - ); + if (description.includes('{{nodeName}}')) { + if (!nodeName) { + throw Error(errorMessage(componentName, classDefinition.className, 'nodeName')); + } + description = description.replace(/{{nodeName}}/, nodeName); } return { ...classDefinition, - description: description - .replace(/{{conditions}}/, conditions!) - .replace(/{{nodeName}}/, nodeName!), + description, deprecationInfo, hash: `${kebabCase(componentName)}-classes-${classDefinition.className}`, }; From ed7b7742f22aba06c298673b46b47c63517c88f9 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 7 Aug 2024 16:57:12 +0200 Subject: [PATCH 15/19] fix build --- .../modules/components/ApiPage/definitions/classes.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/src/modules/components/ApiPage/definitions/classes.ts b/docs/src/modules/components/ApiPage/definitions/classes.ts index 286e77456a668a..ac8a8ef0e57d3e 100644 --- a/docs/src/modules/components/ApiPage/definitions/classes.ts +++ b/docs/src/modules/components/ApiPage/definitions/classes.ts @@ -49,9 +49,14 @@ export function getClassApiDefinitions(params: GetClassApiDefinitionsParams): Cl const { componentClasses, classDescriptions, componentName } = params; return componentClasses.map((classDefinition) => { - const { conditions, nodeName, deprecationInfo } = classDescriptions[classDefinition.key]; + const { + conditions, + nodeName, + deprecationInfo, + description: translatedDescription, + } = classDescriptions[classDefinition.key] ?? {}; // Not all classes have a description. - let description = classDescriptions[classDefinition.key].description; + let description = translatedDescription ?? classDefinition.description; if (description.includes('{{conditions}}')) { if (!conditions) { From fdc91396962d5de20caee8d279193177d8dd2a1c Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 8 Aug 2024 10:16:33 +0200 Subject: [PATCH 16/19] remove wrongly introduced parenthesis --- docs/src/modules/components/ApiPage.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/src/modules/components/ApiPage.tsx b/docs/src/modules/components/ApiPage.tsx index 95c775ecb3a89d..0e31845fbb7842 100644 --- a/docs/src/modules/components/ApiPage.tsx +++ b/docs/src/modules/components/ApiPage.tsx @@ -343,7 +343,6 @@ export default function ApiPage(props: ApiPageProps) { /> )} - ( - ) Date: Thu, 8 Aug 2024 10:55:50 +0200 Subject: [PATCH 17/19] Fix management of optional abreviations --- .../modules/components/ApiPage/definitions/properties.ts | 7 +++++-- .../components/ApiPage/sections/PropertiesSection.tsx | 7 +++++++ docs/src/modules/components/HooksApiContent.js | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/src/modules/components/ApiPage/definitions/properties.ts b/docs/src/modules/components/ApiPage/definitions/properties.ts index 6e81b2faee2bd3..fcdfeeaa34601c 100644 --- a/docs/src/modules/components/ApiPage/definitions/properties.ts +++ b/docs/src/modules/components/ApiPage/definitions/properties.ts @@ -140,6 +140,7 @@ export function getPropsApiDefinitions(params: GetPropsApiDefinitionsParams): Pr interface HookCommonApiParams { hookName: string; + showOptionalAbbr?: boolean; } interface GetHookReturnApiDefinitionsParams extends HookCommonApiParams { @@ -157,10 +158,11 @@ interface GetHookParametersApiDefinitions extends HookCommonApiParams { export function getHookApiDefinitions( params: GetHookReturnApiDefinitionsParams | GetHookParametersApiDefinitions, ): PropertyDefinition[] { - const { properties, translations, hookName, kind } = params; + const { properties, translations, hookName, kind, showOptionalAbbr } = params; return Object.entries(properties).map(([propName, propData]) => { - const isOptional = !propData.required; + const isRequired = propData.required && !showOptionalAbbr; + const isOptional = !propData.required && showOptionalAbbr; const isDeprecated = propData.deprecated; const deprecationInfo = propData.deprecationInfo; @@ -173,6 +175,7 @@ export function getHookApiDefinitions( hash: `${kebabCase(hookName)}-${kind === 'parameters' ? 'parameters' : 'return-value'}-${propName}`, propName, description: propDescription?.description, + isRequired, isOptional, isDeprecated, deprecationInfo, diff --git a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx index d4b938e81c0b96..818aa8ced2d285 100644 --- a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx @@ -65,8 +65,13 @@ type PropertiesSectionProps = ( }; propertiesDescriptions: PropsTranslations['propDescriptions']; componentName: string; + /** + * Add indicators that the properties is optional instead of showing it is required. + */ + showOptionalAbbr?: boolean; } | { + showOptionalAbbr?: undefined; properties: PropertyDefinition[]; propertiesDescriptions?: undefined; componentName?: undefined; @@ -103,6 +108,7 @@ export default function PropertiesSection(props: PropertiesSectionProps) { spreadHint, defaultLayout, layoutStorageKey, + showOptionalAbbr, } = props; const t = useTranslate(); @@ -114,6 +120,7 @@ export default function PropertiesSection(props: PropertiesSectionProps) { properties, propertiesDescriptions: propertiesDescriptions!, componentName: componentName!, + showOptionalAbbr, }); return ( diff --git a/docs/src/modules/components/HooksApiContent.js b/docs/src/modules/components/HooksApiContent.js index a412b8f55cb86d..d619922cd21976 100644 --- a/docs/src/modules/components/HooksApiContent.js +++ b/docs/src/modules/components/HooksApiContent.js @@ -91,6 +91,7 @@ export default function HooksApiContent(props) { hookName, properties: returnValue, translations: returnValueDescriptions, + showOptionalAbbr: true, })} level="h3" title="api-docs.returnValue" From 9853d68581cab4370eb942b8fdad2045f91cd8b2 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 8 Aug 2024 10:58:03 +0200 Subject: [PATCH 18/19] support pro plans for X --- .../components/ApiPage/definitions/properties.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/src/modules/components/ApiPage/definitions/properties.ts b/docs/src/modules/components/ApiPage/definitions/properties.ts index fcdfeeaa34601c..42273bfbad48dd 100644 --- a/docs/src/modules/components/ApiPage/definitions/properties.ts +++ b/docs/src/modules/components/ApiPage/definitions/properties.ts @@ -68,7 +68,16 @@ export const getPropertiesToC = ({ interface GetPropsApiDefinitionsParams { componentName: string; properties: { - [name: string]: PropsTableItem; + [name: string]: PropsTableItem & { + /** + * Only to be compatible the time of the migration for X + */ + isProPlan?: boolean; + /** + * Only to be compatible the time of the migration for X + */ + isPremiumPlan?: boolean; + }; }; propertiesDescriptions: PropsTranslations['propDescriptions']; /** @@ -128,6 +137,8 @@ export function getPropsApiDefinitions(params: GetPropsApiDefinitionsParams): Pr signature, signatureArgs, signatureReturnDescription, + isProPlan: propData.isProPlan, + isPremiumPlan: propData.isPremiumPlan, }; }); } From 2138bdaed6b8ebde46e6a1ce8953e467785b1694 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 8 Aug 2024 11:59:08 +0200 Subject: [PATCH 19/19] type spreadHint as optional --- .../modules/components/ApiPage/sections/PropertiesSection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx index 818aa8ced2d285..9f04a579017a44 100644 --- a/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx +++ b/docs/src/modules/components/ApiPage/sections/PropertiesSection.tsx @@ -77,7 +77,7 @@ type PropertiesSectionProps = ( componentName?: undefined; } ) & { - spreadHint: string; + spreadHint?: string; defaultLayout: ApiDisplayOptions; layoutStorageKey: LayoutStorageKeys['props']; /**