Skip to content

Commit

Permalink
Merge branch 'trunk' into fix/issue-65339-task1
Browse files Browse the repository at this point in the history
  • Loading branch information
hbhalodia committed Oct 17, 2024
2 parents 12532be + 1bb2779 commit 20d8650
Show file tree
Hide file tree
Showing 246 changed files with 1,328 additions and 367 deletions.
3 changes: 3 additions & 0 deletions backport-changelog/6.8/7575.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
https://github.com/WordPress/wordpress-develop/pull/7575

* https://github.com/WordPress/gutenberg/pull/66154
112 changes: 112 additions & 0 deletions bin/api-docs/gen-components-docs/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* External dependencies
*/
import docgen from 'react-docgen-typescript';
import glob from 'glob';
import fs from 'node:fs/promises';
import path from 'path';

/**
* Internal dependencies
*/
import { generateMarkdownDocs } from './markdown/index.mjs';

const MANIFEST_GLOB = 'packages/components/src/**/docs-manifest.json';

// For consistency, options should generally match the options used in Storybook.
const OPTIONS = {
shouldExtractLiteralValuesFromEnum: true,
shouldRemoveUndefinedFromOptional: true,
propFilter: ( prop ) =>
prop.parent ? ! /node_modules/.test( prop.parent.fileName ) : true,
savePropValueAsString: true,
};

function getTypeDocsForComponent( {
manifestPath,
componentFilePath,
displayName,
} ) {
const resolvedPath = path.resolve(
path.dirname( manifestPath ),
componentFilePath
);

const typeDocs = docgen.parse( resolvedPath, OPTIONS );

if ( typeDocs.length === 0 ) {
throw new Error(
`react-docgen-typescript could not generate any type docs from ${ resolvedPath }`
);
}

const matchingTypeDoc = typeDocs.find(
( obj ) => obj.displayName === displayName
);

if ( typeof matchingTypeDoc === 'undefined' ) {
const unmatchedTypeDocs = typeDocs
.map( ( obj ) => `\`${ obj.displayName }\`` )
.join( ', ' );

throw new Error(
`react-docgen-typescript could not find type docs for ${ displayName } in ${ resolvedPath }. (Found ${ unmatchedTypeDocs })`
);
}

return matchingTypeDoc;
}

async function parseManifest( manifestPath ) {
try {
return JSON.parse( await fs.readFile( manifestPath, 'utf8' ) );
} catch ( e ) {
throw new Error(
`Error parsing docs manifest at ${ manifestPath }: ${ e.message }`
);
}
}

const manifests = glob.sync( MANIFEST_GLOB );

await Promise.all(
manifests.map( async ( manifestPath ) => {
const manifest = await parseManifest( manifestPath );

const typeDocs = getTypeDocsForComponent( {
manifestPath,
componentFilePath: manifest.filePath,
displayName: manifest.displayName,
} );

const subcomponentTypeDocs = manifest.subcomponents?.map(
( subcomponent ) => {
const docs = getTypeDocsForComponent( {
manifestPath,
componentFilePath: subcomponent.filePath,
displayName: subcomponent.displayName,
} );

if ( subcomponent.preferredDisplayName ) {
docs.displayName = subcomponent.preferredDisplayName;
}

return docs;
}
);
const docs = generateMarkdownDocs( { typeDocs, subcomponentTypeDocs } );
const outputFile = path.resolve(
path.dirname( manifestPath ),
'./README.md'
);

try {
console.log( `Writing docs to ${ outputFile }` );
return fs.writeFile( outputFile, docs );
} catch ( e ) {
throw new Error(
`Error writing docs to ${ outputFile }: ${ e.message }`
);
}
} )
);
40 changes: 40 additions & 0 deletions bin/api-docs/gen-components-docs/markdown/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* External dependencies
*/
import json2md from 'json2md';

/**
* Internal dependencies
*/
import { generateMarkdownPropsJson } from './props.mjs';

export function generateMarkdownDocs( { typeDocs, subcomponentTypeDocs } ) {
const mainDocsJson = [
'<!-- This file is generated automatically and cannot be edited directly. -->\n',
{ h1: typeDocs.displayName },
{
p: `<p class="callout callout-info">See the <a href="https://wordpress.github.io/gutenberg/?path=/docs/components-${ typeDocs.displayName.toLowerCase() }--docs">WordPress Storybook</a> for more detailed, interactive documentation.</p>`,
},
typeDocs.description,
...generateMarkdownPropsJson( typeDocs.props ),
];

const subcomponentDocsJson = subcomponentTypeDocs?.length
? [
{ h2: 'Subcomponents' },
...subcomponentTypeDocs.flatMap( ( subcomponentTypeDoc ) => [
{
h3: subcomponentTypeDoc.displayName,
},
subcomponentTypeDoc.description,
...generateMarkdownPropsJson( subcomponentTypeDoc.props, {
headingLevel: 4,
} ),
] ),
]
: [];

return json2md(
[ ...mainDocsJson, ...subcomponentDocsJson ].filter( Boolean )
);
}
51 changes: 51 additions & 0 deletions bin/api-docs/gen-components-docs/markdown/props.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
function renderPropType( type ) {
const MAX_ENUM_VALUES = 10;

switch ( type.name ) {
case 'enum': {
const string = type.value
.slice( 0, MAX_ENUM_VALUES )
.map( ( { value } ) => value )
.join( ' | ' );

if ( type.value.length > MAX_ENUM_VALUES ) {
return `${ string } | ...`;
}
return string;
}
default:
return type.name;
}
}

export function generateMarkdownPropsJson( props, { headingLevel = 2 } = {} ) {
const sortedKeys = Object.keys( props ).sort( ( [ a ], [ b ] ) =>
a.localeCompare( b )
);

const propsJson = sortedKeys
.flatMap( ( key ) => {
const prop = props[ key ];

if ( prop.description?.includes( '@ignore' ) ) {
return null;
}

return [
{ [ `h${ headingLevel + 1 }` ]: `\`${ key }\`` },
prop.description,
{
ul: [
`Type: \`${ renderPropType( prop.type ) }\``,
`Required: ${ prop.required ? 'Yes' : 'No' }`,
prop.defaultValue &&
`Default: \`${ prop.defaultValue.value }\``,
].filter( Boolean ),
},
];
} )
.filter( Boolean );

return [ { [ `h${ headingLevel }` ]: 'Props' }, ...propsJson ];
}

Loading

0 comments on commit 20d8650

Please sign in to comment.