terra-list
Advanced tools
Comparing version 1.12.0 to 1.12.1
@@ -17,2 +17,8 @@ Changelog | ||
### Added | ||
* SelectableList component | ||
### Changed | ||
* Update SingleSelectList and MultiSelectList components to use SelectableList | ||
1.10.0 - (September 19, 2017) | ||
@@ -19,0 +25,0 @@ ------------------ |
@@ -8,5 +8,5 @@ # Dependency Information | ||
| prop-types | ^15.5.8 | -- | Runtime type checking for React props and similar objects. | | ||
| terra-arrange | ^1.11.0 | ^15.4.2 | The arrange component is used for horizontally arranging and vertically aligning a single row of container elements. | | ||
| terra-base | ^2.5.0 | ^15.4.2 | The base component sets minimal global styles for an application. | | ||
| terra-icon | ^1.11.0 | ^15.4.2 | terra-icon | | ||
| terra-arrange | ^1.12.0 | ^15.4.2 | The arrange component is used for horizontally arranging and vertically aligning a single row of container elements. | | ||
| terra-base | ^2.6.0 | ^15.4.2 | The base component sets minimal global styles for an application. | | ||
| terra-icon | ^1.12.0 | ^15.4.2 | terra-icon | | ||
@@ -16,3 +16,3 @@ ## devDependencies | ||
|-|-|-|-| | ||
| terra-props-table | ^1.9.0 | ^15.4.2 | terra-props-table | | ||
| terra-props-table | ^1.10.0 | ^15.4.2 | terra-props-table | | ||
@@ -24,3 +24,3 @@ ## peerDependencies | ||
| react-dom | ^15.4.2 | ^15.6.2 | React package for working with the DOM. | | ||
| terra-base | ^2.5.0 | ^15.4.2 | The base component sets minimal global styles for an application. | | ||
| terra-icon | ^1.11.0 | ^15.4.2 | terra-icon | | ||
| terra-base | ^2.6.0 | ^15.4.2 | The base component sets minimal global styles for an application. | | ||
| terra-icon | ^1.12.0 | ^15.4.2 | terra-icon | |
@@ -31,2 +31,3 @@ # Terra List | ||
Terra also provides two variations for the list component. | ||
* [Selectable List](https://github.com/cerner/terra-core/tree/master/packages/terra-list/docs/Selectable.md) | ||
@@ -37,2 +38,3 @@ * [Single Select List](https://github.com/cerner/terra-core/tree/master/packages/terra-list/docs/SingleSelect.md) | ||
## Component Features | ||
@@ -39,0 +41,0 @@ * [Cross-Browser Support](https://github.com/cerner/terra-core/wiki/Component-Features#cross-browser-support) |
@@ -21,5 +21,5 @@ 'use strict'; | ||
var _List = require('./List'); | ||
var _SelectableList = require('./SelectableList'); | ||
var _List2 = _interopRequireDefault(_List); | ||
var _SelectableList2 = _interopRequireDefault(_SelectableList); | ||
@@ -36,7 +36,2 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var KEYCODES = { | ||
ENTER: 13, | ||
SPACE: 32 | ||
}; | ||
var propTypes = { | ||
@@ -71,18 +66,2 @@ /** | ||
_createClass(MultiSelectList, null, [{ | ||
key: 'selectedIndexesFromItems', | ||
value: function selectedIndexesFromItems(items, maxSelectionCount) { | ||
var selectedIndexes = []; | ||
for (var i = 0; i < items.length; i += 1) { | ||
if (selectedIndexes.length >= maxSelectionCount) { | ||
break; | ||
} | ||
if (items[i].props.isSelected) { | ||
selectedIndexes.push(i); | ||
} | ||
} | ||
return selectedIndexes; | ||
} | ||
}]); | ||
function MultiSelectList(props) { | ||
@@ -93,5 +72,4 @@ _classCallCheck(this, MultiSelectList); | ||
_this.handleSelection = _this.handleSelection.bind(_this); | ||
_this.shouldHandleSelection = _this.shouldHandleSelection.bind(_this); | ||
_this.state = { selectedIndexes: MultiSelectList.selectedIndexesFromItems(_this.props.children, _this.validatedMaxCount()) }; | ||
_this.handleOnChange = _this.handleOnChange.bind(_this); | ||
_this.state = { selectedIndexes: _SelectableList2.default.Utils.initialMultiSelectedIndexes(props.children, props.maxSelectionCount) }; | ||
return _this; | ||
@@ -101,141 +79,37 @@ } | ||
_createClass(MultiSelectList, [{ | ||
key: 'handleSelection', | ||
value: function handleSelection(event, index) { | ||
event.preventDefault(); | ||
key: 'handleOnChange', | ||
value: function handleOnChange(event, index) { | ||
var _props = this.props, | ||
children = _props.children, | ||
maxSelectionCount = _props.maxSelectionCount; | ||
var newIndexes = []; | ||
if (this.state.selectedIndexes.length) { | ||
if (this.state.selectedIndexes.indexOf(index) >= 0) { | ||
newIndexes = this.state.selectedIndexes.slice(); | ||
newIndexes.splice(newIndexes.indexOf(index), 1); | ||
} else { | ||
newIndexes = this.state.selectedIndexes.concat([index]); | ||
} | ||
} else { | ||
newIndexes.push(index); | ||
} | ||
if (_SelectableList2.default.Utils.shouldHandleMultiSelect(children, maxSelectionCount, this.state.selectedIndexes, index)) { | ||
event.preventDefault(); | ||
var newIndexes = _SelectableList2.default.Utils.updatedMultiSelectedIndexes(this.state.selectedIndexes, index); | ||
this.setState({ selectedIndexes: newIndexes }); | ||
if (this.props.onChange) { | ||
this.props.onChange(event, newIndexes); | ||
} | ||
} | ||
}, { | ||
key: 'shouldHandleSelection', | ||
value: function shouldHandleSelection(index) { | ||
if (this.state.selectedIndexes.length < this.validatedMaxCount()) { | ||
return true; | ||
} | ||
if (this.state.selectedIndexes.indexOf(index) >= 0) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
}, { | ||
key: 'cloneChildItems', | ||
value: function cloneChildItems(items) { | ||
var _this2 = this; | ||
var disableUnselectedItems = this.state.selectedIndexes.length >= this.validatedMaxCount(); | ||
return _react2.default.Children.map(items, function (child, index) { | ||
var wrappedOnClick = _this2.wrappedOnClickForItem(child, index); | ||
var wrappedOnKeyDown = _this2.wrappedOnKeyDownForItem(child, index); | ||
var newProps = _this2.newPropsForItem(child, index, wrappedOnClick, wrappedOnKeyDown, disableUnselectedItems); | ||
return _react2.default.cloneElement(child, newProps); | ||
}); | ||
} | ||
}, { | ||
key: 'wrappedOnClickForItem', | ||
value: function wrappedOnClickForItem(item, index) { | ||
var _this3 = this; | ||
var initialOnClick = item.props.onClick; | ||
return function (event) { | ||
// The default isSelectable attribute is either undefined or true, unless the consumer specifies the item isSelectable attribute as false. | ||
if (item.props.isSelectable !== false && _this3.shouldHandleSelection(index)) { | ||
_this3.handleSelection(event, index); | ||
this.setState({ selectedIndexes: newIndexes }); | ||
if (this.props.onChange) { | ||
this.props.onChange(event, newIndexes); | ||
} | ||
if (initialOnClick) { | ||
initialOnClick(event); | ||
} | ||
}; | ||
} | ||
}, { | ||
key: 'wrappedOnKeyDownForItem', | ||
value: function wrappedOnKeyDownForItem(item, index) { | ||
var _this4 = this; | ||
var initialOnKeyDown = item.props.onKeyDown; | ||
return function (event) { | ||
if (event.nativeEvent.keyCode === KEYCODES.ENTER || event.nativeEvent.keyCode === KEYCODES.SPACE) { | ||
// The default isSelectable attribute is either undefined or true, unless the consumer specifies the item isSelectable attribute as false. | ||
if (item.props.isSelectable !== false && _this4.shouldHandleSelection(index)) { | ||
_this4.handleSelection(event, index); | ||
} | ||
} | ||
if (initialOnKeyDown) { | ||
initialOnKeyDown(event); | ||
} | ||
}; | ||
} | ||
}, { | ||
key: 'newPropsForItem', | ||
value: function newPropsForItem(item, index, onClick, onKeyDown, disableUnselectedItems) { | ||
var isSelected = this.state.selectedIndexes.indexOf(index) >= 0; | ||
var newProps = {}; | ||
// Set the isSelected attribute to false for all the items except the items whose index is set to state selectedIndex | ||
if (isSelected !== item.isSelected) { | ||
newProps.isSelected = isSelected; | ||
} | ||
// Set the default isSelectable attribute to true, unless the consumer specifies the item isSelectable attribute as false. | ||
newProps.isSelectable = true; | ||
if (item.props.isSelectable === false) { | ||
newProps.isSelectable = item.props.isSelectable; | ||
} | ||
// If selectable, add tabIndex on items to navigate through keyboard tab key for selectable lists and add | ||
// onClick and onKeyDown functions. | ||
if (newProps.isSelectable) { | ||
newProps.tabIndex = '0'; | ||
newProps.onClick = onClick; | ||
newProps.onKeyDown = onKeyDown; | ||
} | ||
if (disableUnselectedItems && !isSelected) { | ||
newProps.isSelectable = false; | ||
} | ||
return newProps; | ||
} | ||
}, { | ||
key: 'validatedMaxCount', | ||
value: function validatedMaxCount() { | ||
if (this.props.maxSelectionCount !== undefined) { | ||
return this.props.maxSelectionCount; | ||
} | ||
return this.props.children.length; | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
var _props = this.props, | ||
children = _props.children, | ||
isDivided = _props.isDivided, | ||
onChange = _props.onChange, | ||
maxSelectionCount = _props.maxSelectionCount, | ||
customProps = _objectWithoutProperties(_props, ['children', 'isDivided', 'onChange', 'maxSelectionCount']); | ||
var _props2 = this.props, | ||
children = _props2.children, | ||
isDivided = _props2.isDivided, | ||
onChange = _props2.onChange, | ||
maxSelectionCount = _props2.maxSelectionCount, | ||
customProps = _objectWithoutProperties(_props2, ['children', 'isDivided', 'onChange', 'maxSelectionCount']); | ||
var clonedChildItems = this.cloneChildItems(children); | ||
return _react2.default.createElement( | ||
_List2.default, | ||
_extends({ isDivided: isDivided }, customProps), | ||
clonedChildItems | ||
_SelectableList2.default, | ||
_extends({}, customProps, { | ||
isDivided: isDivided, | ||
onChange: this.handleOnChange, | ||
selectedIndexes: this.state.selectedIndexes, | ||
disableUnselectedItems: this.state.selectedIndexes.length >= _SelectableList2.default.Utils.validatedMaxCount(children, maxSelectionCount) | ||
}), | ||
children | ||
); | ||
@@ -250,4 +124,4 @@ } | ||
MultiSelectList.defaultProps = defaultProps; | ||
MultiSelectList.Item = _List2.default.Item; | ||
MultiSelectList.Item = _SelectableList2.default.Item; | ||
exports.default = MultiSelectList; |
@@ -21,5 +21,5 @@ 'use strict'; | ||
var _List = require('./List'); | ||
var _SelectableList = require('./SelectableList'); | ||
var _List2 = _interopRequireDefault(_List); | ||
var _SelectableList2 = _interopRequireDefault(_SelectableList); | ||
@@ -36,7 +36,2 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var KEYCODES = { | ||
ENTER: 13, | ||
SPACE: 32 | ||
}; | ||
var propTypes = { | ||
@@ -71,14 +66,2 @@ /** | ||
_createClass(SingleSelectList, null, [{ | ||
key: 'selectedIndexFromItems', | ||
value: function selectedIndexFromItems(items) { | ||
for (var i = 0; i < items.length; i += 1) { | ||
if (items[i].props.isSelected) { | ||
return i; | ||
} | ||
} | ||
return -1; | ||
} | ||
}]); | ||
function SingleSelectList(props) { | ||
@@ -89,5 +72,4 @@ _classCallCheck(this, SingleSelectList); | ||
_this.handleSelection = _this.handleSelection.bind(_this); | ||
_this.shouldHandleSelection = _this.shouldHandleSelection.bind(_this); | ||
_this.state = { selectedIndex: SingleSelectList.selectedIndexFromItems(_this.props.children) }; | ||
_this.handleOnChange = _this.handleOnChange.bind(_this); | ||
_this.state = { selectedIndex: _SelectableList2.default.Utils.initialSingleSelectedIndex(_this.props.children) }; | ||
return _this; | ||
@@ -97,98 +79,11 @@ } | ||
_createClass(SingleSelectList, [{ | ||
key: 'handleSelection', | ||
value: function handleSelection(event, index) { | ||
event.preventDefault(); | ||
this.setState({ selectedIndex: index }); | ||
if (this.props.onChange) { | ||
this.props.onChange(event, index); | ||
} | ||
} | ||
}, { | ||
key: 'shouldHandleSelection', | ||
value: function shouldHandleSelection(index) { | ||
return index !== this.state.selectedIndex; | ||
} | ||
}, { | ||
key: 'cloneChildItems', | ||
value: function cloneChildItems(items) { | ||
var _this2 = this; | ||
return _react2.default.Children.map(items, function (child, index) { | ||
var wrappedOnClick = _this2.wrappedOnClickForItem(child, index); | ||
var wrappedOnKeyDown = _this2.wrappedOnKeyDownForItem(child, index); | ||
var newProps = _this2.newPropsForItem(child, index, wrappedOnClick, wrappedOnKeyDown); | ||
return _react2.default.cloneElement(child, newProps); | ||
}); | ||
} | ||
}, { | ||
key: 'wrappedOnClickForItem', | ||
value: function wrappedOnClickForItem(item, index) { | ||
var _this3 = this; | ||
var initialOnClick = item.props.onClick; | ||
return function (event) { | ||
// The default isSelectable attribute is either undefined or true, unless the consumer specifies the item isSelectable attribute as false. | ||
if (item.props.isSelectable !== false && _this3.shouldHandleSelection(index)) { | ||
_this3.handleSelection(event, index); | ||
key: 'handleOnChange', | ||
value: function handleOnChange(event, index) { | ||
if (_SelectableList2.default.Utils.shouldHandleSingleSelect(this.state.selectedIndex, index)) { | ||
event.preventDefault(); | ||
this.setState({ selectedIndex: index }); | ||
if (this.props.onChange) { | ||
this.props.onChange(event, index); | ||
} | ||
if (initialOnClick) { | ||
initialOnClick(event); | ||
} | ||
}; | ||
} | ||
}, { | ||
key: 'wrappedOnKeyDownForItem', | ||
value: function wrappedOnKeyDownForItem(item, index) { | ||
var _this4 = this; | ||
var initialOnKeyDown = item.props.onKeyDown; | ||
return function (event) { | ||
if (event.nativeEvent.keyCode === KEYCODES.ENTER || event.nativeEvent.keyCode === KEYCODES.SPACE) { | ||
// The default isSelectable attribute is either undefined or true, unless the consumer specifies the item isSelectable attribute as false. | ||
if (item.props.isSelectable !== false && _this4.shouldHandleSelection(index)) { | ||
_this4.handleSelection(event, index); | ||
} | ||
} | ||
if (initialOnKeyDown) { | ||
initialOnKeyDown(event); | ||
} | ||
}; | ||
} | ||
}, { | ||
key: 'newPropsForItem', | ||
value: function newPropsForItem(item, index, onClick, onKeyDown) { | ||
var isSelected = this.state.selectedIndex === index; | ||
var newProps = {}; | ||
// Set the isSelected attribute to false for all the items except the items whose index is set to state selectedIndex | ||
if (isSelected !== item.isSelected) { | ||
newProps.isSelected = isSelected; | ||
} | ||
// Set the default isSelectable attribute to true, unless the consumer specifies the item isSelectable attribute as false. | ||
newProps.isSelectable = true; | ||
if (item.props.isSelectable === false) { | ||
newProps.isSelectable = item.props.isSelectable; | ||
} | ||
// If selectable, add tabIndex on items to navigate through keyboard tab key for selectable lists and add | ||
// onClick and onKeyDown functions. | ||
if (newProps.isSelectable) { | ||
newProps.tabIndex = '0'; | ||
newProps.onClick = onClick; | ||
newProps.onKeyDown = onKeyDown; | ||
} | ||
// Uses the props.hasChevron value, unless the consumer specifies the item hasChevron attribute as false. | ||
newProps.hasChevron = this.props.hasChevrons; | ||
if (item.props.hasChevron !== undefined) { | ||
newProps.hasChevron = item.props.hasChevron; | ||
} | ||
return newProps; | ||
} | ||
@@ -205,8 +100,12 @@ }, { | ||
var clonedChildItems = this.cloneChildItems(children); | ||
return _react2.default.createElement( | ||
_List2.default, | ||
_extends({ isDivided: isDivided }, customProps), | ||
clonedChildItems | ||
_SelectableList2.default, | ||
_extends({}, customProps, { | ||
isDivided: isDivided, | ||
onChange: this.handleOnChange, | ||
selectedIndexes: [this.state.selectedIndex], | ||
hasChevrons: hasChevrons, | ||
disableUnselectedItems: false | ||
}), | ||
children | ||
); | ||
@@ -221,4 +120,4 @@ } | ||
SingleSelectList.defaultProps = defaultProps; | ||
SingleSelectList.Item = _List2.default.Item; | ||
SingleSelectList.Item = _SelectableList2.default.Item; | ||
exports.default = SingleSelectList; |
{ | ||
"name": "terra-list", | ||
"main": "lib/List.js", | ||
"version": "1.12.0", | ||
"version": "1.12.1", | ||
"description": "terra-list", | ||
@@ -24,3 +24,3 @@ "repository": { | ||
"devDependencies": { | ||
"terra-props-table": "^1.10.0" | ||
"terra-props-table": "^1.10.1" | ||
}, | ||
@@ -30,4 +30,4 @@ "peerDependencies": { | ||
"react-dom": "^15.4.2", | ||
"terra-base": "^2.6.0", | ||
"terra-icon": "^1.12.0" | ||
"terra-base": "^2.6.1", | ||
"terra-icon": "^1.12.1" | ||
}, | ||
@@ -37,5 +37,5 @@ "dependencies": { | ||
"prop-types": "^15.5.8", | ||
"terra-arrange": "^1.12.0", | ||
"terra-base": "^2.6.0", | ||
"terra-icon": "^1.12.0" | ||
"terra-arrange": "^1.12.1", | ||
"terra-base": "^2.6.1", | ||
"terra-icon": "^1.12.1" | ||
}, | ||
@@ -49,3 +49,3 @@ "scripts": { | ||
"lint:scss": "stylelint src/**/*.scss", | ||
"props-table": "props-table ./src/List.jsx ./src/SingleSelectList.jsx ./src/MultiSelectList.jsx --out-dir ./docs/props-table", | ||
"props-table": "props-table ./src/List.jsx ./src/SelectableList.jsx ./src/SingleSelectList.jsx ./src/MultiSelectList.jsx --out-dir ./docs/props-table", | ||
"test": "npm run test:jest && npm run test:nightwatch", | ||
@@ -52,0 +52,0 @@ "test:jest": "jest ./tests/jest/* --config ../../jestconfig.json", |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
41527
20
578
2
Updatedterra-arrange@^1.12.1
Updatedterra-base@^2.6.1
Updatedterra-icon@^1.12.1