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