diff --git a/addons/info/src/__snapshots__/index.test.js.snap b/addons/info/src/__snapshots__/index.test.js.snap
index e3cb3ea64eaa..b2411d48c6be 100644
--- a/addons/info/src/__snapshots__/index.test.js.snap
+++ b/addons/info/src/__snapshots__/index.test.js.snap
@@ -67,8 +67,8 @@ exports[`addon Info should render and external markdown 1`] = `
function func(x) {
- return x + 1;
- }
+ return x + 1;
+ }
[object Object]
@@ -230,9 +230,1346 @@ exports[`addon Info should render and external markdown 1`] = `
Object {
"__html": "HTML Mock
",
}
- }
- key="0"
- />
+ }
+ key="0"
+ />
+
+
+
+ Story Source
+
+
+
+
+
+ It's a
+ story:
+
+
+ }
+ >
+
+
+
+ <
+ div
+
+
+ It's a
+ story:
+
+
+ }
+ singleLine={false}
+ >
+
+
+
+ >
+
+
+
+
+
+ It's a
+
+
+
+
+
+
+
+
+
+
+
+ story:
+
+
+
+
+ }
+ >
+
+
+ <
+ TestComponent
+
+
+ }
+ singleLine={true}
+ >
+
+
+
+
+
+
+
+ func
+
+
+ =
+
+ {
+
+
+ func
+
+
+ }
+
+
+
+
+
+
+
+
+
+ obj
+
+
+ =
+
+ {
+
+
+
+ {
+
+
+ a
+
+
+ :
+
+
+ 'a'
+
+
+ ,
+
+
+ b
+
+
+ :
+
+
+ 'b'
+
+
+ }
+
+
+
+ }
+
+
+
+
+
+
+
+
+
+ array
+
+
+ =
+
+ {
+
+
+
+ [
+
+
+
+ 1
+
+
+
+ ,
+
+
+
+ 2
+
+
+
+ ,
+
+
+
+ 3
+
+
+
+ ]
+
+
+
+ }
+
+
+
+
+
+
+
+
+
+ number
+
+
+ =
+
+ {
+
+
+ 7
+
+
+ }
+
+
+
+
+
+
+
+
+
+ string
+
+
+ =
+
+ "
+
+
+ seven
+
+
+ "
+
+
+
+
+
+
+
+
+
+ bool
+
+
+
+
+
+
+ />
+
+
+
+
+
+ </
+ div
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Prop Types
+
+
+
+ "
+ TestComponent
+ " Component
+
+
+
+
+ No propTypes defined!
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`addon Info should render and markdown 1`] = `
+
+
+
+
+
+ It's a
+ story:
+
+
+
+ function func(x) {
+ return x + 1;
+ }
+
+
+ [object Object]
+
+
+ 1,2,3
+
+
+ 7
+
+
+ seven
+
+
+ true
+
+
+ undefined
+
+
+ test
+
+
+ storiesOf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Test story
+
+
+
+
+ with markdown info
+
+
+
+
+ containing
+
+ bold
+
+ ,
+
+ cursive
+
+ text,
+
+ code
+
+ and
+
+
+ a link
+
+
+
+
and external markdown 1`] = `
`;
-exports[`addon Info should render
and markdown 1`] = `
+exports[`addon Info should render
for memoized component 1`] = `
and markdown 1`] = `
}
context={Object {}}
excludedPropTypes={Array []}
- info="# Test story
-## with markdown info
-containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
+ info=""
maxPropArrayLength={3}
maxPropObjectKeys={3}
maxPropStringLength={50}
maxPropsIntoLine={3}
- propTables={Array []}
+ propTables={null}
propTablesExclude={Array []}
showHeader={true}
showInline={false}
@@ -1319,47 +2654,45 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
}
string="seven"
>
-
-
- function func(x) {
- return x + 1;
- }
-
-
- [object Object]
-
-
- 1,2,3
-
-
- 7
-
-
- seven
-
-
- true
-
-
- undefined
-
-
- test
-
-
- storiesOf
-
-
-
+
+ function func(x) {
+ return x + 1;
+ }
+
+
+ [object Object]
+
+
+ 1,2,3
+
+
+ 7
+
+
+ seven
+
+
+ true
+
+
+ undefined
+
+
+ test
+
+
+ storiesOf
+
+
@@ -1473,104 +2806,6 @@ containing **bold**, *cursive* text, \`code\` and [a link](https://github.com)"
}
/>
-
-
-
- Test story
-
-
-
-
- with markdown info
-
-
-
-
- containing
-
- bold
-
- ,
-
- cursive
-
- text,
-
- code
-
- and
-
-
- a link
-
-
-
-
-
It's a
story:
-
It's a
story:
-
-
-
- Prop Types
-
-
-
- "
- TestComponent
- " Component
-
-
-
-
- No propTypes defined!
-
-
-
-
-
@@ -2712,8 +3898,8 @@ exports[`addon Info should render component description if story kind matches co
function func(x) {
- return x + 1;
- }
+ return x + 1;
+ }
[object Object]
@@ -3931,8 +5117,8 @@ exports[`addon Info should render component description if story name matches co
function func(x) {
- return x + 1;
- }
+ return x + 1;
+ }
[object Object]
diff --git a/addons/info/src/components/Node.js b/addons/info/src/components/Node.js
index 926b664c3588..a51c716a27ad 100644
--- a/addons/info/src/components/Node.js
+++ b/addons/info/src/components/Node.js
@@ -2,6 +2,7 @@ import React from 'react';
import { isForwardRef } from 'react-is';
import PropTypes from 'prop-types';
import Props from './Props';
+import { getDisplayName } from '../react-utils';
const stylesheet = {
containerStyle: {},
@@ -32,13 +33,7 @@ function getData(element) {
}
data.children = element.props.children;
- const { type } = element;
-
- if (typeof type === 'string') {
- data.name = type;
- } else {
- data.name = type.displayName || type.name || 'Unknown';
- }
+ data.name = getDisplayName(element.type);
return data;
}
diff --git a/addons/info/src/components/Props.js b/addons/info/src/components/Props.js
index 851b160ee1ea..722c4aa8be28 100644
--- a/addons/info/src/components/Props.js
+++ b/addons/info/src/components/Props.js
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import PropVal from './PropVal';
+import { getType } from '../react-utils';
const stylesheet = {
propStyle: {},
@@ -18,7 +19,7 @@ export default function Props(props) {
singleLine,
} = props;
const nodeProps = node.props;
- const { defaultProps } = node.type;
+ const { defaultProps } = getType(node.type);
if (!nodeProps || typeof nodeProps !== 'object') {
return ;
}
diff --git a/addons/info/src/components/Story.js b/addons/info/src/components/Story.js
index 939b4bb50dca..0716aa6a76a9 100644
--- a/addons/info/src/components/Story.js
+++ b/addons/info/src/components/Story.js
@@ -9,12 +9,11 @@ import global from 'global';
import marksy from 'marksy';
import Node from './Node';
import { Pre } from './markdown';
+import { getDisplayName, getType } from '../react-utils';
global.STORYBOOK_REACT_CLASSES = global.STORYBOOK_REACT_CLASSES || [];
const { STORYBOOK_REACT_CLASSES } = global;
-const getName = type => type.displayName || type.name;
-
const stylesheetBase = {
button: {
base: {
@@ -379,14 +378,14 @@ class Story extends Component {
extract(children);
const array = Array.from(types.keys());
- array.sort((a, b) => (getName(a) > getName(b) ? 1 : -1));
+ array.sort((a, b) => (getDisplayName(a) > getDisplayName(b) ? 1 : -1));
propTables = array.map((type, i) => (
// eslint-disable-next-line react/no-array-index-key
-
-
"{getName(type)}" Component
+
+
"{getDisplayName(type)}" Component
{
// eslint-disable-next-line react/prop-types
- const storyFn = ({ name }) => (
+ const createStoryFn = Component => ({ name }) => (
It's a {name} story:
- x + 1}
obj={{ a: 'a', b: 'b' }}
array={[1, 2, 3]}
@@ -59,6 +59,8 @@ describe('addon Info', () => {
/>
);
+ const storyFn = createStoryFn(TestComponent);
+
it('should render and markdown', () => {
const Info = withInfo(testMarkdown)(storyFn);
@@ -78,6 +80,12 @@ describe('addon Info', () => {
const Info = withInfo()(storyFn);
mount();
});
+ it('should render for memoized component', () => {
+ const MemoizedTestComponent = React.memo(TestComponent);
+ const Info = withInfo()(createStoryFn(MemoizedTestComponent));
+
+ expect(mount()).toMatchSnapshot();
+ });
it('should render component description if story kind matches component', () => {
const previousReactClassesValue = global.STORYBOOK_REACT_CLASSES[reactClassPath];
diff --git a/addons/info/src/react-utils.js b/addons/info/src/react-utils.js
new file mode 100644
index 000000000000..c85ff7bb90eb
--- /dev/null
+++ b/addons/info/src/react-utils.js
@@ -0,0 +1,14 @@
+import { isMemo } from 'react-is';
+
+export function getType(typeOrMemo) {
+ return isMemo(typeOrMemo) ? typeOrMemo.type : typeOrMemo;
+}
+
+export function getDisplayName(typeOrMemo) {
+ if (typeof typeOrMemo === 'string') {
+ return typeOrMemo;
+ }
+
+ const type = getType(typeOrMemo);
+ return type.displayName || type.name || 'Unknown';
+}
diff --git a/examples/official-storybook/stories/__snapshots__/addon-info.stories.storyshot b/examples/official-storybook/stories/__snapshots__/addon-info.stories.storyshot
index eb3917327d2e..171cc888c88b 100644
--- a/examples/official-storybook/stories/__snapshots__/addon-info.stories.storyshot
+++ b/examples/official-storybook/stories/__snapshots__/addon-info.stories.storyshot
@@ -940,7 +940,7 @@ exports[`Storyshots Addons|Info/GitHub issues #1814 1`] = `
- "" Component
+ "Unknown" Component
No propTypes defined!
@@ -950,7 +950,7 @@ exports[`Storyshots Addons|Info/GitHub issues #1814 1`] = `
- "" Component
+ "Unknown" Component
No propTypes defined!