chowa
Version:
UI component library based on React
161 lines (160 loc) • 6.24 kB
JavaScript
/**
* @license chowa v1.1.3
*
* Copyright (c) Chowa Techonlogies Co.,Ltd.(http://www.chowa.cn).
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const React = require("react");
const PropTypes = require("prop-types");
const utils_1 = require("../utils");
const classNames = require("classnames");
const input_1 = require("../input");
const dropdown_1 = require("../dropdown");
const tool_1 = require("./tool");
const auto_complete_selector_1 = require("./auto-complete-selector");
class AutoComplete extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
result: props.value || props.defaultValue,
hasChange: false,
activeValue: undefined,
renderOptions: props.options
};
[
'onInputChangeHandler',
'onKeyDownHandler',
'updateActiveValue',
'onSelectValue',
'onVisibleChangeHandler'
].forEach((fn) => {
this[fn] = this[fn].bind(this);
});
}
componentDidUpdate(preProps) {
if (!utils_1.isEqual(preProps.options, this.props.options)) {
this.setState({
activeValue: undefined,
renderOptions: tool_1.compileOptions(this.props.options, this.props.mode, this.state.result)
});
}
if (preProps.value !== this.props.value && this.state.result !== this.props.value) {
this.setState({
activeValue: undefined,
result: this.props.value,
renderOptions: tool_1.compileOptions(this.props.options, this.props.mode, this.props.value)
});
}
}
onInputChangeHandler(e) {
const { options, mode } = this.props;
const result = e.target.value;
this.setState({
result,
hasChange: true,
renderOptions: tool_1.compileOptions(options, mode, result)
}, () => {
this.triggerChange();
});
}
onKeyDownHandler(e) {
const { result, hasChange, renderOptions, activeValue } = this.state;
const { mode } = this.props;
if (!utils_1.isExist(result) || !hasChange) {
return;
}
switch (e.keyCode) {
case 40:
this.setState({
activeValue: tool_1.getNextValue(renderOptions, activeValue)
});
e.preventDefault();
break;
case 38:
this.setState({
activeValue: tool_1.getPreValue(renderOptions, activeValue)
});
e.preventDefault();
break;
case 13:
if (utils_1.isExist(activeValue)) {
this.setState({
result: mode === 'concat'
? `${result}${activeValue}`
: `${activeValue}`,
renderOptions: [],
activeValue: undefined
}, () => {
this.triggerChange();
});
}
e.preventDefault();
break;
}
}
onVisibleChangeHandler(v) {
if (!v) {
this.inputIns.blur();
}
}
triggerChange() {
const { result } = this.state;
if (this.props.onChange) {
this.props.onChange(result);
}
}
updateActiveValue(value) {
this.setState({
activeValue: value
});
}
onSelectValue(displayValue) {
this.setState({
result: `${displayValue}`,
hasChange: false,
renderOptions: [],
activeValue: undefined
}, () => {
this.triggerChange();
});
}
renderDrop() {
const { result, hasChange, renderOptions, activeValue } = this.state;
const { mode, formatter, size, concatExempt } = this.props;
if (!utils_1.isExist(result)
|| !hasChange
|| !utils_1.isExist(renderOptions)
|| ((mode === 'concat' && utils_1.isExist(concatExempt) && result.indexOf(concatExempt) > -1))) {
return null;
}
return (React.createElement(auto_complete_selector_1.default, { searchValue: result, options: renderOptions, mode: mode, formatter: formatter, size: size, activeValue: activeValue, updateActiveValue: this.updateActiveValue, onSelectValue: this.onSelectValue }));
}
render() {
const { className, size, autoFocus, disabled, externalWheelHide, placeholder, addonBefore, addonAfter, prefix, suffix, prepend, append, onPressEnter, clearable, tabIndex, style } = this.props;
const { result } = this.state;
const componentClass = classNames({
[utils_1.preClass('auto-complete')]: true,
[className]: utils_1.isExist(className)
});
return (React.createElement(dropdown_1.default, { trigger: 'focus', onVisibleChange: this.onVisibleChangeHandler, externalWheelHide: externalWheelHide, matchTriggerWidth: true, content: this.renderDrop() },
React.createElement(input_1.default, { className: componentClass, style: style, size: size, tabIndex: tabIndex, autoFocus: autoFocus, disabled: disabled, placeholder: placeholder, addonBefore: addonBefore, addonAfter: addonAfter, prefix: prefix, suffix: suffix, prepend: prepend, append: append, onPressEnter: onPressEnter, onChange: this.onInputChangeHandler, clearable: clearable, onKeyDown: this.onKeyDownHandler, value: result, ref: (ins) => {
this.inputIns = ins;
} })));
}
}
AutoComplete.propTypes = {
mode: PropTypes.oneOf(['concat', 'search', 'remote']),
concatExempt: PropTypes.string,
options: PropTypes.array.isRequired,
externalWheelHide: PropTypes.bool,
formatter: PropTypes.func
};
AutoComplete.defaultProps = {
mode: 'concat',
externalWheelHide: true
};
exports.default = AutoComplete;