diff --git a/dist/index.js b/dist/index.js index f37f691..ba3baee 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3021,28 +3021,30 @@ var Picky$1 = function (_React$Component) { } }, { key: 'selectValue', - value: function selectValue(value) { + value: function selectValue(val) { var _this2 = this; - if (this.props.multiple && Array.isArray(this.props.value)) { - if (this.props.value.includes(value)) { - var currIndex = this.props.value.indexOf(value); + var valueLookup = this.isControlled() ? this.props.value : this.state.selectedValue; + + if (this.props.multiple && Array.isArray(valueLookup)) { + if (valueLookup.includes(val)) { + var currIndex = valueLookup.indexOf(val); // Remove this.setState({ - selectedValue: [].concat(_toConsumableArray(this.props.value.slice(0, currIndex)), _toConsumableArray(this.props.value.slice(currIndex + 1))) + selectedValue: [].concat(_toConsumableArray(valueLookup.slice(0, currIndex)), _toConsumableArray(valueLookup.slice(currIndex + 1))) }, function () { _this2.props.onChange(_this2.state.selectedValue); }); } else { this.setState({ - selectedValue: [].concat(_toConsumableArray(this.state.selectedValue), [value]) + selectedValue: [].concat(_toConsumableArray(this.state.selectedValue), [val]) }, function () { _this2.props.onChange(_this2.state.selectedValue); }); } } else { this.setState({ - selectedValue: value + selectedValue: val }, function () { _this2.props.onChange(_this2.state.selectedValue); }); @@ -3070,6 +3072,11 @@ var Picky$1 = function (_React$Component) { _this3.props.onChange(_this3.state.selectedValue); }); } + }, { + key: 'isControlled', + value: function isControlled() { + return this.props.value != null; + } }, { key: 'renderOptions', value: function renderOptions() { @@ -3098,8 +3105,12 @@ var Picky$1 = function (_React$Component) { var item = items[index]; var key = isDataObject(item, labelKey, valueKey) ? item[valueKey] : item; - - var isSelected = Array.isArray(value) && value.includes(item) || !Array.isArray(value) && value === item; + var isSelected = false; + if (_this4.isControlled()) { + isSelected = Array.isArray(value) && value.includes(item) || !Array.isArray(value) && value === item; + } else { + isSelected = Array.isArray(_this4.state.selectedValue) && _this4.state.selectedValue.includes(item) || !Array.isArray(_this4.state.selectedValue) && _this4.state.selectedValue === item; + } if (typeof _this4.props.render === 'function') { return _this4.props.render({ @@ -3130,10 +3141,10 @@ var Picky$1 = function (_React$Component) { } }, { key: 'onFilterChange', - value: function onFilterChange(value) { + value: function onFilterChange(term) { var _this5 = this; - if (!value.trim()) { + if (!term.trim()) { return this.setState({ filtered: false, filteredOptions: [] @@ -3141,9 +3152,9 @@ var Picky$1 = function (_React$Component) { } var filteredOptions = this.props.options.filter(function (option) { if (isDataObject(option, _this5.props.labelKey, _this5.props.valueKey)) { - return String(option[_this5.props.labelKey]).toLowerCase().includes(value.toLowerCase()); + return String(option[_this5.props.labelKey]).toLowerCase().includes(term.toLowerCase()); } - return String(option).toLowerCase().includes(value.toLowerCase()); + return String(option).toLowerCase().includes(term.toLowerCase()); }); this.setState({ filtered: true, @@ -3212,7 +3223,7 @@ var Picky$1 = function (_React$Component) { }, React__default.createElement(Placeholder, { placeholder: placeholder, - value: value, + value: this.isControlled() ? value : this.state.selectedValue, multiple: multiple, numberDisplayed: numberDisplayed, valueKey: valueKey, diff --git a/src/Picky.js b/src/Picky.js index 326fc38..d1b227c 100644 --- a/src/Picky.js +++ b/src/Picky.js @@ -45,16 +45,20 @@ class Picky extends React.Component { } } - selectValue(value) { - if (this.props.multiple && Array.isArray(this.props.value)) { - if (this.props.value.includes(value)) { - const currIndex = this.props.value.indexOf(value); + selectValue(val) { + const valueLookup = this.isControlled() + ? this.props.value + : this.state.selectedValue; + + if (this.props.multiple && Array.isArray(valueLookup)) { + if (valueLookup.includes(val)) { + const currIndex = valueLookup.indexOf(val); // Remove this.setState( { selectedValue: [ - ...this.props.value.slice(0, currIndex), - ...this.props.value.slice(currIndex + 1) + ...valueLookup.slice(0, currIndex), + ...valueLookup.slice(currIndex + 1) ] }, () => { @@ -64,7 +68,7 @@ class Picky extends React.Component { } else { this.setState( { - selectedValue: [...this.state.selectedValue, value] + selectedValue: [...this.state.selectedValue, val] }, () => { this.props.onChange(this.state.selectedValue); @@ -74,7 +78,7 @@ class Picky extends React.Component { } else { this.setState( { - selectedValue: value + selectedValue: val }, () => { this.props.onChange(this.state.selectedValue); @@ -102,6 +106,9 @@ class Picky extends React.Component { } ); } + isControlled() { + return this.props.value != null; + } renderOptions() { const { @@ -127,10 +134,18 @@ class Picky extends React.Component { const key = isDataObject(item, labelKey, valueKey) ? item[valueKey] : item; - - const isSelected = - (Array.isArray(value) && value.includes(item)) || - (!Array.isArray(value) && value === item); + let isSelected = false; + if (this.isControlled()) { + isSelected = + (Array.isArray(value) && value.includes(item)) || + (!Array.isArray(value) && value === item); + } else { + isSelected = + (Array.isArray(this.state.selectedValue) && + this.state.selectedValue.includes(item)) || + (!Array.isArray(this.state.selectedValue) && + this.state.selectedValue === item); + } if (typeof this.props.render === 'function') { return this.props.render({ @@ -162,8 +177,8 @@ class Picky extends React.Component { /> ); } - onFilterChange(value) { - if (!value.trim()) { + onFilterChange(term) { + if (!term.trim()) { return this.setState({ filtered: false, filteredOptions: [] @@ -173,11 +188,11 @@ class Picky extends React.Component { if (isDataObject(option, this.props.labelKey, this.props.valueKey)) { return String(option[this.props.labelKey]) .toLowerCase() - .includes(value.toLowerCase()); + .includes(term.toLowerCase()); } return String(option) .toLowerCase() - .includes(value.toLowerCase()); + .includes(term.toLowerCase()); }); this.setState( { @@ -243,7 +258,7 @@ class Picky extends React.Component { > { expect(onChange).toHaveBeenCalledWith([1, 2, 3, 4, 5]); }); - it('should select single value', () => { + it('should select single value controlled', () => { const onChange = jest.fn(); const wrapper = mount( { .simulate('click'); expect(onChange).lastCalledWith(2); }); - it('should select multiple value', () => { + + it('should select single value uncontrolled', () => { + const onChange = jest.fn(); + const wrapper = mount( + + ); + expect(wrapper.state('selectedValue')).toEqual(null); + wrapper + .find('.picky__dropdown .option') + .at(1) + .simulate('click'); + expect(onChange).lastCalledWith(2); + }); + it('should select multiple value controlled', () => { const onChange = jest.fn(); const wrapper = mount( { expect(onChange).lastCalledWith([2]); expect(wrapper.state('selectedValue')).toEqual([2]); }); + it('should select multiple value uncontrolled', () => { + const onChange = jest.fn(); + const wrapper = mount( + + ); + + expect(wrapper.state('selectedValue')).toEqual([]); + wrapper + .find('.picky__dropdown .option') + .at(1) + .simulate('click'); + expect(onChange).lastCalledWith([2]); + expect(wrapper.state('selectedValue')).toEqual([2]); + }); + it('should deselect multiple value', () => { const onChange = jest.fn(); const wrapper = mount(