zent
Version:
一套前端设计语言和基于React的实现
227 lines (226 loc) • 9.69 kB
JavaScript
import { __assign, __extends } from "tslib";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Component, createRef } from 'react';
import cn from 'classnames';
import memoize from '../utils/memorize-one';
import Input from '../input';
import Popover from '../popover';
import SelectMenu from '../select-menu';
import { DisabledContext } from '../disabled';
var caselessMatchFilterOption = SelectMenu.caselessMatchFilterOption;
var AutoComplete = (function (_super) {
__extends(AutoComplete, _super);
function AutoComplete(props) {
var _this = _super.call(this, props) || this;
_this.blurHandlerPrevented = false;
_this.refMenuItemList = createRef();
_this.onSearchTextChange = function (e) {
var searchText = e.target.value;
var value = _this.props.valueFromOptions
? _this.getSelectedValueFromSearchText(searchText)
: searchText;
_this.setState({
searchText: searchText,
value: value,
});
if (!_this.state.open) {
_this.open();
}
_this.props.onSearch && _this.props.onSearch(searchText);
_this.props.onChange && _this.props.onChange(value);
};
_this.onSearchKeyDown = function (e) {
switch (e.key) {
case 'Escape':
_this.close();
break;
case 'Tab':
_this.close();
break;
case 'ArrowDown':
e.preventDefault();
if (_this.state.open) {
_this.moveFocusIndexDown();
}
break;
case 'ArrowUp': {
e.preventDefault();
if (_this.state.open) {
_this.moveFocusIndexUp();
}
break;
}
case 'Enter': {
if (_this.state.open) {
_this.selectCurrentFocusIndex(e);
}
break;
}
default:
}
};
_this.onSearchBlur = function () {
if (_this.props.valueFromOptions) {
setTimeout(function () {
if (!_this.blurHandlerPrevented) {
var _a = _this.state, searchText = _a.searchText, value = _a.value;
var selectedValue = _this.getSelectedValueFromSearchText(searchText);
if (selectedValue) {
if (selectedValue !== value) {
_this.props.onSelect && _this.props.onSelect(selectedValue);
_this.props.onChange && _this.props.onChange(selectedValue);
}
}
else {
_this.props.onSelect && _this.props.onSelect(null);
_this.props.onChange && _this.props.onChange(null);
}
}
_this.blurHandlerPrevented = false;
}, 100);
}
};
_this.getSelectedValueFromSearchText = function (searchText) {
var selectedValue = null;
_this.getTransformedItemConfigsFromProps().some(function (item) {
if (item.searchContent === searchText ||
item.content === searchText ||
item.value === searchText) {
selectedValue = item.value;
return true;
}
return false;
});
return selectedValue;
};
_this.onSelect = function (value) {
_this.blurHandlerPrevented = true;
_this.setState({
value: value,
});
_this.props.onSelect && _this.props.onSelect(value);
_this.props.onChange && _this.props.onChange(value);
_this.close();
};
_this.getTransformedItemConfigs = memoize(function (valueField, textField, contentField, items, data) {
return (items || data || []).map(function (item) {
if (typeof item === 'string' || typeof item === 'number') {
return {
value: item,
content: item,
};
}
if (typeof item === 'object') {
return __assign(__assign({}, item), { value: item[valueField], content: item[contentField] || item[textField] || item[valueField] });
}
throw new Error('AutoComplete unresolvable option!');
});
});
_this.getDisplayText = function () {
var value = _this.state.value;
var displayValue = value || '';
var item = _this.getItemByValue(value);
if (item) {
if (typeof item.searchContent === 'string') {
displayValue = item.searchContent;
}
else if (typeof item.content === 'string') {
displayValue = item.content;
}
}
return displayValue;
};
_this.open = function () {
var newState = {
open: true,
searchText: _this.getDisplayText() || '',
};
_this.setState(newState);
};
_this.close = function () {
_this.setState({
open: false,
});
};
_this.togglePopoverOpen = function () {
if (_this.state.open) {
_this.close();
}
else {
_this.open();
}
};
_this.iterateItems = function (items, value) {
var result = null;
(items || []).some(function (item) {
if (item && item.value === value) {
result = item;
return true;
}
return false;
});
return result;
};
_this.getItemByValue = function (value) {
return _this.iterateItems(_this.getTransformedItemConfigsFromProps(), value);
};
_this.moveFocusIndexDown = function () {
var menuList = _this.refMenuItemList.current;
if (menuList) {
return menuList.moveFocusIndexDown();
}
};
_this.moveFocusIndexUp = function () {
var menuList = _this.refMenuItemList.current;
if (menuList) {
return menuList.moveFocusIndexUp();
}
};
_this.selectCurrentFocusIndex = function (e) {
var menuList = _this.refMenuItemList.current;
if (menuList) {
return menuList.selectCurrentFocusIndex(e);
}
};
_this.state = {
open: false,
value: props.initialValue || props.value || null,
searchText: '',
};
return _this;
}
AutoComplete.getDerivedStateFromProps = function (props, state) {
var value = props.value;
return value === undefined || state.value === value
? null
: {
value: props.value,
};
};
AutoComplete.prototype.getTransformedItemConfigsFromProps = function () {
var _a = this.props, items = _a.items, data = _a.data, textField = _a.textField, valueField = _a.valueField, contentField = _a.contentField;
return this.getTransformedItemConfigs(valueField, textField, contentField, items, data);
};
AutoComplete.prototype.render = function () {
var _a = this.props, width = _a.width, placeholder = _a.placeholder, className = _a.className, popupClassName = _a.popupClassName, _b = _a.disabled, disabled = _b === void 0 ? this.context.value : _b, inline = _a.inline;
var _c = this.state, open = _c.open, searchText = _c.searchText;
var items = this.getTransformedItemConfigsFromProps();
var prefixCls = 'zent-auto-complete';
var displayValue = this.getDisplayText();
return (_jsxs(Popover, __assign({ position: Popover.Position.AutoBottomLeft, visible: open, className: cn(prefixCls, popupClassName), onVisibleChange: this.togglePopoverOpen, cushion: 4 }, { children: [_jsx(Popover.Trigger.Click, { children: _jsx(Input, { className: cn('zent-auto-complete', className, {
active: open,
}), value: (open ? searchText : displayValue) || '', placeholder: placeholder, onChange: this.onSearchTextChange, onKeyDown: this.onSearchKeyDown, onBlur: this.onSearchBlur, disabled: disabled, width: width, inline: inline }, void 0) }, void 0), _jsx(Popover.Content, { children: _jsx(SelectMenu, { ref: this.refMenuItemList, items: items, value: this.state.value, searchText: this.state.searchText, onSelect: this.onSelect, filterOption: this.props.filterOption, onRequestClose: this.close }, void 0) }, void 0)] }), void 0));
};
AutoComplete.defaultProps = {
filterOption: caselessMatchFilterOption,
valueFromOptions: false,
valueField: 'value',
contentField: 'content',
textField: 'text',
width: 160,
};
AutoComplete.contextType = DisabledContext;
return AutoComplete;
}(Component));
export { AutoComplete };
export default AutoComplete;