@@ -15,6 +15,7 @@ import {
1515 ComponentType ,
1616 ExoticComponent ,
1717 isValidElement ,
18+ Component ,
1819} from 'react' ;
1920import { Args , StoryContext } from '@storybook/react' ;
2021import * as prettier from 'prettier' ;
@@ -56,8 +57,11 @@ export const getElementDisplayName = (
5657 node : ReactElement
5758) : string | undefined => {
5859 let displayName ;
60+ const isClassComponent = node instanceof Component ;
5961
60- if ( typeof node . type === 'function' || typeof node . type === 'object' ) {
62+ if ( isClassComponent ) {
63+ displayName = node . constructor . name ;
64+ } else if ( typeof node . type === 'function' || typeof node . type === 'object' ) {
6165 const component = node . type as FunctionComponent ;
6266 displayName = component . displayName ?? component . name ?? undefined ;
6367 }
@@ -92,10 +96,10 @@ export const getEmotionComponentDisplayName = (
9296 : emotionTypeName ?? emotionLabelData ?. displayName ;
9397
9498 // remove internal component underscore markings
95- return replacementName ? replacementName . replace ( '_' , '' ) : displayName ;
99+ return replacementName ?? displayName ;
96100 }
97101
98- return displayName ;
102+ return displayName ? displayName . replace ( '_' , '' ) : displayName ;
99103} ;
100104
101105export const getStoryComponentDisplayName = (
@@ -127,15 +131,18 @@ export const isStoryComponent = (
127131) : boolean => {
128132 if ( ! context ) return false ;
129133
130- const displayName = getEmotionComponentDisplayName ( node ) ?. replace ( / ^ _ / , '' ) ;
134+ const isClassComponent = node instanceof Component ;
135+ const displayName = isClassComponent
136+ ? node . constructor ?. name
137+ : getEmotionComponentDisplayName ( node ) ?. replace ( / ^ _ / , '' ) ;
131138 const isCurrentStory = displayName
132139 ? displayName === context ?. component ?. displayName
133140 : false ;
134141
135142 return isCurrentStory ;
136143} ;
137144
138- const isStoryWrapper = ( node : ReactElement , context : StoryContext ) => {
145+ export const isStoryWrapper = ( node : ReactElement , context : StoryContext ) => {
139146 const displayName = getEmotionComponentDisplayName ( node ) ;
140147 const isStoryWrapper =
141148 ( typeof displayName === 'string' && displayName . startsWith ( 'Story' ) ) ||
@@ -210,9 +217,15 @@ export const getResolvedStoryChild = (
210217 child : ReactElement ,
211218 context : StoryContext
212219) => {
213- return child . type && typeof child . type === 'function'
214- ? ( child . type as ( args : Args ) => ReactElement ) ( context ?. args )
215- : child ;
220+ if ( ! child . type ) return child ;
221+ if ( typeof child . type !== 'function' ) return child ;
222+
223+ const isClassComponent = child . type . prototype instanceof Component ;
224+ const resolvedChild = isClassComponent
225+ ? child
226+ : ( child . type as ( args : Args ) => ReactElement ) ( context ?. args ) ;
227+
228+ return resolvedChild ;
216229} ;
217230
218231/**
@@ -245,9 +258,15 @@ export const getStoryComponent = (
245258 // skip non-ReactElement children
246259 if ( ! isValidElement ( child ) ) continue ;
247260
261+ const displayName = getEmotionComponentDisplayName ( child ) ;
248262 // Story wrappers need to be resolved first to ensure the right data
249263 const resolvedChild = getResolvedStoryChild ( child , context ) ;
250- resolveChildren ( resolvedChild ) ;
264+ const resolvedDisplayName =
265+ getEmotionComponentDisplayName ( resolvedChild ) ;
266+
267+ if ( resolvedDisplayName !== displayName ) {
268+ resolveChildren ( resolvedChild ) ;
269+ }
251270 }
252271 } else if (
253272 // CASE: story wrapper; no children
@@ -260,15 +279,15 @@ export const getStoryComponent = (
260279 const resolvedDisplayName =
261280 getEmotionComponentDisplayName ( resolvedChild ) ;
262281
263- if ( resolvedDisplayName && resolvedDisplayName !== displayName ) {
282+ if ( resolvedDisplayName !== displayName ) {
264283 resolveChildren ( resolvedChild ) ;
265284 }
266285 } else if (
267286 // CASE: single child element
268287 childNode . props ?. children &&
269288 ! Array . isArray ( childNode . props ?. children )
270289 ) {
271- resolveChildren ( childNode . props ? .children ) ;
290+ storyNode = childNode . props . children ;
272291 }
273292 }
274293 } ;
@@ -302,9 +321,11 @@ export const getDefaultPropsfromDocgenInfo = (
302321
303322 if ( ! storyComponent ) return undefined ;
304323
305- let propsInfo = isEmotionComponent ( storyComponent )
306- ? storyComponent . props ?. [ EMOTION_TYPE_KEY ] ?. __docgenInfo . props
307- : storyComponent . type ?. __docgenInfo ?. props ;
324+ let propsInfo =
325+ isEmotionComponent ( storyComponent ) &&
326+ typeof storyComponent . props ?. [ EMOTION_TYPE_KEY ] !== 'string'
327+ ? storyComponent . props ?. [ EMOTION_TYPE_KEY ] ?. __docgenInfo . props
328+ : storyComponent . type ?. __docgenInfo ?. props ;
308329
309330 const args = context . args ;
310331
0 commit comments