react-autowhatever
Advanced tools
Comparing version 4.1.0 to 4.2.0
@@ -7,6 +7,6 @@ 'use strict'; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
@@ -26,6 +26,10 @@ | ||
var _Item = require('./Item'); | ||
var _SectionTitle = require('./SectionTitle'); | ||
var _Item2 = _interopRequireDefault(_Item); | ||
var _SectionTitle2 = _interopRequireDefault(_SectionTitle); | ||
var _ItemsList = require('./ItemsList'); | ||
var _ItemsList2 = _interopRequireDefault(_ItemsList); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -39,2 +43,6 @@ | ||
var alwaysTrue = function alwaysTrue() { | ||
return true; | ||
}; | ||
var Autowhatever = function (_Component) { | ||
@@ -48,6 +56,10 @@ _inherits(Autowhatever, _Component); | ||
_this.setSectionsItems(props); | ||
_this.setSectionIterator(props); | ||
_this.setTheme(props); | ||
_this.onKeyDown = _this.onKeyDown.bind(_this); | ||
_this.storeInputReference = _this.storeInputReference.bind(_this); | ||
_this.storeItemsContainerReference = _this.storeItemsContainerReference.bind(_this); | ||
_this.storeFocusedItemReference = _this.storeFocusedItemReference.bind(_this); | ||
_this.storeItemsListReference = _this.storeItemsListReference.bind(_this); | ||
_this.getItemId = _this.getItemId.bind(_this); | ||
return _this; | ||
@@ -57,12 +69,45 @@ } | ||
_createClass(Autowhatever, [{ | ||
key: 'componentDidMount', | ||
value: function componentDidMount() { | ||
this.ensureFocusedSuggestionIsVisible(); | ||
key: 'componentWillReceiveProps', | ||
value: function componentWillReceiveProps(nextProps) { | ||
if (nextProps.items !== this.props.items) { | ||
this.setSectionsItems(nextProps); | ||
} | ||
if (nextProps.items !== this.props.items || nextProps.multiSection !== this.props.multiSection) { | ||
this.setSectionIterator(nextProps); | ||
} | ||
if (nextProps.theme !== this.props.theme) { | ||
this.setTheme(nextProps); | ||
} | ||
} | ||
}, { | ||
key: 'componentDidUpdate', | ||
value: function componentDidUpdate() { | ||
this.ensureFocusedSuggestionIsVisible(); | ||
key: 'setSectionsItems', | ||
value: function setSectionsItems(props) { | ||
if (props.multiSection) { | ||
this.sectionsItems = props.items.map(function (section) { | ||
return props.getSectionItems(section); | ||
}); | ||
this.sectionsLengths = this.sectionsItems.map(function (items) { | ||
return items.length; | ||
}); | ||
this.allSectionsAreEmpty = this.sectionsLengths.every(function (itemsCount) { | ||
return itemsCount === 0; | ||
}); | ||
} | ||
} | ||
}, { | ||
key: 'setSectionIterator', | ||
value: function setSectionIterator(props) { | ||
this.sectionIterator = (0, _sectionIterator2.default)({ | ||
multiSection: props.multiSection, | ||
data: props.multiSection ? this.sectionsLengths : props.items.length | ||
}); | ||
} | ||
}, { | ||
key: 'setTheme', | ||
value: function setTheme(props) { | ||
this.theme = (0, _reactThemeable2.default)(props.theme); | ||
} | ||
}, { | ||
key: 'storeInputReference', | ||
@@ -74,17 +119,13 @@ value: function storeInputReference(input) { | ||
} | ||
// Needed only for testing | ||
}, { | ||
key: 'storeItemsContainerReference', | ||
value: function storeItemsContainerReference(itemsContainer) { | ||
if (itemsContainer !== null) { | ||
this.itemsContainer = itemsContainer; | ||
key: 'storeItemsListReference', | ||
value: function storeItemsListReference(itemsList) { | ||
if (itemsList !== null) { | ||
this.itemsList = itemsList; | ||
} | ||
} | ||
}, { | ||
key: 'storeFocusedItemReference', | ||
value: function storeFocusedItemReference(focusedItem) { | ||
if (focusedItem !== null) { | ||
this.focusedItem = focusedItem.item; | ||
} | ||
} | ||
}, { | ||
key: 'getItemId', | ||
@@ -108,12 +149,20 @@ value: function getItemId(sectionIndex, itemIndex) { | ||
return 'react-whatever-' + id; | ||
return 'react-autowhatever-' + id; | ||
} | ||
}, { | ||
key: 'renderItemsList', | ||
value: function renderItemsList(theme, items, sectionIndex) { | ||
key: 'renderSections', | ||
value: function renderSections() { | ||
var _this2 = this; | ||
if (this.allSectionsAreEmpty) { | ||
return null; | ||
} | ||
var theme = this.theme; | ||
var _props = this.props; | ||
var id = _props.id; | ||
var items = _props.items; | ||
var renderItem = _props.renderItem; | ||
var shouldRenderSection = _props.shouldRenderSection; | ||
var renderSectionTitle = _props.renderSectionTitle; | ||
var focusedSectionIndex = _props.focusedSectionIndex; | ||
@@ -123,58 +172,6 @@ var focusedItemIndex = _props.focusedItemIndex; | ||
var isItemPropsFunction = typeof itemProps === 'function'; | ||
var sectionPrefix = sectionIndex === null ? '' : 'section-' + sectionIndex + '-'; | ||
return items.map(function (item, itemIndex) { | ||
var isFocused = sectionIndex === focusedSectionIndex && itemIndex === focusedItemIndex; | ||
var itemKey = 'react-autowhatever-' + id + '-' + sectionPrefix + 'item-' + itemIndex; | ||
var itemPropsObj = isItemPropsFunction ? itemProps({ sectionIndex: sectionIndex, itemIndex: itemIndex }) : itemProps; | ||
var allItemProps = _extends({ | ||
id: _this2.getItemId(sectionIndex, itemIndex) | ||
}, theme(itemKey, 'item', isFocused && 'itemFocused'), itemPropsObj); | ||
if (isFocused) { | ||
allItemProps.ref = _this2.storeFocusedItemReference; | ||
} | ||
return _react2.default.createElement(_Item2.default, _extends({}, allItemProps, { | ||
sectionIndex: sectionIndex, | ||
itemIndex: itemIndex, | ||
item: item, | ||
renderItem: renderItem, | ||
key: itemKey })); | ||
}); | ||
} | ||
}, { | ||
key: 'renderSections', | ||
value: function renderSections(theme) { | ||
var _this3 = this; | ||
var _props2 = this.props; | ||
var items = _props2.items; | ||
var getSectionItems = _props2.getSectionItems; | ||
var sectionItemsArray = items.map(function (section) { | ||
return getSectionItems(section); | ||
}); | ||
var noItemsExist = sectionItemsArray.every(function (sectionItems) { | ||
return sectionItems.length === 0; | ||
}); | ||
if (noItemsExist) { | ||
return null; | ||
} | ||
var _props3 = this.props; | ||
var id = _props3.id; | ||
var shouldRenderSection = _props3.shouldRenderSection; | ||
var renderSectionTitle = _props3.renderSectionTitle; | ||
return _react2.default.createElement( | ||
'div', | ||
_extends({ | ||
id: this.getItemsContainerId(), | ||
ref: this.storeItemsContainerReference, | ||
role: 'listbox' | ||
}, theme('react-autowhatever-' + id + '-items-container', 'itemsContainer')), | ||
theme('react-autowhatever-' + id + '-items-container', 'itemsContainer'), | ||
items.map(function (section, sectionIndex) { | ||
@@ -185,3 +182,4 @@ if (!shouldRenderSection(section)) { | ||
var sectionTitle = renderSectionTitle(section); | ||
var keyPrefix = 'react-autowhatever-' + id + '-'; | ||
var sectionKeyPrefix = keyPrefix + 'section-' + sectionIndex + '-'; | ||
@@ -192,13 +190,19 @@ // `key` is provided by theme() | ||
'div', | ||
theme('react-autowhatever-' + id + '-section-' + sectionIndex + '-container', 'sectionContainer'), | ||
sectionTitle && _react2.default.createElement( | ||
'div', | ||
theme('react-autowhatever-' + id + '-section-' + sectionIndex + '-title', 'sectionTitle'), | ||
sectionTitle | ||
), | ||
_react2.default.createElement( | ||
'ul', | ||
theme('react-autowhatever-' + id + '-section-' + sectionIndex + '-items-container', 'sectionItemsContainer'), | ||
_this3.renderItemsList(theme, sectionItemsArray[sectionIndex], sectionIndex) | ||
) | ||
theme(sectionKeyPrefix + 'container', 'sectionContainer'), | ||
_react2.default.createElement(_SectionTitle2.default, { | ||
section: section, | ||
renderSectionTitle: renderSectionTitle, | ||
theme: theme, | ||
sectionKeyPrefix: sectionKeyPrefix }), | ||
_react2.default.createElement(_ItemsList2.default, { | ||
id: _this2.getItemsContainerId(), | ||
items: _this2.sectionsItems[sectionIndex], | ||
itemProps: itemProps, | ||
renderItem: renderItem, | ||
sectionIndex: sectionIndex, | ||
focusedItemIndex: focusedSectionIndex === sectionIndex ? focusedItemIndex : null, | ||
getItemId: _this2.getItemId, | ||
theme: theme, | ||
keyPrefix: keyPrefix, | ||
ref: _this2.storeItemsListReference }) | ||
); | ||
@@ -211,3 +215,3 @@ /* eslint-enable react/jsx-key */ | ||
key: 'renderItems', | ||
value: function renderItems(theme) { | ||
value: function renderItems() { | ||
var items = this.props.items; | ||
@@ -220,14 +224,21 @@ | ||
var id = this.props.id; | ||
var theme = this.theme; | ||
var _props2 = this.props; | ||
var id = _props2.id; | ||
var renderItem = _props2.renderItem; | ||
var focusedSectionIndex = _props2.focusedSectionIndex; | ||
var focusedItemIndex = _props2.focusedItemIndex; | ||
var itemProps = _props2.itemProps; | ||
return _react2.default.createElement( | ||
'ul', | ||
_extends({ | ||
id: this.getItemsContainerId(), | ||
ref: this.storeItemsContainerReference, | ||
role: 'listbox' | ||
}, theme('react-autowhatever-' + id + '-items-container', 'itemsContainer')), | ||
this.renderItemsList(theme, items, null) | ||
); | ||
return _react2.default.createElement(_ItemsList2.default, { | ||
id: this.getItemsContainerId(), | ||
items: items, | ||
itemProps: itemProps, | ||
renderItem: renderItem, | ||
focusedItemIndex: focusedSectionIndex === null ? focusedItemIndex : null, | ||
getItemId: this.getItemId, | ||
theme: theme, | ||
keyPrefix: 'react-autowhatever-' + id + '-', | ||
ref: this.storeItemsListReference }); | ||
} | ||
@@ -237,12 +248,7 @@ }, { | ||
value: function onKeyDown(event) { | ||
var _this4 = this; | ||
var _props3 = this.props; | ||
var inputProps = _props3.inputProps; | ||
var focusedSectionIndex = _props3.focusedSectionIndex; | ||
var focusedItemIndex = _props3.focusedItemIndex; | ||
var _props4 = this.props; | ||
var inputProps = _props4.inputProps; | ||
var focusedSectionIndex = _props4.focusedSectionIndex; | ||
var focusedItemIndex = _props4.focusedItemIndex; | ||
var onKeyDownFn = inputProps.onKeyDown; // Babel is throwing: | ||
// "onKeyDown" is read-only | ||
// on: | ||
// const { onKeyDown } = inputProps; | ||
@@ -253,72 +259,31 @@ switch (event.key) { | ||
{ | ||
var _ret = function () { | ||
var _props5 = _this4.props; | ||
var multiSection = _props5.multiSection; | ||
var items = _props5.items; | ||
var getSectionItems = _props5.getSectionItems; | ||
var nextPrev = event.key === 'ArrowDown' ? 'next' : 'prev'; | ||
var sectionIterator = (0, _sectionIterator2.default)({ | ||
multiSection: multiSection, | ||
data: multiSection ? items.map(function (section) { | ||
return getSectionItems(section).length; | ||
}) : items.length | ||
}); | ||
var nextPrev = event.key === 'ArrowDown' ? 'next' : 'prev'; | ||
var _sectionIterator$next = this.sectionIterator[nextPrev]([focusedSectionIndex, focusedItemIndex]); | ||
var _sectionIterator$next = sectionIterator[nextPrev]([focusedSectionIndex, focusedItemIndex]); | ||
var _sectionIterator$next2 = _slicedToArray(_sectionIterator$next, 2); | ||
var _sectionIterator$next2 = _slicedToArray(_sectionIterator$next, 2); | ||
var newFocusedSectionIndex = _sectionIterator$next2[0]; | ||
var newFocusedItemIndex = _sectionIterator$next2[1]; | ||
var newFocusedSectionIndex = _sectionIterator$next2[0]; | ||
var newFocusedItemIndex = _sectionIterator$next2[1]; | ||
onKeyDownFn(event, { newFocusedSectionIndex: newFocusedSectionIndex, newFocusedItemIndex: newFocusedItemIndex }); | ||
return 'break'; | ||
}(); | ||
if (_ret === 'break') break; | ||
inputProps.onKeyDown(event, { newFocusedSectionIndex: newFocusedSectionIndex, newFocusedItemIndex: newFocusedItemIndex }); | ||
break; | ||
} | ||
default: | ||
onKeyDownFn(event, { focusedSectionIndex: focusedSectionIndex, focusedItemIndex: focusedItemIndex }); | ||
inputProps.onKeyDown(event, { focusedSectionIndex: focusedSectionIndex, focusedItemIndex: focusedItemIndex }); | ||
} | ||
} | ||
}, { | ||
key: 'ensureFocusedSuggestionIsVisible', | ||
value: function ensureFocusedSuggestionIsVisible() { | ||
if (!this.focusedItem) { | ||
return; | ||
} | ||
var focusedItem = this.focusedItem; | ||
var itemsContainer = this.itemsContainer; | ||
var itemOffsetRelativeToContainer = focusedItem.offsetParent === itemsContainer ? focusedItem.offsetTop : focusedItem.offsetTop - itemsContainer.offsetTop; | ||
var scrollTop = itemsContainer.scrollTop; // Top of the visible area | ||
if (itemOffsetRelativeToContainer < scrollTop) { | ||
// Item is off the top of the visible area | ||
scrollTop = itemOffsetRelativeToContainer; | ||
} else if (itemOffsetRelativeToContainer + focusedItem.offsetHeight > scrollTop + itemsContainer.offsetHeight) { | ||
// Item is off the bottom of the visible area | ||
scrollTop = itemOffsetRelativeToContainer + focusedItem.offsetHeight - itemsContainer.offsetHeight; | ||
} | ||
if (scrollTop !== itemsContainer.scrollTop) { | ||
itemsContainer.scrollTop = scrollTop; | ||
} | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
var _props6 = this.props; | ||
var id = _props6.id; | ||
var multiSection = _props6.multiSection; | ||
var focusedSectionIndex = _props6.focusedSectionIndex; | ||
var focusedItemIndex = _props6.focusedItemIndex; | ||
var theme = this.theme; | ||
var _props4 = this.props; | ||
var id = _props4.id; | ||
var multiSection = _props4.multiSection; | ||
var focusedSectionIndex = _props4.focusedSectionIndex; | ||
var focusedItemIndex = _props4.focusedItemIndex; | ||
var theme = (0, _reactThemeable2.default)(this.props.theme); | ||
var renderedItems = multiSection ? this.renderSections(theme) : this.renderItems(theme); | ||
var renderedItems = multiSection ? this.renderSections() : this.renderItems(); | ||
var isOpen = renderedItems !== null; | ||
@@ -370,5 +335,3 @@ var ariaActivedescendant = this.getItemId(focusedSectionIndex, focusedItemIndex); | ||
multiSection: false, | ||
shouldRenderSection: function shouldRenderSection() { | ||
return true; | ||
}, | ||
shouldRenderSection: alwaysTrue, | ||
renderItem: function renderItem() { | ||
@@ -375,0 +338,0 @@ throw new Error('`renderItem` must be provided'); |
@@ -15,2 +15,6 @@ 'use strict'; | ||
var _compareObjects = require('./compareObjects'); | ||
var _compareObjects2 = _interopRequireDefault(_compareObjects); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -45,9 +49,3 @@ | ||
value: function shouldComponentUpdate(nextProps) { | ||
for (var key in nextProps) { | ||
if (nextProps[key] !== this.props[key]) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
return (0, _compareObjects2.default)(nextProps, this.props); | ||
} | ||
@@ -54,0 +52,0 @@ }, { |
{ | ||
"name": "react-autowhatever", | ||
"version": "4.1.0", | ||
"version": "4.2.0", | ||
"description": "Accessible rendering layer for Autosuggest and Autocomplete components", | ||
@@ -14,3 +14,3 @@ "main": "dist/Autowhatever.js", | ||
"lint": "eslint src test demo/src server.js webpack.dev.config.js webpack.gh-pages.config.js", | ||
"test": "mocha 'test/*.test.js' --compilers js:babel-register --require test/setup.js", | ||
"test": "mocha 'test/**/*.test.js' --compilers js:babel-register --require test/setup.js", | ||
"copy-static-files": "cp demo/src/index.html demo/dist/", | ||
@@ -46,2 +46,3 @@ "dist": "rm -rf dist && mkdir dist && babel src -d dist", | ||
"eslint": "^3.0.1", | ||
"eslint-plugin-mocha": "^4.2.0", | ||
"eslint-plugin-react": "^6.0.0-alpha.1", | ||
@@ -48,0 +49,0 @@ "extract-text-webpack-plugin": "^1.0.1", |
35448
8
643
31