@@ -64,7 +64,6 @@ export const AvatarGroupMixin = (superClass) =>
6464 */
6565 items : {
6666 type : Array ,
67- observer : '__itemsChanged' ,
6867 sync : true ,
6968 } ,
7069
@@ -79,37 +78,21 @@ export const AvatarGroupMixin = (superClass) =>
7978 sync : true ,
8079 } ,
8180
82- /** @private */
83- _avatars : {
84- type : Array ,
85- value : ( ) => [ ] ,
86- sync : true ,
87- } ,
88-
8981 /** @private */
9082 __itemsInView : {
9183 type : Number ,
9284 value : null ,
9385 sync : true ,
9486 } ,
9587
96- /** @private */
97- _overflow : {
98- type : Object ,
99- sync : true ,
100- } ,
101-
10288 /** @private */
10389 _overflowItems : {
10490 type : Array ,
105- observer : '__overflowItemsChanged' ,
106- computed : '__computeOverflowItems(items, __itemsInView, maxItemsVisible)' ,
10791 } ,
10892
10993 /** @private */
110- _overflowTooltip : {
111- type : Object ,
112- sync : true ,
94+ _overflowLimit : {
95+ type : Number ,
11396 } ,
11497
11598 /** @private */
@@ -120,17 +103,6 @@ export const AvatarGroupMixin = (superClass) =>
120103 } ;
121104 }
122105
123- static get observers ( ) {
124- return [
125- '__i18nItemsChanged(__effectiveI18n, items)' ,
126- '__openedChanged(_opened, _overflow)' ,
127- '__updateAvatarsTheme(_overflow, _avatars, _theme)' ,
128- '__updateAvatars(items, __itemsInView, maxItemsVisible, _overflow, __effectiveI18n)' ,
129- '__updateOverflowAvatar(_overflow, items, __itemsInView, maxItemsVisible)' ,
130- '__updateOverflowTooltip(_overflowTooltip, items, __itemsInView, maxItemsVisible)' ,
131- ] ;
132- }
133-
134106 /**
135107 * The object used to localize this component. To change the default
136108 * localization, replace this with an object that provides all properties, or
@@ -167,6 +139,11 @@ export const AvatarGroupMixin = (superClass) =>
167139 super . i18n = value ;
168140 }
169141
142+ /** @protected */
143+ get _avatars ( ) {
144+ return [ ...this . children ] . filter ( ( node ) => node . localName === 'vaadin-avatar' ) ;
145+ }
146+
170147 constructor ( ) {
171148 super ( ) ;
172149
@@ -205,6 +182,58 @@ export const AvatarGroupMixin = (superClass) =>
205182 this . _opened = false ;
206183 }
207184
185+ /** @protected */
186+ willUpdate ( props ) {
187+ super . willUpdate ( props ) ;
188+
189+ if ( props . has ( 'items' ) || props . has ( '__itemsInView' ) || props . has ( 'maxItemsVisible' ) ) {
190+ // Calculate overflow limit only once to reuse it in updated() observers
191+ const count = Array . isArray ( this . items ) ? this . items . length : 0 ;
192+ const limit = this . __getLimit ( count , this . __itemsInView , this . maxItemsVisible ) ;
193+ this . _overflowLimit = limit ;
194+ this . _overflowItems = limit ? this . items . slice ( limit ) : [ ] ;
195+ }
196+ }
197+
198+ /** @protected */
199+ updated ( props ) {
200+ super . updated ( props ) ;
201+
202+ if ( props . has ( 'items' ) ) {
203+ this . __itemsChanged ( this . items , props . get ( 'items' ) ) ;
204+ }
205+
206+ if ( props . has ( 'items' ) || props . has ( '_overflowLimit' ) || props . has ( '__effectiveI18n' ) || props . has ( '_theme' ) ) {
207+ const limit = this . _overflowLimit ;
208+ this . __renderAvatars ( limit ? this . items . slice ( 0 , limit ) : this . items || [ ] ) ;
209+ }
210+
211+ if ( props . has ( 'items' ) || props . has ( '_overflowLimit' ) ) {
212+ this . __updateOverflowTooltip ( this . items , this . _overflowLimit ) ;
213+ this . __updateOverflowAvatar ( this . items , this . _overflowLimit , this . __itemsInView ) ;
214+ }
215+
216+ if ( props . has ( '__effectiveI18n' ) || props . has ( 'items' ) ) {
217+ this . __i18nItemsChanged ( this . __effectiveI18n , this . items ) ;
218+ }
219+
220+ if ( props . has ( '_opened' ) ) {
221+ this . __openedChanged ( this . _opened , props . get ( '_opened' ) ) ;
222+ }
223+
224+ if ( props . has ( '_theme' ) ) {
225+ if ( this . _theme ) {
226+ this . _overflow . setAttribute ( 'theme' , this . _theme ) ;
227+ } else {
228+ this . _overflow . removeAttribute ( 'theme' ) ;
229+ }
230+ }
231+
232+ if ( props . has ( '_overflowItems' ) ) {
233+ this . __overflowItemsChanged ( this . _overflowItems , props . get ( '_overflowItems' ) ) ;
234+ }
235+ }
236+
208237 /** @private */
209238 __getMessage ( user , action ) {
210239 return action . replace ( '{user}' , user . name || user . abbr || this . __effectiveI18n . anonymous ) ;
@@ -305,6 +334,7 @@ export const AvatarGroupMixin = (superClass) =>
305334 .img ="${ item . img } "
306335 .colorIndex ="${ item . colorIndex } "
307336 .i18n ="${ this . __effectiveI18n } "
337+ theme ="${ ifDefined ( this . _theme ) } "
308338 class ="${ ifDefined ( item . className ) } "
309339 with-tooltip
310340 > </ vaadin-avatar >
@@ -317,58 +347,25 @@ export const AvatarGroupMixin = (superClass) =>
317347 }
318348
319349 /** @private */
320- __updateAvatars ( items , itemsInView , maxItemsVisible , overflow ) {
321- if ( ! overflow || ! Array . isArray ( items ) ) {
322- return ;
323- }
324-
325- const limit = this . __getLimit ( items . length , itemsInView , maxItemsVisible ) ;
326-
327- this . __renderAvatars ( limit ? items . slice ( 0 , limit ) : items ) ;
328-
329- this . _avatars = [ ...this . querySelectorAll ( 'vaadin-avatar' ) ] ;
330- }
331-
332- /** @private */
333- __computeOverflowItems ( items , itemsInView , maxItemsVisible ) {
334- const count = Array . isArray ( items ) ? items . length : 0 ;
335- const limit = this . __getLimit ( count , itemsInView , maxItemsVisible ) ;
336- return limit ? items . slice ( limit ) : [ ] ;
337- }
338-
339- /** @private */
340- __updateOverflowAvatar ( overflow , items , itemsInView , maxItemsVisible ) {
350+ __updateOverflowAvatar ( items , limit , itemsInView ) {
351+ const overflow = this . _overflow ;
341352 if ( overflow ) {
342353 const count = Array . isArray ( items ) ? items . length : 0 ;
343- const maxReached = maxItemsVisible != null && count > this . __getMax ( maxItemsVisible ) ;
354+ const maxReached = this . maxItemsVisible != null && count > this . __getMax ( this . maxItemsVisible ) ;
344355
345- overflow . abbr = `+${ count - this . __getLimit ( count , itemsInView , maxItemsVisible ) } ` ;
356+ overflow . abbr = `+${ count - limit } ` ;
346357 const hasOverflow = maxReached || ( itemsInView && itemsInView < count ) ;
347358 overflow . toggleAttribute ( 'hidden' , ! hasOverflow ) ;
348359 this . toggleAttribute ( 'has-overflow' , hasOverflow ) ;
349360 }
350361 }
351362
352363 /** @private */
353- __updateAvatarsTheme ( overflow , avatars , theme ) {
354- if ( overflow ) {
355- [ overflow , ...avatars ] . forEach ( ( avatar ) => {
356- if ( theme ) {
357- avatar . setAttribute ( 'theme' , theme ) ;
358- } else {
359- avatar . removeAttribute ( 'theme' ) ;
360- }
361- } ) ;
362- }
363- }
364-
365- /** @private */
366- __updateOverflowTooltip ( tooltip , items , itemsInView , maxItemsVisible ) {
367- if ( ! tooltip || ! Array . isArray ( items ) ) {
364+ __updateOverflowTooltip ( items , limit ) {
365+ if ( ! Array . isArray ( items ) ) {
368366 return ;
369367 }
370368
371- const limit = this . __getLimit ( items . length , itemsInView , maxItemsVisible ) ;
372369 if ( limit == null ) {
373370 return ;
374371 }
@@ -381,7 +378,7 @@ export const AvatarGroupMixin = (superClass) =>
381378 }
382379 }
383380
384- tooltip . text = result . join ( '\n' ) ;
381+ this . _overflowTooltip . text = result . join ( '\n' ) ;
385382 }
386383
387384 /** @private */
@@ -450,34 +447,25 @@ export const AvatarGroupMixin = (superClass) =>
450447 if ( effectiveI18n . activeUsers [ field ] ) {
451448 this . setAttribute ( 'aria-label' , effectiveI18n . activeUsers [ field ] . replace ( '{count}' , count || 0 ) ) ;
452449 }
453-
454- this . _avatars . forEach ( ( avatar ) => {
455- avatar . i18n = effectiveI18n ;
456- } ) ;
457450 }
458451 }
459452
460453 /** @private */
461- __openedChanged ( opened , overflow ) {
462- if ( ! overflow ) {
463- return ;
464- }
465-
454+ __openedChanged ( opened , oldOpened ) {
466455 if ( opened ) {
467456 if ( ! this . _menuElement ) {
468457 this . _menuElement = this . $ . overlay . querySelector ( 'vaadin-avatar-group-menu' ) ;
469458 }
470459
471- this . _openedWithFocusRing = overflow . hasAttribute ( 'focus-ring' ) ;
472- } else if ( this . __oldOpened ) {
473- overflow . focus ( ) ;
460+ this . _openedWithFocusRing = this . _overflow . hasAttribute ( 'focus-ring' ) ;
461+ } else if ( oldOpened ) {
462+ this . _overflow . focus ( ) ;
474463 if ( this . _openedWithFocusRing ) {
475- overflow . setAttribute ( 'focus-ring' , '' ) ;
464+ this . _overflow . setAttribute ( 'focus-ring' , '' ) ;
476465 }
477466 }
478467
479- overflow . setAttribute ( 'aria-expanded' , opened === true ) ;
480- this . __oldOpened = opened ;
468+ this . _overflow . setAttribute ( 'aria-expanded' , opened === true ) ;
481469 }
482470
483471 /** @private */
0 commit comments