diff --git a/src/handlers/__tests__/__snapshots__/defaultPropsHandler-test.js.snap b/src/handlers/__tests__/__snapshots__/defaultPropsHandler-test.js.snap
index 8d0b2a9ce69..e0803b09162 100644
--- a/src/handlers/__tests__/__snapshots__/defaultPropsHandler-test.js.snap
+++ b/src/handlers/__tests__/__snapshots__/defaultPropsHandler-test.js.snap
@@ -299,6 +299,17 @@ Object {
}
`;
+exports[`defaultPropsHandler forwardRef resolves when the function is not inline 1`] = `
+Object {
+ "foo": Object {
+ "defaultValue": Object {
+ "computed": false,
+ "value": "'bar'",
+ },
+ },
+}
+`;
+
exports[`defaultPropsHandler should only consider Property nodes, not e.g. spread properties 1`] = `
Object {
"bar": Object {
diff --git a/src/handlers/__tests__/defaultPropsHandler-test.js b/src/handlers/__tests__/defaultPropsHandler-test.js
index c03a4775429..a2e739a9066 100644
--- a/src/handlers/__tests__/defaultPropsHandler-test.js
+++ b/src/handlers/__tests__/defaultPropsHandler-test.js
@@ -290,5 +290,18 @@ describe('defaultPropsHandler', () => {
defaultPropsHandler(documentation, parse(src).get('body', 1));
expect(documentation.descriptors).toMatchSnapshot();
});
+
+ it('resolves when the function is not inline', () => {
+ const src = `
+ import React from 'react';
+ const ComponentImpl = ({ foo = 'bar' }, ref) =>
{foo}
;
+ React.forwardRef(ComponentImpl);
+ `;
+ defaultPropsHandler(
+ documentation,
+ parse(src).get('body', 2, 'expression'),
+ );
+ expect(documentation.descriptors).toMatchSnapshot();
+ });
});
});
diff --git a/src/handlers/__tests__/flowTypeHandler-test.js b/src/handlers/__tests__/flowTypeHandler-test.js
index c63f9b30cad..c05167409a5 100644
--- a/src/handlers/__tests__/flowTypeHandler-test.js
+++ b/src/handlers/__tests__/flowTypeHandler-test.js
@@ -8,7 +8,7 @@
jest.mock('../../Documentation');
-import { expression, statement } from '../../../tests/utils';
+import { expression, statement, parse } from '../../../tests/utils';
describe('flowTypeHandler', () => {
let getFlowTypeMock;
@@ -334,4 +334,39 @@ describe('flowTypeHandler', () => {
`);
});
});
+
+ describe('forwardRef', () => {
+ it('resolves prop type from function expression', () => {
+ const src = `
+ import React from 'react';
+ type Props = { foo: string };
+ React.forwardRef((props: Props, ref) => {props.foo}
);
+ `;
+ flowTypeHandler(documentation, parse(src).get('body', 2, 'expression'));
+ expect(documentation.descriptors).toEqual({
+ foo: {
+ flowType: {},
+ required: true,
+ description: '',
+ },
+ });
+ });
+
+ it('resolves when the function is not inline', () => {
+ const src = `
+ import React from 'react';
+ type Props = { foo: string };
+ const ComponentImpl = (props: Props, ref) => {props.foo}
;
+ React.forwardRef(ComponentImpl);
+ `;
+ flowTypeHandler(documentation, parse(src).get('body', 3, 'expression'));
+ expect(documentation.descriptors).toEqual({
+ foo: {
+ flowType: {},
+ required: true,
+ description: '',
+ },
+ });
+ });
+ });
});
diff --git a/src/handlers/defaultPropsHandler.js b/src/handlers/defaultPropsHandler.js
index 8abcfde1f0f..638f08d7781 100644
--- a/src/handlers/defaultPropsHandler.js
+++ b/src/handlers/defaultPropsHandler.js
@@ -51,7 +51,7 @@ function getDefaultValue(path: NodePath) {
function getStatelessPropsPath(componentDefinition): NodePath {
const value = resolveToValue(componentDefinition);
if (isReactForwardRefCall(value)) {
- const inner = value.get('arguments', 0);
+ const inner = resolveToValue(value.get('arguments', 0));
return inner.get('params', 0);
}
return value.get('params', 0);
diff --git a/src/utils/getFlowTypeFromReactComponent.js b/src/utils/getFlowTypeFromReactComponent.js
index fd037b10b4d..74f98b7c062 100644
--- a/src/utils/getFlowTypeFromReactComponent.js
+++ b/src/utils/getFlowTypeFromReactComponent.js
@@ -19,7 +19,7 @@ import resolveToValue from './resolveToValue';
function getStatelessPropsPath(componentDefinition): NodePath {
const value = resolveToValue(componentDefinition);
if (isReactForwardRefCall(value)) {
- const inner = value.get('arguments', 0);
+ const inner = resolveToValue(value.get('arguments', 0));
return inner.get('params', 0);
}
return value.get('params', 0);