Skip to content
This repository has been archived by the owner on Jan 15, 2021. It is now read-only.

Commit

Permalink
feat(Picky): Support uncontrolled components (#20)
Browse files Browse the repository at this point in the history
* Revert "Merge branch 'master' into dev"

This reverts commit 12d8924, reversing
changes made to 222eba7.

* feat(Picky): Support uncontrolled components

closes #19
  • Loading branch information
Aidurber authored Dec 29, 2017
1 parent 9297f49 commit fd7a5b7
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 33 deletions.
39 changes: 25 additions & 14 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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({
Expand Down Expand Up @@ -3130,20 +3141,20 @@ 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: []
});
}
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,
Expand Down Expand Up @@ -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,
Expand Down
49 changes: 32 additions & 17 deletions src/Picky.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
]
},
() => {
Expand All @@ -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);
Expand All @@ -74,7 +78,7 @@ class Picky extends React.Component {
} else {
this.setState(
{
selectedValue: value
selectedValue: val
},
() => {
this.props.onChange(this.state.selectedValue);
Expand Down Expand Up @@ -102,6 +106,9 @@ class Picky extends React.Component {
}
);
}
isControlled() {
return this.props.value != null;
}

renderOptions() {
const {
Expand All @@ -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({
Expand Down Expand Up @@ -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: []
Expand All @@ -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(
{
Expand Down Expand Up @@ -243,7 +258,7 @@ class Picky extends React.Component {
>
<Placeholder
placeholder={placeholder}
value={value}
value={this.isControlled() ? value : this.state.selectedValue}
multiple={multiple}
numberDisplayed={numberDisplayed}
valueKey={valueKey}
Expand Down
37 changes: 35 additions & 2 deletions tests/Picky.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ describe('Picky', () => {
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(
<Picky
Expand All @@ -172,7 +172,20 @@ describe('Picky', () => {
.simulate('click');
expect(onChange).lastCalledWith(2);
});
it('should select multiple value', () => {

it('should select single value uncontrolled', () => {
const onChange = jest.fn();
const wrapper = mount(
<Picky options={[1, 2, 3, 4, 5]} open={true} onChange={onChange} />
);
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(
<Picky
Expand All @@ -192,6 +205,26 @@ describe('Picky', () => {
expect(onChange).lastCalledWith([2]);
expect(wrapper.state('selectedValue')).toEqual([2]);
});
it('should select multiple value uncontrolled', () => {
const onChange = jest.fn();
const wrapper = mount(
<Picky
options={[1, 2, 3, 4, 5]}
open={true}
multiple
onChange={onChange}
/>
);

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(
Expand Down

0 comments on commit fd7a5b7

Please sign in to comment.