"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Input = void 0;
const tslib_1 = require("tslib");
const classnames_1 = tslib_1.__importDefault(require("classnames"));
const react_1 = tslib_1.__importDefault(require("react"));
const icon_1 = require("../icon");
const warning_1 = tslib_1.__importDefault(require("../utils/warning"));
require("./input.less");
function isUndefined(obj) {
    return typeof obj === 'undefined';
}
// copied from https://github.com/ant-design/ant-design/blob/master/components/input/Input.tsx#L33
// simulate a Form.ChangeEvent in react.js
function resolveOnChange(target, e, onChange) {
    if (typeof onChange === 'function') {
        let event = e;
        if (e.type === 'click') {
            // click clear icon
            event = Object.create(e);
            event.target = target;
            event.currentTarget = target;
            const originalInputValue = target.value;
            // change target ref value cause e.target.value should be '' when clear input
            target.value = '';
            onChange(event);
            // reset target ref value
            target.value = originalInputValue;
            return;
        }
        onChange(event);
    }
}
exports.Input = react_1.default.forwardRef((props, ref) => {
    const { defaultValue, className, wrapperStyle, size = 'default', controls, onChange, selection, addonBefore, addonAfter, persistFocus = true, hasClear, afterClear, value, onValueChange, onPressEnter, onKeyDown, as: Component = 'input', ...restProps } = props;
    (0, warning_1.default)(!controls, '[@opensumi/ide-components Input]: `controls` was deprecated, please use `addonAfter` instead');
    const inputRef = react_1.default.useRef(null);
    const [isDirty, setIsDirty] = react_1.default.useState(false);
    // handle initial value from `value` or `defaultValue`
    const [inputValue, setInputValue] = react_1.default.useState(() => (value !== null && value !== void 0 ? value : defaultValue) || '');
    const [preValue, setPrevValue] = react_1.default.useState(() => (value !== null && value !== void 0 ? value : defaultValue) || '');
    // make `ref` to input works
    react_1.default.useImperativeHandle(ref, () => inputRef.current);
    // handle `selection`
    react_1.default.useEffect(() => {
        if (selection && !isUndefined(selection.start) && !isDirty) {
            inputRef.current.setSelectionRange(selection.start, selection.end);
        }
    }, [selection, isDirty]);
    // implements for `getDerivedStateFromProps` to update `state#inputValue` from `props#value`
    react_1.default.useEffect(() => {
        // what if value is null??
        // 如果不加这一句的话，后面又会把 inputValue 设置成 null
        if (value === null || typeof value === 'undefined') {
            return;
        }
        if (value !== preValue && value !== inputValue) {
            setInputValue(value);
        }
        // save prev props into state
        if (value !== preValue) {
            setPrevValue(value);
        }
    }, [value]);
    const handleChange = (e) => {
        triggerChange(e.target.value);
        resolveOnChange(inputRef.current, e, onChange);
    };
    const handleClearIconClick = (e) => {
        e.preventDefault();
        triggerChange('');
        resolveOnChange(inputRef.current, e, onChange);
        if (typeof afterClear === 'function') {
            afterClear();
        }
    };
    const triggerChange = (value) => {
        setInputValue(value);
        if (typeof onValueChange === 'function') {
            onValueChange(value);
        }
        // trigger `dirty` state
        if (!isDirty) {
            setIsDirty(true);
        }
    };
    const handleKeyDown = (e) => {
        if (e.keyCode === 13 && typeof onPressEnter === 'function') {
            onPressEnter(e);
        }
        if (typeof onKeyDown === 'function') {
            onKeyDown(e);
        }
    };
    // addonAfter 优先级高于被废弃的 controls 属性
    const addonAfterNode = addonAfter || controls;
    const persistFocusProps = persistFocus
        ? {
            onMouseDown: (e) => {
                e.preventDefault();
            },
        }
        : {};
    const addonRender = (addonNodes, klassName) => {
        if (!addonNodes) {
            return null;
        }
        return (react_1.default.createElement("div", { className: (0, classnames_1.default)('kt-input-addon', klassName), ...persistFocusProps }, react_1.default.Children.map(addonNodes, (child) => react_1.default.isValidElement(child) ? react_1.default.cloneElement(child, persistFocusProps) : null)));
    };
    const inputClx = (0, classnames_1.default)('kt-input', className, {
        [`kt-input-${size}`]: size,
        ['kt-input-disabled']: props.disabled,
    });
    return (react_1.default.createElement("div", { className: inputClx, style: wrapperStyle },
        addonRender(addonBefore, 'kt-input-addon-before'),
        react_1.default.createElement("div", { className: 'kt-input-box' },
            react_1.default.createElement(Component, { ref: inputRef, type: 'text', autoCapitalize: 'off', autoCorrect: 'off', autoComplete: 'off', spellCheck: false, ...restProps, value: inputValue, onChange: handleChange, onKeyDown: handleKeyDown }),
            hasClear && inputValue && (react_1.default.createElement(icon_1.Icon, { className: 'kt-input-clear', icon: 'close-circle-fill', onClick: handleClearIconClick, ...persistFocusProps }))),
        addonRender(addonAfterNode, 'kt-input-addon-after')));
});
exports.Input.displayName = 'OpenSumiInput';
//# sourceMappingURL=Input.js.map