1- import { Observable } from '@microsoft/fast-element' ;
2- import { attr , FASTElement , observable } from '@microsoft/fast-element' ;
1+ import { attr , FASTElement , Observable , observable , Updates } from '@microsoft/fast-element' ;
32import { BaseAccordionItem } from '../accordion-item/accordion-item.base.js' ;
3+ import { waitForConnectedDescendants } from '../utils/request-idle-callback.js' ;
4+ import { isAccordionItem } from '../accordion-item/accordion-item.options.js' ;
45import { AccordionExpandMode } from './accordion.options.js' ;
56
67/**
@@ -24,8 +25,8 @@ export class Accordion extends FASTElement {
2425 * HTML attribute: expand-mode
2526 */
2627 @attr ( { attribute : 'expand-mode' } )
27- public expandmode : AccordionExpandMode = AccordionExpandMode . multi ;
28- public expandmodeChanged ( prev : AccordionExpandMode , next : AccordionExpandMode ) {
28+ public expandmode ! : AccordionExpandMode ;
29+ public expandmodeChanged ( prev : AccordionExpandMode | undefined , next : AccordionExpandMode ) {
2930 if ( ! this . $fastController . isConnected ) {
3031 return ;
3132 }
@@ -88,14 +89,13 @@ export class Accordion extends FASTElement {
8889 * @returns {void }
8990 */
9091 private findExpandedItem ( ) : BaseAccordionItem | Element | null {
91- if ( this . accordionItems . length === 0 ) {
92+ if ( ! this . accordionItems || this . accordionItems ? .length === 0 ) {
9293 return null ;
9394 }
9495
9596 return (
96- this . accordionItems . find (
97- ( item : Element | BaseAccordionItem ) => item instanceof BaseAccordionItem && item . expanded ,
98- ) ?? this . accordionItems [ 0 ]
97+ this . accordionItems . find ( ( item : Element | BaseAccordionItem ) => isAccordionItem ( item ) && item . expanded ) ??
98+ this . accordionItems [ 0 ]
9999 ) ;
100100 }
101101
@@ -105,29 +105,31 @@ export class Accordion extends FASTElement {
105105 * @returns {void }
106106 */
107107 private setItems = ( ) : void => {
108- if ( this . slottedAccordionItems . length === 0 ) {
109- return ;
110- }
108+ waitForConnectedDescendants ( this , ( ) => {
109+ if ( this . slottedAccordionItems . length === 0 ) {
110+ return ;
111+ }
111112
112- // Get all existing children and remove event listeners
113- const children : Element [ ] = Array . from ( this . children ) ;
114- this . removeItemListeners ( children ) ;
113+ // Get all existing children and remove event listeners
114+ const children : Element [ ] = Array . from ( this . children ) ;
115+ this . removeItemListeners ( children ) ;
115116
116- // Resubscribe to the `disabled` attribute of all children
117- children . forEach ( ( child : Element ) => Observable . getNotifier ( child ) . subscribe ( this , 'disabled' ) ) ;
117+ // Resubscribe to the `disabled` attribute of all children
118+ children . forEach ( ( child : Element ) => Observable . getNotifier ( child ) . subscribe ( this , 'disabled' ) ) ;
118119
119- // Add event listeners to each non-disabled AccordionItem
120- this . accordionItems = children . filter ( child => ! child . hasAttribute ( 'disabled' ) ) ;
121- this . accordionItems . forEach ( ( item : Element , index : number ) => {
122- item . addEventListener ( 'click' , this . expandedChangedHandler ) ;
123- // Subscribe to the expanded attribute of the item
124- Observable . getNotifier ( item ) . subscribe ( this , 'expanded' ) ;
125- } ) ;
120+ // Add event listeners to each non-disabled AccordionItem
121+ this . accordionItems = children . filter ( child => ! child . hasAttribute ( 'disabled' ) ) ;
122+ this . accordionItems . forEach ( ( item : Element , index : number ) => {
123+ item . addEventListener ( 'click' , this . expandedChangedHandler ) ;
124+ // Subscribe to the expanded attribute of the item
125+ Observable . getNotifier ( item ) . subscribe ( this , 'expanded' ) ;
126+ } ) ;
126127
127- if ( this . isSingleExpandMode ( ) ) {
128- const expandedItem = this . findExpandedItem ( ) as BaseAccordionItem ;
129- this . setSingleExpandMode ( expandedItem ) ;
130- }
128+ if ( this . isSingleExpandMode ( ) ) {
129+ const expandedItem = this . findExpandedItem ( ) as BaseAccordionItem ;
130+ this . setSingleExpandMode ( expandedItem ) ;
131+ }
132+ } ) ;
131133 } ;
132134
133135 /**
@@ -144,25 +146,27 @@ export class Accordion extends FASTElement {
144146 * @returns {void }
145147 */
146148 private setSingleExpandMode ( expandedItem : Element ) : void {
147- if ( this . accordionItems . length === 0 ) {
148- return ;
149- }
150- const currentItems = Array . from ( this . accordionItems ) ;
151- this . activeItemIndex = currentItems . indexOf ( expandedItem ) ;
152-
153- currentItems . forEach ( ( item : Element , index : number ) => {
154- if ( item instanceof BaseAccordionItem ) {
155- if ( this . activeItemIndex === index ) {
156- item . expanded = true ;
157- item . expandbutton . setAttribute ( 'aria-disabled' , 'true' ) ;
158- } else {
159- item . expanded = false ;
160-
161- if ( ! item . hasAttribute ( 'disabled' ) ) {
162- item . expandbutton . removeAttribute ( 'aria-disabled' ) ;
149+ requestAnimationFrame ( ( ) => {
150+ if ( this . accordionItems . length === 0 ) {
151+ return ;
152+ }
153+ const currentItems = Array . from ( this . accordionItems ) ;
154+ this . activeItemIndex = currentItems . indexOf ( expandedItem ) ;
155+
156+ currentItems . forEach ( ( item : Element , index : number ) => {
157+ if ( isAccordionItem ( item ) ) {
158+ if ( this . activeItemIndex === index ) {
159+ item . expanded = true ;
160+ item . expandbutton . setAttribute ( 'aria-disabled' , 'true' ) ;
161+ } else {
162+ item . expanded = false ;
163+
164+ if ( ! item . hasAttribute ( 'disabled' ) ) {
165+ item . expandbutton . removeAttribute ( 'aria-disabled' ) ;
166+ }
163167 }
164168 }
165- }
169+ } ) ;
166170 } ) ;
167171 }
168172
@@ -186,7 +190,7 @@ export class Accordion extends FASTElement {
186190 private expandedChangedHandler : EventListener = ( evt : Event ) : void => {
187191 const item = evt . target as HTMLElement ;
188192
189- if ( item instanceof BaseAccordionItem ) {
193+ if ( isAccordionItem ( item ) ) {
190194 if ( ! this . isSingleExpandMode ( ) ) {
191195 item . expanded = ! item . expanded ;
192196 // setSingleExpandMode sets activeItemIndex on its own
@@ -198,4 +202,13 @@ export class Accordion extends FASTElement {
198202 this . $emit ( 'change' ) ;
199203 }
200204 } ;
205+
206+ connectedCallback ( ) : void {
207+ super . connectedCallback ( ) ;
208+
209+ requestAnimationFrame ( ( ) => {
210+ this . expandmode = this . expandmode || AccordionExpandMode . multi ;
211+ this . setItems ( ) ;
212+ } ) ;
213+ }
201214}
0 commit comments