@@ -78,15 +78,16 @@ function createImportSourceElement(props: {
78
78
stringifyImportSource ( props . model . importSource ) ,
79
79
) ;
80
80
return null ;
81
- } else if ( ! props . module [ props . model . tagName ] ) {
82
- log . error (
83
- "Module from source " +
84
- stringifyImportSource ( props . currentImportSource ) +
85
- ` does not export ${ props . model . tagName } ` ,
86
- ) ;
87
- return null ;
88
81
} else {
89
- type = props . module [ props . model . tagName ] ;
82
+ type = getComponentFromModule (
83
+ props . module ,
84
+ props . model . tagName ,
85
+ props . model . importSource ,
86
+ ) ;
87
+ if ( ! type ) {
88
+ // Error message logged within getComponentFromModule
89
+ return null ;
90
+ }
90
91
}
91
92
} else {
92
93
type = props . model . tagName ;
@@ -103,6 +104,42 @@ function createImportSourceElement(props: {
103
104
) ;
104
105
}
105
106
107
+ function getComponentFromModule (
108
+ module : ReactPyModule ,
109
+ componentName : string ,
110
+ importSource : ReactPyVdomImportSource ,
111
+ ) : any {
112
+ /* Gets the component with the provided name from the provided module.
113
+
114
+ Built specifically to work on inifinitely deep nested components.
115
+ For example, component "My.Nested.Component" is accessed from
116
+ ModuleA like so: ModuleA["My"]["Nested"]["Component"].
117
+ */
118
+ const componentParts : string [ ] = componentName . split ( "." ) ;
119
+ let Component : any = null ;
120
+ for ( let i = 0 ; i < componentParts . length ; i ++ ) {
121
+ const iterAttr = componentParts [ i ] ;
122
+ Component = i == 0 ? module [ iterAttr ] : Component [ iterAttr ] ;
123
+ if ( ! Component ) {
124
+ if ( i == 0 ) {
125
+ log . error (
126
+ "Module from source " +
127
+ stringifyImportSource ( importSource ) +
128
+ ` does not export ${ iterAttr } ` ,
129
+ ) ;
130
+ } else {
131
+ console . error (
132
+ `Component ${ componentParts . slice ( 0 , i ) . join ( "." ) } from source ` +
133
+ stringifyImportSource ( importSource ) +
134
+ ` does not have subcomponent ${ iterAttr } ` ,
135
+ ) ;
136
+ }
137
+ break ;
138
+ }
139
+ }
140
+ return Component ;
141
+ }
142
+
106
143
function isImportSourceEqual (
107
144
source1 : ReactPyVdomImportSource ,
108
145
source2 : ReactPyVdomImportSource ,
0 commit comments