All files / components/Accordion index.jsx

83.5% Statements 81/97
23.07% Branches 3/13
40% Functions 2/5
83.5% Lines 81/97

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 981x 1x 1x 1x 1x 1x 1x 1x 1x         1x 1x 1x 1x 1x     1x 1x     1x 1x 1x 1x 1x 1x 1x   1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x   1x 1x 1x       1x 1x       1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
import React, { useState, useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import { Chevron } from '../../lib/Chevron.jsx';
 
const Accordion = (props) => {
  const content = useRef(null);
  const [setActive, setActiveState] = useState(props.isOpen ? 'active' : '');
  const ariaPressed = setActive ? 'true' : 'false';
  const getHeight = (node) => {
    if (node) {
      return `${node.scrollHeight}px`;
    }
    return 'auto';
  };
  const height = setActive ? getHeight(content.current) : '0px';
  const rotate = setActive ? 'accordion-icon rotate' : 'accordion-icon';
 
  function toggleAccordion() {
    setActiveState(setActive === '' ? 'active' : '');
  }
 
  function openAccordion() {
    setActiveState('active');
  }
 
  function closeAccordion() {
    setActiveState('');
  }
 
  useEffect(() => {
    if (props.isOpen) {
      openAccordion();
    } else {
      closeAccordion();
    }
  }, [props.isOpen]);
 
  return (
    <div className="accordion-section" data-testid="accordion">
      <button
        className={`accordion ${setActive} ${
          setActive && props.isSticky ? 'sticky' : ''
        }`}
        aria-label={props.title}
        aria-pressed={ariaPressed}
        aria-expanded={ariaPressed}
        tabIndex="0"
        onClick={toggleAccordion}
      >
        <div className="accordion-left-title">
          <p className="accordion-title">{props.title}</p>
          {props.subTitle && (
            <p className="accordion-subtitle">{props.subTitle}</p>
          )}
        </div>
        {props.centerItem && (
          <div className="accordion-center">
            <p>{props.centerItem}</p>
          </div>
        )}
        {props.rightItem && (
          <div className="accordion-right">
            <p>{props.rightItem}</p>
          </div>
        )}
        <div className="chevron-container">
          <Chevron className={rotate} />
        </div>
      </button>
      <div
        ref={content}
        style={{ maxHeight: height }}
        className="accordion-content"
      >
        <div className="accordion-text dashed-border">{props.children}</div>
      </div>
    </div>
  );
};
 
Accordion.propTypes = {
  title: PropTypes.string.isRequired,
  subTitle: PropTypes.string,
  children: PropTypes.any.isRequired,
  centerItem: PropTypes.string,
  rightItem: PropTypes.string,
  isOpen: PropTypes.bool,
  isSticky: PropTypes.bool,
};
 
Accordion.defaultProps = {
  title: '',
  isOpen: false,
  isSticky: false,
};
 
export default Accordion;