var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var __assign = (this && this.__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;
};
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
define(["require", "exports", "react", "../../common/DirectionalHint", "../../Callout", "../../Label", "../../Button", "../../Panel", "../../FocusZone", "../../utilities/decorators/withResponsiveMode", "../../Utilities", "./Dropdown.scss"], function (require, exports, React, DirectionalHint_1, Callout_1, Label_1, Button_1, Panel_1, FocusZone_1, withResponsiveMode_1, Utilities_1, Dropdown_scss_1) {
    "use strict";
    var Dropdown = Dropdown_1 = (function (_super) {
        __extends(Dropdown, _super);
        function Dropdown(props) {
            var _this = _super.call(this, props, {
                'isDisabled': 'disabled'
            }) || this;
            _this._id = props.id || Utilities_1.getId('Dropdown');
            var selectedKey = props.defaultSelectedKey !== undefined ? props.defaultSelectedKey : props.selectedKey;
            _this.state = {
                isOpen: false,
                selectedIndex: _this._getSelectedIndex(props.options, selectedKey)
            };
            return _this;
        }
        Dropdown.prototype.componentWillReceiveProps = function (newProps) {
            // In controlled component usage where selectedKey is provided, update the selectedIndex
            // state if the key or options change.
            if (newProps.selectedKey !== undefined &&
                (newProps.selectedKey !== this.props.selectedKey || newProps.options !== this.props.options)) {
                this.setState({
                    selectedIndex: this._getSelectedIndex(newProps.options, newProps.selectedKey)
                });
            }
        };
        Dropdown.prototype.componentDidUpdate = function (prevProps, prevState) {
            if (prevState.isOpen === true && this.state.isOpen === false) {
                this._dropDown.focus();
            }
        };
        // Primary Render
        Dropdown.prototype.render = function () {
            var id = this._id;
            var _a = this.props, className = _a.className, label = _a.label, options = _a.options, disabled = _a.disabled, isDisabled = _a.isDisabled, ariaLabel = _a.ariaLabel, required = _a.required, _b = _a.onRenderTitle, onRenderTitle = _b === void 0 ? this._onRenderTitle : _b, _c = _a.onRenderContainer, onRenderContainer = _c === void 0 ? this._onRenderContainer : _c;
            var _d = this.state, isOpen = _d.isOpen, selectedIndex = _d.selectedIndex;
            var selectedOption = options[selectedIndex];
            // Remove this deprecation workaround at 1.0.0
            if (isDisabled !== undefined) {
                disabled = isDisabled;
            }
            return (React.createElement("div", { ref: 'root' },
                label && (React.createElement(Label_1.Label, { id: id + '-label', ref: this._resolveRef('_dropdownLabel'), required: required }, label)),
                React.createElement("div", { "data-is-focusable": !disabled, ref: this._resolveRef('_dropDown'), id: id, className: Utilities_1.css('ms-Dropdown', Dropdown_scss_1.default.root, className, (_e = {
                            'is-open': isOpen
                        },
                        _e['is-disabled ' + Dropdown_scss_1.default.rootIsDisabled] = disabled,
                        _e)), tabIndex: disabled ? -1 : 0, onKeyDown: this._onDropdownKeyDown, onClick: this._onDropdownClick, "aria-expanded": isOpen ? 'true' : 'false', role: 'combobox', "aria-live": disabled || isOpen ? 'off' : 'assertive', "aria-label": ariaLabel || label, "aria-describedby": id + '-option', "aria-activedescendant": isOpen && selectedIndex >= 0 ? (this._id + '-list' + selectedIndex) : null, "aria-disabled": disabled },
                    React.createElement("span", { id: id + '-option', className: Utilities_1.css('ms-Dropdown-title', Dropdown_scss_1.default.title), key: selectedIndex, "aria-atomic": true }, selectedOption && (onRenderTitle(selectedOption, this._onRenderTitle))),
                    React.createElement("i", { className: Utilities_1.css('ms-Dropdown-caretDown ms-Icon ms-Icon--ChevronDown', Dropdown_scss_1.default.caretDown) })),
                isOpen && (onRenderContainer(this.props, this._onRenderContainer))));
            var _e;
        };
        Dropdown.prototype.focus = function () {
            if (this._dropDown && this._dropDown.tabIndex !== -1) {
                this._dropDown.focus();
            }
        };
        Dropdown.prototype.setSelectedIndex = function (index) {
            var _a = this.props, onChanged = _a.onChanged, options = _a.options;
            var selectedIndex = this.state.selectedIndex;
            index = Math.max(0, Math.min(options.length - 1, index));
            if (index !== selectedIndex) {
                // Set the selected option.
                this.setState({
                    selectedIndex: index
                });
                if (onChanged) {
                    onChanged(options[index], index);
                }
            }
        };
        // Render text in dropdown input
        Dropdown.prototype._onRenderTitle = function (item) {
            return React.createElement("span", null, item.text);
        };
        // Render Callout or Panel container and pass in list
        Dropdown.prototype._onRenderContainer = function (props) {
            var _a = this.props, _b = _a.onRenderList, onRenderList = _b === void 0 ? this._onRenderList : _b, responsiveMode = _a.responsiveMode;
            var isSmall = responsiveMode <= withResponsiveMode_1.ResponsiveMode.medium;
            return (isSmall ?
                React.createElement(Panel_1.Panel, { className: Utilities_1.css('ms-Dropdown-panel', Dropdown_scss_1.default.panel), isOpen: true, isLightDismiss: true, onDismissed: this._onDismiss, hasCloseButton: false }, onRenderList(props, this._onRenderList))
                :
                    React.createElement(Callout_1.Callout, { isBeakVisible: false, className: Utilities_1.css('ms-Dropdown-callout', Dropdown_scss_1.default.callout), gapSpace: 0, doNotLayer: false, targetElement: this._dropDown, directionalHint: DirectionalHint_1.DirectionalHint.bottomLeftEdge, onDismiss: this._onDismiss, onPositioned: this._onPositioned },
                        React.createElement("div", { style: { width: this._dropDown.clientWidth - 2 } }, onRenderList(props, this._onRenderList))));
        };
        // Render List of items
        Dropdown.prototype._onRenderList = function (props) {
            var _this = this;
            var _a = this.props.onRenderItem, onRenderItem = _a === void 0 ? this._onRenderItem : _a;
            var id = this._id;
            var selectedIndex = this.state.selectedIndex;
            return (React.createElement(FocusZone_1.FocusZone, { ref: this._resolveRef('_focusZone'), direction: FocusZone_1.FocusZoneDirection.vertical, defaultActiveElement: '#' + id + '-list' + selectedIndex, id: id + '-list', className: Utilities_1.css('ms-Dropdown-items', Dropdown_scss_1.default.items), "aria-labelledby": id + '-label', onKeyDown: this._onZoneKeyDown }, this.props.options.map(function (item, index) { return onRenderItem(__assign({}, item, { index: index }), _this._onRenderItem); })));
        };
        // Render Items
        Dropdown.prototype._onRenderItem = function (item) {
            var _this = this;
            var _a = this.props.onRenderOption, onRenderOption = _a === void 0 ? this._onRenderOption : _a;
            var id = this._id;
            return (React.createElement(Button_1.CommandButton, { id: id + '-list' + item.index, ref: Dropdown_1.Option + item.index, key: item.key, "data-index": item.index, "data-is-focusable": true, className: Utilities_1.css('ms-Dropdown-item', Dropdown_scss_1.default.item, (_b = {},
                    _b['is-selected ' + Dropdown_scss_1.default.itemIsSelected] = this.state.selectedIndex === item.index,
                    _b['is-disabled ' + Dropdown_scss_1.default.itemIsDisabled] = this.props.disabled === true,
                    _b)), onClick: function () { return _this._onItemClick(item.index); }, role: 'option', "aria-selected": this.state.selectedIndex === item.index ? 'true' : 'false', "aria-label": item.text },
                " ",
                onRenderOption(item, this._onRenderOption)));
            var _b;
        };
        // Render content of item (i.e. text/icon inside of button)
        Dropdown.prototype._onRenderOption = function (item) {
            return React.createElement("span", null, item.text);
        };
        Dropdown.prototype._onPositioned = function () {
            this._focusZone.focus();
        };
        Dropdown.prototype._onItemClick = function (index) {
            this.setSelectedIndex(index);
            this.setState({
                isOpen: false
            });
        };
        Dropdown.prototype._onDismiss = function () {
            this.setState({ isOpen: false });
            this._dropDown.focus();
        };
        Dropdown.prototype._getSelectedIndex = function (options, selectedKey) {
            return Utilities_1.findIndex(options, (function (option) { return (option.isSelected || option.selected || (selectedKey != null) && option.key === selectedKey); }));
        };
        Dropdown.prototype._onDropdownKeyDown = function (ev) {
            switch (ev.which) {
                case Utilities_1.KeyCodes.enter:
                    this.setState({
                        isOpen: !this.state.isOpen
                    });
                    break;
                case Utilities_1.KeyCodes.escape:
                    if (!this.state.isOpen) {
                        return;
                    }
                    this.setState({
                        isOpen: false
                    });
                    break;
                case Utilities_1.KeyCodes.up:
                    this.setSelectedIndex(this.state.selectedIndex - 1);
                    break;
                case Utilities_1.KeyCodes.down:
                    if (ev.altKey || ev.metaKey) {
                        this.setState({ isOpen: true });
                    }
                    else {
                        this.setSelectedIndex(this.state.selectedIndex + 1);
                    }
                    break;
                case Utilities_1.KeyCodes.home:
                    this.setSelectedIndex(0);
                    break;
                case Utilities_1.KeyCodes.end:
                    this.setSelectedIndex(this.props.options.length - 1);
                    break;
                default:
                    return;
            }
            ev.stopPropagation();
            ev.preventDefault();
        };
        Dropdown.prototype._onZoneKeyDown = function (ev) {
            switch (ev.which) {
                case Utilities_1.KeyCodes.up:
                    if (ev.altKey || ev.metaKey) {
                        this.setState({ isOpen: false });
                        break;
                    }
                    return;
                case Utilities_1.KeyCodes.escape:
                    this.setState({ isOpen: false });
                    break;
                default:
                    return;
            }
            ev.stopPropagation();
            ev.preventDefault();
        };
        Dropdown.prototype._onDropdownClick = function () {
            var _a = this.props, disabled = _a.disabled, isDisabled = _a.isDisabled;
            var isOpen = this.state.isOpen;
            // Remove this deprecation workaround at 1.0.0
            if (isDisabled !== undefined) {
                disabled = isDisabled;
            }
            if (!disabled) {
                this.setState({
                    isOpen: !isOpen
                });
            }
        };
        return Dropdown;
    }(Utilities_1.BaseComponent));
    Dropdown.defaultProps = {
        options: []
    };
    Dropdown.Option = 'option';
    __decorate([
        Utilities_1.autobind
    ], Dropdown.prototype, "_onRenderTitle", null);
    __decorate([
        Utilities_1.autobind
    ], Dropdown.prototype, "_onRenderContainer", null);
    __decorate([
        Utilities_1.autobind
    ], Dropdown.prototype, "_onRenderList", null);
    __decorate([
        Utilities_1.autobind
    ], Dropdown.prototype, "_onRenderItem", null);
    __decorate([
        Utilities_1.autobind
    ], Dropdown.prototype, "_onRenderOption", null);
    __decorate([
        Utilities_1.autobind
    ], Dropdown.prototype, "_onPositioned", null);
    __decorate([
        Utilities_1.autobind
    ], Dropdown.prototype, "_onDismiss", null);
    __decorate([
        Utilities_1.autobind
    ], Dropdown.prototype, "_onDropdownKeyDown", null);
    __decorate([
        Utilities_1.autobind
    ], Dropdown.prototype, "_onZoneKeyDown", null);
    __decorate([
        Utilities_1.autobind
    ], Dropdown.prototype, "_onDropdownClick", null);
    Dropdown = Dropdown_1 = __decorate([
        withResponsiveMode_1.withResponsiveMode
    ], Dropdown);
    exports.Dropdown = Dropdown;
    var Dropdown_1;
});

//# sourceMappingURL=Dropdown.js.map
