rc-select
Advanced tools
Comparing version 3.5.0 to 4.0.0
@@ -26,2 +26,6 @@ 'use strict'; | ||
function isCombobox(props) { | ||
return props.combobox; | ||
} | ||
function isMultipleOrTags(props) { | ||
@@ -31,22 +35,12 @@ return props.multiple || props.tags; | ||
function noop() {} | ||
function isMultipleOrTagsOrCombobox(props) { | ||
return isMultipleOrTags(props) || isCombobox(props); | ||
} | ||
function getValueFromOptionChild(child) { | ||
var optionProps = child.props; | ||
var children = optionProps.children; | ||
var ret; | ||
if (optionProps.value !== undefined) { | ||
if (typeof optionProps.value === 'string') { | ||
ret = optionProps.value; | ||
} | ||
} else if (typeof children === 'string') { | ||
ret = children; | ||
} | ||
if (!ret && !child.props.disabled) { | ||
throw new Error('must set value string on Option element!'); | ||
} | ||
return ret; | ||
function isSingleMode(props) { | ||
return !isMultipleOrTagsOrCombobox(props); | ||
} | ||
function noop() {} | ||
function normValue(value) { | ||
@@ -61,2 +55,6 @@ if (value === undefined) { | ||
function filterFn(input, child) { | ||
return child.props[this.props.optionFilterProp].indexOf(input) > -1; | ||
} | ||
var Select = (function (_React$Component) { | ||
@@ -69,4 +67,10 @@ function Select(props) { | ||
_get(Object.getPrototypeOf(Select.prototype), 'constructor', this).call(this, props); | ||
var value = []; | ||
if ('value' in props) { | ||
value = normValue(props.value); | ||
} else if ('defaultValue' in props) { | ||
value = normValue(props.defaultValue); | ||
} | ||
this.state = { | ||
value: normValue(props.value), | ||
value: value, | ||
inputValue: '' | ||
@@ -84,10 +88,56 @@ }; | ||
value: function componentWillReceiveProps(nextProps) { | ||
if ('value' in nextProps) { | ||
this.setState({ | ||
value: normValue(nextProps.value) | ||
}); | ||
} | ||
} | ||
}, { | ||
key: 'fireChange', | ||
value: function fireChange(value) { | ||
this.props.onChange(isMultipleOrTags(this.props) ? value : value[0]); | ||
this.setState({ | ||
value: normValue(nextProps.value) | ||
value: value | ||
}); | ||
} | ||
}, { | ||
key: 'getLabelByValue', | ||
value: function getLabelByValue(children, value) { | ||
var _this2 = this; | ||
if (value === undefined) { | ||
return value; | ||
} | ||
var label; | ||
React.Children.forEach(children, function (c) { | ||
if (c.type === OptGroup) { | ||
var maybe = _this2.getLabelByValue(c.props.children, value); | ||
if (maybe !== undefined) { | ||
label = maybe; | ||
} | ||
} else if (c.props.value === value) { | ||
label = c.props[_this2.props.optionLabelProp]; | ||
} | ||
}); | ||
return label; | ||
} | ||
}, { | ||
key: 'filterOption', | ||
value: function filterOption(input, child) { | ||
if (!input) { | ||
return true; | ||
} | ||
var filterOption = this.props.filterOption; | ||
if (!filterOption) { | ||
return true; | ||
} | ||
if (child.props.disabled) { | ||
return false; | ||
} | ||
return filterOption.call(this, input, child); | ||
} | ||
}, { | ||
key: 'renderFilterOptionsFromChildren', | ||
value: function renderFilterOptionsFromChildren(children, showNotFound) { | ||
var _this2 = this; | ||
var _this3 = this; | ||
@@ -98,7 +148,6 @@ var inputValue = this.state.inputValue; | ||
var childrenKeys = []; | ||
var filterOption = props.filterOption; | ||
var tags = props.tags; | ||
React.Children.forEach(children, function (child) { | ||
if (child.type === OptGroup) { | ||
var innerItems = _this2.renderFilterOptionsFromChildren(child.props.children, false); | ||
var innerItems = _this3.renderFilterOptionsFromChildren(child.props.children, false); | ||
if (innerItems.length) { | ||
@@ -118,18 +167,19 @@ var label = child.props.label; | ||
} | ||
if (!filterOption || !inputValue || !child.props.disabled && getValueFromOptionChild(child).indexOf(inputValue) > -1) { | ||
sel.push(React.createElement( | ||
MenuItem, | ||
{ | ||
disabled: child.props.disabled, | ||
value: getValueFromOptionChild(child), | ||
key: child.key || getValueFromOptionChild(child) }, | ||
child.props.children | ||
)); | ||
var childValue = child.props.value; | ||
if (typeof childValue !== 'string') { | ||
throw new Error('Option must set string value'); | ||
} | ||
if (_this3.filterOption(inputValue, child)) { | ||
sel.push(React.createElement(MenuItem, _extends({ | ||
value: childValue, | ||
key: childValue | ||
}, child.props))); | ||
} | ||
if (tags && !child.props.disabled) { | ||
childrenKeys.push(getValueFromOptionChild(child)); | ||
childrenKeys.push(childValue); | ||
} | ||
}); | ||
if (tags) { | ||
var value = this.state.value || []; | ||
// tags value must be string | ||
var value = this.state.value; | ||
value = value.filter(function (v) { | ||
@@ -147,3 +197,3 @@ return childrenKeys.indexOf(v) === -1 && (!inputValue || v.indexOf(inputValue) > -1); | ||
var notFindInputItem = sel.every(function (s) { | ||
return getValueFromOptionChild(s) !== inputValue; | ||
return s.props.value !== inputValue; | ||
}); | ||
@@ -176,3 +226,3 @@ if (notFindInputItem) { | ||
value: function setOpenState(open) { | ||
var _this3 = this; | ||
var _this4 = this; | ||
@@ -183,3 +233,3 @@ var refs = this.refs; | ||
}, function () { | ||
if (open || isMultipleOrTags(_this3.props) || _this3.props.combobox) { | ||
if (open || isMultipleOrTagsOrCombobox(_this4.props)) { | ||
if (refs.input) { | ||
@@ -197,2 +247,3 @@ React.findDOMNode(refs.input).focus(); | ||
var val = e.target.value; | ||
var props = this.props; | ||
this.setState({ | ||
@@ -202,8 +253,6 @@ inputValue: val, | ||
}); | ||
if (this.props.combobox) { | ||
this.setState({ | ||
value: val ? [val] : [] | ||
}); | ||
this.props.onChange(val); | ||
if (isCombobox(props)) { | ||
props.onChange(val); | ||
} | ||
props.onSearch(val); | ||
} | ||
@@ -224,3 +273,4 @@ }, { | ||
value: function openIfHasChildren() { | ||
if (React.Children.count(this.props.children)) { | ||
var props = this.props; | ||
if (React.Children.count(props.children) || isSingleMode(props)) { | ||
this.setOpenState(true); | ||
@@ -234,3 +284,4 @@ } | ||
value: function handleKeyDown(e) { | ||
if (this.props.disabled) { | ||
var props = this.props; | ||
if (props.disabled) { | ||
return; | ||
@@ -249,2 +300,11 @@ } | ||
value: function handleInputKeyDown(e) { | ||
if (isMultipleOrTags(this.props) && !e.target.value && e.keyCode === KeyCode.BACKSPACE) { | ||
var value = this.state.value.concat(); | ||
if (value.length) { | ||
value.pop(); | ||
this.fireChange(value); | ||
} | ||
return; | ||
} | ||
if (e.keyCode === KeyCode.DOWN) { | ||
@@ -276,10 +336,9 @@ if (!this.state.open) { | ||
value: function handleMenuSelect(key, item) { | ||
var value; | ||
var value = this.state.value; | ||
var props = this.props; | ||
var selectedValue = item.props.value; | ||
if (isMultipleOrTags(props)) { | ||
value = this.state.value.concat(); | ||
value.push(selectedValue); | ||
value = value.concat([selectedValue]); | ||
} else { | ||
if (this.state.value[0] === selectedValue) { | ||
if (value[0] === selectedValue) { | ||
this.setOpenState(false); | ||
@@ -290,12 +349,11 @@ return; | ||
} | ||
props.onSelect(selectedValue); | ||
props.onChange(isMultipleOrTags(props) ? value : value[0]); | ||
props.onSelect(selectedValue, item); | ||
this.fireChange(value); | ||
this.setState({ | ||
value: value, | ||
inputValue: '' | ||
}); | ||
this.setOpenState(false); | ||
if (props.combobox) { | ||
if (isCombobox(props)) { | ||
this.setState({ | ||
inputValue: value[0] | ||
inputValue: item.props[this.props.optionLabelProp] | ||
}); | ||
@@ -318,3 +376,3 @@ } | ||
value: function handleBlur() { | ||
var _this4 = this; | ||
var _this5 = this; | ||
@@ -325,3 +383,3 @@ if (this._blurTimer) { | ||
this._blurTimer = setTimeout(function () { | ||
_this4.setState({ | ||
_this5.setState({ | ||
open: false | ||
@@ -349,6 +407,3 @@ }); | ||
} | ||
props.onChange(isMultipleOrTags(props) ? value : value[0]); | ||
this.setState({ | ||
value: value | ||
}); | ||
this.fireChange(value); | ||
} | ||
@@ -358,10 +413,11 @@ }, { | ||
value: function handleClearSelection(e) { | ||
if (this.props.disabled) { | ||
var props = this.props; | ||
var state = this.state; | ||
if (props.disabled) { | ||
return; | ||
} | ||
e.stopPropagation(); | ||
if (this.state.inputValue || this.state.value.length) { | ||
this.props.onChange(isMultipleOrTags(this.props) ? [] : undefined); | ||
if (state.inputValue || state.value.length) { | ||
this.fireChange([]); | ||
this.setState({ | ||
value: [], | ||
inputValue: '' | ||
@@ -383,3 +439,3 @@ }); | ||
React.Children.forEach(menuItems, function (item) { | ||
if (value.indexOf(item.props.value) !== -1) { | ||
if (value.indexOf(item.props.value) !== -1 && item.key) { | ||
selectedKeys.push(item.key); | ||
@@ -410,7 +466,9 @@ } | ||
value: function renderTopControlNode(input) { | ||
var _this5 = this; | ||
var _this6 = this; | ||
var value = this.state.value; | ||
var prefixCls = this.props.prefixCls; | ||
var allowClear = this.props.allowClear; | ||
var props = this.props; | ||
var prefixCls = props.prefixCls; | ||
var allowClear = props.allowClear; | ||
var children = props.children; | ||
var clear = React.createElement( | ||
@@ -422,9 +480,12 @@ 'span', | ||
); | ||
var props = this.props; | ||
// single and not combobox, input is inside dropdown | ||
if (!props.combobox && !isMultipleOrTags(props)) { | ||
if (isSingleMode(props)) { | ||
return React.createElement( | ||
'span', | ||
{ className: prefixCls + '-selection__rendered' }, | ||
value[0], | ||
React.createElement( | ||
'span', | ||
null, | ||
this.getLabelByValue(children, value[0]) || props.placeholder | ||
), | ||
allowClear ? clear : null | ||
@@ -439,7 +500,11 @@ ); | ||
{ className: prefixCls + '-selection__choice' }, | ||
v, | ||
React.createElement( | ||
'span', | ||
{ className: prefixCls + '-selection__choice__content' }, | ||
_this6.getLabelByValue(children, v) || v | ||
), | ||
React.createElement( | ||
'span', | ||
{ className: prefixCls + '-selection__choice__remove', | ||
onClick: _this5.removeSelected.bind(_this5, v) | ||
onClick: _this6.removeSelected.bind(_this6, v) | ||
}, | ||
@@ -459,4 +524,3 @@ '×' | ||
{ className: joinClasses(prefixCls + '-search', prefixCls + '-search--inline') }, | ||
input, | ||
' ' | ||
input | ||
) | ||
@@ -472,3 +536,3 @@ ); | ||
var prefixCls = props.prefixCls; | ||
var rootCls = (_rootCls = {}, _defineProperty(_rootCls, prefixCls, true), _defineProperty(_rootCls, prefixCls + '-open', this.state.open), _defineProperty(_rootCls, prefixCls + '-combobox', props.combobox), _defineProperty(_rootCls, prefixCls + '-disabled', props.disabled), _defineProperty(_rootCls, prefixCls + '-show-arrow', props.showArrow), _rootCls); | ||
var rootCls = (_rootCls = {}, _defineProperty(_rootCls, prefixCls, true), _defineProperty(_rootCls, prefixCls + '-open', this.state.open), _defineProperty(_rootCls, prefixCls + '-combobox', isCombobox(props)), _defineProperty(_rootCls, prefixCls + '-disabled', props.disabled), _rootCls); | ||
return React.createElement( | ||
@@ -479,3 +543,2 @@ 'span', | ||
className: joinClasses(props.className, classSet(rootCls)), | ||
dir: 'ltr', | ||
onFocus: this.handleFocus, | ||
@@ -528,2 +591,3 @@ onBlur: this.handleBlur }, | ||
disabled: props.disabled, | ||
placeholder: props.searchPlaceholder, | ||
className: prefixCls + '-search__field', | ||
@@ -536,3 +600,3 @@ role: 'textbox' }); | ||
if (state.open) { | ||
var search = multiple || props.combobox || !props.showSearch ? null : React.createElement( | ||
var search = isMultipleOrTagsOrCombobox(props) || !props.showSearch ? null : React.createElement( | ||
'span', | ||
@@ -561,3 +625,3 @@ { className: joinClasses(prefixCls + '-search', prefixCls + '-search--dropdown') }, | ||
var extraSelectionProps = {}; | ||
if (!props.combobox) { | ||
if (!isCombobox(props)) { | ||
extraSelectionProps = { | ||
@@ -595,2 +659,3 @@ onKeyDown: this.handleKeyDown, | ||
multiple: React.PropTypes.bool, | ||
filterOption: React.PropTypes.any, | ||
showSearch: React.PropTypes.bool, | ||
@@ -600,5 +665,10 @@ showArrow: React.PropTypes.bool, | ||
transitionName: React.PropTypes.string, | ||
optionLabelProp: React.PropTypes.string, | ||
optionFilterProp: React.PropTypes.string, | ||
animation: React.PropTypes.string, | ||
onChange: React.PropTypes.func, | ||
onSelect: React.PropTypes.func, | ||
onSearch: React.PropTypes.func, | ||
searchPlaceholder: React.PropTypes.string, | ||
placeholder: React.PropTypes.any, | ||
onDeselect: React.PropTypes.func | ||
@@ -609,13 +679,17 @@ }; | ||
prefixCls: 'rc-select', | ||
filterOption: true, | ||
filterOption: filterFn, | ||
showSearch: true, | ||
allowClear: false, | ||
placeholder: '', | ||
searchPlaceholder: '', | ||
onChange: noop, | ||
onSelect: noop, | ||
onSearch: noop, | ||
onDeselect: noop, | ||
showArrow: true, | ||
optionFilterProp: 'value', | ||
optionLabelProp: 'value', | ||
notFoundContent: 'Not Found' | ||
}; | ||
module.exports = Select; | ||
/*<i className="anticon anticon-search"></i>*/ | ||
module.exports = Select; |
{ | ||
"name": "rc-select", | ||
"version": "3.5.0", | ||
"version": "4.0.0", | ||
"description": "select ui component for react", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
# rc-select | ||
--- | ||
select ui component for react | ||
React Select | ||
@@ -57,5 +57,5 @@ [![NPM version][npm-image]][npm-url] | ||
<Select> | ||
<Option value="1">jack</Option> | ||
<Option value="2">lucy</Option> | ||
<Option value="3">jim</Option> | ||
<Option value="jack">jack</Option> | ||
<Option value="lucy">lucy</Option> | ||
<Option value="jim">jim</Option> | ||
</Select> | ||
@@ -88,2 +88,20 @@ ); | ||
<tr> | ||
<td>filterOption</td> | ||
<td></td> | ||
<td>true|Function(inputValue:string, option:Option)</td> | ||
<td>whether filter options by input value. default filter by option's optionFilterProp prop's value</td> | ||
</tr> | ||
<tr> | ||
<td>optionLabelProp</td> | ||
<td>String</td> | ||
<td>value</td> | ||
<td>which prop value of option will render as content of select</td> | ||
</tr> | ||
<tr> | ||
<td>optionFilterProp</td> | ||
<td>String</td> | ||
<td>value</td> | ||
<td>which prop value of option will be used for filter if filterOption is true</td> | ||
</tr> | ||
<tr> | ||
<td>showSearch</td> | ||
@@ -95,2 +113,8 @@ <td>Boolean</td> | ||
<tr> | ||
<td>onSearch</td> | ||
<td>Function</td> | ||
<td></td> | ||
<td>called when input changed</td> | ||
</tr> | ||
<tr> | ||
<td>disabled</td> | ||
@@ -117,15 +141,15 @@ <td>Boolean</td> | ||
<td></td> | ||
<td>specify the default selected item(s)</td> | ||
</tr> | ||
<td>specify the selected option(s)</td> | ||
</tr> | ||
<tr> | ||
<td>multiple</td> | ||
<td>defaultValue</td> | ||
<td>String | Array<String></td> | ||
<td></td> | ||
<td>false</td> | ||
<td>can select more than one option </td> | ||
<td>specify the default selected option(s)</td> | ||
</tr> | ||
<tr> | ||
<td>filterOption</td> | ||
<td>multiple</td> | ||
<td></td> | ||
<td>true</td> | ||
<td>whether filter options by input value</td> | ||
<td>false</td> | ||
<td>can select more than one option</td> | ||
</tr> | ||
@@ -152,5 +176,5 @@ <tr> | ||
<td>onSelect</td> | ||
<td>Function</td> | ||
<td>Function(value:string, option:Option)</td> | ||
<td></td> | ||
<td>called when a option is selected. param is option's value</td> | ||
<td>called when a option is selected. param is option's value and option instance</td> | ||
</tr> | ||
@@ -164,6 +188,6 @@ <tr> | ||
<tr> | ||
<td>onChange</td> | ||
<td>function(value)</td> | ||
<th></th> | ||
<td>called when select an option or input value change(combobox)</td> | ||
<td>onChange</td> | ||
<td>function(value)</td> | ||
<th></th> | ||
<td>called when select an option or input value change(combobox)</td> | ||
</tr> | ||
@@ -197,8 +221,2 @@ </tbody> | ||
</tr> | ||
<tr> | ||
<td>key</td> | ||
<td>String</td> | ||
<td></td> | ||
<td></td> | ||
</tr> | ||
</tbody> | ||
@@ -205,0 +223,0 @@ </table> |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
40081
994
270