@@ -5,17 +5,33 @@ import { COMPONENT_FLAG, DIRECTIVE_PREFIX } from '@models/generics';
5
5
// This is generally used for browser builds only, but it can be accessed in bundling environments
6
6
const init = ( element : HTMLElement | Document = document ) : void => {
7
7
const stateDirective = `${ DIRECTIVE_PREFIX } state` ;
8
- const componentElements = element . querySelectorAll ( `[${ stateDirective } ]` ) ;
8
+ const tagDirective = `${ DIRECTIVE_PREFIX } tag` ;
9
+ const componentElements = element . querySelectorAll ( `[${ stateDirective } ], [${ tagDirective } ]` ) ;
9
10
const uninitializedComponents = [ ...componentElements ] . filter (
10
11
( el ) => ( el as HTMLElement ) [ COMPONENT_FLAG ] === undefined
11
12
) ;
13
+ let needsReInit = false ;
12
14
13
15
uninitializedComponents . forEach ( ( uninitializedComponent ) => {
14
- const stateExpression = uninitializedComponent . getAttribute ( stateDirective ) ;
15
- const state = new Function ( `return ${ stateExpression } ` ) ( ) || { } ;
16
- const currentComponent = component ( state ) ;
17
- currentComponent . mount ( uninitializedComponent as HTMLElement ) ;
16
+ if ( uninitializedComponent . hasAttribute ( tagDirective ) ) {
17
+ const tag = uninitializedComponent . getAttribute ( tagDirective ) ! ;
18
+ const customComponents = [ ...element . querySelectorAll ( tag ) ] ;
19
+ // @ts -expect-error: this is a template element
20
+ const realElement = uninitializedComponent . content . firstElementChild ;
21
+ customComponents . forEach ( ( customComponent ) => {
22
+ customComponent . replaceWith ( realElement . cloneNode ( true ) ) ;
23
+ } ) ;
24
+ if ( customComponents . length > 0 ) needsReInit = true ;
25
+ } else {
26
+ const stateExpression = uninitializedComponent . getAttribute ( stateDirective ) ;
27
+ const state = new Function ( `return ${ stateExpression } ` ) ( ) || { } ;
28
+ const currentComponent = component ( state ) ;
29
+
30
+ currentComponent . mount ( uninitializedComponent as HTMLElement ) ;
31
+ }
18
32
} ) ;
33
+
34
+ if ( needsReInit ) init ( element ) ;
19
35
} ;
20
36
21
37
export { init , component } ;
0 commit comments