11import  clsx  from  'clsx' ; 
2- import  React ,  {  useContext ,  useState  }  from  'react' ; 
2+ import  React ,  {  useContext ,  useMemo ,   useCallback  }  from  'react' ; 
33import  {  AccordionContext  }  from  '../AccordionContext' ; 
44import  type  {  AccordionItemProps  }  from  './types' ; 
55import  MDBCollapse  from  '../../Collapse/Collapse' ; 
@@ -21,26 +21,42 @@ const MDBAccordionItem: React.FC<AccordionItemProps> = React.forwardRef<HTMLAllC
2121    } , 
2222    ref 
2323  )  =>  { 
24-     const  {  activeItem,  setActiveItem,  alwaysOpen,  initialActive  }  =  useContext ( AccordionContext ) ; 
24+     const  {  activeItem,  setActiveItem,  alwaysOpen,  onChange  }  =  useContext ( AccordionContext ) ; 
2525
26-     const  [ openState ,  setOpenState ]  =  useState ( initialActive ) ; 
26+     const  isCollapsed : boolean  =  useMemo ( ( )  =>  { 
27+       const  isArray  =  Array . isArray ( activeItem ) ; 
28+       if  ( isArray )  { 
29+         return  activeItem . includes ( collapseId ) ; 
30+       } 
31+       return  activeItem  ===  collapseId ; 
32+     } ,  [ activeItem ,  collapseId ] ) ; 
2733
2834    const  classes  =  clsx ( 'accordion-item' ,  className ) ; 
2935    const  headerClasses  =  clsx ( 'accordion-header' ,  headerClassName ) ; 
3036    const  bodyClasses  =  clsx ( 'accordion-body' ,  bodyClassName ) ; 
31-     const  buttonClasses  =  clsx ( 
32-       'accordion-button' , 
33-       alwaysOpen  ? collapseId  !==  openState  &&  'collapsed'  : collapseId  !==  activeItem  &&  'collapsed' , 
34-       btnClassName 
35-     ) ; 
37+     const  buttonClasses  =  clsx ( 'accordion-button' ,  ! isCollapsed  &&  'collapsed' ,  btnClassName ) ; 
3638
37-     const  toggleAccordion  =  ( value : number )  =>  { 
38-       if  ( alwaysOpen )  { 
39-         value  !==  openState  ? setOpenState ( value )  : setOpenState ( 0 ) ; 
40-       }  else  { 
41-         value  !==  activeItem  ? setActiveItem ( value )  : setActiveItem ( 0 ) ; 
42-       } 
43-     } ; 
39+     const  toggleAccordion  =  useCallback ( 
40+       ( itemId : number )  =>  { 
41+         let  newValue : number  |  number [ ]  =  itemId ; 
42+         const  isArray  =  Array . isArray ( activeItem ) ; 
43+ 
44+         if  ( isArray )  { 
45+           activeItem . includes ( itemId ) 
46+             ? ( newValue  =  activeItem . filter ( ( item )  =>  item  !==  itemId ) ) 
47+             : ( newValue  =  alwaysOpen  ? [ ...activeItem ,  itemId ]  : [ itemId ] ) ; 
48+         }  else  { 
49+           newValue  =  activeItem  ===  itemId  ? 0  : itemId ; 
50+ 
51+           // if alwaysOpen is true, we must convert newValue to array 
52+           alwaysOpen  &&  ( newValue  =  [ newValue ] ) ; 
53+         } 
54+ 
55+         onChange ?.( newValue ) ; 
56+         setActiveItem ( newValue ) ; 
57+       } , 
58+       [ onChange ,  activeItem ,  setActiveItem ,  alwaysOpen ] 
59+     ) ; 
4460
4561    return  ( 
4662      < Tag  className = { classes }  ref = { ref }  { ...props } > 
@@ -49,10 +65,7 @@ const MDBAccordionItem: React.FC<AccordionItemProps> = React.forwardRef<HTMLAllC
4965            { headerTitle } 
5066          </ button > 
5167        </ h2 > 
52-         < MDBCollapse 
53-           id = { collapseId . toString ( ) } 
54-           show = { alwaysOpen  ? openState  ===  collapseId  : activeItem  ===  collapseId } 
55-         > 
68+         < MDBCollapse  id = { collapseId . toString ( ) }  show = { isCollapsed } > 
5669          < div  className = { bodyClasses }  style = { bodyStyle } > 
5770            { children } 
5871          </ div > 
0 commit comments