var _a, _b;
import { __awaiter, __decorate, __extends, __generator } from "tslib";
import { Component, Emit, Prop, Watch } from 'vue-property-decorator';
import { InputWidth } from '../../../mixins/input-width/input-width';
import { POPUP_NAME as DIRECTIVE_POPUP_NAME } from '../../../directives/directive-names';
import { MPopupDirective } from '../../../directives/popup/popup';
import { MediaQueries } from '../../../mixins/media-queries/media-queries';
import { ModulVue } from '../../../utils/vue/vue';
import { POPUP_NAME } from '../../component-names';
import { MPopup } from '../../popup/popup';
import { MSelectItem } from '../../select/select-item/select-item';
import WithRender from './base-select.html';
import './base-select.scss';
var DROPDOWN_STYLE_TRANSITION = 'max-height 0.3s ease';
var MBaseSelect = /** @class */ (function (_super) {
    __extends(MBaseSelect, _super);
    function MBaseSelect() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.internalOpen = false;
        _this.focusedIndex = -1;
        return _this;
    }
    MBaseSelect.prototype.onOpen = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.$nextTick()];
                    case 1:
                        _a.sent();
                        this.focusFirstSelected();
                        this.scrollToFocused();
                        this.$emit('update:open', true);
                        return [2 /*return*/];
                }
            });
        });
    };
    Object.defineProperty(MBaseSelect.prototype, "ariaControls", {
        get: function () {
            return this.controlId + '-controls';
        },
        enumerable: true,
        configurable: true
    });
    MBaseSelect.prototype.onClose = function () {
        this.$emit('update:open', false);
        this.focusedIndex = -1;
    };
    MBaseSelect.prototype.select = function (option, index, $event) {
        this.$emit('select-item', option, index, $event);
    };
    MBaseSelect.prototype.onPopupOpen = function (open) {
        if (open !== this.internalOpen) {
            this.internalOpen = open;
        }
    };
    MBaseSelect.prototype.onSelectItem = function (option, index, $event) {
        this.select(option, index, $event);
        if (this.closeOnSelect) {
            this.closePopup();
        }
    };
    MBaseSelect.prototype.getItemProps = function (item, index) {
        return {
            value: item,
            focused: index === this.focusedIndex,
            selected: this.isSelected(item),
            hideRadioButtonMobile: this.hideRadioButtonMobile
        };
    };
    MBaseSelect.prototype.getItemHandlers = function (item, index) {
        var _this = this;
        return {
            click: function (event) { return _this.onSelectItem(item, index, event); }
        };
    };
    MBaseSelect.prototype.togglePopup = function () {
        if (this.active) {
            this.internalOpen = !this.internalOpen;
        }
    };
    MBaseSelect.prototype.closePopup = function () {
        this.internalOpen = false;
    };
    MBaseSelect.prototype.setFocusedIndex = function (index) {
        this.focusedIndex = index;
    };
    MBaseSelect.prototype.selectFocusedItem = function ($event) {
        this.select(this.items[this.focusedIndex], this.focusedIndex, $event);
    };
    MBaseSelect.prototype.focusFirstSelected = function () {
        if (this.selectedItems && this.selectedItems.length > 0) {
            this.focusedIndex = this.items.indexOf(this.selectedItems[0]);
        }
        else {
            this.focusedIndex = 0;
        }
    };
    MBaseSelect.prototype.focusNextItem = function () {
        if (this.focusedIndex > -1) {
            this.focusedIndex++;
            if (this.focusedIndex >= this.items.length) {
                this.focusedIndex = 0;
            }
        }
        else {
            this.focusedIndex = this.items.length === 0 ? -1 : 0;
        }
        this.scrollToFocused();
    };
    MBaseSelect.prototype.focusPreviousItem = function () {
        if (this.focusedIndex > -1) {
            this.focusedIndex--;
            if (this.focusedIndex < 0) {
                this.focusedIndex = this.items.length - 1;
            }
        }
        else {
            this.focusedIndex = this.items.length - 1;
        }
        this.scrollToFocused();
    };
    MBaseSelect.prototype.update = function () {
        this.$refs.popup.update();
    };
    MBaseSelect.prototype.isSelected = function (option) {
        if (this.selectedItems && this.selectedItems.length > 0) {
            return this.selectedItems.indexOf(option) > -1;
        }
        return false;
    };
    MBaseSelect.prototype.scrollToFocused = function () {
        if (this.focusedIndex > -1 && this.as().isMqMinS) {
            var container = this.$refs.items;
            if (container) {
                var element = container.children[this.focusedIndex];
                if (element) {
                    var top_1 = element.offsetTop;
                    var bottom = element.offsetTop + element.offsetHeight;
                    var viewRectTop = container.scrollTop;
                    var viewRectBottom = viewRectTop + container.clientHeight;
                    if (top_1 < viewRectTop) {
                        container.scrollTop = top_1;
                    }
                    else if (bottom > viewRectBottom) {
                        container.scrollTop = bottom - container.clientHeight;
                    }
                }
            }
        }
    };
    MBaseSelect.prototype.findFirstItemWithLetter = function (key) {
        if (this.as().isMqMinS) {
            var index = this.items.indexOf(this.items.find(function (item) { return item.startsWith(key); }));
            if (index !== -1) {
                this.focusedIndex = index;
                this.scrollToFocused();
            }
        }
    };
    MBaseSelect.prototype.transitionEnter = function (el, done) {
        var _this = this;
        if (this.enableAnimation) {
            this.$nextTick(function () {
                if (_this.as().isMqMinS) {
                    var height_1 = el.clientHeight;
                    el.style.transition = DROPDOWN_STYLE_TRANSITION;
                    el.style.overflowY = 'hidden';
                    el.style.maxHeight = '0';
                    el.style.width = _this.$el.clientWidth + 'px';
                    if (_this.listMinWidth) {
                        el.style.minWidth = _this.listMinWidth;
                    }
                    requestAnimationFrame(function () {
                        el.style.maxHeight = height_1 + 'px';
                        done();
                    });
                }
                else {
                    done();
                }
            });
        }
        else {
            done();
        }
    };
    MBaseSelect.prototype.transitionLeave = function (el, done) {
        var _this = this;
        if (this.enableAnimation) {
            this.$nextTick(function () {
                if (_this.as().isMqMinS) {
                    var height = el.clientHeight;
                    el.style.maxHeight = height + 'px';
                    el.style.maxHeight = '0';
                    setTimeout(function () {
                        el.style.maxHeight = 'none';
                        done();
                    }, 300);
                }
                else {
                    done();
                }
            });
        }
        else {
            done();
        }
    };
    // keyboard navigation of a drowdown
    // tab or esc : close the popup
    // up and down : change the focused option
    // enter : select the focused option and close popup
    // space : open the popup
    MBaseSelect.prototype.onKeydownDown = function ($event) {
        if (!this.internalOpen) {
            this.togglePopup();
        }
        else {
            this.focusNextItem();
        }
    };
    MBaseSelect.prototype.onKeydownUp = function ($event) {
        if (!this.internalOpen) {
            this.togglePopup();
        }
        this.focusPreviousItem();
    };
    MBaseSelect.prototype.onKeydownSpace = function ($event) {
        if (this.focusedIndex > -1) {
            this.select(this.items[this.focusedIndex], this.focusedIndex, $event);
            this.closePopup();
        }
        else {
            this.togglePopup();
        }
    };
    MBaseSelect.prototype.onKeydownTab = function ($event) {
        this.closePopup();
    };
    MBaseSelect.prototype.onKeydownEsc = function ($event) {
        this.closePopup();
    };
    MBaseSelect.prototype.onKeydownEnter = function ($event) {
        if (this.focusedIndex > -1) {
            this.select(this.items[this.focusedIndex], this.focusedIndex, $event);
            this.closePopup();
        }
        else {
            this.togglePopup();
        }
    };
    MBaseSelect.prototype.onKeydownHome = function ($event) {
        if (this.internalOpen) {
            this.focusedIndex = 0;
            this.scrollToFocused();
        }
    };
    MBaseSelect.prototype.onKeydownEnd = function ($event) {
        if (this.internalOpen) {
            this.focusedIndex = this.items.length - 1;
            this.scrollToFocused();
        }
    };
    MBaseSelect.prototype.onKeydownLetter = function ($event) {
        if (/^[a-z0-9]$/i.test($event.key)) {
            this.findFirstItemWithLetter($event.key);
        }
    };
    __decorate([
        Prop()
    ], MBaseSelect.prototype, "items", void 0);
    __decorate([
        Prop()
    ], MBaseSelect.prototype, "selectedItems", void 0);
    __decorate([
        Prop()
    ], MBaseSelect.prototype, "active", void 0);
    __decorate([
        Prop({ required: true })
    ], MBaseSelect.prototype, "controlId", void 0);
    __decorate([
        Prop({ default: false })
    ], MBaseSelect.prototype, "open", void 0);
    __decorate([
        Prop({ default: true })
    ], MBaseSelect.prototype, "closeOnSelect", void 0);
    __decorate([
        Prop({ default: false })
    ], MBaseSelect.prototype, "hideRadioButtonMobile", void 0);
    __decorate([
        Prop({ default: false })
    ], MBaseSelect.prototype, "sidebarFullHeight", void 0);
    __decorate([
        Prop({ default: true })
    ], MBaseSelect.prototype, "enableAnimation", void 0);
    __decorate([
        Prop({ default: false })
    ], MBaseSelect.prototype, "virtualScroll", void 0);
    __decorate([
        Prop()
    ], MBaseSelect.prototype, "listMinWidth", void 0);
    __decorate([
        Emit('open')
    ], MBaseSelect.prototype, "onOpen", null);
    __decorate([
        Emit('close')
    ], MBaseSelect.prototype, "onClose", null);
    __decorate([
        Watch('open', { immediate: true })
    ], MBaseSelect.prototype, "onPopupOpen", null);
    MBaseSelect = __decorate([
        WithRender,
        Component({
            components: (_a = {
                    MSelectItem: MSelectItem
                },
                _a[POPUP_NAME] = MPopup,
                _a),
            directives: (_b = {},
                _b[DIRECTIVE_POPUP_NAME] = MPopupDirective,
                _b),
            mixins: [
                InputWidth,
                MediaQueries
            ]
        })
    ], MBaseSelect);
    return MBaseSelect;
}(ModulVue));
export { MBaseSelect };
//# sourceMappingURL=base-select.js.map