From 16a51504bcd8e2705b870963fbfd4c81f3665dd9 Mon Sep 17 00:00:00 2001 From: "patrick.lafrance" Date: Tue, 19 Nov 2019 22:57:11 -0500 Subject: [PATCH 1/2] Fix some issue for flow and rework the docgen utils --- addons/docs/src/blocks/Description.tsx | 2 +- addons/docs/src/frameworks/common/index.ts | 1 - .../docs/src/frameworks/react/extractProps.ts | 4 +- .../react/propTypes/handleProp.test.ts | 8 +- addons/docs/src/frameworks/vue/config.tsx | 2 +- .../docs/src/frameworks/vue/extractProps.ts | 4 +- .../docs/src/lib/docgen/createDefaultValue.ts | 22 --- addons/docs/src/lib/docgen/createPropDef.ts | 18 +- .../src/lib/docgen/extractDocgenProps.test.ts | 164 ++++++++++-------- .../docs/src/lib/docgen/extractDocgenProps.ts | 8 +- .../src/lib/docgen/flow/createDefaultValue.ts | 9 +- addons/docs/src/lib/docgen/flow/createType.ts | 12 +- .../docs/src/lib/docgen/utils/defaultValue.ts | 5 + .../lib/docgen/{utils.ts => utils/docgen.ts} | 18 +- addons/docs/src/lib/docgen/utils/index.ts | 3 + addons/docs/src/lib/docgen/utils/string.ts | 9 + 16 files changed, 159 insertions(+), 130 deletions(-) delete mode 100644 addons/docs/src/frameworks/common/index.ts delete mode 100644 addons/docs/src/lib/docgen/createDefaultValue.ts create mode 100644 addons/docs/src/lib/docgen/utils/defaultValue.ts rename addons/docs/src/lib/docgen/{utils.ts => utils/docgen.ts} (52%) create mode 100644 addons/docs/src/lib/docgen/utils/index.ts create mode 100644 addons/docs/src/lib/docgen/utils/string.ts diff --git a/addons/docs/src/blocks/Description.tsx b/addons/docs/src/blocks/Description.tsx index 5fa8852a375..ce34756634c 100644 --- a/addons/docs/src/blocks/Description.tsx +++ b/addons/docs/src/blocks/Description.tsx @@ -2,7 +2,7 @@ import React, { FunctionComponent, useContext } from 'react'; import { Description, DescriptionProps as PureDescriptionProps } from '@storybook/components'; import { DocsContext, DocsContextProps } from './DocsContext'; import { Component, CURRENT_SELECTION, DescriptionSlot } from './shared'; -import { str } from '../lib/docgen/utils'; +import { str } from '../lib/docgen'; export enum DescriptionType { INFO = 'info', diff --git a/addons/docs/src/frameworks/common/index.ts b/addons/docs/src/frameworks/common/index.ts deleted file mode 100644 index 3de17860d84..00000000000 --- a/addons/docs/src/frameworks/common/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '../../lib/docgen'; diff --git a/addons/docs/src/frameworks/react/extractProps.ts b/addons/docs/src/frameworks/react/extractProps.ts index 73a2e116ad9..5d0e9f6c6ad 100644 --- a/addons/docs/src/frameworks/react/extractProps.ts +++ b/addons/docs/src/frameworks/react/extractProps.ts @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import { isForwardRef, isMemo } from 'react-is'; import { PropDef } from '@storybook/components'; -import { hasDocgen, extractPropsFromDocgen, PropsExtractor, TypeSystem } from '../../lib/docgen'; +import { hasDocgen, extractComponentProps, PropsExtractor, TypeSystem } from '../../lib/docgen'; import { Component } from '../../blocks/shared'; import { enhancePropTypesProps } from './propTypes/handleProp'; @@ -32,7 +32,7 @@ function getPropDefs(component: Component, section: string): PropDef[] { } } - const extractedProps = extractPropsFromDocgen(processedComponent, section); + const extractedProps = extractComponentProps(processedComponent, section); if (extractedProps.length === 0) { return []; } diff --git a/addons/docs/src/frameworks/react/propTypes/handleProp.test.ts b/addons/docs/src/frameworks/react/propTypes/handleProp.test.ts index a77ebf694aa..b0addf1941a 100644 --- a/addons/docs/src/frameworks/react/propTypes/handleProp.test.ts +++ b/addons/docs/src/frameworks/react/propTypes/handleProp.test.ts @@ -3,7 +3,7 @@ import { PropDef } from '@storybook/components'; import PropTypes from 'prop-types'; import { Component } from '../../../blocks/shared'; -import { extractPropsFromDocgen, DocgenInfo } from '../../../lib/docgen'; +import { extractComponentProps, DocgenInfo } from '../../../lib/docgen'; import { enhancePropTypesProp, enhancePropTypesProps } from './handleProp'; const DOCGEN_SECTION = 'props'; @@ -43,7 +43,7 @@ function createComponent({ propTypes = {}, defaultProps = {}, docgenInfo = {} }) } function extractPropDef(component: Component): PropDef { - return enhancePropTypesProp(extractPropsFromDocgen(component, DOCGEN_SECTION)[0]); + return enhancePropTypesProp(extractComponentProps(component, DOCGEN_SECTION)[0]); } describe('enhancePropTypesProp', () => { @@ -914,7 +914,7 @@ describe('enhancePropTypesProps', () => { }); const props = enhancePropTypesProps( - extractPropsFromDocgen(component, DOCGEN_SECTION), + extractComponentProps(component, DOCGEN_SECTION), component ); @@ -945,7 +945,7 @@ describe('enhancePropTypesProps', () => { }); const props = enhancePropTypesProps( - extractPropsFromDocgen(component, DOCGEN_SECTION), + extractComponentProps(component, DOCGEN_SECTION), component ); diff --git a/addons/docs/src/frameworks/vue/config.tsx b/addons/docs/src/frameworks/vue/config.tsx index e08d3430877..680e4616579 100644 --- a/addons/docs/src/frameworks/vue/config.tsx +++ b/addons/docs/src/frameworks/vue/config.tsx @@ -4,7 +4,7 @@ import toReact from '@egoist/vue-to-react'; import { StoryFn } from '@storybook/addons'; import { addParameters } from '@storybook/client-api'; import { extractProps } from './extractProps'; -import { extractComponentDescription } from '../../lib/docgen/utils'; +import { extractComponentDescription } from '../../lib/docgen'; addParameters({ docs: { diff --git a/addons/docs/src/frameworks/vue/extractProps.ts b/addons/docs/src/frameworks/vue/extractProps.ts index 495dd8b0c24..f4a26acc76c 100644 --- a/addons/docs/src/frameworks/vue/extractProps.ts +++ b/addons/docs/src/frameworks/vue/extractProps.ts @@ -1,5 +1,5 @@ import { PropDef } from '@storybook/components'; -import { PropsExtractor, hasDocgen, extractPropsFromDocgen } from '../../lib/docgen'; +import { PropsExtractor, hasDocgen, extractComponentProps } from '../../lib/docgen'; const SECTIONS = ['props', 'events', 'slots']; @@ -9,7 +9,7 @@ export const extractProps: PropsExtractor = component => { } const sections: Record = {}; SECTIONS.forEach(section => { - sections[section] = extractPropsFromDocgen(component, section).map(x => x.propDef); + sections[section] = extractComponentProps(component, section).map(x => x.propDef); }); return { sections }; }; diff --git a/addons/docs/src/lib/docgen/createDefaultValue.ts b/addons/docs/src/lib/docgen/createDefaultValue.ts deleted file mode 100644 index 1c09f72d171..00000000000 --- a/addons/docs/src/lib/docgen/createDefaultValue.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { isNil } from 'lodash'; -import { PropDefaultValue } from '@storybook/components'; -import { DocgenPropDefaultValue } from './types'; -import { createSummaryValue } from '../utils'; - -const BLACKLIST = ['null', 'undefined']; - -function isDefaultValueBlacklisted(value: string) { - return BLACKLIST.some(x => x === value); -} - -export function createDefaultValue(defaultValue: DocgenPropDefaultValue): PropDefaultValue { - if (!isNil(defaultValue)) { - const { value } = defaultValue; - - if (!isDefaultValueBlacklisted(value)) { - return createSummaryValue(value); - } - } - - return null; -} diff --git a/addons/docs/src/lib/docgen/createPropDef.ts b/addons/docs/src/lib/docgen/createPropDef.ts index 6d295074115..ea8ac3ad425 100644 --- a/addons/docs/src/lib/docgen/createPropDef.ts +++ b/addons/docs/src/lib/docgen/createPropDef.ts @@ -1,10 +1,10 @@ import { isNil } from 'lodash'; -import { PropDef } from '@storybook/components'; -import { TypeSystem, DocgenInfo, DocgenType } from './types'; +import { PropDef, PropDefaultValue } from '@storybook/components'; +import { TypeSystem, DocgenInfo, DocgenType, DocgenPropDefaultValue } from './types'; import { JsDocParsingResult } from '../jsdocParser'; -import { createDefaultValue } from './createDefaultValue'; import { createSummaryValue } from '../utils'; import { createFlowPropDef } from './flow/createPropDef'; +import { isDefaultValueBlacklisted } from './utils/defaultValue'; export type PropDefFactory = ( propName: string, @@ -12,6 +12,18 @@ export type PropDefFactory = ( jsDocParsingResult?: JsDocParsingResult ) => PropDef; +function createDefaultValue(defaultValue: DocgenPropDefaultValue): PropDefaultValue { + if (!isNil(defaultValue)) { + const { value } = defaultValue; + + if (!isDefaultValueBlacklisted(value)) { + return createSummaryValue(value); + } + } + + return null; +} + function createBasicPropDef(name: string, type: DocgenType, docgenInfo: DocgenInfo): PropDef { const { description, required, defaultValue } = docgenInfo; diff --git a/addons/docs/src/lib/docgen/extractDocgenProps.test.ts b/addons/docs/src/lib/docgen/extractDocgenProps.test.ts index 6c6bc49600a..d2b7c57aa0a 100644 --- a/addons/docs/src/lib/docgen/extractDocgenProps.test.ts +++ b/addons/docs/src/lib/docgen/extractDocgenProps.test.ts @@ -1,7 +1,7 @@ /* eslint-disable no-underscore-dangle */ import { Component } from '../../blocks/shared'; -import { extractPropsFromDocgen } from './extractDocgenProps'; +import { extractComponentProps } from './extractDocgenProps'; const DOCGEN_SECTION = 'props'; const PROP_NAME = 'propName'; @@ -54,103 +54,127 @@ function createComponent(docgenInfo: Record): Component { } TypeSystems.forEach(x => { - it('should map defaults docgen info properly', () => { - const component = createComponent({ - ...createStringType(x), - description: 'Hey! Hey!', - defaultValue: { - value: 'Default', - }, + describe(`${x.name}`, () => { + it('should map defaults docgen info properly', () => { + const component = createComponent({ + ...createStringType(x), + description: 'Hey! Hey!', + defaultValue: { + value: 'Default', + }, + }); + + const { propDef } = extractComponentProps(component, DOCGEN_SECTION)[0]; + + expect(propDef.name).toBe(PROP_NAME); + expect(propDef.type.summary).toBe('string'); + expect(propDef.description).toBe('Hey! Hey!'); + expect(propDef.required).toBe(false); + expect(propDef.defaultValue.summary).toBe('Default'); }); - const { propDef } = extractPropsFromDocgen(component, DOCGEN_SECTION)[0]; + it('should remove JSDoc tags from the description', () => { + const component = createComponent({ + ...createStringType(x), + description: 'Hey!\n@param event\nreturns {string}', + }); - expect(propDef.name).toBe(PROP_NAME); - expect(propDef.type.summary).toBe('string'); - expect(propDef.description).toBe('Hey! Hey!'); - expect(propDef.required).toBe(false); - expect(propDef.defaultValue.summary).toBe('Default'); - }); + const { propDef } = extractComponentProps(component, DOCGEN_SECTION)[0]; - it('should remove JSDoc tags from the description', () => { - const component = createComponent({ - ...createStringType(x), - description: 'Hey!\n@param event\nreturns {string}', + expect(propDef.description).toBe('Hey!'); }); - const { propDef } = extractPropsFromDocgen(component, DOCGEN_SECTION)[0]; + it('should not remove newline characters of multilines description without JSDoc tags', () => { + const component = createComponent({ + ...createStringType(x), + description: 'onClick description\nis a\nmulti-lines\ndescription', + }); - expect(propDef.description).toBe('Hey!'); - }); + const { propDef } = extractComponentProps(component, DOCGEN_SECTION)[0]; - it('should not remove newline characters of multilines description without JSDoc tags', () => { - const component = createComponent({ - ...createStringType(x), - description: 'onClick description\nis a\nmulti-lines\ndescription', + expect(propDef.description).toBe('onClick description\nis a\nmulti-lines\ndescription'); }); - const { propDef } = extractPropsFromDocgen(component, DOCGEN_SECTION)[0]; + it('should not remove newline characters of multilines description with JSDoc tags', () => { + const component = createComponent({ + ...createFuncType(x), + description: 'onClick description\nis a\nmulti-lines\ndescription\n@param event', + }); - expect(propDef.description).toBe('onClick description\nis a\nmulti-lines\ndescription'); - }); + const { propDef } = extractComponentProps(component, DOCGEN_SECTION)[0]; - it('should not remove newline characters of multilines description with JSDoc tags', () => { - const component = createComponent({ - ...createFuncType(x), - description: 'onClick description\nis a\nmulti-lines\ndescription\n@param event', + expect(propDef.description).toBe('onClick description\nis a\nmulti-lines\ndescription'); }); - const { propDef } = extractPropsFromDocgen(component, DOCGEN_SECTION)[0]; + it('should not remove markdown from description without JSDoc tags', () => { + const component = createComponent({ + ...createStringType(x), + description: 'onClick *emphasis*, **strong**, `formatted` description.', + }); - expect(propDef.description).toBe('onClick description\nis a\nmulti-lines\ndescription'); - }); + const { propDef } = extractComponentProps(component, DOCGEN_SECTION)[0]; - it('should not remove markdown from description without JSDoc tags', () => { - const component = createComponent({ - ...createStringType(x), - description: 'onClick *emphasis*, **strong**, `formatted` description.', + expect(propDef.description).toBe('onClick *emphasis*, **strong**, `formatted` description.'); }); - const { propDef } = extractPropsFromDocgen(component, DOCGEN_SECTION)[0]; + it('should not remove markdown from description with JSDoc tags', () => { + const component = createComponent({ + ...createFuncType(x), + description: 'onClick *emphasis*, **strong**, `formatted` description.\n@param event', + }); - expect(propDef.description).toBe('onClick *emphasis*, **strong**, `formatted` description.'); - }); + const { propDef } = extractComponentProps(component, DOCGEN_SECTION)[0]; - it('should not remove markdown from description with JSDoc tags', () => { - const component = createComponent({ - ...createFuncType(x), - description: 'onClick *emphasis*, **strong**, `formatted` description.\n@param event', + expect(propDef.description).toBe('onClick *emphasis*, **strong**, `formatted` description.'); }); - const { propDef } = extractPropsFromDocgen(component, DOCGEN_SECTION)[0]; + it('should return null when the property is marked with @ignore', () => { + const component = createComponent({ + ...createStringType(x), + description: 'onClick description\n@ignore', + }); - expect(propDef.description).toBe('onClick *emphasis*, **strong**, `formatted` description.'); - }); - - it('should return null when the property is marked with @ignore', () => { - const component = createComponent({ - ...createStringType(x), - description: 'onClick description\n@ignore', + expect(extractComponentProps(component, DOCGEN_SECTION).length).toBe(0); }); - expect(extractPropsFromDocgen(component, DOCGEN_SECTION).length).toBe(0); - }); + it('should provide raw @param tags', () => { + const component = createComponent({ + ...createFuncType(x), + description: + 'onClick description\n@param {SyntheticEvent} event - Original event.\n@param {string} value', + }); - it('should provide raw @param tags', () => { - const component = createComponent({ - ...createFuncType(x), - description: - 'onClick description\n@param {SyntheticEvent} event - Original event.\n@param {string} value', + const { propDef } = extractComponentProps(component, DOCGEN_SECTION)[0]; + + expect(propDef.description).toBe('onClick description'); + expect(propDef.jsDocTags).toBeDefined(); + expect(propDef.jsDocTags.params).toBeDefined(); + expect(propDef.jsDocTags.params[0].name).toBe('event'); + expect(propDef.jsDocTags.params[0].description).toBe('Original event.'); + expect(propDef.jsDocTags.params[1].name).toBe('value'); + expect(propDef.jsDocTags.params[1].description).toBeNull(); }); - const { propDef } = extractPropsFromDocgen(component, DOCGEN_SECTION)[0]; + it("should not return 'null' default value", () => { + const component = createComponent({ + ...createStringType(x), + defaultValue: { value: 'null' }, + }); - expect(propDef.description).toBe('onClick description'); - expect(propDef.jsDocTags).toBeDefined(); - expect(propDef.jsDocTags.params).toBeDefined(); - expect(propDef.jsDocTags.params[0].name).toBe('event'); - expect(propDef.jsDocTags.params[0].description).toBe('Original event.'); - expect(propDef.jsDocTags.params[1].name).toBe('value'); - expect(propDef.jsDocTags.params[1].description).toBeNull(); + const { propDef } = extractComponentProps(component, DOCGEN_SECTION)[0]; + + expect(propDef.defaultValue).toBeNull(); + }); + + it("should not return 'undefined' default value", () => { + const component = createComponent({ + ...createStringType(x), + defaultValue: { value: 'undefined' }, + }); + + const { propDef } = extractComponentProps(component, DOCGEN_SECTION)[0]; + + expect(propDef.defaultValue).toBeNull(); + }); }); }); diff --git a/addons/docs/src/lib/docgen/extractDocgenProps.ts b/addons/docs/src/lib/docgen/extractDocgenProps.ts index adcf4d906da..39af9353d05 100644 --- a/addons/docs/src/lib/docgen/extractDocgenProps.ts +++ b/addons/docs/src/lib/docgen/extractDocgenProps.ts @@ -3,7 +3,7 @@ import { PropDef } from '@storybook/components'; import { Component } from '../../blocks/shared'; import { ExtractedJsDoc, parseJsDoc } from '../jsdocParser'; import { DocgenInfo, TypeSystem } from './types'; -import { getDocgenSection, isValidDocgenSection } from './utils'; +import { getDocgenSection, isValidDocgenSection, getDocgenDescription } from './utils'; import { getPropDefFactory, PropDefFactory } from './createPropDef'; export interface ExtractedProp { @@ -31,7 +31,7 @@ const getTypeSystem = (docgenInfo: DocgenInfo): TypeSystem => { return TypeSystem.UNKNOWN; }; -export const extractPropsFromDocgen: ExtractProps = (component, section) => { +export const extractComponentProps: ExtractProps = (component, section) => { const docgenSection = getDocgenSection(component, section); if (!isValidDocgenSection(docgenSection)) { @@ -75,3 +75,7 @@ function extractProp( return null; } + +export function extractComponentDescription(component: Component): string { + return getDocgenDescription(component); +} diff --git a/addons/docs/src/lib/docgen/flow/createDefaultValue.ts b/addons/docs/src/lib/docgen/flow/createDefaultValue.ts index 91f22c5aeea..0bec4162d38 100644 --- a/addons/docs/src/lib/docgen/flow/createDefaultValue.ts +++ b/addons/docs/src/lib/docgen/flow/createDefaultValue.ts @@ -2,6 +2,7 @@ import { PropDefaultValue } from '@storybook/components'; import { isNil } from 'lodash'; import { DocgenPropDefaultValue, DocgenPropType } from '../types'; import { createSummaryValue, isTooLongForDefaultValueSummary } from '../../utils'; +import { isDefaultValueBlacklisted } from '../utils/defaultValue'; export function createDefaultValue( defaultValue: DocgenPropDefaultValue, @@ -10,9 +11,11 @@ export function createDefaultValue( if (!isNil(defaultValue)) { const { value } = defaultValue; - return !isTooLongForDefaultValueSummary(value) - ? createSummaryValue(value) - : createSummaryValue(type.name, value); + if (!isDefaultValueBlacklisted(value)) { + return !isTooLongForDefaultValueSummary(value) + ? createSummaryValue(value) + : createSummaryValue(type.name, value); + } } return null; diff --git a/addons/docs/src/lib/docgen/flow/createType.ts b/addons/docs/src/lib/docgen/flow/createType.ts index b27d31ae4b4..98be7fa31d9 100644 --- a/addons/docs/src/lib/docgen/flow/createType.ts +++ b/addons/docs/src/lib/docgen/flow/createType.ts @@ -1,4 +1,4 @@ -import { PropType, PropSummaryValue } from '@storybook/components'; +import { PropType } from '@storybook/components'; import { isNil } from 'lodash'; import { DocgenFlowType } from '../types'; import { createSummaryValue, isTooLongForTypeSummary } from '../../utils'; @@ -12,7 +12,7 @@ interface DocgenFlowUnionType extends DocgenFlowType { elements: { name: string; value: string }[]; } -function generateUnion({ name, raw, elements }: DocgenFlowUnionType): PropSummaryValue { +function generateUnion({ name, raw, elements }: DocgenFlowUnionType): PropType { if (!isNil(raw)) { return createSummaryValue(raw); } @@ -24,7 +24,7 @@ function generateUnion({ name, raw, elements }: DocgenFlowUnionType): PropSummar return createSummaryValue(name); } -function generateFuncSignature({ type, raw }: DocgenFlowType) { +function generateFuncSignature({ type, raw }: DocgenFlowType): PropType { if (!isNil(raw)) { return createSummaryValue(raw); } @@ -32,7 +32,7 @@ function generateFuncSignature({ type, raw }: DocgenFlowType) { return createSummaryValue(type); } -function generateObjectSignature({ type, raw }: DocgenFlowType) { +function generateObjectSignature({ type, raw }: DocgenFlowType): PropType { if (!isNil(raw)) { return !isTooLongForTypeSummary(raw) ? createSummaryValue(raw) : createSummaryValue(type, raw); } @@ -40,13 +40,13 @@ function generateObjectSignature({ type, raw }: DocgenFlowType) { return createSummaryValue(type); } -function generateSignature(flowType: DocgenFlowType): PropSummaryValue { +function generateSignature(flowType: DocgenFlowType): PropType { const { type } = flowType; return type === 'object' ? generateObjectSignature(flowType) : generateFuncSignature(flowType); } -function generateDefault({ name, raw }: DocgenFlowType): PropSummaryValue { +function generateDefault({ name, raw }: DocgenFlowType): PropType { if (!isNil(raw)) { return !isTooLongForTypeSummary(raw) ? createSummaryValue(raw) : createSummaryValue(name, raw); } diff --git a/addons/docs/src/lib/docgen/utils/defaultValue.ts b/addons/docs/src/lib/docgen/utils/defaultValue.ts new file mode 100644 index 00000000000..0757f9eef6e --- /dev/null +++ b/addons/docs/src/lib/docgen/utils/defaultValue.ts @@ -0,0 +1,5 @@ +const BLACKLIST = ['null', 'undefined']; + +export function isDefaultValueBlacklisted(value: string): boolean { + return BLACKLIST.some(x => x === value); +} diff --git a/addons/docs/src/lib/docgen/utils.ts b/addons/docs/src/lib/docgen/utils/docgen.ts similarity index 52% rename from addons/docs/src/lib/docgen/utils.ts rename to addons/docs/src/lib/docgen/utils/docgen.ts index 4bdc8c7138a..623047c7e38 100644 --- a/addons/docs/src/lib/docgen/utils.ts +++ b/addons/docs/src/lib/docgen/utils/docgen.ts @@ -1,17 +1,8 @@ /* eslint-disable no-underscore-dangle */ import { isNil } from 'lodash'; -import { Component } from '../../blocks/shared'; - -export const str = (obj: any) => { - if (!obj) { - return ''; - } - if (typeof obj === 'string') { - return obj as string; - } - throw new Error(`Description: expected string, got: ${JSON.stringify(obj)}`); -}; +import { Component } from '../../../blocks/shared'; +import { str } from './string'; export function hasDocgen(component: Component): boolean { return !!component.__docgenInfo; @@ -25,5 +16,6 @@ export function getDocgenSection(component: Component, section: string): any { return hasDocgen(component) ? component.__docgenInfo[section] : null; } -export const extractComponentDescription = (component?: Component) => - component && hasDocgen(component) && str(component.__docgenInfo.description); +export function getDocgenDescription(component: Component): string { + return hasDocgen(component) && str(component.__docgenInfo.description); +} diff --git a/addons/docs/src/lib/docgen/utils/index.ts b/addons/docs/src/lib/docgen/utils/index.ts new file mode 100644 index 00000000000..4d3acb13d2f --- /dev/null +++ b/addons/docs/src/lib/docgen/utils/index.ts @@ -0,0 +1,3 @@ +export * from './defaultValue'; +export * from './string'; +export * from './docgen'; diff --git a/addons/docs/src/lib/docgen/utils/string.ts b/addons/docs/src/lib/docgen/utils/string.ts new file mode 100644 index 00000000000..9accdd8d063 --- /dev/null +++ b/addons/docs/src/lib/docgen/utils/string.ts @@ -0,0 +1,9 @@ +export const str = (obj: any) => { + if (!obj) { + return ''; + } + if (typeof obj === 'string') { + return obj as string; + } + throw new Error(`Description: expected string, got: ${JSON.stringify(obj)}`); +}; From 6fc021be09a00e5e3cb267aafba44f54e5e2c475 Mon Sep 17 00:00:00 2001 From: "patrick.lafrance" Date: Wed, 20 Nov 2019 09:19:06 -0500 Subject: [PATCH 2/2] Added more test cases for prop types from an external file --- .../src/stories/docgen-tests/types/ext.js | 12 ++++++++++++ .../src/stories/docgen-tests/types/prop-types.js | 4 ++++ 2 files changed, 16 insertions(+) create mode 100644 examples/cra-ts-kitchen-sink/src/stories/docgen-tests/types/ext.js diff --git a/examples/cra-ts-kitchen-sink/src/stories/docgen-tests/types/ext.js b/examples/cra-ts-kitchen-sink/src/stories/docgen-tests/types/ext.js new file mode 100644 index 00000000000..df0f646a519 --- /dev/null +++ b/examples/cra-ts-kitchen-sink/src/stories/docgen-tests/types/ext.js @@ -0,0 +1,12 @@ +import PropTypes from 'prop-types'; + +export const PRESET_SHAPE = { + text: PropTypes.string.isRequired, + startDate: PropTypes.object.isRequired, + endDate: PropTypes.object.isRequired, +}; + +export const SOME_PROP_TYPES = { + ext1: PropTypes.string, + ext2: PropTypes.number, +}; diff --git a/examples/cra-ts-kitchen-sink/src/stories/docgen-tests/types/prop-types.js b/examples/cra-ts-kitchen-sink/src/stories/docgen-tests/types/prop-types.js index bcd6246ad96..71cbc5841cb 100644 --- a/examples/cra-ts-kitchen-sink/src/stories/docgen-tests/types/prop-types.js +++ b/examples/cra-ts-kitchen-sink/src/stories/docgen-tests/types/prop-types.js @@ -1,6 +1,8 @@ +/* eslint-disable react/require-default-props */ /* eslint-disable react/no-unused-prop-types */ import React from 'react'; import PropTypes, { string, shape } from 'prop-types'; +import { PRESET_SHAPE, SOME_PROP_TYPES } from './ext'; const NAMED_OBJECT = { text: PropTypes.string.isRequired, @@ -159,6 +161,7 @@ PropTypesProps.propTypes = { ), }) ), + arrayExternalShape: PropTypes.arrayOf(PropTypes.shape(PRESET_SHAPE)), /** * A simple `objectOf` propType. */ @@ -257,6 +260,7 @@ PropTypesProps.propTypes = { requiredString: PropTypes.string.isRequired, nullDefaultValue: PropTypes.string, undefinedDefaultValue: PropTypes.string, + ...SOME_PROP_TYPES, }; PropTypesProps.defaultProps = {