React

by evgkch

HTML

<div id="app"></div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.done {
  color: rgba(0, 0, 0, 0.3);
  text-decoration: line-through;
}

input {
  margin-right: 5px;
}

React

const data = Array.from({ length: 5 }, (v, k) => ({
	id: k,
  name: `name_${k}`,
}));

class Select extends React.Component {
	
  static matchOptionId = (id) => (option) => option.id === id;
  
  constructor(props) {
    super(props);
    this.state = {
    	selectMode: false,
      option: this.props.defaultOption || this.props.data[0],
    };
  }
  
  componentDidMount() {
  	window.addEventListener('click', this.onClick);
  }
  
  onClick = (evt) => {
  	switch(evt)
    {
    case this.selectTarget: break;
    default: this
    }
  }
  
  setSelectTarget = (target) => {
  	this.selectTarget = target;
  }
  
  onSwitchSelectMode = (flag) => {
  	this.setState(prevState =>
    	({ selectMode: !prevState.selectMode })
    );
  }
  
  onSelectOption = (id) => {
  	const { data } = this.props;
  	const { option } = this.state;
    if (id !== option.id)
    {
    	this.setState({
      	option: data.find(Select.matchOptionId(id)),
        selectMode: false,
      })
    };
  }
  
  renderOption = ({ name, id }) =>
  	<div
      key={id}
      onClick={() => this.onSelectOption(id)}
    >
      {name}
    </div>;
  
  render() {
  	const { data } = this.props;
    const { selectMode, option = {} } = this.state;
    return (
      <div
        className="rlx__select"
        ref={this.setSelectTarget}
      >
        <div
          className="rlx__select__selected-option"
          onClick={this.onSwitchSelectMode}          
        >
          {option.name}
        </div>
        {selectMode &&
        	<div
            className="rlx__select__options"
            style={{ cursor: 'pointer' }}
          >
            {data.filter(!Select.matchOptionId(option.id).map(this.renderOption)}
          </div>
        }
      </div>
    )
  }
}

ReactDOM.render(<Select data={data} />, document.querySelector("#app"))