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

Commit

Permalink
fix(Picky): Select all inconsistencies
Browse files Browse the repository at this point in the history
Needed to better check if values are equal to determine if all selected. Needed to sort arrays.

fix #74
  • Loading branch information
Aidurber committed Oct 21, 2018
1 parent 6833c21 commit 18b7ba1
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 39 deletions.
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
"semantic-release": "semantic-release",
"precommit": "npm run test"
},
"dependencies": {
"lodash.isequal": "^4.5.0"
},
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.1.2",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
Expand Down
84 changes: 49 additions & 35 deletions src/Picky.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import {
hasItem,
keyExtractor,
hasItemIndex,
sortCollection,
arraysEqual,
} from './lib/utils';
import isEqual from 'lodash.isequal';
import Placeholder from './Placeholder';
import Filter from './Filter';
import Option from './Option';
import './Picky.css';

class Picky extends React.PureComponent {
constructor(props) {
super(props);
Expand All @@ -36,10 +38,8 @@ class Picky extends React.PureComponent {
this.focusFilterInput = this.focusFilterInput.bind(this);
}
UNSAFE_componentWillMount() {
const allSelected = this.allSelected();

this.setState({
allSelected,
allSelected: this.allSelected(),
});
}

Expand All @@ -52,8 +52,12 @@ class Picky extends React.PureComponent {
this.props.options !== nextProps.options ||
this.props.value !== nextProps.value
) {
let areEqual = Array.isArray(nextProps.value)
? arraysEqual(nextProps.value, this.props.value)
: nextProps.value === this.props.value;

this.setState({
allSelected: !isEqual(nextProps.value, this.props.value)
allSelected: !areEqual
? this.allSelected(nextProps.value)
: this.allSelected(),
});
Expand All @@ -62,11 +66,6 @@ class Picky extends React.PureComponent {

selectValue(val) {
const valueLookup = this.props.value;
const isObject = isDataObject(
val,
this.props.valueKey,
this.props.labelKey
);
if (this.props.multiple && Array.isArray(valueLookup)) {
const itemIndex = hasItemIndex(
valueLookup,
Expand All @@ -82,15 +81,7 @@ class Picky extends React.PureComponent {
...valueLookup.slice(itemIndex + 1),
];
} else {
let ids = valueLookup;
const item = isObject ? val[this.props.valueKey] : val;
if (isObject) {
ids = valueLookup.map(value => value[this.props.valueKey]);
}
selectedValue =
ids.indexOf(item) === -1
? [...this.props.value, val]
: [...this.props.value];
selectedValue = [...this.props.value, val];
}
this.setState(
{
Expand All @@ -114,11 +105,25 @@ class Picky extends React.PureComponent {
allSelected(overrideSelected) {
const selectedValue = overrideSelected || this.props.value;
const { options } = this.props;
const copiedOptions = options.slice(0);
const copiedSelectedValue = Array.isArray(selectedValue)
const isObject = isDataObject(
options && options[0],
this.props.valueKey,
this.props.labelKey
);

let copiedOptions = options.slice(0);
let copiedValues = Array.isArray(selectedValue)
? selectedValue.slice(0)
: [];
return isEqual(copiedOptions, copiedSelectedValue);
if (isObject) {
copiedOptions = sortCollection(copiedOptions, this.props.valueKey);
copiedValues = sortCollection(copiedValues, this.props.valueKey);
} else {
copiedOptions = sortCollection(copiedOptions);
copiedValues = sortCollection(copiedValues);
}

return arraysEqual(copiedOptions, copiedValues);
}

/**
Expand All @@ -128,8 +133,11 @@ class Picky extends React.PureComponent {
*/
toggleSelectAll() {
this.setState(
{
allSelected: !this.state.allSelected,
state => {
return {
...state,
allSelected: !this.state.allSelected,
};
},
() => {
if (!this.state.allSelected) {
Expand Down Expand Up @@ -211,10 +219,9 @@ class Picky extends React.PureComponent {
});
}
renderOptions() {
const { options } = this.props;
const items = this.state.filtered ? this.state.filteredOptions : options;

return this.renderPlainList(items);
return this.renderPlainList(
this.state.filtered ? this.state.filteredOptions : this.props.options
);
}
/**
* Called when Filter term changes. Sets filteredOptions and filtered state.
Expand All @@ -230,12 +237,16 @@ class Picky extends React.PureComponent {
filteredOptions: [],
});
}
const isObject = isDataObject(
this.props.options && this.props.options[0],
this.props.valueKey,
this.props.labelKey
);
const filteredOptions = this.props.options.filter(option => {
let val = option;
if (isDataObject(option, this.props.labelKey, this.props.valueKey)) {
val = option[this.props.labelKey];
if (isObject) {
return includes(option[this.props.labelKey], term);
}
return includes(val, term);
return includes(option, term);
});
this.setState(
{
Expand Down Expand Up @@ -288,9 +299,12 @@ class Picky extends React.PureComponent {
}

this.setState(
{
// Toggle open state
open: !this.state.open,
state => {
return {
...state,
// Toggle open state
open: !state.open,
};
},
() => {
const isOpen = this.state.open;
Expand Down
21 changes: 21 additions & 0 deletions src/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,24 @@ export const hasItemIndex = (all, item, valueKey, labelKey) =>

export const keyExtractor = (item, valueKey, labelKey) =>
isDataObject(item, valueKey, labelKey) ? item[valueKey] : item;
export const labelExtractor = (item, valueKey, labelKey) =>
isDataObject(item, valueKey, labelKey) ? item[labelKey] : item;

export const sortCollection = (array, valueKey) => {
if (valueKey) {
return array.sort((a, b) => a[valueKey] - b[valueKey]);
} else {
return array.sort((a, b) => a - b);
}
};

export function arraysEqual(left, right) {
if (left.length !== right.length) return false;
const leftLen = left.length;
let i = leftLen;
while (i) {
if (left[i] !== right[i]) return false;
i--;
}
return true;
}
35 changes: 35 additions & 0 deletions tests/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
hasItem,
keyExtractor,
hasItemIndex,
sortCollection,
arraysEqual,
} from '../src/lib/utils';
describe('Utils', () => {
describe('isDataObject', () => {
Expand Down Expand Up @@ -85,4 +87,37 @@ describe('Utils', () => {
expect(keyExtractor(2)).toEqual(2);
});
});

describe('sort', () => {
it('should sort simple array ascending', () => {
const data = [2, 3, 1];
const result = sortCollection(data);
expect(result).toEqual([1, 2, 3]);
});
it('should sort object array ascending', () => {
const data = [{ id: 2 }, { id: 3 }, { id: 1 }];
const result = sortCollection(data, 'id');
expect(result).toEqual([{ id: 1 }, { id: 2 }, { id: 3 }]);
});
});
describe('arrays equal', () => {
it('should return false if arrays are different lengths', () => {
const left = [1, 2, 3];
const right = [1, 2];
const result = arraysEqual(left, right);
expect(result).toBe(false);
});
it('should return return true if arrays are equal', () => {
const left = [1, 2, 3];
const right = [1, 2, 3];
const result = arraysEqual(left, right);
expect(result).toBe(true);
});
it('should return return false if arrays are not equal', () => {
const left = [1, 2, 3];
const right = [2, 1, 3];
const result = arraysEqual(left, right);
expect(result).toBe(false);
});
});
});

0 comments on commit 18b7ba1

Please sign in to comment.