Home Reference Source

src/components/regions/ListOld/List.jsx

import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import _ from 'lodash';

/**
 * Компонент Список
 * @reactProps {string} className - css-класс
 * @reactProps {boolean} animation
 * @reactProps {function} onSelect
 * @reactProps {node} children - элемент потомок компонента List
 * @example
 *  <List>
 * {
 *  containers.map((cnt) =>
 *    <ListItem id={cnt.id}
 *              title={cnt.name || cnt.id}
 *              active={cnt.opened}>
 *      <WidgetFactory containerId={cnt.id} pageId={cnt.pageId} fetchOnInit={cnt.fetchOnInit} {...cnt.widget} />
 *    </ListItem>
 *  )
 *}
 * </List>
 */

class List extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      activeIds: List.defaultOpenedId(props.children),
    };

    this.handleChangeActive = this.handleChangeActive.bind(this);
  }

  /**
   * Установка нового активного эдмента списка
   * @param e
   * @param id
   */
  handleChangeActive(e, id) {
    let oldIds = Object.assign([], this.state.activeIds);
    if (_.includes(oldIds, id)) {
      _.pull(oldIds, id);
    } else {
      oldIds = oldIds.concat(id);
    }
    this.setState({
      activeIds: oldIds,
    });
  }

  /**
   * getter для айдишников открытых по умолчанию элементов списка
   */
  static defaultOpenedId(children) {
    return _.map(
      _.filter(React.Children.toArray(children), child => {
        return child.props.active;
      }),
      child => child.props.id
    );
  }

  /**
   * getter для пропсов дочернего компонента
   */
  getChildProps(child) {
    const { activeIds } = this.state;
    return {
      active: _.includes(activeIds, child.props.id),
      onClick: this.handleChangeActive,
    };
  }

  render() {
    const { className, children } = this.props;
    return (
      <div className={className} style={{ marginBottom: 2 }}>
        {React.Children.map(children, child =>
          React.cloneElement(child, this.getChildProps(child))
        )}
      </div>
    );
  }
}

List.propTypes = {
  className: PropTypes.string,
  animation: PropTypes.bool,
  onSelect: PropTypes.func,
  children: PropTypes.node,
};

export default List;