bee-select
Version:
select ui component for react
1,517 lines (1,344 loc) • 52.1 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _reactLifecyclesCompat = require('react-lifecycles-compat');
var _tinperBeeCore = require('tinper-bee-core');
var _classnames2 = require('classnames');
var _classnames3 = _interopRequireDefault(_classnames2);
var _beeAnimate = require('bee-animate');
var _beeAnimate2 = _interopRequireDefault(_beeAnimate);
var _componentClasses = require('component-classes');
var _componentClasses2 = _interopRequireDefault(_componentClasses);
var _rcMenu = require('rc-menu');
var _MenuItem = require('rc-menu/lib/MenuItem');
var _MenuItem2 = _interopRequireDefault(_MenuItem);
var _warning = require('warning');
var _warning2 = _interopRequireDefault(_warning);
var _Option = require('./Option');
var _Option2 = _interopRequireDefault(_Option);
var _omit = require('omit.js');
var _omit2 = _interopRequireDefault(_omit);
var _util = require('./util');
var _SelectTrigger = require('./SelectTrigger');
var _SelectTrigger2 = _interopRequireDefault(_SelectTrigger);
var _PropTypes = require('./PropTypes');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); } /**
* This source code is quoted from rc-select.
* homepage: https://github.com/react-component/select
*/
function noop() {}
function chaining() {
for (var _len = arguments.length, fns = Array(_len), _key = 0; _key < _len; _key++) {
fns[_key] = arguments[_key];
}
return function () {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
// eslint-disable-line
// eslint-disable-line
for (var i = 0; i < fns.length; i++) {
if (fns[i] && typeof fns[i] === 'function') {
fns[i].apply(this, args);
}
}
};
}
var Select = function (_React$Component) {
_inherits(Select, _React$Component);
function Select(props) {
_classCallCheck(this, Select);
var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
_initialiseProps.call(_this);
var optionsInfo = Select.getOptionsInfoFromProps(props);
_this.state = {
value: Select.getValueFromProps(props, true), // true: use default value
inputValue: props.combobox ? Select.getInputValueForCombobox(props, optionsInfo, true // use default value
) : '',
open: props.defaultOpen,
optionsInfo: optionsInfo,
// a flag for aviod redundant getOptionsInfoFromProps call
skipBuildOptionsInfo: true
};
_this.saveInputRef = (0, _util.saveRef)(_this, 'inputRef');
_this.saveInputMirrorRef = (0, _util.saveRef)(_this, 'inputMirrorRef');
_this.saveTopCtrlRef = (0, _util.saveRef)(_this, 'topCtrlRef');
_this.saveSelectTriggerRef = (0, _util.saveRef)(_this, 'selectTriggerRef');
_this.saveRootRef = (0, _util.saveRef)(_this, 'rootRef');
_this.saveSelectionRef = (0, _util.saveRef)(_this, 'selectionRef');
return _this;
}
Select.prototype.componentDidMount = function componentDidMount() {
if (this.props.autoFocus) {
this.focus();
}
};
Select.prototype.componentDidUpdate = function componentDidUpdate() {
if ((0, _util.isMultipleOrTags)(this.props)) {
var inputNode = this.getInputDOMNode();
var mirrorNode = this.getInputMirrorDOMNode();
if (inputNode.value) {
inputNode.style.width = '';
inputNode.style.width = mirrorNode.clientWidth + 'px';
} else {
inputNode.style.width = '';
}
}
this.forcePopupAlign();
};
Select.prototype.componentWillUnmount = function componentWillUnmount() {
this.clearFocusTime();
this.clearBlurTime();
if (this.dropdownContainer) {
_reactDom2["default"].unmountComponentAtNode(this.dropdownContainer);
document.body.removeChild(this.dropdownContainer);
this.dropdownContainer = null;
}
};
// combobox ignore
// 选择下拉列表内容时调用
Select.prototype.focus = function focus() {
if ((0, _util.isSingleMode)(this.props)) {
this.selectionRef.focus();
} else {
this.getInputDOMNode().focus();
}
};
Select.prototype.blur = function blur() {
if ((0, _util.isSingleMode)(this.props)) {
this.selectionRef.blur();
} else {
this.getInputDOMNode().blur();
}
};
/**
* noCheck 判断输入的值是否不需要匹配option
*/
// 超出长度时hover "+n" 显示的option的名称
Select.prototype.renderClear = function renderClear() {
var _props = this.props,
prefixCls = _props.prefixCls,
allowClear = _props.allowClear,
clearIcon = _props.clearIcon;
var _state = this.state,
value = _state.value,
inputValue = _state.inputValue;
var clear = _react2["default"].createElement(
'span',
_extends({
key: 'clear',
className: prefixCls + '-selection-clear',
onMouseDown: _util.preventDefaultEvent,
style: _util.UNSELECTABLE_STYLE
}, _util.UNSELECTABLE_ATTRIBUTE, {
onClick: this.onClearSelection
}),
clearIcon || _react2["default"].createElement('i', { className: prefixCls + '-selection-clear-icon' })
);
if (!allowClear) {
return null;
}
if ((0, _util.isCombobox)(this.props)) {
if (inputValue) {
return clear;
}
return null;
}
if (inputValue || value.length) {
return clear;
}
return null;
};
Select.prototype.render = function render() {
var _rootCls;
var props = this.props;
var multiple = (0, _util.isMultipleOrTags)(props);
var state = this.state;
var className = props.className,
disabled = props.disabled,
prefixCls = props.prefixCls,
inputIcon = props.inputIcon;
var ctrlNode = this.renderTopControlNode();
var open = this.state.open;
if (open) {
this._options = this.renderFilterOptions();
}
var realOpen = this.getRealOpenState();
var options = this._options || [];
var dataOrAriaAttributeProps = {};
var customProps = _extends({}, (0, _omit2["default"])(props, ['transitionName', 'choiceTransitionName', 'optionLabelProp', 'notFoundContent', 'clsPrefix', 'prefixCls', 'placeholder', 'dropdownStyle', 'dropdownMenuStyle', 'optionFilterProp', 'showAction', 'tokenSeparators', 'showSearch', 'allowClear', 'enterKeyDown', 'defaultOpen', 'labelInValue', 'defaultActiveFirstOption', 'onSearch', 'onDeselect', 'onInputKeyDown', 'showArrow', 'dropdownMatchSelectWidth', 'autoClearSearchValue', 'searchPlaceholder', 'scrollToEnd', 'filterOption', 'backfill', 'tags', 'combobox', 'supportWrite', 'onChange', 'onFocus', 'onBlur', 'onSelect', 'onSearch', 'onDeselect', 'onInputKeyDown', 'onKeyDown', 'userSelectText']));
for (var key in props) {
if (Object.prototype.hasOwnProperty.call(props, key) && (key.substr(0, 5) === 'data-' || key.substr(0, 5) === 'aria-' || key === 'role')) {
dataOrAriaAttributeProps[key] = props[key];
}
}
var extraSelectionProps = _extends({}, dataOrAriaAttributeProps);
if (!(0, _util.isMultipleOrTagsOrCombobox)(props)) {
extraSelectionProps = _extends({}, extraSelectionProps, {
onKeyDown: this.onKeyDown,
tabIndex: props.disabled ? -1 : 0
});
}
var rootCls = (_rootCls = {}, _defineProperty(_rootCls, className, !!className), _defineProperty(_rootCls, prefixCls, 1), _defineProperty(_rootCls, prefixCls + '-open', open), _defineProperty(_rootCls, prefixCls + '-focused', open || !!this._focused), _defineProperty(_rootCls, prefixCls + '-combobox', (0, _util.isCombobox)(props)), _defineProperty(_rootCls, prefixCls + '-disabled', disabled), _defineProperty(_rootCls, prefixCls + '-enabled', !disabled), _defineProperty(_rootCls, prefixCls + '-allow-clear', !!props.allowClear), _defineProperty(_rootCls, prefixCls + '-no-arrow', !props.showArrow), _rootCls);
return _react2["default"].createElement(
_SelectTrigger2["default"],
{
open: props.open,
onPopupFocus: this.onPopupFocus,
onMouseEnter: this.props.onMouseEnter,
onMouseLeave: this.props.onMouseLeave,
dropdownAlign: props.dropdownAlign,
dropdownClassName: props.dropdownClassName,
dropdownMatchSelectWidth: props.dropdownMatchSelectWidth,
defaultActiveFirstOption: props.defaultActiveFirstOption,
dropdownMenuStyle: props.dropdownMenuStyle,
transitionName: props.transitionName,
animation: props.animation,
prefixCls: props.prefixCls,
dropdownStyle: props.dropdownStyle,
combobox: props.combobox,
showSearch: props.showSearch,
options: options,
multiple: multiple,
disabled: disabled,
visible: realOpen,
inputValue: state.inputValue,
value: state.value,
backfillValue: state.backfillValue,
firstActiveValue: props.firstActiveValue,
onDropdownVisibleChange: this.onDropdownVisibleChange,
getPopupContainer: props.getPopupContainer,
onMenuSelect: this.onMenuSelect,
onMenuDeselect: this.onMenuDeselect,
onPopupScroll: props.onPopupScroll,
showAction: props.showAction,
ref: this.saveSelectTriggerRef,
clsPrefix: props.clsPrefix + '-dropdown',
menuItemSelectedIcon: props.menuItemSelectedIcon,
popData: props.popData
},
_react2["default"].createElement(
'div',
_extends({}, customProps, {
id: props.id,
style: props.style,
ref: this.saveRootRef,
onBlur: this.onOuterBlur,
onFocus: this.onOuterFocus,
onClick: this.onOuterClick //sp
, className: (0, _classnames3["default"])(rootCls),
onMouseDown: this.markMouseDown,
onMouseUp: this.markMouseLeave,
onMouseOut: this.markMouseLeave
}),
_react2["default"].createElement(
'div',
_extends({
ref: this.saveSelectionRef,
key: 'selection',
className: prefixCls + '-selection\n ' + prefixCls + '-selection--' + (multiple ? 'multiple' : 'single'),
role: 'combobox',
'aria-autocomplete': 'list',
'aria-haspopup': 'true',
'aria-expanded': realOpen
}, extraSelectionProps),
ctrlNode,
this.renderClear(),
!props.showArrow ? null : //sp
_react2["default"].createElement(
'span',
_extends({
key: 'arrow',
className: prefixCls + '-arrow',
style: _util.UNSELECTABLE_STYLE
}, _util.UNSELECTABLE_ATTRIBUTE, {
onClick: this.onArrowClick
}),
inputIcon || _react2["default"].createElement('i', { className: prefixCls + '-arrow-icon' })
)
)
)
);
};
return Select;
}(_react2["default"].Component);
Select.propTypes = _PropTypes.SelectPropTypes;
Select.defaultProps = {
prefixCls: 'u-select',
defaultOpen: false,
labelInValue: false,
defaultActiveFirstOption: true,
showSearch: true,
allowClear: false,
placeholder: '',
onChange: noop,
onFocus: noop,
onBlur: noop,
onSelect: noop,
onSearch: noop,
onDeselect: noop,
onInputKeyDown: noop,
showArrow: true,
dropdownMatchSelectWidth: true,
dropdownStyle: {},
dropdownMenuStyle: {},
optionFilterProp: 'value',
optionLabelProp: 'value',
notFoundContent: 'Not Found',
backfill: false,
showAction: ['click'],
tokenSeparators: [],
autoClearSearchValue: true,
onKeyDown: noop
};
Select.getDerivedStateFromProps = function (nextProps, prevState) {
var optionsInfo = prevState.skipBuildOptionsInfo ? prevState.optionsInfo : Select.getOptionsInfoFromProps(nextProps, prevState);
var newState = {
optionsInfo: optionsInfo,
skipBuildOptionsInfo: false
};
if ('open' in nextProps) {
newState.open = nextProps.open;
}
if ('value' in nextProps) {
var value = Select.getValueFromProps(nextProps);
newState.value = value;
if (nextProps.combobox) {
newState.inputValue = Select.getInputValueForCombobox(nextProps, optionsInfo);
}
}
return newState;
};
Select.getOptionsFromChildren = function (children) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
_react2["default"].Children.forEach(children, function (child) {
if (!child) {
return;
}
if (child && child.type && child.type.isSelectOptGroup) {
Select.getOptionsFromChildren(child.props.children, options);
} else {
options.push(child);
}
});
return options;
};
Select.getInputValueForCombobox = function (props, optionsInfo, useDefaultValue) {
var value = [];
if ('value' in props && !useDefaultValue) {
value = (0, _util.toArray)(props.value);
}
if ('defaultValue' in props && useDefaultValue) {
value = (0, _util.toArray)(props.defaultValue);
}
if (value.length) {
value = value[0];
} else {
return '';
}
var label = value;
if (props.labelInValue) {
label = value.label;
} else if (optionsInfo[(0, _util.getMapKey)(value)]) {
label = optionsInfo[(0, _util.getMapKey)(value)].label;
}
if (label === undefined) {
label = '';
}
return label;
};
Select.getLabelFromOption = function (props, option) {
return (0, _util.getPropValue)(option, props.optionLabelProp);
};
Select.getOptionsInfoFromProps = function (props, preState) {
var options = Select.getOptionsFromChildren(props.children);
var optionsInfo = {};
options.forEach(function (option) {
var singleValue = (0, _util.getValuePropValue)(option);
optionsInfo[(0, _util.getMapKey)(singleValue)] = {
option: option,
value: singleValue,
label: Select.getLabelFromOption(props, option),
title: option.props.title
};
});
if (preState) {
// keep option info in pre state value.
var oldOptionsInfo = preState.optionsInfo;
var value = preState.value;
value.forEach(function (v) {
var key = (0, _util.getMapKey)(v);
if (!optionsInfo[key] && oldOptionsInfo[key] !== undefined) {
optionsInfo[key] = oldOptionsInfo[key];
}
});
}
return optionsInfo;
};
Select.getValueFromProps = function (props, useDefaultValue) {
var value = [];
if ('value' in props && !useDefaultValue) {
value = (0, _util.toArray)(props.value);
}
if ('defaultValue' in props && useDefaultValue) {
value = (0, _util.toArray)(props.defaultValue);
}
if (props.labelInValue) {
value = value.map(function (v) {
return v.key;
});
}
return value;
};
var _initialiseProps = function _initialiseProps() {
var _this2 = this;
this.onInputChange = function (event) {
var tokenSeparators = _this2.props.tokenSeparators;
var val = event.target.value;
if ((0, _util.isMultipleOrTags)(_this2.props) && tokenSeparators.length && (0, _util.includesSeparators)(val, tokenSeparators)) {
var nextValue = _this2.getValueByInput(val);
if (nextValue !== undefined) {
_this2.fireChange(nextValue);
}
_this2.setOpenState(false, true);
_this2.setInputValue('', false);
return;
}
_this2.setInputValue(val);
_this2.setState({
open: true
});
if ((0, _util.isCombobox)(_this2.props)) {
_this2.fireChange([val]);
}
};
this.onDropdownVisibleChange = function (open) {
if (open && !_this2._focused) {
_this2.clearBlurTime();
_this2.timeoutFocus();
_this2._focused = true;
_this2.updateFocusClassName();
}
_this2.setOpenState(open);
};
this.onKeyDown = function (event) {
var open = _this2.state.open;
var _props2 = _this2.props,
disabled = _props2.disabled,
onKeyDown = _props2.onKeyDown,
enterKeyDown = _props2.enterKeyDown;
if (disabled) {
return;
}
var keyCode = event.keyCode;
if (open && !_this2.getInputDOMNode()) {
_this2.onInputKeyDown(event);
} else if (keyCode === _tinperBeeCore.KeyCode.DOWN) {
if (!open) {
_this2.setOpenState(true);
event.target._dataTransfer = {
_cancelBubble: true
};
} else {
_this2.appendDataTransferToEvent(event);
}
event.preventDefault();
} else if (keyCode === _tinperBeeCore.KeyCode.UP) {
if (open) {
_this2.appendDataTransferToEvent(event);
}
event.preventDefault();
} else if (keyCode === _tinperBeeCore.KeyCode.ENTER) {
if (!open && enterKeyDown) _this2.setOpenState(true);
event.preventDefault();
}
onKeyDown(event); //sp
};
this.appendDataTransferToEvent = function (event) {
var _props3 = _this2.props,
eventKey = _props3.eventKey,
children = _props3.children;
var _eventKey = eventKey || '0-menu-';
var keyCode = event.keyCode;
var activeKeyKey = _this2.refs.menuItemRef.store.getState().activeKey[_eventKey];
var activeIndex = children.findIndex(function (data) {
return data.key == activeKeyKey;
});
var activeIndexOld = children.findIndex(function (data) {
return data.key == _this2.old_activeKeyKey;
});
// console.log('activeIndex', activeIndex, activeIndexOld);
if (keyCode === _tinperBeeCore.KeyCode.DOWN && activeIndex > activeIndexOld || keyCode === _tinperBeeCore.KeyCode.UP && (activeIndex < activeIndexOld || activeIndexOld == -1)) {
event.target._dataTransfer = {
_cancelBubble: true
};
}
_this2.old_activeKeyKey = activeKeyKey;
return activeIndex;
};
this.onInputKeyDown = function (event) {
var props = _this2.props;
if (props.disabled) {
return;
}
var state = _this2.state;
var keyCode = event.keyCode;
if ((0, _util.isMultipleOrTags)(props) && !event.target.value && keyCode === _tinperBeeCore.KeyCode.BACKSPACE) {
event.preventDefault();
var value = state.value;
if (value.length) {
_this2.removeSelected(value[value.length - 1]);
}
return;
}
if (keyCode === _tinperBeeCore.KeyCode.DOWN) {
if (!state.open) {
_this2.openIfHasChildren();
event.preventDefault();
event.stopPropagation();
return;
}
} else if (keyCode === _tinperBeeCore.KeyCode.ENTER && state.open) {
// Aviod trigger form submit when select item
// https://github.com/ant-design/ant-design/issues/10861
event.preventDefault();
} else if (keyCode === _tinperBeeCore.KeyCode.ESC) {
if (state.open) {
if (_this2.props.needFocusAfterSetOpenState) {
_this2.setOpenState(false, true);
} else {
_this2.setOpenState(false);
}
event.preventDefault();
event.stopPropagation();
}
if (props.showSearch) props.onKeyDown(event); //sp
return;
}
if (_this2.getRealOpenState(state)) {
var menu = _this2.selectTriggerRef.getInnerMenu();
if (menu && menu.onKeyDown(event, _this2.handleBackfill)) {
event.preventDefault();
event.stopPropagation();
}
}
};
this.onMenuSelect = function (_ref) {
var item = _ref.item;
if (!item) {
return;
}
var value = _this2.state.value;
var props = _this2.props;
var selectedValue = (0, _util.getValuePropValue)(item);
var lastValue = value[value.length - 1];
_this2.fireSelect(selectedValue);
if ((0, _util.isMultipleOrTags)(props)) {
if ((0, _util.findIndexInValueBySingleValue)(value, selectedValue) !== -1) {
return;
}
value = value.concat([selectedValue]);
} else {
if (lastValue !== undefined && lastValue === selectedValue && selectedValue !== _this2.state.backfillValue) {
_this2.setOpenState(false, true);
return;
}
value = [selectedValue];
_this2.setOpenState(false, true);
}
_this2.fireChange(value);
var inputValue = void 0;
if ((0, _util.isCombobox)(props)) {
inputValue = (0, _util.getPropValue)(item, props.optionLabelProp);
} else {
inputValue = '';
}
if (props.autoClearSearchValue) {
_this2.setInputValue(inputValue, false);
}
};
this.onMenuDeselect = function (_ref2) {
var item = _ref2.item,
domEvent = _ref2.domEvent;
if (domEvent.type === 'keydown' && domEvent.keyCode === _tinperBeeCore.KeyCode.ENTER) {
_this2.removeSelected((0, _util.getValuePropValue)(item));
return;
}
if (domEvent.type === 'click') {
_this2.removeSelected((0, _util.getValuePropValue)(item));
}
var props = _this2.props;
if (props.autoClearSearchValue) {
_this2.setInputValue('', false);
}
};
this.onArrowClick = function (e) {
e.stopPropagation();
e.preventDefault();
_this2.props.onFocus(_this2.state.value);
if (!_this2.props.disabled) {
_this2.setOpenState(!_this2.state.open, !_this2.state.open);
}
};
this.onPlaceholderClick = function () {
if (_this2.getInputDOMNode()) {
_this2.getInputDOMNode().focus();
}
};
this.onOuterFocus = function (e) {
if (_this2.props.disabled) {
e.preventDefault();
return;
}
_this2.clearBlurTime();
if (!(0, _util.isMultipleOrTagsOrCombobox)(_this2.props) && e.target === _this2.getInputDOMNode()) {
return;
}
if (_this2._focused) {
return;
}
_this2._focused = true;
_this2.updateFocusClassName();
if (!_this2._mouseDown) {
_this2.timeoutFocus();
}
};
this.onPopupFocus = function () {
// fix ie scrollbar, focus element again
_this2.maybeFocus(true, true);
};
this.onOuterBlur = function (e) {
if (_this2.props.disabled) {
e.preventDefault();
return;
}
_this2.blurTimer = setTimeout(function () {
_this2._focused = false;
_this2.updateFocusClassName();
var props = _this2.props;
var value = _this2.state.value;
var inputValue = _this2.state.inputValue;
if ((0, _util.isSingleMode)(props) && props.showSearch && inputValue && props.defaultActiveFirstOption) {
var options = _this2._options || [];
if (options.length) {
// const firstOption = findFirstMenuItem(options); // 自定义输入时失去焦点触发两次onChange解决
// if (firstOption) {
// value = [getValuePropValue(firstOption)];
// this.fireChange(value);
// }
if (props.showSearch && props.supportWrite) {
//查询时是否支持自定义输入
value = [inputValue];
_this2.fireChange(value, true);
}
}
} else if ((0, _util.isMultipleOrTags)(props) && inputValue) {
if (_this2._mouseDown) {
// need update dropmenu when not blur
_this2.setInputValue('');
} else {
// why not use setState?
_this2.state.inputValue = _this2.getInputDOMNode().value = '';
}
value = _this2.getValueByInput(inputValue);
if (value !== undefined) {
_this2.fireChange(value);
}
}
// if click the rest space of Select in multiple mode
if ((0, _util.isMultipleOrTags)(props) && _this2._mouseDown) {
_this2.maybeFocus(true, true);
_this2._mouseDown = false;
return;
}
_this2.setOpenState(false);
props.onBlur(_this2.getVLForOnChange(value));
}, 10);
};
this.onClearSelection = function (event) {
var props = _this2.props;
var state = _this2.state;
if (props.disabled) {
return;
}
var inputValue = state.inputValue,
value = state.value;
event.stopPropagation();
if (inputValue || value.length) {
if (value.length) {
_this2.fireChange([]);
}
_this2.setOpenState(false, true);
if (inputValue) {
_this2.setInputValue('');
}
}
};
this.onChoiceAnimationLeave = function () {
_this2.forcePopupAlign();
};
this.getOptionInfoBySingleValue = function (value, optionsInfo) {
var info = void 0;
optionsInfo = optionsInfo || _this2.state.optionsInfo;
if (optionsInfo[(0, _util.getMapKey)(value)]) {
info = optionsInfo[(0, _util.getMapKey)(value)];
}
if (info) {
return info;
}
var defaultLabel = value;
if (_this2.props.labelInValue) {
var label = (0, _util.getLabelFromPropsValue)(_this2.props.value, value);
if (label !== undefined) {
defaultLabel = label;
}
}
var defaultInfo = {
option: _react2["default"].createElement(
_Option2["default"],
{ value: value, key: value },
value
),
value: value,
label: defaultLabel
};
return defaultInfo;
};
this.getOptionBySingleValue = function (value) {
var _getOptionInfoBySingl = _this2.getOptionInfoBySingleValue(value),
option = _getOptionInfoBySingl.option;
return option;
};
this.getOptionsBySingleValue = function (values) {
return values.map(function (value) {
return _this2.getOptionBySingleValue(value);
});
};
this.getValueByLabel = function (label) {
if (label === undefined) {
return null;
}
var value = null;
Object.keys(_this2.state.optionsInfo).forEach(function (key) {
var info = _this2.state.optionsInfo[key];
if ((0, _util.toArray)(info.label).join('') === label) {
value = info.value;
}
});
return value;
};
this.getVLBySingleValue = function (value) {
if (_this2.props.labelInValue) {
return {
key: value,
label: _this2.getLabelBySingleValue(value)
};
}
return value;
};
this.getVLForOnChange = function (vls_) {
var vls = vls_;
if (vls !== undefined) {
if (!_this2.props.labelInValue) {
vls = vls.map(function (v) {
return v;
});
} else {
vls = vls.map(function (vl) {
return {
key: vl,
label: _this2.getLabelBySingleValue(vl)
};
});
}
return (0, _util.isMultipleOrTags)(_this2.props) ? vls : vls[0];
}
return vls;
};
this.getLabelBySingleValue = function (value, optionsInfo) {
var _getOptionInfoBySingl2 = _this2.getOptionInfoBySingleValue(value, optionsInfo),
label = _getOptionInfoBySingl2.label;
return label;
};
this.getDropdownContainer = function () {
if (!_this2.dropdownContainer) {
_this2.dropdownContainer = document.createElement('div');
document.body.appendChild(_this2.dropdownContainer);
}
return _this2.dropdownContainer;
};
this.getPlaceholderElement = function () {
var props = _this2.props,
state = _this2.state;
var hidden = false;
if (state.inputValue) {
hidden = true;
}
if (state.value[0]) {
hidden = true;
}
if ((0, _util.isCombobox)(props) && state.value.length === 1 && !state.value[0]) {
hidden = false;
}
var placeholder = props.placeholder;
if (placeholder) {
return _react2["default"].createElement(
'div',
_extends({
onMouseDown: _util.preventDefaultEvent,
style: _extends({
display: hidden ? 'none' : 'block'
}, _util.UNSELECTABLE_STYLE)
}, _util.UNSELECTABLE_ATTRIBUTE, {
onClick: _this2.onPlaceholderClick,
className: props.prefixCls + '-selection-placeholder'
}),
placeholder
);
}
return null;
};
this.getInputElement = function () {
var props = _this2.props;
var inputElement = props.getInputElement ? props.getInputElement() : _react2["default"].createElement('input', { id: props.id, autoComplete: 'off' });
var inputCls = (0, _classnames3["default"])(inputElement.props.className, _defineProperty({}, props.prefixCls + '-search-field', true));
// https://github.com/ant-design/ant-design/issues/4992#issuecomment-281542159
// Add space to the end of the inputValue as the width measurement tolerance
return _react2["default"].createElement(
'div',
{ className: props.prefixCls + '-search-field-wrap' },
_react2["default"].cloneElement(inputElement, {
ref: _this2.saveInputRef,
onChange: _this2.onInputChange,
onKeyDown: chaining(_this2.onInputKeyDown, inputElement.props.onKeyDown, _this2.props.onInputKeyDown),
value: _this2.state.inputValue,
disabled: props.disabled,
className: inputCls
}),
_react2["default"].createElement(
'span',
{
ref: _this2.saveInputMirrorRef,
className: props.prefixCls + '-search-field-mirror'
},
_this2.state.inputValue,
'\xA0'
)
);
};
this.getInputDOMNode = function () {
return _this2.topCtrlRef ? _this2.topCtrlRef.querySelector('input,textarea,div[contentEditable]') : _this2.inputRef;
};
this.getInputMirrorDOMNode = function () {
return _this2.inputMirrorRef;
};
this.getPopupDOMNode = function () {
return _this2.selectTriggerRef.getPopupDOMNode();
};
this.getPopupMenuComponent = function () {
return _this2.selectTriggerRef.getInnerMenu();
};
this.setOpenState = function (open, needFocus) {
var props = _this2.props,
state = _this2.state;
if (state.open === open) {
_this2.maybeFocus(open, needFocus);
return;
}
if (_this2.props.onDropdownVisibleChange) {
_this2.props.onDropdownVisibleChange(open);
}
var nextState = {
open: open,
backfillValue: undefined
};
// clear search input value when open is false in singleMode.
if (!open && (0, _util.isSingleMode)(props) && props.showSearch) {
_this2.setInputValue('', false);
}
if (!open) {
_this2.maybeFocus(open, needFocus);
}
_this2.setState(nextState, function () {
if (open) {
_this2.maybeFocus(open, needFocus);
}
});
};
this.setInputValue = function (inputValue) {
var fireSearch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (inputValue !== _this2.state.inputValue) {
_this2.setState({
inputValue: inputValue
}, _this2.forcePopupAlign);
if (fireSearch) {
_this2.props.onSearch(inputValue);
}
}
};
this.getValueByInput = function (string) {
var _props4 = _this2.props,
multiple = _props4.multiple,
tokenSeparators = _props4.tokenSeparators;
var nextValue = _this2.state.value;
var hasNewValue = false;
(0, _util.splitBySeparators)(string, tokenSeparators).forEach(function (label) {
var selectedValue = [label];
if (multiple) {
var value = _this2.getValueByLabel(label);
if (value && (0, _util.findIndexInValueBySingleValue)(nextValue, value) === -1) {
nextValue = nextValue.concat(value);
hasNewValue = true;
_this2.fireSelect(value);
}
} else {
// tag
if ((0, _util.findIndexInValueBySingleValue)(nextValue, label) === -1) {
nextValue = nextValue.concat(selectedValue);
hasNewValue = true;
_this2.fireSelect(label);
}
}
});
return hasNewValue ? nextValue : undefined;
};
this.getRealOpenState = function (state) {
var _open = _this2.props.open;
if (typeof _open === 'boolean') {
return _open;
}
var open = (state || _this2.state).open;
var options = _this2._options || [];
if ((0, _util.isMultipleOrTagsOrCombobox)(_this2.props) || !_this2.props.showSearch) {
if (open && !options.length) {
open = false;
}
}
return open;
};
this.markMouseDown = function () {
_this2._mouseDown = true;
};
this.markMouseLeave = function () {
_this2._mouseDown = false;
};
this.handleBackfill = function (item) {
if (!_this2.props.backfill || !((0, _util.isSingleMode)(_this2.props) || (0, _util.isCombobox)(_this2.props))) {
return;
}
var key = (0, _util.getValuePropValue)(item);
if ((0, _util.isCombobox)(_this2.props)) {
_this2.setInputValue(key, false);
}
_this2.setState({
value: [key],
backfillValue: key
});
};
this.filterOption = function (input, child) {
var defaultFilter = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _util.defaultFilterFn;
var value = _this2.state.value;
var lastValue = value[value.length - 1];
if (!input || lastValue && lastValue === _this2.state.backfillValue) {
return true;
}
var filterFn = _this2.props.filterOption;
if ('filterOption' in _this2.props) {
if (_this2.props.filterOption === true) {
filterFn = defaultFilter;
}
} else {
filterFn = defaultFilter;
}
if (!filterFn) {
return true;
} else if (typeof filterFn === 'function') {
return filterFn.call(_this2, input, child);
} else if (child.props.disabled) {
return false;
}
return true;
};
this.timeoutFocus = function () {
if (_this2.focusTimer) {
_this2.clearFocusTime();
}
_this2.focusTimer = setTimeout(function () {
_this2.props.onFocus();
}, 10);
};
this.clearFocusTime = function () {
if (_this2.focusTimer) {
clearTimeout(_this2.focusTimer);
_this2.focusTimer = null;
}
};
this.clearBlurTime = function () {
if (_this2.blurTimer) {
clearTimeout(_this2.blurTimer);
_this2.blurTimer = null;
}
};
this.updateFocusClassName = function () {
var rootRef = _this2.rootRef,
props = _this2.props;
// avoid setState and its side effect
if (_this2._focused) {
(0, _componentClasses2["default"])(rootRef).add(props.prefixCls + '-focused');
} else {
(0, _componentClasses2["default"])(rootRef).remove(props.prefixCls + '-focused');
}
};
this.maybeFocus = function (open, needFocus) {
if (needFocus || open) {
var input = _this2.getInputDOMNode();
var _document = document,
activeElement = _document.activeElement;
if (input && (open || (0, _util.isMultipleOrTagsOrCombobox)(_this2.props))) {
if (activeElement !== input) {
input.focus();
_this2._focused = true;
}
} else if (activeElement !== _this2.selectionRef) {
_this2.selectionRef.focus();
_this2._focused = true;
}
}
};
this.removeSelected = function (selectedKey, e) {
var props = _this2.props;
if (props.disabled || _this2.isChildDisabled(selectedKey)) {
return;
}
// Do not trigger Trigger popup
if (e && e.stopPropagation) {
e.stopPropagation();
}
var value = _this2.state.value.filter(function (singleValue) {
return singleValue !== selectedKey;
});
var canMultiple = (0, _util.isMultipleOrTags)(props);
if (canMultiple) {
var event = selectedKey;
if (props.labelInValue) {
event = {
key: selectedKey,
label: _this2.getLabelBySingleValue(selectedKey)
};
}
props.onDeselect(event, _this2.getOptionBySingleValue(selectedKey));
}
_this2.fireChange(value);
};
this.openIfHasChildren = function () {
var props = _this2.props;
if (_react2["default"].Children.count(props.children) || (0, _util.isSingleMode)(props)) {
_this2.setOpenState(true);
}
};
this.fireSelect = function (value) {
_this2.props.onSelect(_this2.getVLBySingleValue(value), _this2.getOptionBySingleValue(value));
};
this.fireChange = function (value, noCheck) {
var props = _this2.props;
if (!('value' in props)) {
_this2.setState({
value: value
}, _this2.forcePopupAlign);
}
if (noCheck) {
props.onChange(value, null);
} else {
var vls = _this2.getVLForOnChange(value);
var options = _this2.getOptionsBySingleValue(value);
props.onChange(vls, (0, _util.isMultipleOrTags)(_this2.props) ? options : options[0]);
}
};
this.isChildDisabled = function (key) {
return (0, _tinperBeeCore.toArray)(_this2.props.children).some(function (child) {
var childValue = (0, _util.getValuePropValue)(child);
return childValue === key && child.props && child.props.disabled;
});
};
this.getOptionName = function (optionsInfo, maxTagCount, value) {
var titleArr = [];
var arr = value.slice(maxTagCount);
Object.keys(optionsInfo).forEach(function (key, index) {
var optionItem = optionsInfo[key];
if (arr.includes(optionItem.value)) {
titleArr.push(optionItem.label);
}
});
return titleArr;
};
this.forcePopupAlign = function () {
if (!_this2.state.open) {
return;
}
if (_this2.selectTriggerRef && _this2.selectTriggerRef.triggerRef && _this2.selectTriggerRef.triggerRef.forcePopupAlign) {
if (typeof _this2.selectTriggerRef.triggerRef.forcePopupAlign == 'function') {
_this2.selectTriggerRef.triggerRef.forcePopupAlign();
}
}
};
this.renderFilterOptions = function () {
var inputValue = _this2.state.inputValue;
var _props5 = _this2.props,
children = _props5.children,
tags = _props5.tags,
filterOption = _props5.filterOption,
notFoundContent = _props5.notFoundContent;
var menuItems = [];
var childrenKeys = [];
var options = _this2.renderFilterOptionsFromChildren(children, childrenKeys, menuItems);
if (tags) {
// tags value must be string
var value = _this2.state.value;
value = value.filter(function (singleValue) {
return childrenKeys.indexOf(singleValue) === -1 && (!inputValue || String(singleValue).indexOf(String(inputValue)) > -1);
});
value.forEach(function (singleValue) {
var key = singleValue;
var menuItem = _react2["default"].createElement(
_MenuItem2["default"],
{
style: _util.UNSELECTABLE_STYLE,
role: 'option',
attribute: _util.UNSELECTABLE_ATTRIBUTE,
value: key,
key: key
},
key
);
options.push(menuItem);
menuItems.push(menuItem);
});
if (inputValue) {
var notFindInputItem = menuItems.every(function (option) {
// this.filterOption return true has two meaning,
// 1, some one exists after filtering
// 2, filterOption is set to false
// condition 2 does not mean the option has same value with inputValue
var filterFn = function filterFn() {
return (0, _util.getValuePropValue)(option) === inputValue;
};
if (filterOption !== false) {
return !_this2.filterOption.call(_this2, inputValue, option, filterFn);
}
return !filterFn();
});
if (notFindInputItem) {
options.unshift(_react2["default"].createElement(
_MenuItem2["default"],
{
style: _util.UNSELECTABLE_STYLE,
role: 'option',
attribute: _util.UNSELECTABLE_ATTRIBUTE,
value: inputValue,
key: inputValue
},
inputValue
));
}
}
}
if (!options.length && notFoundContent) {
options = [_react2["default"].createElement(
_MenuItem2["default"],
{
style: _util.UNSELECTABLE_STYLE,
attribute: _util.UNSELECTABLE_ATTRIBUTE,
disabled: true,
role: 'option',
value: 'NOT_FOUND',
key: 'NOT_FOUND'
},
notFoundContent
)];
}
return options;
};
this.renderFilterOptionsFromChildren = function (children, childrenKeys, menuItems) {
var sel = [];
var props = _this2.props;
var inputValue = _this2.state.inputValue;
var tags = props.tags;
_react2["default"].Children.forEach(children, function (child) {
if (!child) {
return;
}
if (child.type.isSelectOptGroup) {
var innerItems = _this2.renderFilterOptionsFromChildren(child.props.children, childrenKeys, menuItems);
if (innerItems.length) {
var label = child.props.label;
var key = child.key;
if (!key && typeof label === 'string') {
key = label;
} else if (!label && key) {
label = key;
}
sel.push(_react2["default"].createElement(
_rcMenu.ItemGroup,
{ key: key, title: label },
innerItems
));
}
return;
}
(0, _warning2["default"])(child.type.isSelectOption, 'the children of `Select` should be `Select.Option` or `Select.OptGroup`, ' + ('instead of `' + (child.type.name || child.type.displayName || child.type) + '`.'));
var childValue = (0, _util.getValuePropValue)(child);
(0, _util.validateOptionValue)(childValue, _this2.props);
if (_this2.filterOption(inputValue, child)) {
var menuItem = _react2["default"].createElement(_MenuItem2["default"], _extends({
ref: 'menuItemRef',
style: _util.UNSELECTABLE_STYLE,
attribute: _util.UNSELECTABLE_ATTRIBUTE,
value: childValue,
key: childValue,
role: 'option'
}, child.props));
sel.push(menuItem);
menuItems.push(menuItem);
}
if (tags) {
childrenKeys.push(childValue);
}
});
return sel;
};
this.renderTopControlNode = function () {
var _state2 = _this2.state,
value = _state2.value,
open = _state2.open,
inputValue = _state2.inputValue,
optionsInfo = _state2.optionsInfo;
var props = _this2.props;
var choiceTransitionName = props.choiceTransitionName,
prefixCls = props.prefixCls,
maxTagTextLength = props.maxTagTextLength,
maxTagCount = props.maxTagCount,
maxTagPlaceholder = props.maxTagPlaceholder,
showSearch = props.showSearch,
removeIcon = props.removeIcon,
userSelectText = props.userSelectText;
var className = prefixCls + '-selection-rendered';
// search input is inside topControlNode in single, multiple & combobox. 2016/04/13
var innerNode = null;
if ((0, _util.isSingleMode)(props)) {
var selectedValue = null;
if (value.length) {
var showSelectedValue = false;
var opacity = 1;
if (!showSearch) {
showSelectedValue = true;
} else if (open) {
showSelectedValue = !inputValue;
if (showSelectedValue) {
opacity = 0.4;
}
} else {
showSelectedValue = true;
}
var singleValue = value[0];
var _getOptionInfoBySingl3 = _this2.getOptionInfoBySingleValue(singleValue),
label = _getOptionInfoBySingl3.label,
title = _getOptionInfoBySingl3.title;
selectedValue = _react2["default"].createElement(
'div',
{
key: 'value',
className: prefixCls + '-selection-selected-value',
title: (0, _util.toTitle)(title || label),
style: {
display: showSelectedValue ? 'block' : 'none',
opacity: opacity
}
},
label
);
}
if (!showSearch) {
innerNode = [selectedValue];
} else {
innerNode = [selectedValue, _react2["default"].createElement(
'div',
{
className: prefixCls + '-search ' + prefixCls + '-search--inline',
key: 'input',
style: {
display: open ? 'block' : 'none'
}
},
_this2.getInputElement()
)];
}
} else {
var selectedValueNodes = [];
var limitedCountValue = value;
var maxTagPlaceholderEl = void 0;
if (maxTagCount !== undefined && value.length > maxTagCount) {
limitedCountValue = limitedCountValue.slice(0, maxTagCount);
var _title = _this2.getOptionName(optionsInfo, maxTagCount, value); // 获取option的中文名
// const omittedValues = this.getVLForOnChange(title.slice(maxTagCount, value.length)); // 截取hover时需要显示的数组
var content = '+ ' + (value.length - maxTagCount) + ' ...';
if (maxTagPlaceholder) {
content = typeof maxTagPlaceholder === 'function' ? maxTagPlaceholder(_title) : maxTagPlaceholder;
}
//超过最大长度显示的内容
maxTagPlaceholderEl = _react2["default"].createElement(
'li',
_extends({
style: _util.UNSELECTABLE_STYLE
}, _util.UNSELECTABLE_ATTRIBUTE, {
onMouseDown: _util.preventDefaultEvent,
className: prefixCls + '-selection-choice ' + prefixCls + '-selection-choice-disabled',
key: 'maxTagPlaceholder',
title: (0, _util.toTitle)(_title)
}),
_react2["default"].createElement(
'div',
{ className: prefixCls + '-selection-choice-content' },
content
)
);
}
if ((0, _util.isMultipleOrTags)(props)) {
selectedValueNodes = limitedCountValue.map(function (singleValue, index) {
var key = singleValue || index;
var info = _this2.getOptionInfoBySingleValue(singleValue);
var content = info.label;
var title = info.title || content;
if (maxTagTextLength && typeof content === 'string' && content.length > maxTagTextLength) {
content = content.slice(0, maxTagTextLength) + '...';
}
var disabled = _this2.isChildDisabled(singleValue);
var choiceClassName = disabled ? prefixCls + '-selection-choice ' + prefixCls + '-selection-choice-disabled' : prefixCls + '-selection-choice';
return _react2["default"].createElement(
'li',
_extends({
style: _util.UNSELECTABLE_STYLE
}, _util.UNSELECTABLE_ATTRIBUTE, {
onMouseDown: _util.preventDefaultEvent,
className: choiceClassName,
key: key,
title: (0, _util.toTitle)(title)
}),
_react2["default"].createElement(
'div',
{ className: prefixCls + '-selection-choice-content' },
content
),
disabled ? null : _react2["default"].createElement(
'span',
{