From 07c97d8c4da9587fd2ebedfc42f57a4af311b5e9 Mon Sep 17 00:00:00 2001 From: philippe Date: Wed, 15 Jun 2022 14:49:56 -0400 Subject: [PATCH 1/5] Fix React.FC typescript components --- .../generator.test.ts | 3 ++- .../src/components/FCComponent.tsx | 8 ++++++++ .../src/index.ts | 12 +++++++----- dash/extract-meta.js | 8 ++++---- 4 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 @plotly/dash-generator-test-component-typescript/src/components/FCComponent.tsx diff --git a/@plotly/dash-generator-test-component-typescript/generator.test.ts b/@plotly/dash-generator-test-component-typescript/generator.test.ts index c2920b136d..0a9ae178a0 100644 --- a/@plotly/dash-generator-test-component-typescript/generator.test.ts +++ b/@plotly/dash-generator-test-component-typescript/generator.test.ts @@ -61,7 +61,8 @@ describe('Test Typescript component metadata generation', () => { describe.each([ 'TypeScriptComponent', 'TypeScriptClassComponent', - 'MemoTypeScriptComponent' + 'MemoTypeScriptComponent', + 'FCComponent', ])('Test prop type names', componentName => { const getPropTypeName = (name, data) => R.path(propPath(componentName, name).concat('type', 'name'), data); diff --git a/@plotly/dash-generator-test-component-typescript/src/components/FCComponent.tsx b/@plotly/dash-generator-test-component-typescript/src/components/FCComponent.tsx new file mode 100644 index 0000000000..0bb9324e88 --- /dev/null +++ b/@plotly/dash-generator-test-component-typescript/src/components/FCComponent.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { TypescriptComponentProps } from '../props'; + +const FCComponent: React.FC = (props) => ( +
{props.children}
+); + +export default FCComponent; diff --git a/@plotly/dash-generator-test-component-typescript/src/index.ts b/@plotly/dash-generator-test-component-typescript/src/index.ts index 0d8962d122..5b75cf4d7f 100644 --- a/@plotly/dash-generator-test-component-typescript/src/index.ts +++ b/@plotly/dash-generator-test-component-typescript/src/index.ts @@ -3,11 +3,13 @@ import TypeScriptClassComponent from './components/TypeScriptClassComponent'; import MemoTypeScriptComponent from './components/MemoTypeScriptComponent'; import StandardComponent from './components/StandardComponent.react'; import WrappedHTML from './components/WrappedHTML'; +import FCComponent from './components/FCComponent'; export { - TypeScriptComponent, - TypeScriptClassComponent, - MemoTypeScriptComponent, - StandardComponent, - WrappedHTML, + TypeScriptComponent, + TypeScriptClassComponent, + MemoTypeScriptComponent, + StandardComponent, + WrappedHTML, + FCComponent, }; diff --git a/dash/extract-meta.js b/dash/extract-meta.js index 812738725c..22b828340e 100755 --- a/dash/extract-meta.js +++ b/dash/extract-meta.js @@ -672,14 +672,14 @@ function gatherComponents(sources, components = {}) { } else { // Function components. rootExp = typeSymbol; - commentSource = rootExp.valueDeclaration; + commentSource = rootExp.valueDeclaration || rootExp.declarations[0]; if ( - rootExp.valueDeclaration && - rootExp.valueDeclaration.parent + commentSource && + commentSource.parent ) { // Function with export later like `const MyComponent = (props) => <>;` commentSource = getParent( - rootExp.valueDeclaration.parent + commentSource.parent ); } } From 1f187d7a6ea034442a37b5abd5f14c61d6f15a22 Mon Sep 17 00:00:00 2001 From: philippe Date: Wed, 15 Jun 2022 15:07:25 -0400 Subject: [PATCH 2/5] Fix empty components. --- .../generator.test.ts | 9 ++++++--- .../src/components/EmptyComponent.tsx | 5 +++++ .../src/index.ts | 2 ++ dash/extract-meta.js | 7 ++++++- 4 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 @plotly/dash-generator-test-component-typescript/src/components/EmptyComponent.tsx diff --git a/@plotly/dash-generator-test-component-typescript/generator.test.ts b/@plotly/dash-generator-test-component-typescript/generator.test.ts index 0a9ae178a0..c34b575350 100644 --- a/@plotly/dash-generator-test-component-typescript/generator.test.ts +++ b/@plotly/dash-generator-test-component-typescript/generator.test.ts @@ -258,9 +258,12 @@ describe('Test Typescript component metadata generation', () => { expect(R.path(['StandardComponent'], metadata)).toBeDefined(); }); }); - describe('Test namespace props', () => { + describe('Test special cases', () => { test('Component with picked boolean prop', () => { expect(R.path(['WrappedHTML', "props", "autoFocus", "type", "name"], metadata)).toBe("bool"); - }) - }) + }); + test('Empty Component', () => { + expect(R.path(['EmptyComponent', 'props'], metadata)).toBeDefined(); + }); + }); }); diff --git a/@plotly/dash-generator-test-component-typescript/src/components/EmptyComponent.tsx b/@plotly/dash-generator-test-component-typescript/src/components/EmptyComponent.tsx new file mode 100644 index 0000000000..935c56a7d1 --- /dev/null +++ b/@plotly/dash-generator-test-component-typescript/src/components/EmptyComponent.tsx @@ -0,0 +1,5 @@ +import React from 'react'; + +const EmptyComponent = () =>
Empty
; + +export default EmptyComponent; diff --git a/@plotly/dash-generator-test-component-typescript/src/index.ts b/@plotly/dash-generator-test-component-typescript/src/index.ts index 5b75cf4d7f..149163d17c 100644 --- a/@plotly/dash-generator-test-component-typescript/src/index.ts +++ b/@plotly/dash-generator-test-component-typescript/src/index.ts @@ -4,6 +4,7 @@ import MemoTypeScriptComponent from './components/MemoTypeScriptComponent'; import StandardComponent from './components/StandardComponent.react'; import WrappedHTML from './components/WrappedHTML'; import FCComponent from './components/FCComponent'; +import EmptyComponent from './components/EmptyComponent'; export { TypeScriptComponent, @@ -12,4 +13,5 @@ export { StandardComponent, WrappedHTML, FCComponent, + EmptyComponent, }; diff --git a/dash/extract-meta.js b/dash/extract-meta.js index 22b828340e..70416d403f 100755 --- a/dash/extract-meta.js +++ b/dash/extract-meta.js @@ -113,7 +113,7 @@ function checkDocstring(name, value) { function docstringWarning(doc) { checkDocstring(doc.displayName, doc.description); - Object.entries(doc.props).forEach(([name, p]) => + Object.entries(doc.props || {}).forEach(([name, p]) => checkDocstring(`${doc.displayName}.${name}`, p.description) ); } @@ -719,6 +719,11 @@ function gatherComponents(sources, components = {}) { ); } + if (!props) { + // Ensure empty components has props. + props = {}; + } + const fullText = source.getFullText(); let description; const commentRanges = ts.getLeadingCommentRanges( From e09bcf3a7f1a64f5b9bdc962313572e096f3662f Mon Sep 17 00:00:00 2001 From: philippe Date: Wed, 15 Jun 2022 15:17:30 -0400 Subject: [PATCH 3/5] Add mixed ts/prop-types component test. --- .../generator.test.ts | 3 +++ .../src/components/MixedComponent.tsx | 19 +++++++++++++++++++ .../src/index.ts | 2 ++ 3 files changed, 24 insertions(+) create mode 100644 @plotly/dash-generator-test-component-typescript/src/components/MixedComponent.tsx diff --git a/@plotly/dash-generator-test-component-typescript/generator.test.ts b/@plotly/dash-generator-test-component-typescript/generator.test.ts index c34b575350..7b81fa07a3 100644 --- a/@plotly/dash-generator-test-component-typescript/generator.test.ts +++ b/@plotly/dash-generator-test-component-typescript/generator.test.ts @@ -257,6 +257,9 @@ describe('Test Typescript component metadata generation', () => { test('Standard js component is parsed', () => { expect(R.path(['StandardComponent'], metadata)).toBeDefined(); }); + test('Mixed component prop-type & typescript', () => { + expect(R.path(['MixedComponent', 'props', 'prop', 'type', 'name'], metadata)).toBe('arrayOf') + }) }); describe('Test special cases', () => { test('Component with picked boolean prop', () => { diff --git a/@plotly/dash-generator-test-component-typescript/src/components/MixedComponent.tsx b/@plotly/dash-generator-test-component-typescript/src/components/MixedComponent.tsx new file mode 100644 index 0000000000..b8b6b28777 --- /dev/null +++ b/@plotly/dash-generator-test-component-typescript/src/components/MixedComponent.tsx @@ -0,0 +1,19 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +type Props = { + id?: string; + prop: string[]; +} + +const MixedComponent: React.FC = (props) => { + return ( +
{props.children}
+ ) +} + +MixedComponent.propTypes = { + prop: PropTypes.arrayOf(PropTypes.string).isRequired +} + +export default MixedComponent; diff --git a/@plotly/dash-generator-test-component-typescript/src/index.ts b/@plotly/dash-generator-test-component-typescript/src/index.ts index 149163d17c..db623b462d 100644 --- a/@plotly/dash-generator-test-component-typescript/src/index.ts +++ b/@plotly/dash-generator-test-component-typescript/src/index.ts @@ -5,6 +5,7 @@ import StandardComponent from './components/StandardComponent.react'; import WrappedHTML from './components/WrappedHTML'; import FCComponent from './components/FCComponent'; import EmptyComponent from './components/EmptyComponent'; +import MixedComponent from './components/MixedComponent'; export { TypeScriptComponent, @@ -14,4 +15,5 @@ export { WrappedHTML, FCComponent, EmptyComponent, + MixedComponent, }; From 2ea3a9cb0441b916b679fb171b9f8fd7938461f1 Mon Sep 17 00:00:00 2001 From: philippe Date: Wed, 15 Jun 2022 15:45:13 -0400 Subject: [PATCH 4/5] Add default description. --- dash/extract-meta.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash/extract-meta.js b/dash/extract-meta.js index 70416d403f..9ec1fd405b 100755 --- a/dash/extract-meta.js +++ b/dash/extract-meta.js @@ -725,7 +725,7 @@ function gatherComponents(sources, components = {}) { } const fullText = source.getFullText(); - let description; + let description = ''; const commentRanges = ts.getLeadingCommentRanges( fullText, commentSource.getFullStart() From fa598b43ab90a2751508870d57fbe3bd212b636f Mon Sep 17 00:00:00 2001 From: philippe Date: Thu, 16 Jun 2022 11:25:46 -0400 Subject: [PATCH 5/5] Update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01d86d678d..9d4d8050a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to `dash` will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). +## [UNRELEASED] + +### Fixed + +- [#2097](https://github.com/plotly/dash/pull/2097) Fix bug [#2095](https://github.com/plotly/dash/issues/2095) with TypeScript compiler and `React.FC` empty valueDeclaration error & support empty props components. + ## [2.5.1] - 2022-06-13 ### Fixed