tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Accordion.js (2102B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
      4 
      5 import { cloneElement, Component } from "devtools/client/shared/vendor/react";
      6 import {
      7  aside,
      8  button,
      9  div,
     10  h2,
     11 } from "devtools/client/shared/vendor/react-dom-factories";
     12 import PropTypes from "devtools/client/shared/vendor/react-prop-types";
     13 
     14 class Accordion extends Component {
     15  static get propTypes() {
     16    return {
     17      items: PropTypes.array.isRequired,
     18    };
     19  }
     20 
     21  handleHeaderClick(i) {
     22    const item = this.props.items[i];
     23    const opened = !item.opened;
     24    item.opened = opened;
     25 
     26    if (item.onToggle) {
     27      item.onToggle(opened);
     28    }
     29 
     30    // We force an update because otherwise the accordion
     31    // would not re-render
     32    this.forceUpdate();
     33  }
     34 
     35  renderContainer = (item, i) => {
     36    const { opened } = item;
     37    const contentElementId = `${item.id}-content`;
     38 
     39    return aside(
     40      {
     41        className: item.className,
     42        key: item.id,
     43        "aria-labelledby": item.id,
     44        role: item.role,
     45      },
     46      h2(
     47        {
     48          className: "_header",
     49        },
     50        button(
     51          {
     52            id: item.id,
     53            className: "header-label",
     54            "aria-expanded": `${opened ? "true" : "false"}`,
     55            "aria-controls": opened ? contentElementId : undefined,
     56            onClick: () => this.handleHeaderClick(i),
     57          },
     58          item.header
     59        ),
     60        item.buttons
     61          ? div(
     62              {
     63                className: "header-buttons",
     64              },
     65              item.buttons
     66            )
     67          : null
     68      ),
     69      opened &&
     70        div(
     71          {
     72            className: "_content",
     73            id: contentElementId,
     74          },
     75          cloneElement(item.component, item.componentProps || {})
     76        )
     77    );
     78  };
     79  render() {
     80    return div(
     81      {
     82        className: "accordion",
     83      },
     84      this.props.items.map(this.renderContainer)
     85    );
     86  }
     87 }
     88 
     89 export default Accordion;