Skip to content

Commit

Permalink
feat(doc): update spec generation to handle multiple sub-components
Browse files Browse the repository at this point in the history
  • Loading branch information
dpellier committed Jul 29, 2024
1 parent f1fc685 commit 99c2bbb
Show file tree
Hide file tree
Showing 16 changed files with 55 additions and 88 deletions.
113 changes: 55 additions & 58 deletions packages/ods/scripts/generate-typedoc-md.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
#! /usr/bin/env node

// TODO either:
// fix with https://github.com/TypeStrong/typedoc/releases/tag/v0.24.0 changes (and remove typedoc-plugin-markdown dep)
// use typedoc-plugin-markdown and adapt our doc

/**
* Script to generate the file spec.md for one specific component
* The file is created in <path>/documentation
* The script need a json typedoc file in <path>/typedoc.json
* Script to generate the file spec.md for one specific ODS component
* The file is created in <component-path>/documentation
* The script need a json typedoc file located in <component-path>/dist/doc-api/typedoc.json
*
* You can pass an optional --prefix <value> to manage components that are not
* in the default "components" package, ex:
* --prefix ovh # for "components-ovh"
*/
const fs = require('fs');
const path = require('path');

const isMultiple = process.argv[2]?.includes('multiple');
const typedocBasePath = path.resolve('dist', 'docs-api');
const pathPrefixIdx = process.argv.indexOf('--prefix');

const ReflectionKind = {
Project: 1,
Module: 2,
Expand All @@ -44,52 +37,55 @@ const ReflectionKind = {
SetSignature: 1048576,
TypeAlias: 2097152,
Reference: 4194304,
}
};

let pathPrefix = '';
if (pathPrefixIdx > -1) {
pathPrefix = process.argv[pathPrefixIdx + 1];
}

function convertJsonToMarkdown(jsonItems) {
const classes = getClasses(jsonItems);
const enums = getEnums(jsonItems);

const hasProps = classes.props.length;
const hasMethods = classes.methods.length;
const hasEvents = classes.events.length;
const hasEnums = enums.length;

return [
hasProps ? '## Properties' : '', ...classes.props,
hasMethods ? '## Methods' : '', ...classes.methods,
hasEvents ? '## Events' : '', ...classes.events,
hasEnums ? '## Enums' : '', ...enums,
].join('\n');
}

function createSpecMd(component = '') {
const typedocJson = require(path.resolve(typedocBasePath, component, 'typedoc.json'));
function createSpecMd() {
const typedocJson = require(path.resolve(typedocBasePath, 'typedoc.json'));
// TODO test for prefixed project (like -ovh)
const dir = path.resolve('documentation');

fs.mkdirSync(dir, { recursive: true });

if (typedocJson.children) {
fs.writeFileSync(path.resolve(dir, 'spec.md'), convertJsonToMarkdown(typedocJson.children), (err) => {
if (err) {
console.error('file write error.');
throw err;
}
});
}
const classesMarkdown = getClassesInfo(typedocJson.children);
const enumsMarkdown = getEnums(typedocJson.children);
const markdown = [].concat(classesMarkdown).concat(enumsMarkdown).join('\n');

fs.writeFileSync(path.resolve(dir, `spec.md`), markdown, (err) => {
if (err) {
console.error('file write error.');
throw err;
}
});
}

function getClasses(jsonItems) {
const classesDefinitions = jsonItems.filter(({ kind }) => kind === ReflectionKind.Class);
function getClassesInfo(jsonItems) {
return jsonItems
.filter(({ kind }) => kind === ReflectionKind.Class)
.map((classData) => {
const { events, methods, props } = getClassInfo(classData);

if (!events.length && !methods.length && !props.length) {
return [
`# ${classData.name}`,
'This component has no properties, events nor methods.',
].join('\n');
}

const children = classesDefinitions.flatMap(({ children }) => children);
return [
`# ${classData.name}`,
props.length ? '## Properties' : '', ...props,
methods.length ? '## Methods' : '', ...methods,
events.length ? '## Events' : '', ...events,
].join('\n');
});
}

function getClassInfo({ children }) {
const props = children
.filter(({ kind, decorators }) => kind === ReflectionKind.Property && decorators[0].escapedText === 'Prop')
.filter((prop) => prop.flags.isPublic)
Expand Down Expand Up @@ -124,19 +120,30 @@ function getClasses(jsonItems) {
});

return {
props,
events,
methods,
props,
};
}

function getEnums(jsonItems) {
return jsonItems
const enums = jsonItems
.filter(({ kind }) => kind === ReflectionKind.Enum)
.flatMap((enumDefinition) => {
const children = enumDefinition.children.map(({ name, type }) => `• **${name}** = \`"${type?.value}"\`\n`);
return `### Enumeration: ${enumDefinition.name}\n\n${children.join('\n')}\n`
});
.map((getEnum));

if (!enums.length) {
return [];
}

return [
`# Enums`,
enums.join('\n'),
];
}

function getEnum(enumDefinition) {
const children = enumDefinition.children.map(({ name, type }) => `• **${name}** = \`"${type?.value}"\`\n`);
return `## ${enumDefinition.name}\n\n${children.join('\n')}\n`
}

function getTypeValue(tObj) {
Expand Down Expand Up @@ -172,14 +179,4 @@ function printType(typeObject) {
return '_unknown_';
}

if (!isMultiple) {
return createSpecMd();
}

// See Radio or Accordion for example multiple
const componentFolders = fs.readdirSync('./src/components', {});

componentFolders.forEach((odsComponent) => {
const component = odsComponent.replace(`ods${pathPrefix ? `-${pathPrefix}` : ''}-`, '');
return createSpecMd(component);
});
return createSpecMd();
2 changes: 0 additions & 2 deletions packages/storybook/stories/components/badge/documentation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Badge show concise metadata or the current status for an item, in a compact form

<DocNavigator of={ BadgeStories } />

# API

<Markdown>{ SpecificationsBadge }</Markdown>

# Style customization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ A list of links showing the current page location in the navigational hierarchy:

<DocNavigator of={ BreadcrumbStories } />

# API

<Markdown>{ SpecificationsBreadcrumb }</Markdown>

# Style customization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Button component aims to initiate an action. Its text indicates the related inte

<DocNavigator of={ ButtonStories } />

# API

<Markdown>{ SpecificationsButton }</Markdown>

# Style customization
Expand Down
2 changes: 0 additions & 2 deletions packages/storybook/stories/components/icon/documentation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Icon is a visual context used to represent a command, navigation, status or comm

<DocNavigator of={ IconStories } />

# API

<Markdown>{ SpecificationsIcon }</Markdown>

# Examples
Expand Down
2 changes: 0 additions & 2 deletions packages/storybook/stories/components/input/documentation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Input component is an input field where users can type into:

<DocNavigator of={ InputStories } />

# API

<Markdown> { SpecificationsInput } </Markdown>

# Style customization
Expand Down
2 changes: 0 additions & 2 deletions packages/storybook/stories/components/link/documentation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Link is a component that enables redirection to a new page, section, website or

<DocNavigator of={ LinkStories } />

# API

<Markdown>{ SpecificationsLink }</Markdown>

# Style customization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Medium is a wrapper for displaying assets such as images:

<DocNavigator of={ MediumStories } />

# API

<Markdown>{ SpecificationsMedium }</Markdown>

# Examples
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Skeleton component indicates that data is loading. It improves the perceived loa

<DocNavigator of={ SkeletonStories } />

# API

<Markdown> { SpecificationsSkeleton } </Markdown>

# Style customization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ A visual indicator that a process is happening in the background but the interfa

<DocNavigator of={ SpinnerStories } />

# API

<Markdown>{ SpecificationsSpinner }</Markdown>

# Style customization
Expand Down
2 changes: 0 additions & 2 deletions packages/storybook/stories/components/table/documentation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Table is a wrapper for displaying tables:

<DocNavigator of={ TableStories } />

# API

<Markdown>{ SpecificationsTable }</Markdown>

# Style customization
Expand Down
2 changes: 0 additions & 2 deletions packages/storybook/stories/components/tag/documentation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Tag show concise metadata or the current status for an item, in a compact format

<DocNavigator of={ TagStories } />

# API

<Markdown>{ SpecificationsTag }</Markdown>

# Style customization
Expand Down
2 changes: 0 additions & 2 deletions packages/storybook/stories/components/text/documentation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ The text component is used to display text with a specific font & style.

<DocNavigator of={ TextStories } />

# API

<Markdown> { SpecificationsText } </Markdown>

# Style customization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ Textarea component is used to type long content:

<DocNavigator of={ TextareaStories } />

# API

<Markdown>{ SpecificationsTextarea }</Markdown>

# Style customization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import * as TooltipStories from './tooltip.stories';

<DocNavigator of={ TooltipStories } />

# API

<Markdown> { SpecificationsTooltip } </Markdown>

# Style customization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ TODO Some text about the component

<DocNavigator of={ {{> ComponentName }}Stories } />

# API

<Markdown>{ Specifications{{> ComponentName }} }</Markdown>

# Style customization [IF RELEVANT]
Expand Down

0 comments on commit 99c2bbb

Please sign in to comment.