'use strict';
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
            t[p[i]] = s[p[i]];
    return t;
};
import { findDOMNode } from 'react-dom';
import { Store } from '../../data/Store';
import { FormGroup } from './FormGroup';
import { FormControl } from './FormControl';
import { Checkbox } from './Checkbox';
import { Filter } from '../Filter';
import { Icon } from '../Icon';
import { Tooltip } from '../Tooltip';
import React from 'react';
import PropTypes from 'prop-types';
import { Dropdown, OverlayTrigger } from 'react-bootstrap';
import _ from 'lodash';
import classnames from 'classnames';
import { highlight } from '../list/utils';
import { translate } from '../../../utils';
import { FocusHelper } from '../../utils/FocusHelper';
import { KeyNames } from '../../../utils/constants';
import lang from '../../../lang/common/index-en_US';
var FC = FormControl;
var doNothing = function () { };
// declare namespace MultiSelectModule {
//     class MultiSelectOption extends React.Component<any> {}
//     class MultiSelectMasterOption extends React.Component<any> {}
//     class MultiSelectOptionGroup extends React.Component<any> {}
//     class MultiSelectField extends React.Component<any> {}
// }
var MultiSelectField = /** @class */ (function (_super) {
    __extends(MultiSelectField, _super);
    function MultiSelectField() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    MultiSelectField.prototype.renderInput = function () {
        var _a = this.getPropsFromContext(), children = _a.children, innerLabel = _a.innerLabel, props = __rest(_a, ["children", "innerLabel"]);
        var MultiSelectTS = MultiSelect;
        return (React.createElement(MultiSelectTS, __assign({}, props, { label: innerLabel, ref: "control", hasFormGroupContainer: true }), children));
    };
    MultiSelectField.propTypes = __assign({}, FormGroup.propTypes);
    MultiSelectField.defaultProps = __assign({}, FormGroup.defaultProps, { testAutomationId: 'multiSelect' });
    return MultiSelectField;
}(FormGroup));
var multiSelectInstanceCounter = 0;
var MultiSelectOption = /** @class */ (function (_super) {
    __extends(MultiSelectOption, _super);
    function MultiSelectOption(props, context) {
        var _this = _super.call(this, props, context) || this;
        _this.handleKeyDown = _this.handleKeyDown.bind(_this);
        return _this;
    }
    MultiSelectOption.compareOptionValue = function (source) {
        if (_.isObject(source)) {
            return _.matches(source);
        }
        return function (value) {
            return value === source;
        };
    };
    MultiSelectOption.prototype.getChildContext = function () {
        var _this = this;
        return {
            getOptionIdPrefix: function () { return _this.getId(); }
        };
    };
    MultiSelectOption.prototype.handleKeyDown = function (event) {
        switch (event.keyCode) {
            case 13: // enter
            case 32: // space
                this.refs.control.click();
                event.preventDefault();
                break;
            default:
                this.props.onKeyDown(event);
        }
    };
    MultiSelectOption.prototype.getId = function () {
        if (!_.isFunction(this.context.getOptionIdPrefix)) {
            return null;
        }
        return this.context.getOptionIdPrefix() + "_" + (this.props.groupMaster ? 'masterOption' : 'option') + "_" + this.props.ariaPosition;
    };
    MultiSelectOption.prototype.finalRender = function (props, content) {
        if (_.isFunction(this.props.tagRenderer)) {
            return this.props.tagRenderer(props, content);
        }
        return content;
    };
    MultiSelectOption.prototype.render = function () {
        var _this = this;
        var _a = this.props, hint = _a.hint, description = _a.description, secondLine = _a.secondLine, overlayProps = _a.overlayProps;
        var behaveAsFlat = this.context.multiSelect.behaveAsFlat;
        var values = this.context.multiSelect.values;
        var filterCallback = this.context.multiSelect.filterCallback;
        var isSelected = false;
        var isMaster = this.props.groupMaster;
        var isOptionDisabled = !!(isMaster &&
            this.context.multiSelect.isSingleSelectMode &&
            this.props.value === undefined) || this.props.disabled;
        var optionValues = [];
        var labelTitle = !description ? this.props.label : this.props.label + " - " + description;
        if (behaveAsFlat) {
            isSelected = values.some(MultiSelectOption.compareOptionValue(this.props.value));
        }
        else if (!isMaster) {
            optionValues = [this.props.value];
            var index = _.findIndex(values, MultiSelectOption.compareOptionValue(this.props.value));
            isSelected = index > -1;
            // Skip not matched options
            if (!filterCallback(this.props.label, this.props.value)) {
                return null;
            }
        }
        else {
            optionValues = this.context.multiSelectGroup.values;
            var selectedValuesCount_1 = 0;
            var groupFilteredLabels = this.context.multiSelectGroup.filteredLabels;
            optionValues.forEach(function (value) {
                var index = _.findIndex(values, MultiSelectOption.compareOptionValue(value));
                if (index > -1) {
                    selectedValuesCount_1++;
                }
            });
            if (selectedValuesCount_1 > 0) {
                isSelected = selectedValuesCount_1 === optionValues.length ? true : null;
            }
            // Skip not matched groups
            if (!filterCallback(this.props.label, this.props.value) &&
                !groupFilteredLabels.length) {
                return null;
            }
        }
        var highlightedLabelText = this.props.customLabel ||
            highlight(this.context.multiSelect.filterRegExp, this.props.label);
        var icon = this.props.icon;
        var content;
        var label = (React.createElement("span", { className: "multi-select__item-text-container" },
            highlightedLabelText,
            description !== null ? (React.createElement("span", { className: "multi-select__item-hint select-description" },
                ' ',
                "- ",
                description)) : null));
        if (this.context.multiSelect.isSingleSelectMode) {
            isSelected =
                this.props.value !== undefined &&
                    MultiSelectOption.compareOptionValue(this.props.value)(values[0]);
            var onClick = function (event) {
                if (_this.props.value !== undefined) {
                    _this.context.multiSelect.setValues([_this.props.value]);
                }
                _this.context.multiSelect.close();
            };
            var labelProps = {
                className: classnames('option-label', this.props.labelClassName, {
                    'selected-option': isSelected
                }),
                ref: 'control'
            };
            if (!isOptionDisabled) {
                labelProps.onClick = onClick;
            }
            var secondLineElement = secondLine ? (React.createElement("div", { className: "second-line text-overflow", title: secondLine }, secondLine)) : null;
            content = (React.createElement("span", __assign({}, labelProps),
                isSelected ? (React.createElement(Icon, { "aria-hidden": "true", name: "checkbox-selected-readonly" })) : null,
                label,
                secondLineElement,
                React.createElement("div", { className: "icon-wrapper", "aria-hidden": "true" }, icon ? React.createElement(Icon, { name: icon }) : null)));
        }
        else {
            content = (React.createElement(Checkbox, { name: undefined, ref: "control", label: label, labelClassName: this.props.labelClassName, checked: isSelected, "aria-hidden": true, "aria-checked": isSelected === null ? 'mixed' : isSelected, disabled: isOptionDisabled, onChange: function () {
                    var isSelected = _this.refs.control.getValue();
                    var next = behaveAsFlat ? [_this.props.value] : optionValues;
                    var newValues = isSelected
                        ? values.concat(next)
                        : values.filter(function (source) {
                            var compare = MultiSelectOption.compareOptionValue(source);
                            return next.every(function (value) { return !compare(value); });
                        });
                    _this.context.multiSelect.setValues(newValues);
                } }));
        }
        var optionId = this.getId();
        var liProps = {
            id: optionId,
            'data-test-automation-id': this.props.testAutomationId || 'option' + this.context.multiSelect.uid(),
            className: classnames("multi-select-option multi-select-option-level-" + this.props.ariaLevel, this.props.className, {
                'master-option': isMaster,
                'option-disabled': isOptionDisabled
            }),
            role: 'treeitem',
            'aria-level': this.props.ariaLevel,
            'aria-setsize': this.props.ariaSetSize,
            'aria-posinset': this.props.ariaPosition
        };
        if (!isOptionDisabled) {
            liProps.tabIndex = '-1';
            liProps.onKeyDown = this.handleKeyDown;
            liProps.onSelect = this.props.onSelect;
            liProps['aria-selected'] = isSelected === true;
            liProps.onFocus = function () {
                if (_.isFunction(_this.context.setAriaActivedescendant)) {
                    _this.context.setAriaActivedescendant(optionId);
                }
            };
        }
        var finalContent = hint ? (React.createElement(OverlayTrigger, __assign({ overlay: React.createElement(Tooltip, null, hint) }, overlayProps), content)) : (this.finalRender(liProps, content));
        return (React.createElement("li", __assign({}, liProps, { title: labelTitle }), finalContent));
    };
    MultiSelectOption.contextTypes = {
        multiSelect: PropTypes.object,
        multiSelectGroup: PropTypes.object,
        getOptionIdPrefix: PropTypes.func,
        setAriaActivedescendant: PropTypes.func
    };
    MultiSelectOption.childContextTypes = {
        getOptionIdPrefix: PropTypes.func
    };
    MultiSelectOption.propTypes = {
        className: PropTypes.string,
        disabled: PropTypes.bool,
        groupMaster: PropTypes.bool,
        icon: PropTypes.string,
        label: PropTypes.string.isRequired,
        labelClassName: PropTypes.string,
        onKeyDown: PropTypes.func,
        onSelect: PropTypes.func,
        testAutomationId: PropTypes.string,
        value: PropTypes.any.isRequired,
        ariaPosition: PropTypes.number,
        ariaLevel: PropTypes.number,
        ariaSetSize: PropTypes.number,
        hint: PropTypes.string,
        customLabel: PropTypes.any,
        tagRenderer: PropTypes.func,
        description: PropTypes.string,
        secondLine: PropTypes.string
    };
    MultiSelectOption.defaultProps = {
        className: null,
        disabled: false,
        groupMaster: false,
        icon: '',
        labelClassName: '',
        onKeyDown: doNothing,
        onSelect: doNothing,
        testAutomationId: null,
        ariaPosition: null,
        ariaLevel: null,
        ariaSetSize: null,
        hint: null,
        customLabel: null,
        tagRenderer: null,
        description: null,
        secondLine: null,
        overlayProps: {}
    };
    return MultiSelectOption;
}(React.Component));
var MultiSelectMasterOptionWrapper = /** @class */ (function (_super) {
    __extends(MultiSelectMasterOptionWrapper, _super);
    function MultiSelectMasterOptionWrapper() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.tagRenderer = function (props, content) {
            return React.createElement("div", { id: _this.props.groupLabelId }, content);
        };
        return _this;
    }
    MultiSelectMasterOptionWrapper.prototype.getTestAutomationId = function () {
        var testAutomationId = this.props.testAutomationId;
        var multiSelect = this.context.multiSelect;
        if (testAutomationId) {
            return testAutomationId;
        }
        return "optionMaster" + multiSelect.uid();
    };
    MultiSelectMasterOptionWrapper.prototype.render = function () {
        return (React.createElement(MultiSelectOption, __assign({}, this.props, { testAutomationId: this.getTestAutomationId(), tagRenderer: this.tagRenderer, groupMaster: true })));
    };
    MultiSelectMasterOptionWrapper.propTypes = __assign({}, MultiSelectOption.propTypes, { testAutomationId: PropTypes.string, groupLabelId: PropTypes.string.isRequired });
    MultiSelectMasterOptionWrapper.defaultProps = __assign({}, MultiSelectOption.defaultProps, { testAutomationId: null });
    MultiSelectMasterOptionWrapper.contextTypes = {
        multiSelect: PropTypes.object
    };
    return MultiSelectMasterOptionWrapper;
}(React.Component));
var MultiSelectMasterOption = /** @class */ (function (_super) {
    __extends(MultiSelectMasterOption, _super);
    function MultiSelectMasterOption() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    MultiSelectMasterOption.prototype.render = function () {
        return null;
    };
    MultiSelectMasterOption.propTypes = __assign({}, MultiSelectOption.propTypes);
    return MultiSelectMasterOption;
}(React.Component));
function getChildrenValues(children) {
    return _.flatten(React.Children.toArray(children)
        .filter(function (child) {
        return ((child.type === MultiSelectOption && !child.props.groupMaster) ||
            child.type === MultiSelectOptionGroup);
    })
        .map(function (child) {
        if (child.type === MultiSelectOption) {
            return child.props.value;
        }
        return getChildrenValues(child.props.children);
    }));
}
function hasValueChild(children) {
    var items = React.Children.toArray(children);
    var hasValue = items.some(function (o) { return o && o.props && o.props.value !== undefined; });
    if (hasValue) {
        return true;
    }
    for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
        var child = items_1[_i];
        if (child && child.props && child.props.children && hasValueChild(child.props.children)) {
            return true;
        }
    }
    return false;
}
function getChildrenLabels(children, filterCallback) {
    return _.flatten(React.Children.toArray(children)
        .filter(function (child) {
        if (child.type === MultiSelectOption || child.type === MultiSelectMasterOption) {
            if (filterCallback && !filterCallback(child.props.label, child.props.value)) {
                return false;
            }
            return true;
        }
        else if (child.type === MultiSelectOptionGroup) {
            return true;
        }
    })
        .map(function (child) {
        if (child.type === MultiSelectOption || child.type === MultiSelectMasterOption) {
            return child.props.label;
        }
        return getChildrenLabels(child.props.children, filterCallback);
    }));
}
function getGroupValueOptionSize(children) {
    if (!Array.isArray(children)) {
        children = React.Children.toArray(children);
    }
    return children.filter(function (o) { return !isMasterOption(o); }).length;
}
function isMasterOption(node) {
    return node && node.type === MultiSelectMasterOption;
}
var TreeItemAriaProps = ['aria-selected', 'aria-level', 'aria-setsize', 'aria-posinset', 'role'];
var MultiSelectOptionGroup = /** @class */ (function (_super) {
    __extends(MultiSelectOptionGroup, _super);
    function MultiSelectOptionGroup() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.getOptionId = function () {
            if (_.isFunction(_this.context.getOptionIdPrefix)) {
                return _this.context.getOptionIdPrefix() + "_" + _this.props.ariaPosition;
            }
            return null;
        };
        _this.getMasterOptionWrapperProps = function (props) {
            return _.omit(props, TreeItemAriaProps);
        };
        return _this;
    }
    MultiSelectOptionGroup.prototype.getChildContext = function () {
        return {
            multiSelectGroup: {
                values: getChildrenValues(this.props.children),
                filteredLabels: getChildrenLabels(this.props.children, this.context.multiSelect.filterCallback)
            },
            getOptionIdPrefix: this.getOptionId
        };
    };
    MultiSelectOptionGroup.prototype.getSiblingOptionSize = function (children) {
        return getGroupValueOptionSize(children);
    };
    MultiSelectOptionGroup.prototype.getGroupProps = function (props) {
        if (_.isEmpty(props)) {
            return null;
        }
        return _.pick(props, TreeItemAriaProps);
    };
    MultiSelectOptionGroup.prototype.render = function () {
        var _this = this;
        var children = React.Children.toArray(this.props.children);
        var ariaSetSize = this.getSiblingOptionSize(children);
        var hasMaster = false;
        var items = children.map(function (child, index) {
            var childProps = child.props || {};
            var isMasterNode = isMasterOption(child);
            if (isMasterNode) {
                hasMaster = true;
            }
            var ariaPosition = hasMaster ? index : index + 1;
            return React.cloneElement(child, {
                ariaPosition: isMasterNode ? _this.props.ariaPosition : ariaPosition,
                ariaLevel: _this.props.ariaLevel + (isMasterNode ? 0 : 1),
                ariaSetSize: isMasterNode ? _this.props.ariaSetSize : ariaSetSize,
                onKeyDown: _this.props.onKeyDown,
                onSelect: _this.props.onSelect
            }, childProps.children);
        });
        var masterItem = _.find(items, isMasterOption);
        var groupLabelId = this.getOptionId() + "_group_node";
        var masterOptionNode = masterItem ? (React.createElement(MultiSelectMasterOptionWrapper, __assign({ groupLabelId: groupLabelId }, this.getMasterOptionWrapperProps(masterItem.props)))) : null;
        var valueItems = items.filter(function (node) { return !isMasterOption(node); });
        var hasAvailableValue = hasValueChild(valueItems);
        var groupProps = __assign({ id: this.getOptionId(), 'data-test-automation-id': this.props.testAutomationId || 'groupOption' + this.context.multiSelect.uid(), role: 'treeitem', 'aria-expanded': true, 'aria-selected': false }, this.getGroupProps(masterItem && masterItem.props));
        groupProps.className = classnames(groupProps.className, {
            'multi-select-has-children': !_.isEmpty(valueItems)
        });
        var ariaProps = {};
        if (hasAvailableValue && masterItem) {
            ariaProps = { 'aria-labelledby': groupLabelId };
        }
        return (React.createElement("div", __assign({}, groupProps),
            masterOptionNode,
            React.createElement("ul", __assign({ className: classnames('multi-select-group', this.props.className), role: hasAvailableValue ? 'group' : '' }, ariaProps), valueItems)));
    };
    MultiSelectOptionGroup.contextTypes = {
        multiSelect: PropTypes.object,
        multiSelectGroup: PropTypes.object,
        getOptionIdPrefix: PropTypes.func
    };
    MultiSelectOptionGroup.childContextTypes = {
        multiSelectGroup: PropTypes.object,
        getOptionIdPrefix: PropTypes.func
    };
    MultiSelectOptionGroup.propTypes = {
        children: PropTypes.node,
        className: PropTypes.string,
        onKeyDown: PropTypes.func,
        onSelect: PropTypes.func,
        testAutomationId: PropTypes.string,
        ariaPosition: PropTypes.number,
        ariaLevel: PropTypes.number,
        ariaSetSize: PropTypes.number
    };
    MultiSelectOptionGroup.defaultProps = {
        children: null,
        className: null,
        onKeyDown: doNothing,
        onSelect: doNothing,
        testAutomationId: null,
        ariaPosition: 1,
        ariaLevel: 1,
        ariaSetSize: 1
    };
    return MultiSelectOptionGroup;
}(React.Component));
var MultiSelectDefaultAutomationId = 'multiSelect';
var MultiSelect = /** @class */ (function (_super) {
    __extends(MultiSelect, _super);
    function MultiSelect(props, context) {
        var _this = _super.call(this, props, context) || this;
        _this.focusHelper = new FocusHelper();
        _this.saveMultiSelectRef = function (ref) {
            _this.multiSelectEle = findDOMNode(ref);
        };
        _this.focus = function () {
            _this.focusHelper.focus();
        };
        /** @param {Array<String>} selectedItemLabels */
        _this.getTitle = function (selectedItemLabels) {
            if (_.isEmpty(selectedItemLabels)) {
                return null;
            }
            var _a = _this.props, label = _a.label, selectedValuesPrefix = _a.selectedValuesPrefix;
            var valueStr = selectedItemLabels.join(', ');
            if (!_this.shouldApplyLabelPrefix()) {
                return valueStr;
            }
            return translate(selectedValuesPrefix, {
                filterName: label,
                values: valueStr
            });
        };
        _this.getAriaLabel = function () {
            var _a = _this.props, label = _a.label, toggleAriaLabel = _a.toggleAriaLabel;
            if (!_this.shouldApplyLabelPrefix()) {
                return label;
            }
            return translate(toggleAriaLabel, { filterName: label });
        };
        /** @param {Array<String>} selectedItems */
        _this.getDisplayLabel = function (selectedItems) {
            var _a = _this.props, label = _a.label, labelItemsLimit = _a.labelItemsLimit;
            if (_.isEmpty(selectedItems)) {
                return label;
            }
            var valueString = selectedItems.join(', ');
            if (selectedItems.length > labelItemsLimit) {
                valueString = selectedItems
                    .slice(0, labelItemsLimit)
                    .concat(['...'])
                    .join(', ');
            }
            return _this.shouldApplyLabelPrefix() ? label + ": " + valueString : valueString;
        };
        /** @returns {Array<String>}*/
        _this.getSelectedItemLabels = function () {
            var children = _this.props.children;
            var props = _this.getPropsFromContext();
            var values = toArray(props.value);
            return getChildrenLabels(children, function (label, value) {
                return _.findIndex(values, MultiSelectOption.compareOptionValue(value)) > -1;
            });
        };
        _this.onToggle = _this.onToggle.bind(_this);
        _this.onKeyDown = _this.onKeyDown.bind(_this);
        _this.showMore = _this.showMore.bind(_this);
        _this.filterByLimit = _this.filterByLimit.bind(_this);
        _this.filterByLabelAndLimit = _this.filterByLabelAndLimit.bind(_this);
        _this.listItemsFilteredByLimit = [];
        _this.listItemsFiltered = [];
        _this.state = {
            filterText: '',
            filterRegExp: null,
            filterCallback: _this.filterByLimit,
            isOpen: false,
            isMoreShowed: false,
            hasFilterFocus: false,
            ariaActivedescendant: null
        };
        _this.instanceId = ++multiSelectInstanceCounter;
        return _this;
    }
    MultiSelect.prototype.componentDidMount = function () {
        var _this = this;
        this.multiSelectEle.addEventListener('keydown', function (event) {
            if (_this.state.isOpen && event.key === KeyNames.Escape) {
                event.stopPropagation();
            }
        });
    };
    MultiSelect.prototype.filterByLimit = function (label, value) {
        if (!(this.props.listItemsLimit > 0)) {
            return true;
        }
        if (this.state.isMoreShowed) {
            return true;
        }
        var validValue = typeof value !== 'undefined';
        // Calculate all visible options
        if (validValue && this.listItemsFiltered.indexOf(value) === -1) {
            this.listItemsFiltered.push(value);
        }
        if (this.listItemsFilteredByLimit.length < this.props.listItemsLimit) {
            if (validValue && this.listItemsFilteredByLimit.indexOf(value) === -1) {
                this.listItemsFilteredByLimit.push(value);
            }
            return true;
        }
        return this.listItemsFilteredByLimit.indexOf(value) !== -1;
    };
    MultiSelect.prototype.filterByLabelAndLimit = function (label, value) {
        var filterRegExp = this.state.filterRegExp;
        if (filterRegExp === null) {
            return this.filterByLimit(label, value);
        }
        filterRegExp.lastIndex = 0;
        return filterRegExp.test(label) && this.filterByLimit(label, value);
    };
    MultiSelect.prototype.outputConverter = function (e) {
        return e;
    };
    MultiSelect.prototype.getValue = function () {
        // FIXME [UIA-10000] Not implemented
        return null;
    };
    MultiSelect.prototype.getChildContext = function () {
        var _this = this;
        var props = this.getPropsFromContext();
        return {
            multiSelect: {
                uid: function () {
                    return ++_this.uid;
                },
                values: toArray(props.value),
                setValues: function (values) {
                    if (_this.props.isSingleSelect) {
                        values = values[0];
                    }
                    props.onChange(values);
                },
                filterCallback: this.state.filterCallback,
                filterRegExp: this.state.filterRegExp,
                isSingleSelectMode: this.props.isSingleSelect,
                behaveAsFlat: this.props.behaveAsFlat,
                close: function () {
                    _this.setState({ isOpen: false });
                }
            },
            level: 0,
            getOptionIdPrefix: function () { return "select_" + _this.instanceId; },
            setAriaActivedescendant: function (ariaActivedescendant) { return _this.setState({ ariaActivedescendant: ariaActivedescendant }); }
        };
    };
    MultiSelect.prototype.onToggle = function (isOpen) {
        this.uid = 0;
        if (!isOpen && this.state.hasFilterFocus) {
            isOpen = true;
        }
        this.setState({ isOpen: isOpen });
    };
    MultiSelect.prototype.onKeyDown = function (event) {
        switch (event.key) {
            case 'Escape':
            case 'Tab':
                this.setState({ isOpen: false });
                break;
        }
    };
    MultiSelect.prototype.setTextFilter = function (text) {
        var filterRegExp = Store.searchStringToRegExp(text);
        this.listItemsFiltered = [];
        this.listItemsFilteredByLimit = [];
        this.setState({
            filterText: text,
            filterRegExp: filterRegExp,
            filterCallback: this.filterByLabelAndLimit,
            isMoreShowed: false
        });
    };
    MultiSelect.prototype.showMore = function (event) {
        event.preventDefault();
        this.setState({
            isMoreShowed: true
        });
    };
    MultiSelect.prototype.renderShowMore = function () {
        if (this.state.isMoreShowed) {
            return null;
        }
        var count = this.listItemsFiltered.length - this.listItemsFilteredByLimit.length;
        if (count <= 0) {
            return null;
        }
        return (React.createElement("li", { role: "menuitem" },
            React.createElement("a", { className: "show-more", onClick: this.showMore }, translate(this.props.showMoreCountTextTemplate, { count: count }))));
    };
    MultiSelect.prototype.getAriaDescribedbyProp = function () {
        var describedby = this.props["aria-describedby"];
        return describedby ? { 'aria-describedby': describedby } : {};
    };
    MultiSelect.prototype.shouldApplyLabelPrefix = function () {
        var _a = this.props, isSingleSelect = _a.isSingleSelect, applyLabelPrefixForSingleMode = _a.applyLabelPrefixForSingleMode, applyLabelPrefixForMultiMode = _a.applyLabelPrefixForMultiMode;
        return isSingleSelect ? applyLabelPrefixForSingleMode : applyLabelPrefixForMultiMode;
    };
    MultiSelect.prototype.render = function () {
        var _this = this;
        this.uid = 0;
        var _a = this.props, id = _a.id, isFilterable = _a.isFilterable, searchText = _a.searchText, noResultsText = _a.noResultsText, label = _a.label, value = _a.value, children = _a.children, labelItemsLimit = _a.labelItemsLimit, testAutomationId = _a.testAutomationId, className = _a.className, block = _a.block, stretch = _a.stretch, listHeader = _a.listHeader, listItemsLimit = _a.listItemsLimit, showMoreCountTextTemplate = _a.showMoreCountTextTemplate, onChange = _a.onChange, ariaLabelledById = _a.ariaLabelledById, toggleAriaLabel = _a.toggleAriaLabel, stretchDropdownMenu = _a.stretchDropdownMenu, otherProps = __rest(_a, ["id", "isFilterable", "searchText", "noResultsText", "label", "value", "children", "labelItemsLimit", "testAutomationId", "className", "block", "stretch", "listHeader", "listItemsLimit", "showMoreCountTextTemplate", "onChange", "ariaLabelledById", "toggleAriaLabel", "stretchDropdownMenu"]);
        var filter = null;
        var isNoResults = false;
        var hasChildren = children && (!(children instanceof Array) || children.length);
        if (isFilterable && hasChildren) {
            filter = (React.createElement(Filter, { value: this.state.filterText, testAutomationId: "filter", className: "multi-select-filter", ref: "filter", placeholder: searchText, tabIndex: -1, onFocus: function (event) {
                    if (!_this.state.hasFilterFocus) {
                        _this.refs.filter.focus();
                        _this.setState({ hasFilterFocus: true });
                    }
                }, onBlur: function (event) { return _this.setState({ hasFilterFocus: false }); }, onKeyDown: function (event) {
                    if (['ArrowUp', 'ArrowDown', 'Escape', 'Tab'].indexOf(event.key) === -1) {
                        event.stopPropagation();
                    }
                }, onChange: function (filterText) { return _this.setTextFilter(filterText); } }));
            isNoResults = getChildrenLabels(children, this.state.filterCallback).length === 0;
        }
        var header = null;
        if (listHeader && filter) {
            header = (React.createElement("li", { className: "multi-select-list-header", role: "none" },
                listHeader,
                filter));
        }
        else if (listHeader) {
            header = (React.createElement("li", { className: "multi-select-list-header", role: "none" }, listHeader));
        }
        else if (filter) {
            header = (React.createElement("li", { className: "multi-select-list-header", role: "none" }, filter));
        }
        var selectedItemLabels = this.getSelectedItemLabels();
        var title = this.getTitle(selectedItemLabels);
        var displayLabel = this.getDisplayLabel(selectedItemLabels);
        id =
            id ||
                (testAutomationId !== MultiSelectDefaultAutomationId
                    ? testAutomationId
                    : Date.now());
        var dropdownMenuClassName = stretchDropdownMenu ? 'stretch' : null;
        return (React.createElement(Dropdown, __assign({ id: id, onToggle: this.onToggle, onKeyDown: this.onKeyDown, open: this.state.isOpen, ref: this.saveMultiSelectRef, "data-test-automation-id": this.props.hasFormGroupContainer ? undefined : testAutomationId, className: classnames('multi-select', className, {
                'btn-block': stretch || block,
                stretch: stretch
            }) }, this.getSafeProps(otherProps)),
            React.createElement(Dropdown.Toggle, __assign({ ref: this.focusHelper.setEl, "data-test-automation-id": "toggle", "aria-labelledby": ariaLabelledById, noCaret: true, disabled: this.props.disabled, "aria-label": this.getAriaLabel() }, this.getAriaDescribedbyProp(), { title: title, className: classnames({ 'btn-block': stretch || block }) }),
                React.createElement("span", { className: "icon-wrapper", "aria-hidden": "true" },
                    React.createElement(Icon, { name: "chevron-down-small" })),
                React.createElement("div", { className: "label-wrapper" },
                    React.createElement("div", { className: "label-wrapper-inner" },
                        React.createElement("div", { className: "label-text-overflow" }, displayLabel)))),
            React.createElement(Dropdown.Menu, { className: dropdownMenuClassName, "data-test-automation-id": "list" },
                header,
                !hasChildren || isNoResults ? (React.createElement("li", { className: "no-results", "data-test-automation-id": "noResult", role: "none" }, noResultsText)) : (React.createElement("li", { className: "multi-select-list-content", role: "menuitem" },
                    React.createElement("ul", { role: "tree", "aria-multiselectable": !this.props.isSingleSelect, "aria-activedescendant": this.state.ariaActivedescendant }, appendAriaPropsForMultiSelectChildren(children)))),
                hasChildren && !isNoResults ? this.renderShowMore() : null)));
    };
    MultiSelect.propTypes = __assign({}, FormControl.propTypes, { id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), isFilterable: PropTypes.bool, searchText: PropTypes.string, noResultsText: PropTypes.string, label: PropTypes.string, value: PropTypes.any, testAutomationId: PropTypes.string, className: PropTypes.string, block: PropTypes.bool, stretch: PropTypes.bool, listHeader: PropTypes.any, listItemsLimit: PropTypes.number, labelItemsLimit: PropTypes.number, onChange: PropTypes.func, isSingleSelect: PropTypes.bool, showMoreCountTextTemplate: PropTypes.string, toggleAriaLabel: PropTypes.string, selectedValuesPrefix: PropTypes.string, applyLabelPrefixForSingleMode: PropTypes.bool, applyLabelPrefixForMultiMode: PropTypes.bool, ariaLabelledById: PropTypes.string, stretchDropdownMenu: PropTypes.bool, behaveAsFlat: PropTypes.bool });
    MultiSelect.childContextTypes = {
        multiSelect: PropTypes.object,
        level: PropTypes.number,
        getOptionIdPrefix: PropTypes.func,
        setAriaActivedescendant: PropTypes.func
    };
    MultiSelect.Option = MultiSelectOption;
    MultiSelect.MasterOption = MultiSelectMasterOption;
    MultiSelect.Group = MultiSelectOptionGroup;
    MultiSelect.MultiSelectField = MultiSelectField;
    // extends defaultProps from superclass
    MultiSelect.defaultProps = __assign({}, FC.defaultProps, { isFilterable: false, labelItemsLimit: 3, testAutomationId: MultiSelectDefaultAutomationId, get searchText() {
            return lang.SEARCH;
        },
        get noResultsText() {
            return lang.NO_RESULTS;
        }, disabled: false, isSingleSelect: false, get showMoreCountTextTemplate() {
            return lang.SHOW_MORE_COUNT;
        },
        /** example string format: "{filterName} filter" */
        get toggleAriaLabel() {
            return lang.MULTI_SELECT_ARIA_LABEL;
        },
        /**  example string format: "selected {filterName}: {values}" */
        get selectedValuesPrefix() {
            return lang.MULTI_SELECT_SELECTED_TITLE_LABEL;
        }, applyLabelPrefixForSingleMode: false, applyLabelPrefixForMultiMode: true, stretchDropdownMenu: false, behaveAsFlat: false });
    return MultiSelect;
}(FormControl));
export { MultiSelect };
function appendAriaPropsForMultiSelectChildren(children) {
    var arr = _.flatten(toArray(children));
    return _.map(arr, function (child, index) {
        if (_.isEmpty(child)) {
            return child;
        }
        var childProps = child.props || {};
        return React.cloneElement(child, {
            ariaPosition: index + 1,
            ariaLevel: 1,
            ariaSetSize: arr.length
        }, childProps.children);
    });
}
function toArray(value) {
    return _.isArray(value) ? value : [value];
}
//# sourceMappingURL=MultiSelect.js.map