ifmeorg/ifme

View on GitHub
client/app/components/Accordion/index.jsx

Summary

Maintainability
A
0 mins
Test Coverage
// @flow
import React, { useState } from 'react';
import type { Node } from 'react';
import { Utils } from 'utils';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCaretDown, faCaretUp } from '@fortawesome/free-solid-svg-icons';
import globalCss from 'styles/_global.scss';
import css from 'components/Input/Input.scss';

export type Props = {
  id: string,
  children: any,
  title: any,
  dark?: boolean,
  large?: boolean,
  open?: boolean,
};

export type State = {
  open: boolean,
};

export const Accordion = ({
  id,
  children,
  title,
  dark,
  large,
  open: openProp,
}: Props): Node => {
  const [open, setOpen] = useState(!!openProp);

  const displayContent = () => (
    <div
      className={`${open ? 'accordionContent' : css.accordionClose}`}
      role="region"
    >
      {Utils.renderContent(children)}
    </div>
  );

  const toggleOpen = () => {
    setOpen(!open);
  };

  const openToggle = (event: SyntheticKeyboardEvent<HTMLDivElement>) => {
    if (event.key === 'Enter') {
      setOpen(!open);
    }
  };
  const inputClassNames = () => `${dark ? css.dark : ''} ${large ? css.large : ''}`;

  return (
    <div id={`${id}_accordion`} className={inputClassNames()}>
      <div
        className={`accordion ${globalCss.gridRowSpaceBetween} ${css.accordion}`}
        onClick={toggleOpen}
        onKeyDown={openToggle}
        role="button"
        tabIndex="0"
        aria-expanded={open}
      >
        <div className={css.accordionTitle}>{Utils.renderContent(title)}</div>
        <div className={css.accordionCaret}>
          <FontAwesomeIcon icon={open ? faCaretUp : faCaretDown} />
        </div>
      </div>
      {displayContent()}
    </div>
  );
};