import defaultTo from 'lodash/defaultTo';
import isEqual from 'lodash/isEqual';
import sortBy from 'lodash/sortBy';
import InputWithOptions from '../InputWithOptions';
import { st, classes } from './Dropdown.st.css.js';
const NO_SELECTED_ID = null;
const DROPDOWN_DOUBLE_CLICK_THRESHOLD = 200;
const OPEN_KEYS = ['Enter', 'Spacebar', ' ', 'ArrowUp', 'ArrowDown'];
class Dropdown extends InputWithOptions {
    constructor(props) {
        super(props);
        this.state = {
            value: '',
            selectedId: NO_SELECTED_ID,
            ...Dropdown.getNextState(props, defaultTo(props.selectedId, props.initialSelectedId)),
        };
    }
    isSelectedIdControlled() {
        return typeof this.props.selectedId !== 'undefined';
    }
    static isOptionsEqual(optionsA, optionsB) {
        return isEqual(sortBy(optionsA, 'id'), sortBy(optionsB, 'id'));
    }
    getSelectedId() {
        return this.isSelectedIdControlled()
            ? this.props.selectedId
            : this.state.selectedId;
    }
    shouldOpenDropdown(key) {
        return OPEN_KEYS.includes(key);
    }
    _onOpenChange(open, reason) {
        super._onOpenChange(open, reason, DROPDOWN_DOUBLE_CLICK_THRESHOLD);
    }
    /**
     * Updates the value by the selectedId.
     * If selectedId is not found in options, then value is NOT changed.
     */
    static getNextState(props, selectedId) {
        if (typeof selectedId !== 'undefined') {
            const option = props.options.find(_option => {
                return _option.id === selectedId;
            });
            if (option) {
                const value = props.valueParser(option) || '';
                return { value, selectedId };
            }
        }
        return { value: '', selectedId: NO_SELECTED_ID };
    }
    UNSAFE_componentWillReceiveProps(nextProps) {
        if (nextProps.selectedId !== this.props.selectedId ||
            !Dropdown.isOptionsEqual(this.props.options, nextProps.options)) {
            this.setState(Dropdown.getNextState(nextProps, nextProps.selectedId, this.state.selectedId));
        }
    }
    inputClasses() {
        const { noBorder, allowTextSelection } = this.props;
        return st(classes.showPointer, { noBorder, allowTextSelection });
    }
    dropdownAdditionalProps() {
        return {
            selectedId: this.getSelectedId(),
            value: this.state.value,
            tabIndex: -1,
            withArrow: false,
            size: ['tiny', 'small'].includes(this.props.size) ? 'small' : 'medium',
        };
    }
    inputAdditionalProps() {
        return {
            disableEditing: true,
            readOnly: this.props.readOnly,
            value: this.state.value,
            role: 'combobox',
            ariaHaspopup: 'listbox',
        };
    }
    _onSelect(option) {
        if (!this.isSelectedIdControlled()) {
            this.setState({
                value: this.props.valueParser(option),
                selectedId: option.id,
            });
        }
        super._onSelect(option);
    }
    _onChange(event) {
        this.setState({ value: event.target.value });
        super._onChange(event);
    }
}
Dropdown.defaultProps = {
    allowTextSelection: true,
    ...InputWithOptions.defaultProps,
};
Dropdown.displayName = 'Dropdown';
export default Dropdown;
//# sourceMappingURL=Dropdown.js.map