import { __assign, __awaiter, __generator } from "tslib";
import { withThemeableProps } from '../../useThemeable';
import { classNamesFunction, getId } from '@uifabric-vue/utilities';
import Vue from 'vue';
import { Label } from '../Label';
var getClassNames = classNamesFunction();
var COMPONENT_NAME = 'TextField';
export var TextFieldBase = Vue.extend({
    name: 'TextFieldBase',
    inheritAttrs: false,
    props: __assign(__assign({}, withThemeableProps()), { multiline: { type: Boolean, default: false }, resizable: { type: Boolean, default: null }, autoAdjustHeight: { type: Boolean, default: null }, borderless: { type: Boolean, default: false }, disabled: { type: Boolean, default: false }, underlined: { type: Boolean, default: false }, focused: { type: Boolean, default: false }, readonly: { type: Boolean, default: false }, required: { type: Boolean, default: false }, label: { type: String, default: null }, value: { type: String, default: '' }, errorMessage: { type: String, default: null }, placeholder: { type: String, default: null }, description: { type: String, default: null } }),
    data: function () {
        return {
            isFocused: false,
            internalValue: this.value || '',
        };
    },
    computed: {
        classNames: function () {
            return getClassNames(this.styles, {
                theme: this.theme,
                className: this.className,
                disabled: this.disabled,
                focused: this.focused,
                required: this.required,
                multiline: this.multiline,
                hasLabel: !!this.label,
                borderless: this.borderless,
                underlined: this.underlined,
                hasIcon: false,
                resizable: this.resizable !== false,
                hasErrorMessage: !!this.errorMessage,
                inputClassName: '',
                autoAdjustHeight: this.autoAdjustHeight,
            });
        },
        descriptionId: function () {
            return getId(COMPONENT_NAME + 'Description');
        },
        fallbackId: function () {
            return getId(COMPONENT_NAME);
        },
        labelId: function () {
            return getId(COMPONENT_NAME + 'Label');
        },
    },
    watch: {
        value: function (newValue) {
            this.internalValue = newValue;
        },
        multiline: function (newValue, oldValue) {
            return __awaiter(this, void 0, void 0, function () {
                var textElement, start, end;
                return __generator(this, function (_a) {
                    switch (_a.label) {
                        case 0:
                            textElement = this.$refs.textElement;
                            start = textElement.selectionStart || 0;
                            end = textElement.selectionEnd || 0;
                            if (!((newValue !== oldValue) && this.isFocused)) return [3 /*break*/, 2];
                            return [4 /*yield*/, this.$nextTick()];
                        case 1:
                            _a.sent();
                            this.$refs.textElement.focus();
                            this.$refs.textElement.setSelectionRange(start, end);
                            _a.label = 2;
                        case 2: return [2 /*return*/];
                    }
                });
            });
        },
    },
    mounted: function () {
        this.adjustInputHeight();
    },
    updated: function () {
        this.adjustInputHeight();
    },
    methods: {
        adjustInputHeight: function () {
            if (this.$refs.textElement && this.autoAdjustHeight && this.multiline) {
                var textField = this.$refs.textElement;
                textField.style.height = '';
                textField.style.height = textField.scrollHeight + 'px';
            }
        },
        onFocus: function () {
            return __awaiter(this, void 0, void 0, function () {
                return __generator(this, function (_a) {
                    this.isFocused = true;
                    this.$refs.textElement.setSelectionRange(this.internalValue.length, this.internalValue.length);
                    return [2 /*return*/];
                });
            });
        },
        onInput: function (ev, value) {
            this.internalValue = value;
            this.$emit('input', value);
            this.$emit('change', ev, value);
        },
    },
    render: function (h) {
        var _this = this;
        var _a, _b;
        var _c = this, classNames = _c.classNames, required = _c.required, label = _c.label, errorMessage = _c.errorMessage, disabled = _c.disabled, multiline = _c.multiline, internalValue = _c.internalValue, readonly = _c.readonly, placeholder = _c.placeholder, resizable = _c.resizable;
        var Component = multiline ? 'textarea' : 'input';
        var id = this.$attrs.id || this.fallbackId;
        var onRenderLabel = function (props) {
            var label = props.label, disabled = props.disabled, required = props.required;
            var labelStyles = classNames.subComponentStyles
                ? classNames.subComponentStyles.label
                : undefined;
            if (!label)
                return null;
            return h(Label, {
                attrs: {
                    id: _this.labelId,
                    for: id,
                },
                props: {
                    styles: labelStyles,
                    disabled: disabled,
                    required: required,
                },
            }, label);
        };
        var onRenderDescription = function (props) {
            if (!_this.description)
                return null;
            return h('span', {
                class: classNames.description,
            }, _this.description);
        };
        var $label = ((_a = this.$scopedSlots.onRenderLabel) !== null && _a !== void 0 ? _a : onRenderLabel)(this.$props);
        var $fieldGroup = h('div', { class: classNames.fieldGroup }, [
            h(Component, {
                ref: 'textElement',
                class: classNames.field,
                attrs: __assign(__assign({}, this.$attrs), { id: id, value: internalValue, disabled: disabled, readonly: readonly, required: required, placeholder: placeholder, rows: +this.$attrs.rows || 1, type: 'text', autocomplete: 'off' }),
                style: { resize: (resizable === false) && 'none' },
                on: {
                    focus: this.onFocus,
                    blur: function () { return (_this.isFocused = false); },
                    input: function (ev) { return _this.onInput(ev, ev.target.value); },
                },
            }, internalValue),
        ]);
        var $errorMessage = errorMessage && h('div', { class: classNames.description }, [
            h('div', { attrs: { role: 'alert' } }, [
                h('p', { class: classNames.errorMessage }, [
                    h('span', errorMessage),
                ]),
            ]),
        ]);
        return h('div', { class: classNames.root }, [
            h('div', { class: classNames.wrapper }, [
                $label,
                $fieldGroup,
            ]),
            h('span', { attrs: { id: this.descriptionId } }, [
                ((_b = this.$scopedSlots.onRenderDescription) !== null && _b !== void 0 ? _b : onRenderDescription)(this.$props),
                $errorMessage,
            ]),
        ]);
    },
});
//# sourceMappingURL=TextField.base.js.map