# All files / composer/components Dropdown.jsx

52% Statements 13/25
50% Branches 8/16
40% Functions 4/10
54.55% Lines 12/22

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
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109

    2x

    2x

    4x

    4x

    4x
    8x

    8x
    4x

    4x

    8x

    8x

    4x

     /**
     * Small abstraction wrapping 'react-simple-dropdown', using locally scoped
     * styles to handle showing/hiding the dropdown's contents.
     *
     * See UpdateSaver component for example usage.
     */

    import React from 'react';
    import PropTypes from 'prop-types';
    import SimpleDropdown, { DropdownTrigger, DropdownContent } from '@bufferapp/react-simple-dropdown';
    import styles from './css/Dropdown.css';

    const getDropdownState = ({ isDropdownExpanded }) => ({
      isDropdownExpanded,
    });

    class Dropdown extends React.Component {
      static propTypes = {
        children: PropTypes.node,
        disabled: PropTypes.bool,
        className: PropTypes.string,
        isDropdownExpanded: PropTypes.bool,
        onHide: PropTypes.func,
        onShow: PropTypes.func,
        title: PropTypes.string,
      };

      static defaultProps = {
        isDropdownExpanded: false,
        onHide: () => {},
        onShow: () => {},
      };

      state = getDropdownState(this.props);

      componentWillReceiveProps = (nextProps) => {
        Iif (this.props.isDropdownExpanded !== nextProps.isDropdownExpanded) {
          this.setState({
            isDropdownExpanded: nextProps.isDropdownExpanded,
          });
        }
      };

      onShow = () => {
        if (this.props.disabled) return;

        this.expandDropdown();
        this.props.onShow();
      };

      onHide = () => {
        if (this.props.disabled) return;

        this.collapseDropdown();
        this.props.onHide();
      };

      expandDropdown = () => this.setState({ isDropdownExpanded: true });
      collapseDropdown = () => this.setState({ isDropdownExpanded: false });

      render() {
        const isDropdownContentVisible = this.state.isDropdownExpanded && !this.props.disabled;

        const dropdownClassName = [
          styles.dropdown,
          this.props.className,
        ].join(' ');

        // Attach some default styles to DropdownTrigger and DropdownContent
        const children = React.Children.map(this.props.children, (child) => {
          Iif (child.type.displayName !== 'DropdownTrigger' &&
            child.type.displayName !== 'DropdownContent') return child;

          let defaultClassName;

          if (child.type.displayName === 'DropdownTrigger') {
            defaultClassName = styles.dropdownTrigger;
          } else {
            defaultClassName = isDropdownContentVisible ?
              styles.visibleDropdownContent : styles.dropdownContent;
          }

          const childClassName = [
            defaultClassName,
            child.props.className,
          ].join(' ');

          return React.cloneElement(child, {
            className: childClassName,
          });
        });

        return (
          <SimpleDropdown
            className={dropdownClassName}
            onShow={this.onShow}
            onHide={this.onHide}
            active={isDropdownContentVisible}
            title={this.props.title}
          >
            {children}
          </SimpleDropdown>
        );
      }
    }

    export { DropdownTrigger, DropdownContent };
    export default Dropdown;