react-native-sectioned-multi-select
Advanced tools
Comparing version 0.5.2 to 0.6.0
# Changelog | ||
## 0.6.0 - 2018-10-02 | ||
### Fixed | ||
- prevent crash when pressing select toggle rapidly | ||
- fix formatting of this document | ||
### Added | ||
- Add `onToggleSelector` callback function #48 | ||
- Add `noItemsComponent` to be shown when there are no items | ||
- Add `loading` boolean prop for loading state | ||
### Changed | ||
- Change `loadingComponent` to be shown when `loading` prop is true (previously was shown when items were empty) | ||
## 0.5.2 - 2018-07-10 | ||
### Fixed | ||
- Added `keyboardShouldPersistTaps` props where needed | ||
- Added `keyboardShouldPersistTaps` props where needed | ||
### Added | ||
- Add `selectedItemText` and `selectedSubItemText` styles (previously only the parent view style was editable when selected). | ||
- Add `selectedItemText` and `selectedSubItemText` styles (previously only the parent view style was editable when selected). | ||
## 0.5.1 - 2018-06-29 | ||
### Added | ||
- Add `chipRemoveIconComponent`, this icon wasn't user replaceable before. | ||
- Add `filterItems` function prop. It will replace the filter used for searching. parameters are `searchTerm`, `items`, `props`. You need to return an array of item objects. (example in `exampleapp/App.js`). | ||
- Add `chipRemoveIconComponent`, this icon wasn't user replaceable before. | ||
- Add `filterItems` function prop. It will replace the filter used for searching. parameters are `searchTerm`, `items`, `props`. You need to return an array of item objects. (example in `exampleapp/App.js`). | ||
## 0.5.0 - 2018-06-12 | ||
### Added | ||
- Add `expandDropDowns` prop. Set to true to expand all parent dropdowns (when using `showDropDowns`). | ||
- Add `animateDropDowns` prop. Set to false to not use LayoutAnimation when toggling the dropdowns. | ||
- Add `customLayoutAnimation` prop. Use your own LayoutAnimation preset or custom layout animation object for the toggling of dropdowns. | ||
- Add `selectLabelNumberOfLines` prop. | ||
- Add `renderSelectText` function that receives props. This allows you to fully customize what the select label says and when, overriding `selectText`, `selectedText` etc. | ||
- Add `expandDropDowns` prop. Set to true to expand all parent dropdowns (when using `showDropDowns`). | ||
- Add `animateDropDowns` prop. Set to false to not use LayoutAnimation when toggling the dropdowns. | ||
- Add `customLayoutAnimation` prop. Use your own LayoutAnimation preset or custom layout animation object for the toggling of dropdowns. | ||
- Add `selectLabelNumberOfLines` prop. | ||
- Add `renderSelectText` function that receives props. This allows you to fully customize what the select label says and when, overriding `selectText`, `selectedText` etc. | ||
### Changed | ||
- `numberOfLines` is now `itemNumberOfLines`, to avoid confusion. | ||
- There were serious perf issues for things like toggling dropdowns with larger lists. To mitigate this, the sub items have been moved inside of the parent items and some functions have been rafactored or moved. The only noticeable difference should be that the parent item's `itemSeparator` shows at the bottom of the group of items, rather than always being directly below the parent item. | ||
- `numberOfLines` is now `itemNumberOfLines`, to avoid confusion. | ||
- There were serious perf issues for things like toggling dropdowns with larger lists. To mitigate this, the sub items have been moved inside of the parent items and some functions have been rafactored or moved. The only noticeable difference should be that the parent item's `itemSeparator` shows at the bottom of the group of items, rather than always being directly below the parent item. | ||
### Fixed | ||
- Cast keyExtractor ids to string #31 | ||
- Should be generally faster... | ||
- Cast keyExtractor ids to string #31 | ||
- Should be generally faster... | ||
## 0.4.7 - 2018-05-07 | ||
### Changed | ||
- Removed lodash dependency: replaced get and reject functions with internal functions. | ||
- Removed lodash dependency: replaced get and reject functions with internal functions. | ||
## 0.4.4 - 2018-04-13 | ||
### Added | ||
- `alwaysShowSelectText` prop - if true the select label won't show the amount selected + `selectedText` or the name of the selected item if only one items is selected. Not applied when `single` is true as single shows the `dispayKey` on the select label only. #23 | ||
- `searchAdornment` prop - function that receives the text of the search input, and is output on the right hand side of the search input. Useful if you need to do something with the search text like add a new item. | ||
- `alwaysShowSelectText` prop - if true the select label won't show the amount selected + `selectedText` or the name of the selected item if only one items is selected. Not applied when `single` is true as single shows the `dispayKey` on the select label only. #23 | ||
- `searchAdornment` prop - function that receives the text of the search input, and is output on the right hand side of the search input. Useful if you need to do something with the search text like add a new item. | ||
## 0.4.2 - 2018-03-29 | ||
### Fixed / Added | ||
- disabled items | ||
- sub item Touchable wasn't being disabled when a truthy disabled key is present | ||
- make item text colors.disabled when item has truthy disabled key | ||
- disabled items | ||
- sub item Touchable wasn't being disabled when a truthy disabled key is present | ||
- make item text colors.disabled when item has truthy disabled key | ||
## 0.4.1 - 2018-03-26 | ||
### Fixed | ||
- cancel / confirm buttons not displaying properly on iOS. Cancel takes a fixed width instead of a flex ratio now. #19 | ||
- cancel / confirm buttons not displaying properly on iOS. Cancel takes a fixed width instead of a flex ratio now. #19 | ||
## 0.4.0 - 2018-03-23 | ||
### Added | ||
- Cancel button #15 | ||
- shows on the modal to the left of the confirm button. Pressing it dismisses the modal AND removes all selected items. | ||
- show with `showCancelButton` prop. | ||
- `cancelButton` style and `cancelIconComponent` are available. (It is a 'close' icon by default, but you could make it a text component if you want). | ||
- Hide select #16 | ||
- hide the select entirely with `hideSelect` prop. | ||
- Display key #14 | ||
- customize the title key with `displayKey` prop, instaed of being forced to use 'name'. | ||
- Added `headerComponent` prop - goes above search bar #17 | ||
- Added `onCancel` and `onConfirm` function props | ||
- Cancel button #15 | ||
- shows on the modal to the left of the confirm button. Pressing it dismisses the modal AND removes all selected items. | ||
- show with `showCancelButton` prop. | ||
- `cancelButton` style and `cancelIconComponent` are available. (It is a 'close' icon by default, but you could make it a text component if you want). | ||
- Hide select #16 | ||
- hide the select entirely with `hideSelect` prop. | ||
- Display key #14 | ||
- customize the title key with `displayKey` prop, instaed of being forced to use 'name'. | ||
- Added `headerComponent` prop - goes above search bar #17 | ||
- Added `onCancel` and `onConfirm` function props | ||
### Changed | ||
- `SelectedText` now allowed to be a function, for more complex translations/ | ||
- `SelectedText` now allowed to be a function, for more complex translations/ | ||
@@ -66,20 +76,20 @@ | ||
### Added | ||
- customizable `selectedText` string (defaults to 'selected'). #13 | ||
- customizable `selectedText` string (defaults to 'selected'). #13 | ||
## 0.3.4 - 2018-02-14 | ||
### Fixed | ||
- fixed `onSelectedItemObjectsChange` for single select mode #9 | ||
- fixed `onSelectedItemObjectsChange` for single select mode #9 | ||
## 0.3.3 - 2018-01-30 | ||
### Added | ||
- Added `numberOfLines` prop, so long labels can be truncated (defaults to null - no truncation). | ||
- Added `numberOfLines` prop, so long labels can be truncated (defaults to null - no truncation). | ||
### Changed | ||
- add flex to label text so checkmark is visible for long items | ||
- add flex to label text so checkmark is visible for long items | ||
## 0.3.2 - 2018-01-18 | ||
### Changed | ||
- Make remove all chip use chipColor | ||
- Make remove all chip use chipColor | ||
## 0.3.1 - 2018-01-17 | ||
### Changed | ||
- Add changelog to Readme | ||
- Add changelog to Readme | ||
@@ -86,0 +96,0 @@ ## 0.3.0 - 2018-01-16 |
@@ -178,70 +178,2 @@ import React, { Component } from 'react' | ||
const fonts = { | ||
condensed: | ||
Platform.select({ | ||
ios: { | ||
fontFamily: 'AvenirNextCondensed-DemiBold', | ||
}, | ||
android: { | ||
fontFamily: 'sans-serif-condensed', | ||
}, | ||
}), | ||
boldCondensed: | ||
Platform.select({ | ||
ios: { | ||
fontFamily: 'AvenirNextCondensed-DemiBold', | ||
}, | ||
android: { | ||
fontFamily: 'sans-serif-condensed', | ||
fontWeight: '700', | ||
}, | ||
}), | ||
regular: | ||
Platform.select({ | ||
ios: { | ||
fontFamily: 'Avenir-Heavy', | ||
}, | ||
android: { | ||
fontFamily: 'sans-serif', | ||
}, | ||
}), | ||
light: | ||
Platform.select({ | ||
ios: { | ||
fontFamily: 'Avenir-Light', | ||
}, | ||
android: { | ||
fontFamily: 'sans-serif-light', | ||
}, | ||
}), | ||
bold: | ||
Platform.select({ | ||
ios: { | ||
fontFamily: 'Avenir-Black', | ||
}, | ||
android: { | ||
fontFamily: 'sans-serif', | ||
fontWeight: '700', | ||
}, | ||
}), | ||
black: | ||
Platform.select({ | ||
ios: { | ||
fontFamily: 'Avenir-Black', | ||
}, | ||
android: { | ||
fontFamily: 'sans-serif', | ||
fontWeight: '900', | ||
}, | ||
}), | ||
serif: | ||
Platform.select({ | ||
ios: { | ||
fontFamily: 'Georgia', | ||
}, | ||
android: { | ||
fontFamily: 'serif', | ||
}, | ||
}), | ||
} | ||
@@ -354,3 +286,4 @@ const styles = StyleSheet.create({ | ||
this.state = { | ||
items: items, | ||
items: null, | ||
loading: false, | ||
selectedItems: [], | ||
@@ -367,2 +300,3 @@ selectedItems2: [], | ||
} | ||
this.termId = 100; | ||
} | ||
@@ -373,2 +307,3 @@ | ||
// this.fetchCategories() | ||
this.pretendToLoad() | ||
} | ||
@@ -384,2 +319,9 @@ componentDidMount() { | ||
pretendToLoad = () => { | ||
this.setState({ loading: true }) | ||
setTimeout(() => { | ||
this.setState({ loading: false, items }) | ||
}, 4000) | ||
} | ||
// testing a custom filtering function that ignores accents | ||
@@ -485,15 +427,16 @@ removerAcentos = (s) => { | ||
<View key="a" style={styles.center}> | ||
<Text>Sorry No results...</Text> | ||
<Text>Sorry! No results...</Text> | ||
</View>; | ||
handleAddSearchTerm = () => { | ||
const searchTerm = this.SectionedMultiSelect._getSearchTerm(); | ||
const id = this.state.items[this.state.items.length - 1].id + 1; | ||
if ( searchTerm.length && !this.state.items.some( item => item.title.includes(searchTerm) ) ) { | ||
const newItem = {id: id, title: searchTerm}; | ||
this.setState(prevState => ({items: [...prevState.items, newItem]})); | ||
this.onSelectedItemsChange([...this.state.selectedItems, id]) | ||
this.SectionedMultiSelect._submitSelection() | ||
handleAddSearchTerm = () => { | ||
const searchTerm = this.SectionedMultiSelect._getSearchTerm(); | ||
const id = this.termId += 1; | ||
if ( searchTerm.length && !(this.state.items || []).some( item => item.title.includes(searchTerm) ) ) { | ||
const newItem = { id: id, title: searchTerm }; | ||
this.setState(prevState => ({items: [...prevState.items || [], newItem]})); | ||
this.onSelectedItemsChange([...this.state.selectedItems, id]) | ||
this.SectionedMultiSelect._submitSelection() | ||
} | ||
} | ||
} | ||
renderSelectText = () => { | ||
@@ -531,2 +474,5 @@ const { selectedItemObjects } = this.state; | ||
} | ||
onToggleSelector = (toggled) => { | ||
console.log('selector is ', toggled ? 'open' : 'closed'); | ||
} | ||
@@ -538,2 +484,3 @@ render() { | ||
React native sectioned multi select example. | ||
</Text> | ||
@@ -547,7 +494,8 @@ <SectionedMultiSelect | ||
showCancelButton | ||
filterItems={this.filterItems} | ||
loading={this.state.loading} | ||
// filterItems={this.filterItems} | ||
// alwaysShowSelectText | ||
searchAdornment={(searchTerm) => this.searchAdornment(searchTerm)} | ||
renderSelectText={this.renderSelectText} | ||
noResultsComponent={this.noResults} | ||
// noResultsComponent={this.noResults} | ||
loadingComponent={ | ||
@@ -586,5 +534,5 @@ <Loading | ||
// }, | ||
itemText: { | ||
color: this.state.selectedItems.length ? 'black' : 'lightgrey' | ||
}, | ||
// itemText: { | ||
// color: this.state.selectedItems.length ? 'black' : 'lightgrey' | ||
// }, | ||
selectedItemText: { | ||
@@ -640,2 +588,3 @@ color: 'blue', | ||
onConfirm={this.onConfirm} | ||
onToggleSelector={this.onToggleSelector} | ||
selectedItems={this.state.selectedItems2} | ||
@@ -642,0 +591,0 @@ styles={{ |
@@ -112,10 +112,26 @@ import React, { PureComponent } from 'react' | ||
const noResults = <Text>Sorry, no results</Text> | ||
const loading = ( | ||
const ComponentContainer = ({ children }) => ( | ||
<View style={{ marginTop: 20, alignItems: 'center', justifyContent: 'center' }}> | ||
<ActivityIndicator /> | ||
{children} | ||
</View> | ||
) | ||
const noResults = ( | ||
<ComponentContainer> | ||
<Text>Sorry, no results</Text> | ||
</ComponentContainer> | ||
) | ||
const noItems = ( | ||
<ComponentContainer> | ||
<Text>Sorry, no items</Text> | ||
</ComponentContainer> | ||
) | ||
const loadingComp = ( | ||
<ComponentContainer> | ||
<ActivityIndicator /> | ||
</ComponentContainer> | ||
) | ||
// let date = new Date() | ||
@@ -126,3 +142,3 @@ class SectionedMultiSelect extends PureComponent { | ||
selectedItems: PropTypes.array, | ||
items: PropTypes.array.isRequired, | ||
items: PropTypes.array, | ||
displayKey: PropTypes.string, | ||
@@ -150,2 +166,3 @@ uniqueKey: PropTypes.string.isRequired, | ||
loadingComponent: PropTypes.object, | ||
loading: PropTypes.bool, | ||
subItemFontFamily: PropTypes.object, | ||
@@ -184,2 +201,4 @@ itemFontFamily: PropTypes.object, | ||
filterItems: PropTypes.func, | ||
onToggleSelector: PropTypes.func, | ||
noItemsComponent: PropTypes.object, | ||
} | ||
@@ -199,3 +218,4 @@ | ||
noResultsComponent: noResults, | ||
loadingComponent: loading, | ||
loadingComponent: loadingComp, | ||
loading: false, | ||
styles: {}, | ||
@@ -222,2 +242,3 @@ colors: {}, | ||
filterItems: null, | ||
noItemsComponent: noItems, | ||
} | ||
@@ -326,3 +347,3 @@ | ||
items.forEach((item) => { | ||
items && items.forEach((item) => { | ||
const parts = searchTerm.trim().split(/[[ \][)(\\/?\-:]+/) | ||
@@ -408,8 +429,12 @@ const regex = new RegExp(`(${parts.join('|')})`, 'i') | ||
_toggleSelector = () => { | ||
const { onToggleSelector } = this.props | ||
const newState = !this.state.selector | ||
this.setState({ | ||
selector: !this.state.selector, | ||
selector: newState, | ||
}) | ||
onToggleSelector && onToggleSelector(newState) | ||
} | ||
_closeSelector = () => { | ||
const { onToggleSelector } = this.props | ||
this.setState({ | ||
@@ -419,2 +444,3 @@ selector: false, | ||
}) | ||
onToggleSelector && onToggleSelector(false) | ||
} | ||
@@ -510,3 +536,3 @@ _submitSelection = () => { | ||
const highlighted = [...highlightedChildren] | ||
if (!items) return | ||
let i = 0 | ||
@@ -549,3 +575,3 @@ for (; i < items.length; i += 1) { | ||
} = this.props | ||
if (!items) return | ||
let i = 0 | ||
@@ -738,2 +764,3 @@ const selected = [] | ||
loadingComponent, | ||
loading, | ||
searchTextFontFamily, | ||
@@ -756,2 +783,3 @@ confirmFontFamily, | ||
selectLabelNumberOfLines, | ||
noItemsComponent | ||
} = this.props | ||
@@ -802,2 +830,3 @@ | ||
<TextInput | ||
value={this.state.searchTerm} | ||
selectionColor={colors.searchSelectionColor} | ||
@@ -826,29 +855,28 @@ onChangeText={searchTerm => this.setState({ searchTerm })} | ||
> | ||
{(items && items.length) ? | ||
<View> | ||
{renderItems.length ? | ||
<View> | ||
<FlatList | ||
keyboardShouldPersistTaps="always" | ||
removeClippedSubviews | ||
initialNumToRender={15} | ||
data={renderItems} | ||
extraData={selectedItems} | ||
keyExtractor={item => `${item[uniqueKey]}`} | ||
ItemSeparatorComponent={this._renderSeparator} | ||
ListFooterComponent={this._renderFooter} | ||
renderItem={this._renderItemFlatList} | ||
/> | ||
</View> | ||
: | ||
<View> | ||
{noResultsComponent} | ||
</View> | ||
} | ||
</View> | ||
: | ||
<View> | ||
{loadingComponent} | ||
</View> | ||
} | ||
<View> | ||
{loading ? | ||
loadingComponent | ||
: | ||
<View> | ||
{!renderItems || !renderItems.length && !searchTerm ? noItemsComponent : null} | ||
{items && renderItems && renderItems.length ? | ||
<View> | ||
<FlatList | ||
keyboardShouldPersistTaps="always" | ||
removeClippedSubviews | ||
initialNumToRender={15} | ||
data={renderItems} | ||
extraData={selectedItems} | ||
keyExtractor={item => `${item[uniqueKey]}`} | ||
ItemSeparatorComponent={this._renderSeparator} | ||
ListFooterComponent={this._renderFooter} | ||
renderItem={this._renderItemFlatList} | ||
/> | ||
</View> | ||
: | ||
searchTerm ? noResultsComponent : null | ||
} | ||
</View> | ||
} | ||
</View> | ||
</ScrollView> | ||
@@ -916,3 +944,3 @@ <View style={{ flexDirection: 'row' }}> | ||
{!hideSelect && | ||
<TouchableWithoutFeedback onPress={this._toggleSelector}> | ||
<TouchableWithoutFeedback onPress={this._toggleSelector} disabled={this.state.selector}> | ||
<View | ||
@@ -919,0 +947,0 @@ style={[{ |
{ | ||
"name": "react-native-sectioned-multi-select", | ||
"version": "0.5.2", | ||
"version": "0.6.0", | ||
"description": "a multi (or single) select component with support for sub categories, search, chips.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -158,3 +158,4 @@ # react-native-sectioned-multi-select | ||
| ------------- |------------- | ----- |----- | | ||
|uniqueKey | 'id' | string |the unique key for your items | ||
|items | | array |the items | | ||
|uniqueKey | 'id' | string |the unique key for your items | | ||
|subKey | 'sub' | string |the array of sub items within items | | ||
@@ -167,2 +168,3 @@ |displayKey | 'name' | string |the key for the display name / title of the item | | ||
|onConfirm | | function |function that runs when the confirm button is pressed | | ||
|onToggleSelector | | function |callback function that runs when the selector is toggled. receives a boolean for the open/close state of the modal | | ||
@@ -173,2 +175,3 @@ ### Options | ||
| ------------- |------------- | ----- |----- | | ||
| loading | false | bool |set the loading state, shows `loadingComponent` if true | | ||
| single | false | bool |allow only one selection | | ||
@@ -203,4 +206,5 @@ | showDropDowns | true | bool |whether to allow dropdown toggles to show/hide the sub items (if false, sub items are always shown)| | ||
|filterItems | null | function | Use a custom filtering function for the search: receives searchText, items, props. Should return an array of item objects.| | ||
|noResultsComponent | `<Text>Sorry, no results</Text>` | object |the component to display when the search results are empty | | ||
|loadingComponent | `<View style={{marginTop:20, alignItems:'center', justifyContent:'center'}}> <ActivityIndicator/> </View>` | object |the component to display when the items are empty | | ||
|noResultsComponent | Sorry, no results | object |the component to display when the search results are empty | | ||
|loadingComponent | `ActivityIndicator` | object |the component to display when `loading` is set to true | | ||
|noItemsComponent | No Items | object | Shown when the items array is empty / null | | ||
|selectToggleIconComponent | Material `keyboard-arrow-down` | object | The icon to the right of the dropdown in its initial state ) | | ||
@@ -212,3 +216,3 @@ |searchIconComponent | Material `search` | object | The search input icon (default Magnifying glass) | ||
|cancelIconComponent | Material `cancel` | object | The cancel button's inner component | | ||
|chipRemoveIconComponent Material `close` | object | The chip remove button's icon component | | ||
|chipRemoveIconComponent | Material `close` | object | The chip remove button's icon component | | ||
|styles | {} | object |Styles object - see styles section | | ||
@@ -221,4 +225,4 @@ |colors | {...} | object |colors object - see colors section | | ||
|itemNumberOfLines |null |number |numberOfLines for item text | | ||
|selectLabelNumberOfLines | 1 |number numberOfLines for select label text | | ||
|customLayoutAnimation | `LayoutAnimation.Presets.easeInEaseOut` | object |define your own `LayoutAnimation` preset or custom animation | | ||
|selectLabelNumberOfLines | 1 |number | numberOfLines for select label text | | ||
|customLayoutAnimation | easeInEaseOut | object |define your own `LayoutAnimation` preset or custom animation | | ||
@@ -225,0 +229,0 @@ ## Colors |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3014268
271
1940