Comparing version 1.2.0 to 1.2.1
@@ -7,2 +7,5 @@ # Change Log | ||
## 1.2.1 - 2015-08-26 | ||
- [Combobox, Select] Improve children manipulation to make Belle work with Radium [#170](https://github.com/nikgraf/belle/issues/170) | ||
## 1.2.0 - 2015-08-19 | ||
@@ -9,0 +12,0 @@ |
@@ -675,9 +675,9 @@ 'use strict'; | ||
var filteredOptions = []; | ||
if (properties.children.length > 0) { | ||
if (!(0, _utilsHelpers.isEmpty)(properties.children)) { | ||
if (inputValue) { | ||
filteredOptions = (0, _utilsHelpers.filter)(properties.children, function (entry) { | ||
filteredOptions = (0, _utilsHelpers.filterReactChildren)(properties.children, function (entry) { | ||
return properties.filterFunc(inputValue, entry.props.value); | ||
}); | ||
} else { | ||
filteredOptions = (0, _utilsHelpers.map)(properties.children, function (entry) { | ||
filteredOptions = (0, _utilsHelpers.getArrayForReactChildren)(properties.children, function (entry) { | ||
return entry; | ||
@@ -699,3 +699,3 @@ }); | ||
value: { | ||
children: _react2['default'].PropTypes.oneOfType([_react2['default'].PropTypes.arrayOf(_react2['default'].PropTypes.node), _react2['default'].PropTypes.node]), | ||
children: _react2['default'].PropTypes.oneOfType([_react2['default'].PropTypes.array, _react2['default'].PropTypes.object]), | ||
defaultValue: _react2['default'].PropTypes.string, | ||
@@ -702,0 +702,0 @@ value: _react2['default'].PropTypes.string, |
@@ -70,23 +70,2 @@ 'use strict'; | ||
/** | ||
* Returns the index of the entry with a certain value from the component's | ||
* children. | ||
* | ||
* The index search includes only option components. | ||
*/ | ||
var findIndexOfFocusedOption = function findIndexOfFocusedOption(component) { | ||
return (0, _utilsHelpers.findIndex)((0, _utilsHelpers.filter)(component.children, isOption), function (element) { | ||
return element.props.value === component.state.focusedOptionValue; | ||
}); | ||
}; | ||
/** | ||
* Verifies that the provided property is an Option or Placeholder component from Belle. | ||
*/ | ||
function optionOrPlaceholderOrSeparatorPropType(props, propName, componentName) { | ||
if (props[propName] && !(isOption(props[propName]) || isPlaceholder(props[propName]) || isSeparator(props[propName]))) { | ||
return new Error('Invalid children supplied to `' + componentName + '`, expected an Option or Placeholder component from Belle.'); | ||
} | ||
} | ||
/** | ||
* Verifies that the children is an array containing only Options & at maximum | ||
@@ -96,9 +75,13 @@ * one Placeholder. | ||
function validateChildrenAreOptionsAndMaximumOnePlaceholder(props, propName, componentName) { | ||
var sanitizedProps = { children: (0, _utilsHelpers.flatten)(props[propName]) }; | ||
var validChildren = (0, _utilsHelpers.filterReactChildren)(props[propName], function (node) { | ||
return isOption(node) || isSeparator(node) || isPlaceholder(node); | ||
}); | ||
if (_react2['default'].Children.count(props[propName]) !== _react2['default'].Children.count(validChildren)) { | ||
return new Error('Invalid children supplied to `' + componentName + '`, expected an Option, Separator or Placeholder component from Belle.'); | ||
} | ||
var error = _react.PropTypes.arrayOf(optionOrPlaceholderOrSeparatorPropType).isRequired(sanitizedProps, 'children', componentName); | ||
if (error) return error; | ||
var placeholders = (0, _utilsHelpers.filter)(sanitizedProps.children, isPlaceholder); | ||
if ((0, _utilsHelpers.size)(placeholders) > 1) { | ||
var placeholders = (0, _utilsHelpers.filterReactChildren)(props[propName], function (node) { | ||
return isPlaceholder(node); | ||
}); | ||
if (_react2['default'].Children.count(placeholders) > 1) { | ||
return new Error('Invalid children supplied to `' + componentName + '`, expected only one Placeholder component.'); | ||
@@ -216,3 +199,4 @@ } | ||
if (properties.children) { | ||
this.children = (0, _utilsHelpers.flatten)(properties.children); | ||
this.children = (0, _utilsHelpers.flattenReactChildren)(properties.children); | ||
this.options = (0, _utilsHelpers.filter)(this.children, isOption); | ||
} | ||
@@ -230,7 +214,7 @@ | ||
} else if (!(0, _utilsHelpers.isEmpty)(this.children) && !(0, _utilsHelpers.some)(this.children, isPlaceholder)) { | ||
var firstOption = (0, _utilsHelpers.first)((0, _utilsHelpers.filter)(this.children, isOption)); | ||
var firstOption = (0, _utilsHelpers.first)(this.options); | ||
selectedValue = firstOption ? firstOption.props.value : void 0; | ||
focusedOptionValue = selectedValue; | ||
} else if (!(0, _utilsHelpers.isEmpty)(this.children)) { | ||
var firstOption = (0, _utilsHelpers.first)((0, _utilsHelpers.filter)(this.children, isOption)); | ||
var firstOption = (0, _utilsHelpers.first)(this.options); | ||
focusedOptionValue = firstOption ? firstOption.props.value : void 0; | ||
@@ -277,3 +261,4 @@ } | ||
if (properties.children) { | ||
this.children = (0, _utilsHelpers.flatten)(properties.children); | ||
this.children = (0, _utilsHelpers.flattenReactChildren)(properties.children); | ||
this.options = (0, _utilsHelpers.filter)(this.children, isOption); | ||
} | ||
@@ -343,6 +328,5 @@ | ||
var options = (0, _utilsHelpers.filter)(this.children, isOption); | ||
var separators = (0, _utilsHelpers.filter)(this.children, isSeparator); | ||
var childrenLength = (options ? options.length : 0) + (separators ? separators.length : 0); | ||
if (!previousState.isOpen && this.state.isOpen && childrenLength) { | ||
var childrenPresent = !(0, _utilsHelpers.isEmpty)(this.options) || !(0, _utilsHelpers.isEmpty)(separators); | ||
if (!previousState.isOpen && this.state.isOpen && childrenPresent) { | ||
var menuStyle = (0, _utilsHelpers.extend)({}, _styleSelect2['default'].menuStyle, this.props.menuStyle); | ||
@@ -614,7 +598,7 @@ menuNode.style.display = menuStyle.display; | ||
if (this.state.focusedOptionValue) { | ||
var indexOfFocusedOption = findIndexOfFocusedOption(this); | ||
var indexOfFocusedOption = this._getIndexOfFocusedOption(); | ||
if (hasNext((0, _utilsHelpers.filter)(this.children, isOption), indexOfFocusedOption)) { | ||
if (hasNext(this.options, indexOfFocusedOption)) { | ||
this.setState({ | ||
focusedOptionValue: (0, _utilsHelpers.filter)(this.children, isOption)[indexOfFocusedOption + 1].props.value | ||
focusedOptionValue: this.options[indexOfFocusedOption + 1].props.value | ||
}); | ||
@@ -624,3 +608,3 @@ } | ||
this.setState({ | ||
focusedOptionValue: (0, _utilsHelpers.first)((0, _utilsHelpers.filter)(this.children, isOption)).props.value | ||
focusedOptionValue: (0, _utilsHelpers.first)(this.options).props.value | ||
}); | ||
@@ -643,7 +627,7 @@ } | ||
if (this.state.focusedOptionValue) { | ||
var indexOfFocusedOption = findIndexOfFocusedOption(this); | ||
var indexOfFocusedOption = this._getIndexOfFocusedOption(); | ||
if (hasPrevious((0, _utilsHelpers.filter)(this.children, isOption), indexOfFocusedOption)) { | ||
if (hasPrevious(this.options, indexOfFocusedOption)) { | ||
this.setState({ | ||
focusedOptionValue: (0, _utilsHelpers.filter)(this.children, isOption)[indexOfFocusedOption - 1].props.value | ||
focusedOptionValue: this.options[indexOfFocusedOption - 1].props.value | ||
}); | ||
@@ -653,3 +637,3 @@ } | ||
this.setState({ | ||
focusedOptionValue: (0, _utilsHelpers.last)((0, _utilsHelpers.filter)(this.children, isOption)).props.value | ||
focusedOptionValue: (0, _utilsHelpers.last)(this.options).props.value | ||
}); | ||
@@ -686,3 +670,3 @@ } | ||
if (!this.props.disabled) { | ||
if ((0, _utilsHelpers.filter)(this.children, isOption).length > 0) { | ||
if (!(0, _utilsHelpers.isEmpty)(this.options)) { | ||
if (!this.state.isOpen) { | ||
@@ -771,5 +755,21 @@ if (event.key === 'ArrowDown' || event.key === 'ArrowUp' || event.key === ' ') { | ||
}, { | ||
key: '_getIndexOfFocusedOption', | ||
/** | ||
* Returns the index of the entry with a certain value from the component's | ||
* children. | ||
* | ||
* The index search includes only option components. | ||
*/ | ||
value: function _getIndexOfFocusedOption() { | ||
var _this = this; | ||
return (0, _utilsHelpers.findIndex)(this.options, function (element) { | ||
return element.props.value === _this.state.focusedOptionValue; | ||
}); | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
var _this = this; | ||
var _this2 = this; | ||
@@ -791,3 +791,3 @@ var defaultStyle = (0, _utilsHelpers.extend)({}, _styleSelect2['default'].style, this.props.style); | ||
var selectedEntry = (0, _utilsHelpers.find)(this.children, function (entry) { | ||
return entry.props.value === _this.state.selectedValue; | ||
return entry.props.value === _this2.state.selectedValue; | ||
}); | ||
@@ -804,6 +804,5 @@ | ||
var options = (0, _utilsHelpers.filter)(this.children, isOption); | ||
var separators = (0, _utilsHelpers.filter)(this.children, isSeparator); | ||
var childrenLength = (options ? options.length : 0) + (separators ? separators.length : 0); | ||
var computedMenuStyle = this.props.disabled || !this.state.isOpen || childrenLength === 0 ? { display: 'none' } : menuStyle; | ||
var childrenNotPresent = (0, _utilsHelpers.isEmpty)(this.options) && (0, _utilsHelpers.isEmpty)(separators); | ||
var computedMenuStyle = this.props.disabled || !this.state.isOpen || childrenNotPresent ? { display: 'none' } : menuStyle; | ||
var hasCustomTabIndex = this.props.wrapperProps && this.props.wrapperProps.tabIndex; | ||
@@ -882,3 +881,3 @@ var tabIndex = hasCustomTabIndex ? this.props.wrapperProps.tabIndex : '0'; | ||
if (isOption(entry)) { | ||
var isHovered = entry.props.value === _this.state.focusedOptionValue; | ||
var isHovered = entry.props.value === _this2.state.focusedOptionValue; | ||
var option = _react2['default'].cloneElement(entry, { | ||
@@ -890,9 +889,9 @@ _isHovered: isHovered | ||
'li', | ||
{ onClick: _this._onClickAtOption.bind(_this), | ||
onTouchStart: _this._onTouchStartAtOption.bind(_this), | ||
onTouchMove: _this._onTouchMoveAtOption.bind(_this), | ||
onTouchEnd: _this._onTouchEndAtOption.bind(_this), | ||
onTouchCancel: _this._onTouchCancelAtOption.bind(_this), | ||
{ onClick: _this2._onClickAtOption.bind(_this2), | ||
onTouchStart: _this2._onTouchStartAtOption.bind(_this2), | ||
onTouchMove: _this2._onTouchMoveAtOption.bind(_this2), | ||
onTouchEnd: _this2._onTouchEndAtOption.bind(_this2), | ||
onTouchCancel: _this2._onTouchCancelAtOption.bind(_this2), | ||
key: index, | ||
onMouseEnter: _this._onMouseEnterAtOption.bind(_this), | ||
onMouseEnter: _this2._onMouseEnterAtOption.bind(_this2), | ||
role: 'option', | ||
@@ -899,0 +898,0 @@ 'aria-selected': isHovered }, |
@@ -29,3 +29,3 @@ 'use strict'; | ||
}; | ||
return (0, _utilsHelpers.findIndex)((0, _utilsHelpers.filter)(component.props.children, filterFunction), function (element) { | ||
return (0, _utilsHelpers.findIndex)((0, _utilsHelpers.filterReactChildren)(component.props.children, filterFunction), function (element) { | ||
return element.props.value === component.state.selectedValue; | ||
@@ -32,0 +32,0 @@ }); |
@@ -1,7 +0,1 @@ | ||
/** | ||
* Returns true if the object contain the given key. | ||
* | ||
* @param {object} obj - object to be inspected | ||
* @param {string} key - name of the property | ||
*/ | ||
'use strict'; | ||
@@ -30,3 +24,19 @@ | ||
exports.flatten = flatten; | ||
exports.filterReactChildren = filterReactChildren; | ||
exports.getArrayForReactChildren = getArrayForReactChildren; | ||
exports.flattenReactChildren = flattenReactChildren; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
var _react = require('react'); | ||
var _react2 = _interopRequireDefault(_react); | ||
/** | ||
* Returns true if the object contain the given key. | ||
* | ||
* @param {object} obj - object to be inspected | ||
* @param {string} key - name of the property | ||
*/ | ||
function has(obj, key) { | ||
@@ -182,9 +192,12 @@ return obj !== undefined && obj !== null && Object.prototype.hasOwnProperty.call(obj, key); | ||
/** | ||
* Returns true if object contains no values (no enumerable own-properties). | ||
* Returns true if object is: | ||
* 1. Falsy | ||
* 2. An array of size 0 | ||
* 3. An object with no key-values | ||
* | ||
* @param {array} iterable - an iterable object | ||
* @param {Object} obj - an object | ||
*/ | ||
function isEmpty(iterable) { | ||
return !iterable || iterable.length === 0; | ||
function isEmpty(obj) { | ||
return !obj || Array.isArray(obj) && obj.length === 0 || Object.keys(obj).length === 0; | ||
} | ||
@@ -377,2 +390,60 @@ | ||
} | ||
} | ||
/** | ||
* Looks through a collection of React children elements, filtering them according to the predicate passed. | ||
* | ||
* @param {Array/Object} children - colleciton of >=1 react elements | ||
* @param {function} predicate - function returning true when provided with an entry as argument | ||
*/ | ||
function filterReactChildren(children, predicate) { | ||
var _this = this; | ||
if (children) { | ||
var _ret5 = (function () { | ||
var result = []; | ||
_react2['default'].Children.forEach(children, function (entry) { | ||
if (predicate && predicate.call(_this, entry)) { | ||
result.push(entry); | ||
} | ||
}); | ||
return { | ||
v: result | ||
}; | ||
})(); | ||
if (typeof _ret5 === 'object') return _ret5.v; | ||
} | ||
} | ||
/** | ||
* Looks through a collection of React children elements, filtering them according to the predicate passed. | ||
* | ||
* @param {Array/Object} children - collection of >=1 react elements | ||
*/ | ||
function getArrayForReactChildren(children) { | ||
if (children) { | ||
var _ret6 = (function () { | ||
var result = []; | ||
_react2['default'].Children.forEach(children, function (entry) { | ||
result.push(entry); | ||
}); | ||
return { | ||
v: result | ||
}; | ||
})(); | ||
if (typeof _ret6 === 'object') return _ret6.v; | ||
} | ||
} | ||
function flattenReactChildren(children) { | ||
if (!isEmpty(children)) { | ||
if (Array.isArray(children)) { | ||
return flatten(children); | ||
} | ||
return getArrayForReactChildren(children); | ||
} | ||
} |
{ | ||
"name": "belle", | ||
"version": "1.2.0", | ||
"version": "1.2.1", | ||
"description": "Configurable React Components with great UX", | ||
@@ -5,0 +5,0 @@ "author": { |
1004092
216
23802