@@ -30,30 +30,16 @@ export function Layout({ saveUpdateHook, sendEvent, loadImportSource }) {
3030
3131function Element ( { model } ) {
3232 if ( model . importSource ) {
33- return html `< ${ ImportedElement } model =${ model } /> ` ;
33+ if ( model . importSource . exportsMount ) {
34+ return html `< ${ MountedImportSource } model =${ model } /> ` ;
35+ } else {
36+ return html `< ${ DynamicImportSource } model =${ model } /> ` ;
37+ }
3438 } else {
3539 return html `< ${ StandardElement } model =${ model } /> ` ;
3640 }
3741}
3842
39- function ImportedElement ( { model } ) {
40- const config = react . useContext ( LayoutConfigContext ) ;
41- const mountPoint = react . useRef ( null ) ;
42-
43- react . useEffect ( ( ) => {
44- config
45- . loadImportSource (
46- model . importSource . source ,
47- model . importSource . sourceType
48- )
49- . then ( ( module ) => {
50- mountImportSource ( mountPoint . current , module , model , config ) ;
51- } ) ;
52- } ) ;
53-
54- return html `< div ref =${ mountPoint } / > ` ;
55- }
56-
5743function StandardElement ( { model } ) {
5844 const config = react . useContext ( LayoutConfigContext ) ;
5945 const children = elementChildren ( model ) ;
@@ -65,6 +51,73 @@ function StandardElement({ model }) {
6551 }
6652}
6753
54+ function MountedImportSource ( { model } ) {
55+ const config = react . useContext ( LayoutConfigContext ) ;
56+ const mountPoint = react . useRef ( null ) ;
57+ const fallback = model . importSource . fallback ;
58+
59+ react . useEffect ( ( ) => {
60+ const unmountPromise = loadImportSource ( config , model ) . then ( ( module ) => {
61+ const element = mountPoint . current ;
62+ const component = module [ model . tagName ] ;
63+ const props = elementAttributes ( model , config . sendEvent ) ;
64+ const children = model . children ;
65+
66+ let args ;
67+ if ( ! children ) {
68+ args = [ element , component , props , config ] ;
69+ } else {
70+ args = [ element , component , props , config , children ] ;
71+ }
72+
73+ reactDOM . unmountComponentAtNode ( element ) ;
74+ return module . mount ( ...args ) ;
75+ } ) ;
76+ return ( ) => {
77+ unmountPromise . then ( ( unmount ) => ( unmount ? unmount ( ) : undefined ) ) ;
78+ } ;
79+ } , [ model , mountPoint , config ] ) ;
80+
81+ return createImportSourceFallback ( mountPoint , fallback ) ;
82+ }
83+
84+ function DynamicImportSource ( { model } ) {
85+ const config = react . useContext ( LayoutConfigContext ) ;
86+ const mountPoint = react . useRef ( null ) ;
87+ const fallback = model . importSource . fallback ;
88+
89+ react . useEffect ( ( ) => {
90+ console . log ( elementAttributes ( model , config . sendEvent ) ) ;
91+ loadImportSource ( config , model ) . then ( ( module ) => {
92+ reactDOM . render (
93+ react . createElement (
94+ module [ model . tagName ] ,
95+ elementAttributes ( model , config . sendEvent ) ,
96+ ...elementChildren ( model )
97+ ) ,
98+ mountPoint . current
99+ ) ;
100+ } ) ;
101+ return ( ) => {
102+ reactDOM . unmountComponentAtNode ( mountPoint . current ) ;
103+ } ;
104+ } , [ model , mountPoint ] ) ;
105+
106+ return createImportSourceFallback ( mountPoint , fallback ) ;
107+ }
108+
109+ function createImportSourceFallback ( mountPointRef , fallback ) {
110+ if ( ! fallback ) {
111+ return html `< div ref =${ mountPointRef } / > ` ;
112+ } else if ( typeof fallback == "string" ) {
113+ return html `< div ref =${ mountPointRef } > ${ fallback } </ div > ` ;
114+ } else {
115+ return html `< div ref =${ mountPointRef } >
116+ < ${ StandardElement } model =${ fallback } />
117+ </ div > ` ;
118+ }
119+ }
120+
68121function elementChildren ( model ) {
69122 if ( ! model . children ) {
70123 return [ ] ;
@@ -84,10 +137,9 @@ function elementAttributes(model, sendEvent) {
84137 const attributes = Object . assign ( { } , model . attributes ) ;
85138
86139 if ( model . eventHandlers ) {
87- Object . keys ( model . eventHandlers ) . forEach ( ( eventName ) => {
88- const eventSpec = model . eventHandlers [ eventName ] ;
140+ for ( const [ eventName , eventSpec ] of Object . entries ( model . eventHandlers ) ) {
89141 attributes [ eventName ] = eventHandler ( sendEvent , eventSpec ) ;
90- } ) ;
142+ }
91143 }
92144
93145 return attributes ;
@@ -119,23 +171,11 @@ function eventHandler(sendEvent, eventSpec) {
119171 } ;
120172}
121173
122- function mountImportSource ( element , module , model , config ) {
123- if ( model . importSource . exportsMount ) {
124- const props = elementAttributes ( model , config . sendEvent ) ;
125- if ( model . children ) {
126- props . children = model . children ;
127- }
128- module . mount ( element , module [ model . tagName ] , props ) ;
129- } else {
130- reactDOM . render (
131- react . createElement (
132- module [ model . tagName ] ,
133- elementAttributes ( model , config . sendEvent ) ,
134- ...elementChildren ( model )
135- ) ,
136- element
137- ) ;
138- }
174+ function loadImportSource ( config , model ) {
175+ return config . loadImportSource (
176+ model . importSource . source ,
177+ model . importSource . sourceType
178+ ) ;
139179}
140180
141181function useInplaceJsonPatch ( doc ) {
0 commit comments