/**
 * Copyright (c) 2018 Dell Inc., or its subsidiaries. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */ import * as React from "react" ; import { classNames } from "../utils" ; import { ClassNames } from "./ClassNames" ; import { Icon , Direction } from "../icon" ; param { style } css param { className } css param { accordionMultiPanel } if param { dataqa } quality param { titleClassName } css type AccordionProps = { style ? : any ; className ? : string ; content : accordionContent [ ] ; accordionMultiPanel ? : boolean ; dataqa ? : string ; titleClassName ? : string ; } ; type accordionContent = { title : React . ReactNode ; itemComponent : React . ReactNode ; isOpen ? : boolean ; } ; type AccordionState = { panelItems : any ; } ; export class Accordion extends React . Component < AccordionProps , AccordionState > { state : AccordionState = { panelItems : [ ] , } ; componentDidMount ( ) { this . getAccordionContent ( ) ; } componentDidUpdate ( prevProps ) { const { content } = this . props ; if ( content && content != prevProps . content ) { this . getAccordionContent ( ) ; } } handleButtonClick = ( clickedItemIndex , accordionMultiPanel ? ) => { let { panelItems } = this . state ; panelItems . forEach ( ( item , index ) => { if ( accordionMultiPanel ) { if ( index === clickedItemIndex ) { item . isOpen = ! item . isOpen ; item . content = this . getItemContent ( index , item . title , item . isOpen ) ; } } else { if ( index === clickedItemIndex ) { item . isOpen = ! item . isOpen ; item . content = this . getItemContent ( index , item . title , item . isOpen ) ; } else { item . isOpen = false ; item . content = this . getItemContent ( index , item . title , item . isOpen ) ; } } } ) ; this . setState ( { panelItems , } ) ; } ; private accordionPanel ( ) { return ( < div > { this . state . panelItems . map ( ( content , index ) => { return ( < div className = { classNames ( [ ClassNames . ACCORDION_PANEL ] ) } key = { "accordionPanel_" + index } > { content . content } { content . isOpen && content . isOpen === true ? ( this . accordionContent ( content ) ) : ( < div className = { classNames ( [ ClassNames . ACCORDION_COLLAPSED_CONTENT ] ) } aria - hidden = "true" / > ) } < /div>); } ) } < /div>); } private accordionContent ( content ) { return ( < div className = { ClassNames . ACCORDION_COLLAPSED_CONTENT } aria - hidden = "false" > < div className = { ClassNames . ACCORDION_TOGGLE_CONTENT } style = { { display : "block" } } > < div className = { ClassNames . ACCORDION_INNER_CONTENT } > < div className = { ClassNames . ACCORDION_COMPONENT } > { content . component } < /div> < /div> < /div> < /div>); } getItemContent = ( index , title , isOpen ) => { const { accordionMultiPanel , titleClassName } = this . props ; const panelClass = classNames ( [ ClassNames . ACCORDION_PANEL_INNER , isOpen && ClassNames . ACCORDION_PANEL_OPEN ] ) ; return ( < div role = "group" className = { panelClass } key = { index } > < div className = { ClassNames . ACCORDION_HEADER } > < button className = { ClassNames . ACCORDION_HEADER_BUTTON } type = "button" aria - disabled = "false" aria - controls = "clr-accordion-content" aria - expanded = { isOpen } onClick = { ( ) => this . handleButtonClick ( index , accordionMultiPanel ) } > < span className = { ClassNames . ACCORDION_SR } /> < span className = { ClassNames . ACCORDION_STATUS } > < Icon className = { ClassNames . ACCORDION_ANGLE } dir = { Direction . RIGHT } shape = "angle" / > < span className = { ClassNames . ACCORDION_NUMBER } /> < /span> < div className = { classNames ( [ ClassNames . ACCORDION_TITLE , titleClassName ] ) } > { title } < /div> < /button> < /div> < /div>); } ; getPanelContent = ( index , contentItem , isOpen ? ) => { return { content : this . getItemContent ( index , contentItem . title , contentItem . isOpen ) , isOpen : isOpen , title : contentItem . title , component : contentItem . itemComponent , } ; } ; getAccordionContent = ( ) => { const { content , accordionMultiPanel } = this . props ; let isAnyPanelOpened = false ; const panelContent = content . map ( ( contentItem , index ) => { if ( accordionMultiPanel ) { return this . getPanelContent ( index , contentItem , contentItem . isOpen ) ; } else { if ( ! isAnyPanelOpened ) { if ( contentItem . isOpen ) { isAnyPanelOpened = true ; return this . getPanelContent ( index , contentItem , contentItem . isOpen ) ; } else { return this . getPanelContent ( index , contentItem , false ) ; } } else { return this . getPanelContent ( index , contentItem , false ) ; } } } ) ; this . setState ( { panelItems : panelContent } ) ; } ; render ( ) { const { className , style , dataqa } = this . props ; return ( < div className = { classNames ( [ ClassNames . ACCORDION , className , ] ) } style = { style } data - qa = { dataqa } > { this . accordionPanel ( ) } < /div>); } }