Improved docgen info interface

This commit is contained in:
patrick.lafrance 2019-11-11 16:40:17 -05:00
parent a9b8cec3e6
commit 0b8f80b342
7 changed files with 72 additions and 79 deletions

View File

@ -12,9 +12,12 @@ export function enhancePropTypesProp(extractedProp: ExtractedProp): PropDef {
propDef.type = newtype;
}
const newDefaultValue = renderDefaultValue(extractedProp);
if (!isNil(newDefaultValue)) {
propDef.defaultValue = newDefaultValue;
const { defaultValue } = extractedProp.docgenInfo;
if (!isNil(defaultValue)) {
const newDefaultValue = renderDefaultValue(defaultValue.value);
if (!isNil(newDefaultValue)) {
propDef.defaultValue = newDefaultValue;
}
}
return propDef;

View File

@ -92,27 +92,19 @@ function renderArray({ ast }: InspectionResult): ReactNode {
: createPropText(ARRAY_CAPTION, { title: generateCode(ast) });
}
// TODO: The function signature might only receive a defaultValue
export function renderDefaultValue({ docgenInfo }: ExtractedProp): ReactNode {
const { defaultValue } = docgenInfo;
export function renderDefaultValue(defaultValue: string): ReactNode {
const inspectionResult = inspectValue(defaultValue);
if (!isNil(defaultValue)) {
const { value } = defaultValue;
const inspectionResult = inspectValue(value);
switch (inspectionResult.inferedType.type) {
case InspectionType.OBJECT:
return renderObject(inspectionResult);
case InspectionType.FUNCTION:
return renderFunc(inspectionResult);
case InspectionType.ELEMENT:
return renderElement(value, inspectionResult);
case InspectionType.ARRAY:
return renderArray(inspectionResult);
default:
break;
}
switch (inspectionResult.inferedType.type) {
case InspectionType.OBJECT:
return renderObject(inspectionResult);
case InspectionType.FUNCTION:
return renderFunc(inspectionResult);
case InspectionType.ELEMENT:
return renderElement(defaultValue, inspectionResult);
case InspectionType.ARRAY:
return renderArray(inspectionResult);
default:
return null;
}
return null;
}

View File

@ -3,7 +3,7 @@ import { ReactNode } from 'react';
import { ExtractedProp } from '../../../lib2/extractDocgenProps';
import { ExtractedJsDocParam } from '../../../lib2/jsdocParser';
import { createPropText } from '../../../lib2/createComponents';
import { PropTypesType } from './types';
import { DocgenPropType } from '../../../lib2/types';
import { inspectValue } from './inspection/inspectValue';
import { generateCode } from './generateCode';
import {
@ -18,12 +18,20 @@ import { InspectionType } from './inspection/types';
const MAX_CAPTION_LENGTH = 35;
interface PropType {
name: string;
value?: any;
computed?: boolean;
raw?: string;
description?: string;
enum PropTypesType {
CUSTOM = 'custom',
ANY = 'any',
FUNC = 'func',
SHAPE = 'shape',
OBJECT = 'object',
INSTANCEOF = 'instanceOf',
OBJECTOF = 'objectOf',
UNION = 'union',
ENUM = 'enum',
ARRAYOF = 'arrayOf',
ELEMENT = 'element',
ELEMENTTYPE = 'elementType',
NODE = 'node',
}
interface EnumValue {
@ -57,12 +65,12 @@ function createTypeDef({
};
}
function shortifyPropTypes(value: string): string {
function cleanPropTypes(value: string): string {
return value.replace(/PropTypes./g, '').replace(/.isRequired/g, '');
}
function prettyObject(ast: any, compact = false): string {
return shortifyPropTypes(generateCode(ast, compact));
return cleanPropTypes(generateCode(ast, compact));
}
function getCaptionFromInspectionType(type: InspectionType): string {
@ -100,7 +108,7 @@ function generateValuesForObjectAst(ast: any): [string, string] {
return [caption, value];
}
function generateCustom({ raw }: PropType): TypeDef {
function generateCustom({ raw }: DocgenPropType): TypeDef {
if (!isNil(raw)) {
const { inferedType, ast } = inspectValue(raw);
const { type, identifier } = inferedType as any;
@ -190,7 +198,7 @@ function generateFunc(extractedProp: ExtractedProp): TypeDef {
return createTypeDef({ name: PropTypesType.FUNC, caption: FUNCTION_CAPTION });
}
function generateShape(type: PropType, extractedProp: ExtractedProp): TypeDef {
function generateShape(type: DocgenPropType, extractedProp: ExtractedProp): TypeDef {
const fields = Object.keys(type.value)
.map((key: string) => `${key}: ${generateType(type.value[key], extractedProp).value}`)
.join(', ');
@ -205,7 +213,7 @@ function generateShape(type: PropType, extractedProp: ExtractedProp): TypeDef {
});
}
function generateObjectOf(type: PropType, extractedProp: ExtractedProp): TypeDef {
function generateObjectOf(type: DocgenPropType, extractedProp: ExtractedProp): TypeDef {
const format = (of: string) => `objectOf(${of})`;
// eslint-disable-next-line prefer-const
@ -224,7 +232,7 @@ function generateObjectOf(type: PropType, extractedProp: ExtractedProp): TypeDef
});
}
function generateUnion(type: PropType, extractedProp: ExtractedProp): TypeDef {
function generateUnion(type: DocgenPropType, extractedProp: ExtractedProp): TypeDef {
if (Array.isArray(type.value)) {
const values = type.value.reduce(
(acc: any, v: any) => {
@ -276,7 +284,7 @@ function generateEnumValue({ value, computed }: EnumValue): TypeDef {
return createTypeDef({ name: 'enumvalue', caption: value });
}
function generateEnum(type: PropType): TypeDef {
function generateEnum(type: DocgenPropType): TypeDef {
if (Array.isArray(type.value)) {
const values = type.value.reduce(
(acc: any, v: EnumValue) => {
@ -316,7 +324,7 @@ function createArrayOfObjectTypeDef(caption: string, value: string): TypeDef {
});
}
function generateArray(type: PropType, extractedProp: ExtractedProp): TypeDef {
function generateArray(type: DocgenPropType, extractedProp: ExtractedProp): TypeDef {
// eslint-disable-next-line prefer-const
let { name, caption, value, inferedType } = generateType(type.value, extractedProp);
@ -331,7 +339,7 @@ function generateArray(type: PropType, extractedProp: ExtractedProp): TypeDef {
return createTypeDef({ name: PropTypesType.ARRAYOF, caption: braceAfter(value) });
}
function generateType(type: PropType, extractedProp: ExtractedProp): TypeDef {
function generateType(type: DocgenPropType, extractedProp: ExtractedProp): TypeDef {
try {
switch (type.name) {
case PropTypesType.CUSTOM:
@ -362,7 +370,7 @@ function generateType(type: PropType, extractedProp: ExtractedProp): TypeDef {
}
export function renderType(extractedProp: ExtractedProp): ReactNode {
const type = extractedProp.docgenInfo.type as PropType;
const { type } = extractedProp.docgenInfo;
switch (type.name) {
case PropTypesType.CUSTOM:

View File

@ -1,15 +0,0 @@
export enum PropTypesType {
CUSTOM = 'custom',
ANY = 'any',
FUNC = 'func',
SHAPE = 'shape',
OBJECT = 'object',
INSTANCEOF = 'instanceOf',
OBJECTOF = 'objectOf',
UNION = 'union',
ENUM = 'enum',
ARRAYOF = 'arrayOf',
ELEMENT = 'element',
ELEMENTTYPE = 'elementType',
NODE = 'node',
}

View File

@ -1,7 +1,7 @@
import { PropText } from '@storybook/components';
import React, { ReactNode } from 'react';
// TODO: since text is now optionnal, no point in not have it any "props"é
// TODO: since text is now optionnal, no point in not have it any "props"
export function createPropText(text?: string, props: Record<string, any> = {}): ReactNode {
return <PropText text={text} {...props} />;
}

View File

@ -1,6 +1,6 @@
import { isNil } from 'lodash';
import { PropDef } from '@storybook/components';
import { TypeSystem, DocgenInfo } from './types';
import { TypeSystem, DocgenInfo, DocgenType } from './types';
import { JsDocParsingResult } from './jsdocParser';
import { createPropText } from './createComponents';
import { renderDefaultValue } from './renderDefaultValue';
@ -11,11 +11,7 @@ export type PropDefFactory = (
jsDocParsingResult?: JsDocParsingResult
) => PropDef;
interface PropType {
name: string;
}
function createDefaultPropDef(name: string, type: PropType, docgenInfo: DocgenInfo): PropDef {
function createDefaultPropDef(name: string, type: DocgenType, docgenInfo: DocgenInfo): PropDef {
const { description, required, defaultValue } = docgenInfo;
return {
@ -29,7 +25,7 @@ function createDefaultPropDef(name: string, type: PropType, docgenInfo: DocgenIn
function createDocgenPropDef(
name: string,
type: PropType,
type: DocgenType,
docgenInfo: DocgenInfo,
jsDocParsingResult: JsDocParsingResult
): PropDef {

View File

@ -1,23 +1,32 @@
import { PropsTableProps, PropDef } from '@storybook/components';
import { PropsTableProps } from '@storybook/components';
import { Component } from '../blocks/shared';
export type PropsExtractor = (component: Component) => PropsTableProps | null;
// TODO: Define proper docgen types and use them all around in addons-doc.
export interface DocgenBaseType {
name: string;
description?: string;
require?: boolean;
}
export interface DocgenPropType extends DocgenBaseType {
value?: any;
raw?: string;
computed?: boolean;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DocgenFlowType extends DocgenBaseType {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DocgenTypeScriptType extends DocgenBaseType {}
export type DocgenType = DocgenPropType | DocgenFlowType | DocgenTypeScriptType;
export interface DocgenInfo {
type?: {
name: string;
value?: {
name?: string;
raw?: string;
};
};
flowType?: {
name: string;
};
tsType?: {
name: string;
};
type?: DocgenPropType;
flowType?: DocgenFlowType;
tsType?: DocgenTypeScriptType;
required: boolean;
description?: string;
defaultValue?: {