Skip to content

Commit 3bb2146

Browse files
eps1londanez
authored andcommitted
feat(defaultPropsHandler): Fully support forwardRef (#350)
* test(failing): defaultPropsHandler and forwardRef * feat(defaultPropsHandler): support forwardRef # Conflicts: # src/handlers/__tests__/__snapshots__/defaultPropsHandler-test.js.snap
1 parent fcfb193 commit 3bb2146

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`defaultPropsHandler forwardRef resolves default props in the parameters 1`] = `
4+
Object {
5+
"foo": Object {
6+
"defaultValue": Object {
7+
"computed": false,
8+
"value": "'bar'",
9+
},
10+
},
11+
}
12+
`;
13+
14+
exports[`defaultPropsHandler forwardRef resolves defaultProps 1`] = `
15+
Object {
16+
"foo": Object {
17+
"defaultValue": Object {
18+
"computed": false,
19+
"value": "'baz'",
20+
},
21+
},
22+
}
23+
`;

src/handlers/__tests__/defaultPropsHandler-test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,28 @@ describe('defaultPropsHandler', () => {
219219
expect(documentation.descriptors).toEqual({});
220220
});
221221
});
222+
223+
describe('forwardRef', () => {
224+
it('resolves default props in the parameters', () => {
225+
const src = `
226+
import React from 'react';
227+
React.forwardRef(({ foo = 'bar' }, ref) => <div ref={ref}>{foo}</div>);
228+
`;
229+
defaultPropsHandler(
230+
documentation,
231+
parse(src).get('body', 1, 'expression'),
232+
);
233+
expect(documentation.descriptors).toMatchSnapshot();
234+
});
235+
236+
it('resolves defaultProps', () => {
237+
const src = `
238+
import React from 'react';
239+
const Component = React.forwardRef(({ foo }, ref) => <div ref={ref}>{foo}</div>);
240+
Component.defaultProps = { foo: 'baz' };
241+
`;
242+
defaultPropsHandler(documentation, parse(src).get('body', 1));
243+
expect(documentation.descriptors).toMatchSnapshot();
244+
});
245+
});
222246
});

src/handlers/defaultPropsHandler.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import printValue from '../utils/printValue';
1818
import recast from 'recast';
1919
import resolveToValue from '../utils/resolveToValue';
2020
import resolveFunctionDefinitionToReturnValue from '../utils/resolveFunctionDefinitionToReturnValue';
21-
import isStatelessComponent from '../utils/isStatelessComponent';
21+
import isReactComponentClass from '../utils/isReactComponentClass';
22+
import isReactForwardRefCall from '../utils/isReactForwardRefCall';
2223

2324
const {
2425
types: { namedTypes: types },
@@ -56,7 +57,12 @@ function getDefaultValue(path: NodePath) {
5657
}
5758

5859
function getStatelessPropsPath(componentDefinition): NodePath {
59-
return resolveToValue(componentDefinition).get('params', 0);
60+
const value = resolveToValue(componentDefinition);
61+
if (isReactForwardRefCall(value)) {
62+
const inner = value.get('arguments', 0);
63+
return inner.get('params', 0);
64+
}
65+
return value.get('params', 0);
6066
}
6167

6268
function getDefaultPropsPath(componentDefinition: NodePath): ?NodePath {
@@ -120,7 +126,10 @@ export default function defaultPropsHandler(
120126
) {
121127
let statelessProps = null;
122128
const defaultPropsPath = getDefaultPropsPath(componentDefinition);
123-
if (isStatelessComponent(componentDefinition)) {
129+
/**
130+
* function, lazy, memo, forwardRef etc components can resolve default props as well
131+
*/
132+
if (!isReactComponentClass(componentDefinition)) {
124133
statelessProps = getStatelessPropsPath(componentDefinition);
125134
}
126135

0 commit comments

Comments
 (0)