Skip to content

Commit

Permalink
Merge pull request #26566 from storybookjs/yann/fix-docs-jsx-decorator
Browse files Browse the repository at this point in the history
Addon Docs: Fix [Object object] displayName in some JSX components

(cherry picked from commit 79abc6c)
  • Loading branch information
yannbf authored and storybook-bot committed Mar 19, 2024
1 parent 910b7f7 commit 0ca1ca4
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 18 deletions.
34 changes: 27 additions & 7 deletions code/renderers/react/src/docs/jsxDecorator.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,22 @@ describe('renderJsx', () => {
}
);

expect(renderJsx(createElement(MyExoticComponentRef, {}, 'I am forwardRef!'), {}))
expect(renderJsx(<MyExoticComponentRef>I am forwardRef!</MyExoticComponentRef>))
.toMatchInlineSnapshot(`
<MyExoticComponent>
<React.ForwardRef>
I am forwardRef!
</MyExoticComponent>
</React.ForwardRef>
`);

// if docgenInfo is present, it should use the displayName from there
(MyExoticComponentRef as any).__docgenInfo = {
displayName: 'ExoticComponent',
};
expect(renderJsx(<MyExoticComponentRef>I am forwardRef!</MyExoticComponentRef>))
.toMatchInlineSnapshot(`
<ExoticComponent>
I am forwardRef!
</ExoticComponent>
`);
});

Expand All @@ -143,11 +154,20 @@ describe('renderJsx', () => {
return <div>{props.children}</div>;
});

expect(renderJsx(createElement(MyMemoComponentRef, {}, 'I am memo!'), {}))
.toMatchInlineSnapshot(`
<MyMemoComponent>
expect(renderJsx(<MyMemoComponentRef>I am memo!</MyMemoComponentRef>)).toMatchInlineSnapshot(`
<React.Memo>
I am memo!
</React.Memo>
`);

// if docgenInfo is present, it should use the displayName from there
(MyMemoComponentRef as any).__docgenInfo = {
displayName: 'MyMemoComponentRef',
};
expect(renderJsx(<MyMemoComponentRef>I am memo!</MyMemoComponentRef>)).toMatchInlineSnapshot(`
<MyMemoComponentRef>
I am memo!
</MyMemoComponent>
</MyMemoComponentRef>
`);
});

Expand Down
35 changes: 24 additions & 11 deletions code/renderers/react/src/docs/jsxDecorator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ const toPascalCase = (str: string) => str.charAt(0).toUpperCase() + str.slice(1)
* @returns {string | null} A displayName for the Symbol in case elementType is a Symbol; otherwise, null.
*/
export const getReactSymbolName = (elementType: any): string => {
const symbolDescription: string = elementType.toString().replace(/^Symbol\((.*)\)$/, '$1');
const elementName = elementType.$$typeof || elementType;
const symbolDescription: string = elementName.toString().replace(/^Symbol\((.*)\)$/, '$1');

const reactComponentName = symbolDescription
.split('.')
Expand Down Expand Up @@ -124,16 +125,28 @@ export const renderJsx = (code: React.ReactElement, options?: JSXOptions) => {
} else {
displayNameDefaults = {
// To get exotic component names resolving properly
displayName: (el: any): string =>
el.type.displayName || typeof el.type === 'symbol'
? getReactSymbolName(el.type)
: null ||
getDocgenSection(el.type, 'displayName') ||
(el.type.name !== '_default' ? el.type.name : null) ||
(typeof el.type === 'function' ? 'No Display Name' : null) ||
(isForwardRef(el.type) ? el.type.render.name : null) ||
(isMemo(el.type) ? el.type.type.name : null) ||
el.type,
displayName: (el: any): string => {
if (el.type.displayName) {
return el.type.displayName;
} else if (getDocgenSection(el.type, 'displayName')) {
return getDocgenSection(el.type, 'displayName');
} else if (
typeof el.type === 'symbol' ||
(el.type.$$typeof && typeof el.type.$$typeof === 'symbol')
) {
return getReactSymbolName(el.type);
} else if (el.type.name && el.type.name !== '_default') {
return el.type.name;
} else if (typeof el.type === 'function') {
return 'No Display Name';
} else if (isForwardRef(el.type)) {
return el.type.render.name;
} else if (isMemo(el.type)) {
return el.type.type.name;
} else {
return el.type;
}
},
};
}

Expand Down

0 comments on commit 0ca1ca4

Please sign in to comment.