Merge pull request #12550 from phated/docgen-flow-converters

Addon-docs: Add converters between Flow types and storybook types
This commit is contained in:
Michael Shilman 2020-09-24 01:36:59 +08:00 committed by GitHub
commit 245112597c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 116 additions and 1 deletions

View File

@ -0,0 +1,55 @@
/* eslint-disable no-case-declarations */
import { SBType } from '@storybook/client-api';
import { FlowType, FlowSigType, FlowLiteralType } from './types';
const isLiteral = (type: FlowType) => type.name === 'literal';
const toEnumOption = (element: FlowLiteralType) => element.value.replace(/['|"]/g, '');
const convertSig = (type: FlowSigType) => {
switch (type.type) {
case 'function':
return { name: 'function' };
case 'object':
const values: any = {};
type.signature.properties.forEach((prop) => {
values[prop.key] = convert(prop.value);
});
return {
name: 'object',
value: values,
};
default:
throw new Error(`Unknown: ${type}`);
}
};
export const convert = (type: FlowType): SBType | void => {
const { name, raw } = type;
const base: any = {};
if (typeof raw !== 'undefined') base.raw = raw;
switch (type.name) {
case 'literal':
return { ...base, name: 'other', value: type.value };
case 'string':
case 'number':
case 'symbol':
case 'boolean': {
return { ...base, name };
}
case 'Array': {
return { ...base, name: 'array', value: type.elements.map(convert) };
}
case 'signature':
return { ...base, ...convertSig(type) };
case 'union':
if (type.elements.every(isLiteral)) {
return { ...base, name: 'enum', value: type.elements.map(toEnumOption) };
}
return { ...base, name, value: type.elements.map(convert) };
case 'intersection':
return { ...base, name, value: type.elements.map(convert) };
default:
return { ...base, name: 'other', value: name };
}
};

View File

@ -0,0 +1,2 @@
export * from './convert';
export * from './types';

View File

@ -0,0 +1,56 @@
interface FlowBaseType {
name: string;
type?: string;
raw?: string;
required?: boolean;
}
type FlowArgType = FlowType;
type FlowCombinationType = FlowBaseType & {
name: 'union' | 'intersection';
elements: FlowType[];
};
type FlowFuncSigType = FlowBaseType & {
name: 'signature';
type: 'function';
signature: {
arguments: FlowArgType[];
return: FlowType;
};
};
type FlowObjectSigType = FlowBaseType & {
name: 'signature';
type: 'object';
signature: {
properties: {
key: string;
value: FlowType;
}[];
};
};
type FlowScalarType = FlowBaseType & {
name: 'any' | 'boolean' | 'number' | 'void' | 'string' | 'symbol';
};
export type FlowLiteralType = FlowBaseType & {
name: 'literal';
value: string;
};
type FlowArrayType = FlowBaseType & {
name: 'Array';
elements: FlowType[];
};
export type FlowSigType = FlowObjectSigType | FlowFuncSigType;
export type FlowType =
| FlowScalarType
| FlowLiteralType
| FlowCombinationType
| FlowSigType
| FlowArrayType;

View File

@ -1,11 +1,13 @@
import { DocgenInfo } from '../docgen/types';
import { convert as tsConvert, TSType } from './typescript';
import { convert as flowConvert, FlowType } from './flow';
import { convert as propTypesConvert } from './proptypes';
export const convert = (docgenInfo: DocgenInfo) => {
const { type, tsType } = docgenInfo;
const { type, tsType, flowType } = docgenInfo;
if (type != null) return propTypesConvert(type);
if (tsType != null) return tsConvert(tsType as TSType);
if (flowType != null) return flowConvert(flowType as FlowType);
return null;
};