// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import {cmdOrCtrlPressed} from 'utils/utils.jsx'; import Constants from 'utils/constants.jsx'; const KeyCodes = Constants.KeyCodes; import React from 'react'; import {FormattedMessage} from 'react-intl'; export default class MultiSelectList extends React.Component { constructor(props) { super(props); this.defaultOptionRenderer = this.defaultOptionRenderer.bind(this); this.handleArrowPress = this.handleArrowPress.bind(this); this.setSelected = this.setSelected.bind(this); this.toSelect = -1; this.state = { selected: -1 }; } componentDidMount() { document.addEventListener('keydown', this.handleArrowPress); } componentWillUnmount() { document.removeEventListener('keydown', this.handleArrowPress); } componentWillReceiveProps(nextProps) { this.setState({selected: this.toSelect}); const options = nextProps.options; if (options && options.length > 0 && this.toSelect >= 0) { this.props.onSelect(options[this.toSelect]); } } componentDidUpdate() { if (this.refs.list && this.refs.selected) { const elemTop = this.refs.selected.getBoundingClientRect().top; const elemBottom = this.refs.selected.getBoundingClientRect().bottom; const listTop = this.refs.list.getBoundingClientRect().top; const listBottom = this.refs.list.getBoundingClientRect().bottom; if (elemBottom > listBottom) { this.refs.selected.scrollIntoView(false); } else if (elemTop < listTop) { this.refs.selected.scrollIntoView(true); } } } setSelected(selected) { this.toSelect = selected; } handleArrowPress(e) { if (cmdOrCtrlPressed(e) && e.shiftKey) { return; } const options = this.props.options; if (options.length === 0) { return; } let selected; switch (e.keyCode) { case KeyCodes.DOWN: if (this.state.selected === -1) { selected = 0; break; } selected = Math.min(this.state.selected + 1, options.length - 1); break; case KeyCodes.UP: if (this.state.selected === -1) { selected = 0; break; } selected = Math.max(this.state.selected - 1, 0); break; default: return; } e.preventDefault(); this.setState({selected}); this.props.onSelect(options[selected]); } defaultOptionRenderer(option, isSelected, onAdd) { var rowSelected = ''; if (isSelected) { rowSelected = 'more-modal__row--selected'; } return (
onAdd(option)} > {option.label}
); } render() { const options = this.props.options; if (options == null || options.length === 0) { return (

); } let renderer; if (this.props.optionRenderer) { renderer = this.props.optionRenderer; } else { renderer = this.defaultOptionRenderer; } const optionControls = options.map((o, i) => renderer(o, this.state.selected === i, this.props.onAdd)); return (
{optionControls}
); } } MultiSelectList.defaultProps = { options: [], perPage: 50, onAction: () => null }; MultiSelectList.propTypes = { options: React.PropTypes.arrayOf(React.PropTypes.object), optionRenderer: React.PropTypes.func, page: React.PropTypes.number, perPage: React.PropTypes.number, onPageChange: React.PropTypes.func, onAdd: React.PropTypes.func, onSelect: React.PropTypes.func };