Skip to content

Commit

Permalink
Merge pull request #12550 from phated/docgen-flow-converters
Browse files Browse the repository at this point in the history
Addon-docs: Add converters between Flow types and storybook types
  • Loading branch information
shilman committed Sep 23, 2020
2 parents 195a08c + 13f80ab commit 2451125
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 1 deletion.
55 changes: 55 additions & 0 deletions addons/docs/src/lib/convert/flow/convert.ts
@@ -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 };
}
};
2 changes: 2 additions & 0 deletions addons/docs/src/lib/convert/flow/index.ts
@@ -0,0 +1,2 @@
export * from './convert';
export * from './types';
56 changes: 56 additions & 0 deletions addons/docs/src/lib/convert/flow/types.ts
@@ -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;
4 changes: 3 additions & 1 deletion addons/docs/src/lib/convert/index.ts
@@ -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;
};

0 comments on commit 2451125

Please sign in to comment.