"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var react_1 = tslib_1.__importDefault(require("react"));
var Options_1 = require("./Options");
var downshift_1 = tslib_1.__importDefault(require("downshift"));
var find_1 = tslib_1.__importDefault(require("lodash/find"));
var react_dom_1 = require("react-dom");
var ResultBox_1 = tslib_1.__importDefault(require("../../components/ResultBox"));
var helper_1 = require("../../utils/helper");
var Spinner_1 = tslib_1.__importDefault(require("../../components/Spinner"));
var Overlay_1 = tslib_1.__importDefault(require("../../components/Overlay"));
var PopOver_1 = tslib_1.__importDefault(require("../../components/PopOver"));
var ListMenu_1 = tslib_1.__importDefault(require("../../components/ListMenu"));
var TagControl = /** @class */ (function (_super) {
    tslib_1.__extends(TagControl, _super);
    function TagControl() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.input = react_1.default.createRef();
        _this.state = {
            isOpened: false,
            inputValue: '',
            isFocused: false
        };
        return _this;
    }
    TagControl.prototype.componentWillReceiveProps = function (nextProps) {
        var props = this.props;
        if (props.value !== nextProps.value) {
            this.setState({
                inputValue: ''
            });
        }
    };
    TagControl.prototype.addItem = function (option) {
        var _a = this.props, selectedOptions = _a.selectedOptions, onChange = _a.onChange, joinValues = _a.joinValues, extractValue = _a.extractValue, delimiter = _a.delimiter, valueField = _a.valueField;
        var newValue = selectedOptions.concat();
        if (find_1.default(newValue, function (item) { return item.value == option.value; })) {
            return;
        }
        newValue.push(option);
        onChange(joinValues
            ? newValue
                .map(function (item) { return item[valueField || 'value']; })
                .join(delimiter || ',')
            : extractValue
                ? newValue.map(function (item) { return item[valueField || 'value']; })
                : newValue);
    };
    TagControl.prototype.handleFocus = function (e) {
        this.setState({
            isFocused: true,
            isOpened: true
        });
        this.props.onFocus && this.props.onFocus(e);
    };
    TagControl.prototype.handleBlur = function (e) {
        var _a = this.props, selectedOptions = _a.selectedOptions, onChange = _a.onChange, joinValues = _a.joinValues, extractValue = _a.extractValue, delimiter = _a.delimiter, valueField = _a.valueField;
        var value = this.state.inputValue.trim();
        this.props.onBlur && this.props.onBlur(e);
        this.setState({
            isFocused: false,
            isOpened: false,
            inputValue: ''
        }, value
            ? function () {
                var newValue = selectedOptions.concat();
                if (!find_1.default(newValue, function (item) { return item.value === value; })) {
                    var option = {
                        label: value,
                        value: value
                    };
                    newValue.push(option);
                    onChange(joinValues
                        ? newValue
                            .map(function (item) { return item[valueField || 'value']; })
                            .join(delimiter || ',')
                        : extractValue
                            ? newValue.map(function (item) { return item[valueField || 'value']; })
                            : newValue);
                }
            }
            : undefined);
    };
    TagControl.prototype.close = function () {
        this.setState({
            isOpened: false
        });
    };
    TagControl.prototype.handleInputChange = function (e) {
        this.setState({
            inputValue: e.currentTarget.value
        });
    };
    TagControl.prototype.handleChange = function (value) {
        var _a = this.props, joinValues = _a.joinValues, extractValue = _a.extractValue, delimiter = _a.delimiter, valueField = _a.valueField, onChange = _a.onChange;
        var newValue = Array.isArray(value) ? value.concat() : [];
        if (joinValues || extractValue) {
            newValue = value.map(function (item) { return item[valueField || 'value']; });
        }
        if (joinValues) {
            newValue = newValue.join(delimiter || ',');
        }
        onChange(newValue);
    };
    TagControl.prototype.renderItem = function (item) {
        var labelField = this.props.labelField;
        return item[labelField || 'label'];
    };
    TagControl.prototype.handleKeyDown = function (evt) {
        var _a = this.props, selectedOptions = _a.selectedOptions, onChange = _a.onChange, joinValues = _a.joinValues, extractValue = _a.extractValue, delimiter = _a.delimiter, valueField = _a.valueField;
        var value = this.state.inputValue.trim();
        if (selectedOptions.length && !value && evt.key == 'Backspace') {
            var newValue = selectedOptions.concat();
            newValue.pop();
            onChange(joinValues
                ? newValue
                    .map(function (item) { return item[valueField || 'value']; })
                    .join(delimiter || ',')
                : extractValue
                    ? newValue.map(function (item) { return item[valueField || 'value']; })
                    : newValue);
        }
        else if (value && (evt.key === 'Enter' || evt.key === delimiter)) {
            evt.preventDefault();
            evt.stopPropagation();
            var newValue = selectedOptions.concat();
            if (!find_1.default(newValue, function (item) { return item.value == value; })) {
                newValue.push({
                    label: value,
                    value: value
                });
                onChange(joinValues
                    ? newValue
                        .map(function (item) { return item[valueField || 'value']; })
                        .join(delimiter || ',')
                    : extractValue
                        ? newValue.map(function (item) { return item[valueField || 'value']; })
                        : newValue);
            }
            this.setState({
                inputValue: ''
            });
        }
    };
    TagControl.prototype.handleOptionChange = function (option) {
        if (this.state.inputValue || !option) {
            return;
        }
        this.addItem(option);
    };
    TagControl.prototype.getTarget = function () {
        return this.input.current;
    };
    TagControl.prototype.getParent = function () {
        return this.input.current && react_dom_1.findDOMNode(this.input.current).parentElement;
    };
    TagControl.prototype.reload = function () {
        var reload = this.props.reloadOptions;
        reload && reload();
    };
    TagControl.prototype.render = function () {
        var _this = this;
        var _a = this.props, className = _a.className, cx = _a.classnames, disabled = _a.disabled, placeholder = _a.placeholder, name = _a.name, clearable = _a.clearable, selectedOptions = _a.selectedOptions, loading = _a.loading, popOverContainer = _a.popOverContainer, options = _a.options;
        var finnalOptions = Array.isArray(options)
            ? helper_1.filterTree(options, function (item) {
                return (Array.isArray(item.children) && !!item.children.length) ||
                    (item.value !== undefined && !~selectedOptions.indexOf(item));
            }, 0, true)
            : [];
        return (react_1.default.createElement(downshift_1.default, { selectedItem: selectedOptions, isOpen: this.state.isFocused, inputValue: this.state.inputValue, onChange: this.handleOptionChange, itemToString: this.renderItem }, function (_a) {
            var isOpen = _a.isOpen, highlightedIndex = _a.highlightedIndex, getItemProps = _a.getItemProps, getInputProps = _a.getInputProps;
            return (react_1.default.createElement("div", { className: cx(className, "TagControl") },
                react_1.default.createElement(ResultBox_1.default, tslib_1.__assign({}, getInputProps({
                    name: name,
                    ref: _this.input,
                    placeholder: placeholder || '暂无标签',
                    onChange: _this.handleInputChange,
                    value: _this.state.inputValue,
                    onKeyDown: _this.handleKeyDown,
                    onFocus: _this.handleFocus,
                    onBlur: _this.handleBlur,
                    disabled: disabled
                }), { className: cx('TagControl-input'), result: selectedOptions, onResultChange: _this.handleChange, itemRender: _this.renderItem, clearable: clearable, allowInput: true }), loading ? react_1.default.createElement(Spinner_1.default, { size: "sm" }) : undefined),
                react_1.default.createElement(Overlay_1.default, { container: popOverContainer || _this.getParent, target: _this.getTarget, placement: 'auto', show: isOpen && !!finnalOptions.length },
                    react_1.default.createElement(PopOver_1.default, { overlay: true, className: cx('TagControl-popover'), onHide: _this.close },
                        react_1.default.createElement(ListMenu_1.default, { options: finnalOptions, itemRender: _this.renderItem, highlightIndex: highlightedIndex, getItemProps: function (_a) {
                                var item = _a.item, index = _a.index;
                                return (tslib_1.__assign({}, getItemProps({
                                    index: index,
                                    item: item,
                                    disabled: item.disabled
                                })));
                            } })))));
        }));
    };
    var _a, _b, _c, _d, _e;
    TagControl.defaultProps = {
        resetValue: '',
        labelField: 'label',
        valueField: 'value',
        multiple: true,
        placeholder: '暂无标签'
    };
    tslib_1.__decorate([
        helper_1.autobind,
        tslib_1.__metadata("design:type", Function),
        tslib_1.__metadata("design:paramtypes", [Object]),
        tslib_1.__metadata("design:returntype", void 0)
    ], TagControl.prototype, "handleFocus", null);
    tslib_1.__decorate([
        helper_1.autobind,
        tslib_1.__metadata("design:type", Function),
        tslib_1.__metadata("design:paramtypes", [Object]),
        tslib_1.__metadata("design:returntype", void 0)
    ], TagControl.prototype, "handleBlur", null);
    tslib_1.__decorate([
        helper_1.autobind,
        tslib_1.__metadata("design:type", Function),
        tslib_1.__metadata("design:paramtypes", []),
        tslib_1.__metadata("design:returntype", void 0)
    ], TagControl.prototype, "close", null);
    tslib_1.__decorate([
        helper_1.autobind,
        tslib_1.__metadata("design:type", Function),
        tslib_1.__metadata("design:paramtypes", [typeof (_a = typeof react_1.default !== "undefined" && react_1.default.ChangeEvent) === "function" ? _a : Object]),
        tslib_1.__metadata("design:returntype", void 0)
    ], TagControl.prototype, "handleInputChange", null);
    tslib_1.__decorate([
        helper_1.autobind,
        tslib_1.__metadata("design:type", Function),
        tslib_1.__metadata("design:paramtypes", [typeof (_b = typeof Array !== "undefined" && Array) === "function" ? _b : Object]),
        tslib_1.__metadata("design:returntype", void 0)
    ], TagControl.prototype, "handleChange", null);
    tslib_1.__decorate([
        helper_1.autobind,
        tslib_1.__metadata("design:type", Function),
        tslib_1.__metadata("design:paramtypes", [typeof (_c = typeof Options_1.Option !== "undefined" && Options_1.Option) === "function" ? _c : Object]),
        tslib_1.__metadata("design:returntype", void 0)
    ], TagControl.prototype, "renderItem", null);
    tslib_1.__decorate([
        helper_1.autobind,
        tslib_1.__metadata("design:type", Function),
        tslib_1.__metadata("design:paramtypes", [typeof (_d = typeof react_1.default !== "undefined" && react_1.default.KeyboardEvent) === "function" ? _d : Object]),
        tslib_1.__metadata("design:returntype", void 0)
    ], TagControl.prototype, "handleKeyDown", null);
    tslib_1.__decorate([
        helper_1.autobind,
        tslib_1.__metadata("design:type", Function),
        tslib_1.__metadata("design:paramtypes", [typeof (_e = typeof Options_1.Option !== "undefined" && Options_1.Option) === "function" ? _e : Object]),
        tslib_1.__metadata("design:returntype", void 0)
    ], TagControl.prototype, "handleOptionChange", null);
    tslib_1.__decorate([
        helper_1.autobind,
        tslib_1.__metadata("design:type", Function),
        tslib_1.__metadata("design:paramtypes", []),
        tslib_1.__metadata("design:returntype", void 0)
    ], TagControl.prototype, "getTarget", null);
    tslib_1.__decorate([
        helper_1.autobind,
        tslib_1.__metadata("design:type", Function),
        tslib_1.__metadata("design:paramtypes", []),
        tslib_1.__metadata("design:returntype", void 0)
    ], TagControl.prototype, "getParent", null);
    return TagControl;
}(react_1.default.PureComponent));
exports.default = TagControl;
var TagControlRenderer = /** @class */ (function (_super) {
    tslib_1.__extends(TagControlRenderer, _super);
    function TagControlRenderer() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    TagControlRenderer = tslib_1.__decorate([
        Options_1.OptionsControl({
            type: 'tag'
        })
    ], TagControlRenderer);
    return TagControlRenderer;
}(TagControl));
exports.TagControlRenderer = TagControlRenderer;
//# sourceMappingURL=./renderers/Form/Tag.js.map
