11import type { ReactiveController , ReactiveElement } from 'lit' ;
22
3- import { bound } from '../decorators/bound.js' ;
43import { Logger } from './logger.js' ;
54
65interface AnonymousSlot {
@@ -50,52 +49,60 @@ const isSlot =
5049export class SlotController implements ReactiveController {
5150 public static anonymous = Symbol ( 'anonymous slot' ) ;
5251
53- private nodes = new Map < string | typeof SlotController . anonymous , Slot > ( ) ;
52+ # nodes = new Map < string | typeof SlotController . anonymous , Slot > ( ) ;
5453
55- private logger : Logger ;
54+ # logger: Logger ;
5655
57- private firstUpdated = false ;
56+ # firstUpdated = false ;
5857
59- private mo = new MutationObserver ( this . onMutation ) ;
58+ # mo = new MutationObserver ( records => this . # onMutation( records ) ) ;
6059
61- private slotNames : ( string | null ) [ ] ;
60+ # slotNames: ( string | null ) [ ] ;
6261
63- private deprecations : Record < string , string > = { } ;
62+ # deprecations: Record < string , string > = { } ;
6463
6564 constructor ( public host : ReactiveElement , ...config : ( [ SlotsConfig ] | ( string | null ) [ ] ) ) {
66- this . logger = new Logger ( this . host ) ;
65+ this . # logger = new Logger ( this . host ) ;
6766
6867 if ( isObjectConfigSpread ( config ) ) {
6968 const [ { slots, deprecations } ] = config ;
70- this . slotNames = slots ;
71- this . deprecations = deprecations ?? { } ;
69+ this . # slotNames = slots ;
70+ this . # deprecations = deprecations ?? { } ;
7271 } else if ( config . length >= 1 ) {
73- this . slotNames = config ;
74- this . deprecations = { } ;
72+ this . # slotNames = config ;
73+ this . # deprecations = { } ;
7574 } else {
76- this . slotNames = [ null ] ;
75+ this . # slotNames = [ null ] ;
7776 }
7877
7978
8079 host . addController ( this ) ;
8180 }
8281
83- hostConnected ( ) {
84- this . host . addEventListener ( 'slotchange' , this . onSlotChange as EventListener ) ;
85- this . firstUpdated = false ;
86- this . mo . observe ( this . host , { childList : true } ) ;
87- this . init ( ) ;
82+ async hostConnected ( ) {
83+ this . host . addEventListener ( 'slotchange' , this . #onSlotChange as EventListener ) ;
84+ this . #firstUpdated = false ;
85+ this . #mo. observe ( this . host , { childList : true } ) ;
86+ // Map the defined slots into an object that is easier to query
87+ this . #nodes. clear ( ) ;
88+ // Loop over the properties provided by the schema
89+ this . #slotNames. forEach ( this . #initSlot) ;
90+ Object . values ( this . #deprecations) . forEach ( this . #initSlot) ;
91+ this . host . requestUpdate ( ) ;
92+ // insurance for framework integrations
93+ await this . host . updateComplete ;
94+ this . host . requestUpdate ( ) ;
8895 }
8996
9097 hostUpdated ( ) {
91- if ( ! this . firstUpdated ) {
92- this . slotNames . forEach ( this . initSlot ) ;
93- this . firstUpdated = true ;
98+ if ( ! this . # firstUpdated) {
99+ this . # slotNames. forEach ( this . # initSlot) ;
100+ this . # firstUpdated = true ;
94101 }
95102 }
96103
97104 hostDisconnected ( ) {
98- this . mo . disconnect ( ) ;
105+ this . # mo. disconnect ( ) ;
99106 }
100107
101108 /**
@@ -106,11 +113,11 @@ export class SlotController implements ReactiveController {
106113 */
107114 hasSlotted ( ...names : string [ ] ) : boolean {
108115 if ( ! names . length ) {
109- this . logger . warn ( `Please provide at least one slot name for which to search.` ) ;
116+ this . # logger. warn ( `Please provide at least one slot name for which to search.` ) ;
110117 return false ;
111118 } else {
112119 return names . some ( x =>
113- this . nodes . get ( x ) ?. hasContent ?? false ) ;
120+ this . # nodes. get ( x ) ?. hasContent ?? false ) ;
114121 }
115122 }
116123
@@ -135,57 +142,44 @@ export class SlotController implements ReactiveController {
135142 */
136143 getSlotted < T extends Element = Element > ( ...slotNames : string [ ] ) : T [ ] {
137144 if ( ! slotNames . length ) {
138- return ( this . nodes . get ( SlotController . anonymous ) ?. elements ?? [ ] ) as T [ ] ;
145+ return ( this . # nodes. get ( SlotController . anonymous ) ?. elements ?? [ ] ) as T [ ] ;
139146 } else {
140147 return slotNames . flatMap ( slotName =>
141- this . nodes . get ( slotName ) ?. elements ?? [ ] ) as T [ ] ;
148+ this . # nodes. get ( slotName ) ?. elements ?? [ ] ) as T [ ] ;
142149 }
143150 }
144151
145- @ bound private onSlotChange ( event : Event & { target : HTMLSlotElement } ) {
152+ #onSlotChange = ( event : Event & { target : HTMLSlotElement } ) => {
146153 const slotName = event . target . name ;
147- this . initSlot ( slotName ) ;
154+ this . # initSlot( slotName ) ;
148155 this . host . requestUpdate ( ) ;
149- }
156+ } ;
150157
151- @ bound private async onMutation ( records : MutationRecord [ ] ) {
158+ #onMutation = async ( records : MutationRecord [ ] ) => {
152159 const changed = [ ] ;
153160 for ( const { addedNodes, removedNodes } of records ) {
154161 for ( const node of [ ...addedNodes , ...removedNodes ] ) {
155162 if ( node instanceof HTMLElement && node . slot ) {
156- this . initSlot ( node . slot ) ;
163+ this . # initSlot( node . slot ) ;
157164 changed . push ( node . slot ) ;
158165 }
159166 }
160167 }
161- if ( changed . length ) {
162- this . host . requestUpdate ( ) ;
163- }
164- }
168+ this . host . requestUpdate ( ) ;
169+ } ;
165170
166- private getChildrenForSlot < T extends Element = Element > ( name : string | typeof SlotController . anonymous ) : T [ ] {
171+ # getChildrenForSlot< T extends Element = Element > ( name : string | typeof SlotController . anonymous ) : T [ ] {
167172 const children = Array . from ( this . host . children ) as T [ ] ;
168173 return children . filter ( isSlot ( name ) ) ;
169174 }
170175
171- @ bound private initSlot ( slotName : string | null ) {
176+ #initSlot = ( slotName : string | null ) => {
172177 const name = slotName || SlotController . anonymous ;
173- const elements = this . nodes . get ( name ) ?. slot ?. assignedElements ?.( ) ?? this . getChildrenForSlot ( name ) ;
178+ const elements = this . # nodes. get ( name ) ?. slot ?. assignedElements ?.( ) ?? this . # getChildrenForSlot( name ) ;
174179 const selector = slotName ? `slot[name="${ slotName } "]` : 'slot:not([name])' ;
175180 const slot = this . host . shadowRoot ?. querySelector ?.< HTMLSlotElement > ( selector ) ?? null ;
176181 const hasContent = ! ! elements . length ;
177- this . nodes . set ( name , { elements, name : slotName ?? '' , hasContent, slot } ) ;
178- this . logger . log ( slotName , hasContent ) ;
179- }
180-
181- /**
182- * Maps the defined slots into an object that is easier to query
183- */
184- @bound private init ( ) {
185- this . nodes . clear ( ) ;
186- // Loop over the properties provided by the schema
187- this . slotNames . forEach ( this . initSlot ) ;
188- Object . values ( this . deprecations ) . forEach ( this . initSlot ) ;
189- this . host . requestUpdate ( ) ;
190- }
182+ this . #nodes. set ( name , { elements, name : slotName ?? '' , hasContent, slot } ) ;
183+ this . #logger. log ( slotName , hasContent ) ;
184+ } ;
191185}
0 commit comments