/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at . */ // @flow import React, { cloneElement, Component } from "react"; import AccessibleImage from "./AccessibleImage"; import "./Accordion.css"; type AccordionItem = { buttons?: Array, component: React$Element, componentProps: Object, header: string, className: string, opened: boolean, onToggle?: () => void, shouldOpen?: () => void }; type Props = { items: Array }; type State = { opened: boolean[], created: boolean[] }; class Accordion extends Component { constructor(props: Props) { super(props); this.state = { opened: props.items.map(item => item.opened), created: [] }; } handleHeaderClick(i: number) { const item = this.props.items[i]; const opened = !item.opened; item.opened = opened; if (item.onToggle) { item.onToggle(opened); } // We force an update because otherwise the accordion // would not re-render this.forceUpdate(); } onHandleHeaderKeyDown( e: SyntheticKeyboardEvent, i: number ) { if (e && (e.key === " " || e.key === "Enter")) { this.handleHeaderClick(i); } } renderContainer = (item: AccordionItem, i: number) => { const { opened } = item; return (
  • this.onHandleHeaderKeyDown(e, i)} onClick={() => this.handleHeaderClick(i)} > {item.header} {item.buttons ? (
    {item.buttons}
    ) : null}

    {opened && (
    {cloneElement(item.component, item.componentProps || {})}
    )}
  • ); }; render() { return (
      {this.props.items.map(this.renderContainer)}
    ); } } export default Accordion;