From 0e69643df02266f1fd4039d2df8ad7384e9f3274 Mon Sep 17 00:00:00 2001 From: atanasster Date: Tue, 10 Mar 2020 20:26:35 -0400 Subject: [PATCH] fix: resolve components in store --- core/instrument/README.md | 35 +++++++++++- .../instrument/src/babel/extract-component.ts | 54 +++++++++++-------- core/instrument/src/index.ts | 13 +---- core/instrument/src/types.ts | 29 ++++++++++ .../extract-component.test.ts.snap | 6 +++ core/specification/src/components.ts | 16 +++--- core/specification/src/stories.ts | 11 +++- .../react-docgen-typescript/src/index.ts | 21 ++++---- .../src/react-docgen-typescript.ts | 8 ++- .../src/transform-props.ts | 11 ++-- .../test/__snapshots__/full.test.ts.snap | 4 +- .../test/__snapshots__/jsx.test.ts.snap | 2 +- .../test/__snapshots__/other.test.ts.snap | 18 +++++++ .../test/fixtures/other/multiple-exports.tsx | 18 +++++++ .../test/loadTestFiles.ts | 2 +- .../test/other.test.ts | 5 ++ props-info/react-docgen/src/index.ts | 22 ++++---- .../react-docgen/src/transform-props.ts | 39 ++++++++------ .../test/__snapshots__/flow-type.test.ts.snap | 5 +- .../__snapshots__/prop-types.test.ts.snap | 19 ++++--- .../__snapshots__/typescript.test.ts.snap | 14 ++++- props-info/react-docgen/test/loadTestFiles.ts | 2 +- props-info/react-docgen/tsconfig.json | 2 +- ui/blocks/src/BlocksContext/BlockContext.tsx | 16 +++--- 24 files changed, 264 insertions(+), 108 deletions(-) create mode 100644 props-info/react-docgen-typescript/test/__snapshots__/other.test.ts.snap create mode 100644 props-info/react-docgen-typescript/test/fixtures/other/multiple-exports.tsx create mode 100644 props-info/react-docgen-typescript/test/other.test.ts diff --git a/core/instrument/README.md b/core/instrument/README.md index 08ce3f530..71003f8bc 100644 --- a/core/instrument/README.md +++ b/core/instrument/README.md @@ -155,6 +155,11 @@ Callback function to resolve the source file name of a component. Return false if this file should not be processed. +• **extractProps**? : *[PropsInfoExtractor](#propsinfoextractor)* + + optional module to extract prop tables information for components + + • **storeSourceFile**? : *boolean* If set to false, will not save the component's source file. @@ -523,4 +528,32 @@ Whether to save the link for project readme file in the repository field. • **storeIssuesLink**? : *boolean* -Whether to save the link for filing issues with the project in the repository field. \ No newline at end of file +Whether to save the link for filing issues with the project in the repository field. + +___ + + +## PropsInfoExtractor + +`(fileName: string, componentName?: string, source?: string) => PropTypes | undefined;` + +Callback function to extract props info table - ie docgen type libraries. Used to extract displayName, and props tables for a component + +*Defined in [core/instrument/src/types.ts](https://github.com/atanasster/component-controls/blob/ab703a5/core/instrument/src/types.ts)* + + +### Arguments + +• **fileName** : *string* + +Full name and path of the component path. react-docgen needs it to extract babel configurations + + +• **componentName**? : *string* + +Optional component name. react-docgen-typescript supports multiple exports for a file. react-docgne does not use it. + + +• **source**? : *string* + +Optional soure, saves time if its already loaded. react-docgen accepts source as input parameter. react-docgen-typescript does not use it. diff --git a/core/instrument/src/babel/extract-component.ts b/core/instrument/src/babel/extract-component.ts index a33aa4519..949667355 100644 --- a/core/instrument/src/babel/extract-component.ts +++ b/core/instrument/src/babel/extract-component.ts @@ -3,6 +3,7 @@ import { StoriesStore, StoryAttributes, StoryComponent, + StoriesKind, } from '@component-controls/specification'; import { followImports } from './follow-imports'; import { packageInfo } from '../project/packageInfo'; @@ -35,6 +36,9 @@ const componentFromParams = ( return undefined; }; +const globalCache: { + [filePath: string]: StoryComponent; +} = {}; export const extractComponent = async ( componentName: string, filePath: string, @@ -42,6 +46,9 @@ export const extractComponent = async ( options?: InstrumentOptions, initialAST?: File, ): Promise => { + if (globalCache[filePath]) { + return globalCache[filePath]; + } const follow = followImports( componentName, filePath, @@ -50,7 +57,7 @@ export const extractComponent = async ( initialAST, ); const { components } = options || {}; - return follow + const component = follow ? { name: componentName, from: follow.from, @@ -66,9 +73,11 @@ export const extractComponent = async ( : { name: componentName, }; + globalCache[filePath] = component; + return component; }; -export const extractSotreComponent = async ( +export const extractStoreComponent = async ( store: StoriesStore, filePath: string, source: string, @@ -77,7 +86,8 @@ export const extractSotreComponent = async ( ) => { const kinds = Object.keys(store.kinds); if (kinds.length > 0) { - const kind = store.kinds[kinds[0]]; + const kind: StoriesKind = store.kinds[kinds[0]]; + kind.components = {}; const componentName = componentFromParams(kind.attributes); if (componentName) { @@ -89,26 +99,28 @@ export const extractSotreComponent = async ( initialAST, ); if (component) { - store.components[componentName] = component; + store.components[filePath] = component; + kind.components[componentName] = filePath; kind.component = componentName; } } - } - Object.keys(store.stories).forEach(async (name: string) => { - const story = store.stories[name]; - const componentName = componentFromParams(story.attributes); - if (componentName) { - const component = await extractComponent( - componentName, - filePath, - source, - options, - initialAST, - ); - if (component) { - store.components[componentName] = component; - story.component = componentName; + Object.keys(store.stories).forEach(async (name: string) => { + const story = store.stories[name]; + const componentName = componentFromParams(story.attributes); + if (componentName) { + const component = await extractComponent( + componentName, + filePath, + source, + options, + initialAST, + ); + if (component) { + store.components[filePath] = component; + kind.components[componentName] = filePath; + story.component = componentName; + } } - } - }); + }); + } }; diff --git a/core/instrument/src/index.ts b/core/instrument/src/index.ts index 48ad0947c..2c318bb45 100644 --- a/core/instrument/src/index.ts +++ b/core/instrument/src/index.ts @@ -17,7 +17,7 @@ import { getASTSource } from '@component-controls/core'; import { extractCSFStories } from './babel/csf-stories'; import { extractMDXStories } from './babel/mdx-stories'; import { removeMDXAttributes } from './babel/remove-mdx-attributes'; -import { extractSotreComponent } from './babel/extract-component'; +import { extractStoreComponent } from './babel/extract-component'; import { packageInfo } from './project/packageInfo'; import { InstrumentOptions, @@ -122,7 +122,7 @@ const parseSource = async ( {}, ); } - await extractSotreComponent(store, filePath, source, mergedOptions, ast); + await extractStoreComponent(store, filePath, source, mergedOptions, ast); const kindsNames = Object.keys(store.kinds); for (let i = 0; i < kindsNames.length; i += 1) { const kind: StoriesKind = store.kinds[kindsNames[i]]; @@ -135,15 +135,6 @@ const parseSource = async ( kind.repository = repository; } } - /* - if (filePath && stories.component && stories.component.from) { - console.log( - stories.component.from, - ': ', - path.resolve(filePath, stories.component.from), - ); - } - */ Object.keys(store.stories).forEach((key: string) => { const story: Story = store.stories[key]; story.source = getASTSource(source, story.loc); diff --git a/core/instrument/src/types.ts b/core/instrument/src/types.ts index 9df905358..dd0a9fe10 100644 --- a/core/instrument/src/types.ts +++ b/core/instrument/src/types.ts @@ -4,6 +4,7 @@ import { Options, ResolveConfigOptions as ResolvePrettierConfigOptions, } from 'prettier'; +import { PropTypes } from '@component-controls/specification'; type PrettierOptions = Options & { resolveConfigOptions?: ResolvePrettierConfigOptions; @@ -19,6 +20,30 @@ export const defaultParserOptions: ParserOptions = { plugins: ['jsx', 'typescript'], }; +/** + * callback function to extract props info table - ie docgen type libraries + * used to extract displayName, and props tables for a component + */ +export type PropsInfoExtractor = ( + /** + * full name and path of the component path + * react-docgen needs it to extract babel configurations + */ + fileName: string, + /** + * optional component name + * react-docgen-typescript supports multiple exports for a file + * react-docgne does not use it + */ + componentName?: string, + /** + * optional soure, saves time if its already loaded + * react-docgen accepts source as input parameter + * react-docgen-typescript does not use it + */ + source?: string, +) => PropTypes | undefined; + export const defaultPackageOptions: PackageInfoOptions = { maxLevels: 10, packageJsonName: 'package.json', @@ -75,6 +100,10 @@ export interface ComponentOptions { */ resolveFile?: (componentName: string, filePath: string) => string | undefined; + /** + * optional module to extract prop tables information for components + */ + extractProps?: PropsInfoExtractor; /** * If set to false, will not save the component's source file */ diff --git a/core/instrument/test/__snapshots__/extract-component.test.ts.snap b/core/instrument/test/__snapshots__/extract-component.test.ts.snap index fd5bfd1d5..4e09cd275 100644 --- a/core/instrument/test/__snapshots__/extract-component.test.ts.snap +++ b/core/instrument/test/__snapshots__/extract-component.test.ts.snap @@ -481,6 +481,12 @@ const Arrow = styled.div(({ borderLeftColor: match('left', placement, borderColor, 'transparent'), borderRightColor: match('right', placement, borderColor, 'transparent') })); +/** + * A Popover container that is triggered by a click, or hover + * used to display enhanced information that could not fit into the main scren + * + */ + const Popover = _a => { var { trigger, diff --git a/core/specification/src/components.ts b/core/specification/src/components.ts index 9e25d9c84..f74f5acdf 100644 --- a/core/specification/src/components.ts +++ b/core/specification/src/components.ts @@ -14,7 +14,7 @@ export type TypeValue = | 'function' | string; -export interface TypeInformatiom { +export interface TypeInformation { name: TypeValue; /** @@ -22,7 +22,7 @@ export interface TypeInformatiom { * elements of enum, array, fields of object * return value of function */ - value?: TypeInformatiom[] | any; + value?: TypeInformation[] | any; /** * raw type code @@ -32,7 +32,11 @@ export interface TypeInformatiom { /** * argument types of function */ - arguments?: TypeInformatiom[] | any; + arguments?: TypeInformation[] | any; + /** + * is the property required + */ + required?: boolean; } /** @@ -48,11 +52,7 @@ export interface PropType { /** * propertty type */ - type: TypeInformatiom; - /** - * is the property required - */ - required: boolean; + type: TypeInformation; /** * description of the property */ diff --git a/core/specification/src/stories.ts b/core/specification/src/stories.ts index 63736e604..4b0e9daf5 100644 --- a/core/specification/src/stories.ts +++ b/core/specification/src/stories.ts @@ -143,6 +143,15 @@ export interface StoriesKind { * project repository information */ repository?: Repository; + + /** + * lookup into the global store.components + * since multiple components of the same name can be used + * example: ['Button']: 'c:/myapp/Button.tsx' + */ + components: { + [name: string]: string; + }; } /** @@ -156,6 +165,6 @@ export interface StoriesStore { [id: string]: Story; }; components: { - [id: string]: StoryComponent; + [fileName: string]: StoryComponent; }; } diff --git a/props-info/react-docgen-typescript/src/index.ts b/props-info/react-docgen-typescript/src/index.ts index d383030ce..30424ee63 100644 --- a/props-info/react-docgen-typescript/src/index.ts +++ b/props-info/react-docgen-typescript/src/index.ts @@ -1,17 +1,20 @@ +import { PropTypes } from '@component-controls/specification'; import { extractDocgenTypescriptInfo, RectDocgenTypescriptOptions, } from './react-docgen-typescript'; import { transformProps } from './transform-props'; -export default ( - fileName: string, - source?: string, - options?: RectDocgenTypescriptOptions, -) => { - const propTable = extractDocgenTypescriptInfo(fileName, options); - return { - ...propTable, - props: transformProps(propTable.props), +export default (options?: RectDocgenTypescriptOptions) => { + return (fileName: string, componentName?: string): PropTypes | undefined => { + const propTable = extractDocgenTypescriptInfo( + fileName, + componentName, + options, + ); + return { + ...propTable, + props: transformProps(propTable.props), + }; }; }; diff --git a/props-info/react-docgen-typescript/src/react-docgen-typescript.ts b/props-info/react-docgen-typescript/src/react-docgen-typescript.ts index 41a3df7dc..93f0c65dd 100644 --- a/props-info/react-docgen-typescript/src/react-docgen-typescript.ts +++ b/props-info/react-docgen-typescript/src/react-docgen-typescript.ts @@ -11,10 +11,16 @@ export type RectDocgenTypescriptOptions = { export const extractDocgenTypescriptInfo = ( fileName: string, + componentName?: string, reactDocGenTypescriptOptions?: RectDocgenTypescriptOptions, ) => { const { - transformProps = (tables: any[]) => tables[0], + transformProps = (tables: any[]) => { + const byName = + componentName && + tables.find(table => table.displayName === componentName); + return byName ? byName : tables[0]; + }, propFilter, componentNameResolver = computeComponentName, shouldExtractLiteralValuesFromEnum = true, diff --git a/props-info/react-docgen-typescript/src/transform-props.ts b/props-info/react-docgen-typescript/src/transform-props.ts index d2f5884e2..d37d3b93b 100644 --- a/props-info/react-docgen-typescript/src/transform-props.ts +++ b/props-info/react-docgen-typescript/src/transform-props.ts @@ -1,7 +1,7 @@ import { PropTypes, PropType, - TypeInformatiom, + TypeInformation, TypeValue, } from '@component-controls/specification'; import { Props, PropItem } from 'react-docgen-typescript'; @@ -22,11 +22,12 @@ export const transformProps = (props: Props): PropTypes => { if (rdProp.defaultValue !== null && rdProp.defaultValue !== undefined) { prop.defaultValue = rdProp.defaultValue.value || rdProp.defaultValue; } + const typeName = rdProp.type.name || ''; + let type: Partial = {}; if (rdProp.required) { - prop.required = rdProp.required; + type.required = rdProp.required; } - const typeName = rdProp.type.name || ''; - let type: Partial = {}; + if (typeName === 'enum') { type.name = 'enum'; type.value = rdProp.type.value.map(({ value }: any) => { @@ -59,7 +60,7 @@ export const transformProps = (props: Props): PropTypes => { if (type.name !== raw) { type.raw = raw; } - prop.type = type as TypeInformatiom; + prop.type = type as TypeInformation; return { ...acc, [name]: prop }; }, {}); }; diff --git a/props-info/react-docgen-typescript/test/__snapshots__/full.test.ts.snap b/props-info/react-docgen-typescript/test/__snapshots__/full.test.ts.snap index 795d01457..540715e9b 100644 --- a/props-info/react-docgen-typescript/test/__snapshots__/full.test.ts.snap +++ b/props-info/react-docgen-typescript/test/__snapshots__/full.test.ts.snap @@ -150,17 +150,17 @@ Object { }, "requiredAny": Object { "parentName": "MyComponentProps", - "required": true, "type": Object { "name": "any", + "required": true, }, }, "requiredFunc": Object { "parentName": "MyComponentProps", - "required": true, "type": Object { "name": "function", "raw": "(prop: any) => any", + "required": true, }, }, }, diff --git a/props-info/react-docgen-typescript/test/__snapshots__/jsx.test.ts.snap b/props-info/react-docgen-typescript/test/__snapshots__/jsx.test.ts.snap index 8f77a136e..acd7886ac 100644 --- a/props-info/react-docgen-typescript/test/__snapshots__/jsx.test.ts.snap +++ b/props-info/react-docgen-typescript/test/__snapshots__/jsx.test.ts.snap @@ -2109,9 +2109,9 @@ import { jsx } from 'theme-ui' }, "title": Object { "parentName": "ButtonProps", - "required": true, "type": Object { "name": "string", + "required": true, }, }, "translate": Object { diff --git a/props-info/react-docgen-typescript/test/__snapshots__/other.test.ts.snap b/props-info/react-docgen-typescript/test/__snapshots__/other.test.ts.snap new file mode 100644 index 000000000..957e696f1 --- /dev/null +++ b/props-info/react-docgen-typescript/test/__snapshots__/other.test.ts.snap @@ -0,0 +1,18 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`other multiple-exports.tsx 1`] = ` +Object { + "description": "", + "displayName": "MyCompoent", + "methods": Array [], + "props": Object { + "prop1": Object { + "parentName": "BarProps", + "type": Object { + "name": "string", + "required": true, + }, + }, + }, +} +`; diff --git a/props-info/react-docgen-typescript/test/fixtures/other/multiple-exports.tsx b/props-info/react-docgen-typescript/test/fixtures/other/multiple-exports.tsx new file mode 100644 index 000000000..f0c24a25c --- /dev/null +++ b/props-info/react-docgen-typescript/test/fixtures/other/multiple-exports.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +export interface BarProps { + prop1: string; +} + +export const MyCompoent = (props: BarProps) =>
{props.prop1}
; + +export interface ShapeProps { + bar: BarProps; + other: number; +} + +export const Shape = ({ bar, other }: ShapeProps) => ( + <> + + {other} + +); diff --git a/props-info/react-docgen-typescript/test/loadTestFiles.ts b/props-info/react-docgen-typescript/test/loadTestFiles.ts index daaee9183..1d15aa61b 100644 --- a/props-info/react-docgen-typescript/test/loadTestFiles.ts +++ b/props-info/react-docgen-typescript/test/loadTestFiles.ts @@ -13,7 +13,7 @@ export const loadTestFiles = (...args: string[]) => { fileNames.forEach(file => { const fileName = path.join(folderName, file); it(file, async () => { - expect(await extractInfo(fileName)).toMatchSnapshot(); + expect(await extractInfo()(fileName, 'MyComponent')).toMatchSnapshot(); }); }); }; diff --git a/props-info/react-docgen-typescript/test/other.test.ts b/props-info/react-docgen-typescript/test/other.test.ts new file mode 100644 index 000000000..5c050d0f0 --- /dev/null +++ b/props-info/react-docgen-typescript/test/other.test.ts @@ -0,0 +1,5 @@ +import { loadTestFiles } from './loadTestFiles'; + +describe('other', () => { + loadTestFiles('other'); +}); diff --git a/props-info/react-docgen/src/index.ts b/props-info/react-docgen/src/index.ts index a34728ae3..3438dcd3b 100644 --- a/props-info/react-docgen/src/index.ts +++ b/props-info/react-docgen/src/index.ts @@ -1,14 +1,18 @@ +import { PropTypes } from '@component-controls/specification'; + import { extractDocgenInfo, RectDocgenOptions } from './react-docgen'; import { transformProps } from './transform-props'; -export default ( - fileName: string, - source?: string, - options?: RectDocgenOptions, -) => { - const propTable = extractDocgenInfo(fileName, source, options); - return { - ...propTable, - props: transformProps(propTable.props), +export default (options?: RectDocgenOptions) => { + return ( + fileName: string, + componentName?: string, + source?: string, + ): PropTypes | undefined => { + const propTable = extractDocgenInfo(fileName, source, options); + return { + ...propTable, + props: transformProps(propTable.props), + }; }; }; diff --git a/props-info/react-docgen/src/transform-props.ts b/props-info/react-docgen/src/transform-props.ts index cfa5ab470..d85c0ca7c 100644 --- a/props-info/react-docgen/src/transform-props.ts +++ b/props-info/react-docgen/src/transform-props.ts @@ -1,8 +1,7 @@ import { PropTypes, PropType, - TypeInformatiom, - TypeValue, + TypeInformation, } from '@component-controls/specification'; const rdPropToCCProp = (rdProp: any): PropType => { @@ -13,22 +12,19 @@ const rdPropToCCProp = (rdProp: any): PropType => { if (rdProp.defaultValue !== null && rdProp.defaultValue !== undefined) { prop.defaultValue = rdProp.defaultValue.value || rdProp.defaultValue; } - if (rdProp.required) { - prop.required = rdProp.required; - } - let type: Partial = {}; + let type: Partial = {}; if (rdProp.type) { - type = propTypeToCCType(rdProp.type); + type = propTypeToCCType({ ...rdProp.type, required: rdProp.required }); } else if (rdProp.tsType) { - type = tsTypeToCCType(rdProp.tsType); + type = tsTypeToCCType({ ...rdProp.tsType, required: rdProp.required }); } else if (rdProp.flowType) { - type = tsTypeToCCType(rdProp.flowType); + type = tsTypeToCCType({ ...rdProp.flowType, required: rdProp.required }); } - prop.type = type as TypeInformatiom; + prop.type = type as TypeInformation; return prop as PropType; }; -const propTypeToCCType = (dgType: any): TypeValue => { - let type: TypeValue = {}; +const propTypeToCCType = (dgType: any): TypeInformation => { + let type: Partial = {}; if (dgType) { const typeName = dgType.name; if (dgType.required) { @@ -71,6 +67,15 @@ const propTypeToCCType = (dgType: any): TypeValue => { }; break; + case 'objectOf': + type = { + name: 'object', + value: Object.keys(dgType.value).map(key => ({ + name: dgType.value[key], + })), + }; + break; + case 'instanceOf': type = { name: 'object', @@ -83,7 +88,7 @@ const propTypeToCCType = (dgType: any): TypeValue => { type = { name: 'object', value: Object.keys(dgType.value).map(name => { - const t: TypeValue = { + const t: TypeInformation = { name: dgType.value[name].name, value: name, }; @@ -112,11 +117,11 @@ const propTypeToCCType = (dgType: any): TypeValue => { type = dgType; } } - return type; + return type as TypeInformation; }; -const tsTypeToCCType = (dgType: any): TypeValue => { - let type: TypeValue = {}; +const tsTypeToCCType = (dgType: any): TypeInformation => { + let type: Partial = {}; if (dgType) { const typeName = dgType.name; if (dgType.required) { @@ -152,7 +157,7 @@ const tsTypeToCCType = (dgType: any): TypeValue => { type = dgType; } } - return type; + return type as TypeInformation; }; export const transformProps = (props: any): PropTypes | undefined => { return props diff --git a/props-info/react-docgen/test/__snapshots__/flow-type.test.ts.snap b/props-info/react-docgen/test/__snapshots__/flow-type.test.ts.snap index 291434f62..f7bf75ff0 100644 --- a/props-info/react-docgen/test/__snapshots__/flow-type.test.ts.snap +++ b/props-info/react-docgen/test/__snapshots__/flow-type.test.ts.snap @@ -7,7 +7,6 @@ Object { "methods": Array [], "props": Object { "arr": Object { - "required": true, "type": Object { "name": "array", "value": Array [ @@ -35,7 +34,6 @@ Object { }, "literalsAndUnion": Object { "description": "Description of prop \\"bar\\".", - "required": true, "type": Object { "elements": Array [ Object { @@ -52,6 +50,7 @@ Object { ], "name": "union", "raw": "'string' | 'otherstring' | number", + "required": true, }, }, "noParameterName": Object { @@ -87,9 +86,9 @@ Object { }, "primitive": Object { "description": "Description of prop \\"foo\\".", - "required": true, "type": Object { "name": "number", + "required": true, }, }, }, diff --git a/props-info/react-docgen/test/__snapshots__/prop-types.test.ts.snap b/props-info/react-docgen/test/__snapshots__/prop-types.test.ts.snap index 0f7b8b22c..6d788e733 100644 --- a/props-info/react-docgen/test/__snapshots__/prop-types.test.ts.snap +++ b/props-info/react-docgen/test/__snapshots__/prop-types.test.ts.snap @@ -63,6 +63,7 @@ it as an enum.", "optionalFunc": Object { "type": Object { "name": "function", + "required": false, }, }, "optionalMessage": Object { @@ -86,20 +87,24 @@ JS's instanceof operator.", "defaultValue": "21", "type": Object { "name": "number", + "required": false, }, }, "optionalObject": Object { "type": Object { "name": "object", + "required": false, }, }, "optionalObjectOf": Object { "description": "An object with property values of a certain type", "type": Object { - "name": "objectOf", - "value": Object { - "name": "number", - }, + "name": "object", + "value": Array [ + Object { + "name": "number", + }, + ], }, }, "optionalObjectWithShape": Object { @@ -139,11 +144,13 @@ JS's instanceof operator.", "optionalString": Object { "type": Object { "name": "string", + "required": false, }, }, "optionalSymbol": Object { "type": Object { "name": "symbol", + "required": false, }, }, "optionalUnion": Object { @@ -167,15 +174,15 @@ JS's instanceof operator.", }, "requiredAny": Object { "description": "A value of any data type", - "required": true, "type": Object { "name": "any", + "required": true, }, }, "requiredFunc": Object { - "required": true, "type": Object { "name": "function", + "required": true, }, }, }, diff --git a/props-info/react-docgen/test/__snapshots__/typescript.test.ts.snap b/props-info/react-docgen/test/__snapshots__/typescript.test.ts.snap index 12df9fa77..9be16d726 100644 --- a/props-info/react-docgen/test/__snapshots__/typescript.test.ts.snap +++ b/props-info/react-docgen/test/__snapshots__/typescript.test.ts.snap @@ -32,6 +32,7 @@ are all optional.", "optionalBool": Object { "type": Object { "name": "boolean", + "required": false, }, }, "optionalElement": Object { @@ -39,12 +40,14 @@ are all optional.", "type": Object { "name": "ReactReactElement", "raw": "React.ReactElement", + "required": false, }, }, "optionalElementType": Object { "description": "A React element type (ie. MyComponent).", "type": Object { "name": "JSX.Element", + "required": false, }, }, "optionalEnum": Object { @@ -63,6 +66,7 @@ it as an enum.", ], "name": "union", "raw": "'News' | 'Photos'", + "required": false, }, }, "optionalFunc": Object { @@ -86,6 +90,7 @@ it as an enum.", JS's instanceof operator.", "type": Object { "name": "Message", + "required": false, }, }, "optionalNode": Object { @@ -94,17 +99,20 @@ JS's instanceof operator.", "type": Object { "name": "ReactReactNode", "raw": "React.ReactNode", + "required": false, }, }, "optionalNumber": Object { "defaultValue": "21", "type": Object { "name": "number", + "required": false, }, }, "optionalObject": Object { "type": Object { "name": "object", + "required": false, }, }, "optionalObjectOf": Object { @@ -173,11 +181,13 @@ An object taking on a particular shape", "optionalString": Object { "type": Object { "name": "string", + "required": false, }, }, "optionalSymbol": Object { "type": Object { "name": "symbol", + "required": false, }, }, "optionalUnion": Object { @@ -196,17 +206,17 @@ An object taking on a particular shape", ], "name": "union", "raw": "string | number | Message", + "required": false, }, }, "requiredAny": Object { "description": "A value of any data type", - "required": true, "type": Object { "name": "any", + "required": true, }, }, "requiredFunc": Object { - "required": true, "type": Object { "arguments": Array [ Object { diff --git a/props-info/react-docgen/test/loadTestFiles.ts b/props-info/react-docgen/test/loadTestFiles.ts index daaee9183..1d15aa61b 100644 --- a/props-info/react-docgen/test/loadTestFiles.ts +++ b/props-info/react-docgen/test/loadTestFiles.ts @@ -13,7 +13,7 @@ export const loadTestFiles = (...args: string[]) => { fileNames.forEach(file => { const fileName = path.join(folderName, file); it(file, async () => { - expect(await extractInfo(fileName)).toMatchSnapshot(); + expect(await extractInfo()(fileName, 'MyComponent')).toMatchSnapshot(); }); }); }; diff --git a/props-info/react-docgen/tsconfig.json b/props-info/react-docgen/tsconfig.json index 90177240e..65cfc86b1 100644 --- a/props-info/react-docgen/tsconfig.json +++ b/props-info/react-docgen/tsconfig.json @@ -8,6 +8,6 @@ "types": ["node", "jest"], "typeRoots": ["../../node_modules/@types", "node_modules/@types"] }, - "include": ["src/**/*", "src/typings.d.ts", "test"], + "include": ["src/**/*", "src/typings.d.ts", "test", "../react-docgen-typescript/test/fixtures/jsx/multiple-exports.tsx"], "exclude": ["node_modules/**", "test/**"] } \ No newline at end of file diff --git a/ui/blocks/src/BlocksContext/BlockContext.tsx b/ui/blocks/src/BlocksContext/BlockContext.tsx index 2adcccdf2..82f10e9fa 100644 --- a/ui/blocks/src/BlocksContext/BlockContext.tsx +++ b/ui/blocks/src/BlocksContext/BlockContext.tsx @@ -72,18 +72,18 @@ export const useControlsContext = ({ const story: Story = myStoryStore && myStoryStore.stories[previewId]; const kind = story && story.kind ? myStoryStore.kinds[story.kind] : undefined; const source: string | undefined = story ? story.source : undefined; - let component; + let componentName: string; if (of === CURRENT_SELECTION) { - component = - story && story.component - ? myStoryStore.components[story.component] - : kind - ? myStoryStore.components[kind.component] - : undefined; + componentName = + story && story.component ? story.component : kind?.component; } else { - component = of; + componentName = typeof of === 'string' ? of : of && (of as any).displayName; } + const component = + componentName && kind && kind.components[componentName] + ? myStoryStore.components[kind.components[componentName]] + : undefined; const sbStory = (storyStore && storyStore.fromId(previewId)) || {}; if (component && !component.info && sbStory && sbStory.parameters.component) { component.info = sbStory.parameters.component.__docgenInfo;