diff --git a/dist/index.js b/dist/index.js index 9e8d74a..7bab8bc 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1 +1 @@ -"use strict";function _interopDefault(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var React=require("react"),React__default=_interopDefault(React);require("prop-types");var isEqual=_interopDefault(require("lodash.isequal"));function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var l=0;l>>0;if("function"!=typeof e)throw new TypeError("predicate must be a function");for(var i=arguments[1],r=0;r>>0;if("function"!=typeof e)throw new TypeError("predicate must be a function");for(var l=arguments[1],n=0;n value[this.props.valueKey]); - } - selectedValue = - ids.indexOf(item) === -1 - ? [...this.props.value, val] - : [...this.props.value]; + selectedValue = [...this.props.value, val]; } this.setState( { @@ -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); } /** @@ -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) { @@ -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. @@ -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( { @@ -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; diff --git a/src/lib/utils.js b/src/lib/utils.js index d29fce1..5e865d4 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -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; +} diff --git a/tests/utils.test.js b/tests/utils.test.js index a4b0b97..6aa8eb0 100644 --- a/tests/utils.test.js +++ b/tests/utils.test.js @@ -3,6 +3,8 @@ import { hasItem, keyExtractor, hasItemIndex, + sortCollection, + arraysEqual, } from '../src/lib/utils'; describe('Utils', () => { describe('isDataObject', () => { @@ -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); + }); + }); });