addons/docs/src/lib/docgen/extractDocgenProps.ts
import { Component } from '../../blocks/types';
import { ExtractedJsDoc, parseJsDoc } from '../jsdocParser';
import { PropDef, DocgenInfo, TypeSystem } from './types';
import { getDocgenSection, isValidDocgenSection, getDocgenDescription } from './utils';
import { getPropDefFactory, PropDefFactory } from './createPropDef';
export interface ExtractedProp {
propDef: PropDef;
docgenInfo: DocgenInfo;
jsDocTags: ExtractedJsDoc;
typeSystem: TypeSystem;
}
export type ExtractProps = (component: Component, section: string) => ExtractedProp[];
const getTypeSystem = (docgenInfo: DocgenInfo): TypeSystem => {
if (docgenInfo.type != null) {
return TypeSystem.JAVASCRIPT;
}
if (docgenInfo.flowType != null) {
return TypeSystem.FLOW;
}
if (docgenInfo.tsType != null) {
return TypeSystem.TYPESCRIPT;
}
return TypeSystem.UNKNOWN;
};
export const extractComponentSectionArray = (docgenSection: any) => {
const typeSystem = getTypeSystem(docgenSection[0]);
const createPropDef = getPropDefFactory(typeSystem);
return docgenSection.map((item: any) => {
let sanitizedItem = item;
if (item.type?.elements) {
sanitizedItem = {
...item,
type: {
...item.type,
value: item.type.elements,
},
};
}
return extractProp(sanitizedItem.name, sanitizedItem, typeSystem, createPropDef);
});
};
export const extractComponentSectionObject = (docgenSection: any) => {
const docgenPropsKeys = Object.keys(docgenSection);
const typeSystem = getTypeSystem(docgenSection[docgenPropsKeys[0]]);
const createPropDef = getPropDefFactory(typeSystem);
return docgenPropsKeys
.map((propName) => {
const docgenInfo = docgenSection[propName];
return docgenInfo != null
? extractProp(propName, docgenInfo, typeSystem, createPropDef)
: null;
})
.filter(Boolean);
};
export const extractComponentProps: ExtractProps = (component, section) => {
const docgenSection = getDocgenSection(component, section);
if (!isValidDocgenSection(docgenSection)) {
return [];
}
// vue-docgen-api has diverged from react-docgen and returns an array
return Array.isArray(docgenSection)
? extractComponentSectionArray(docgenSection)
: extractComponentSectionObject(docgenSection);
};
function extractProp(
propName: string,
docgenInfo: DocgenInfo,
typeSystem: TypeSystem,
createPropDef: PropDefFactory
): ExtractedProp {
const jsDocParsingResult = parseJsDoc(docgenInfo.description);
const isIgnored = jsDocParsingResult.includesJsDoc && jsDocParsingResult.ignore;
if (!isIgnored) {
const propDef = createPropDef(propName, docgenInfo, jsDocParsingResult);
return {
propDef,
jsDocTags: jsDocParsingResult.extractedTags,
docgenInfo,
typeSystem,
};
}
return null;
}
export function extractComponentDescription(component?: Component): string {
return component != null && getDocgenDescription(component);
}