From 3ea2265d4f1a943698cf91267db3e10faa646fc4 Mon Sep 17 00:00:00 2001 From: rohan km Date: Tue, 21 Feb 2023 18:49:37 +0530 Subject: [PATCH 1/5] added multiple select with optimisations and updated readMe --- README.md | 129 ++++++++++++++- index.js | 3 +- src/FlashSelectDropdown.js | 283 +++++++++++++++++++++++++++++++++ src/SelectDropdown.js | 108 ++++++++++--- src/hooks/useSelectDropdown.js | 81 +++++++++- src/styles.js | 10 ++ yarn.lock | 4 + 7 files changed, 580 insertions(+), 38 deletions(-) create mode 100644 src/FlashSelectDropdown.js create mode 100644 yarn.lock diff --git a/README.md b/README.md index dded4b8..c7efd51 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,10 @@ yarn add react-native-select-dropdown

+## Optimization + +Install `yarn add @shopify/flash-list` then use `` instead of `` for optimised benifits. + ## Usage ``` @@ -56,6 +60,49 @@ const countries = ["Egypt", "Canada", "Australia", "Ireland"] /> ``` +#### Multiple Select + +``` +const [data,setData]=useState() + + { + return ( + + + + ); + }} + onSelect={async (selectedItem) => { + setData(selectedItem); + }} + buttonTextAfterSelection={"Selected"} + rowTextForSelection={(item, index) => { + return item.title; + }} +/>; + +``` + ### Props - [`data`](#data) @@ -128,6 +175,18 @@ const countries = ["Egypt", "Canada", "Australia", "Ireland"] - [`onChangeSearchInputText`](#onChangeSearchInputText) +- [`onlyDropdownIcon`](#onlyDropdownIcon) + +- [`textNumberOfLines`](#textNumberOfLines) + +- [`multipleSelect`](#multipleSelect) + +- [`searchKey`](#searchKey) + +- [`emptyStyle`](#emptyStyle) + +- [`allowSelectAll`](#allowSelectAll) + ### Methods - [`reset`](#License) @@ -151,6 +210,8 @@ array of data that will be represented in dropdown 'can be array of objects function recieves selected item and its index in data array +if multipleSelect is true then recives only array of item. + | Type | Required | | -------- | -------- | | function | Yes | @@ -171,9 +232,11 @@ default button text when no item is selected function recieves selected item and its index, this function should return a string that will be represented in button after item is selected -| Type | Required | -| -------- | -------------------------------------------------------------------- | -| function | Yes "unless you customized button using renderCustomizedButtonChild" | +if multiple select is true then pass the string value + +| Type | Required | +| ------------------ | -------------------------------------------------------------------- | +| function or string | Yes "unless you customized button using renderCustomizedButtonChild" | --- @@ -189,7 +252,7 @@ function recieves item and index for each row in dropdown, this function shoud r ### defaultValue -default selected item in dropdown ( check examples in Demo1) +default selected item in dropdown ( check examples in Demo1). If multiple select is true then pass the array of selected items. | Type | Required | | ---- | -------- | @@ -199,11 +262,11 @@ default selected item in dropdown ( check examples in Demo1) ### defaultValueByIndex -default selected item index +default selected item index. If multipleSelect is true then pass the array of default indices (check Demo2). -| Type | Required | -| ------- | -------- | -| integer | No | +| Type | Required | +| ---------------- | -------- | +| integer or array | No | --- @@ -399,6 +462,16 @@ style object for selected row text --- +### emptyStyle + +style object for empty list + +| Type | Required | +| ------ | -------- | +| object | No | + +--- + ### renderCustomizedRowChild function recieves item and its index, this function should return React component as a child for customized row `rowStyle` should be used for parent row view style. @@ -481,6 +554,46 @@ function returns React component for search input icon --- +### textNumberOfLines + +Drop Down Button Text number of lines (numberOfLines prop for Text) + +| Type | Required | default | +| ------ | -------- | ------- | +| number | No | 1 | + +--- + +### multipleSelect + +Select Multiple values from the Drop down List + +| Type | Required | default | +| ------- | -------- | ------- | +| boolean | No | false | + +--- + +### searchKey + +Searches only the specified keys if the data is object (by default searches all keys) + +| Type | Required | +| ----- | -------- | +| array | No | + +--- + +### allowSelectAll + +Allows user to select all data (works only if multiple select is true) + +| Type | Required | default | +| ------- | -------- | ------- | +| boolean | No | false | + +--- + ### onChangeSearchInputText function callback when the search input text changes, this will automatically disable the dropdown's internal search to be implemented manually outside the component diff --git a/index.js b/index.js index 62d954f..63f041a 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,4 @@ import SelectDropdown from './src/SelectDropdown'; +import FlashSelectDropdown from './src/FlashSelectDropdown'; -export default SelectDropdown; \ No newline at end of file +export {SelectDropdown, FlashSelectDropdown}; diff --git a/src/FlashSelectDropdown.js b/src/FlashSelectDropdown.js new file mode 100644 index 0000000..f8eb6c7 --- /dev/null +++ b/src/FlashSelectDropdown.js @@ -0,0 +1,283 @@ +import React, {forwardRef, useImperativeHandle, useState} from 'react'; +import {View, Text, TouchableOpacity, FlatList, Switch} from 'react-native'; +import styles from './styles'; +import {isExist} from './helpers/isExist'; +import Input from './components/Input'; +import DropdownOverlay from './components/DropdownOverlay'; +import DropdownModal from './components/DropdownModal'; +import DropdownWindow from './components/DropdownWindow'; +import {useSelectDropdown} from './hooks/useSelectDropdown'; +import {useLayoutDropdown} from './hooks/useLayoutDropdown'; +import {useRefs} from './hooks/useRefs'; +import {FlashList} from '@shopify/flash-list'; + +const FlashSelectDropdown = ( + { + data /* array */, + onSelect /* function */, + defaultButtonText /* String */, + buttonTextAfterSelection /* function or string */, + rowTextForSelection /* function */, + defaultValue /* any */, + defaultValueByIndex /* integer */, + disabled /* boolean */, + disableAutoScroll /* boolean */, + disabledIndexs /* array of disabled Row index */, + onFocus /* function */, + onBlur /* function */, + onScrollEndReached /* function */, + ///////////////////////////// + buttonStyle /* style object for button */, + buttonTextStyle /* style object for button text */, + renderCustomizedButtonChild /* function returns React component for customized button */, + ///////////////////////////// + renderDropdownIcon, + dropdownIconPosition, + statusBarTranslucent, + dropdownStyle, + dropdownOverlayColor /* string */, + ///////////////////////////// + rowStyle /* style object for row */, + rowTextStyle /* style object for row text */, + selectedRowStyle /* style object for selected row */, + disabledStyle, + selectedRowTextStyle /* style object for selected row text */, + renderCustomizedRowChild /* function returns React component for customized row */, + ///////////////////////////// + search /* boolean */, + searchInputStyle /* style object for search input */, + searchInputTxtColor /* text color for search input */, + searchInputTxtStyle /* text style for search input */, + searchPlaceHolder /* placeholder text for search input */, + searchPlaceHolderColor /* text color for search input placeholder */, + renderSearchInputLeftIcon /* function returns React component for search input icon */, + renderSearchInputRightIcon /* function returns React component for search input icon */, + onChangeSearchInputText /* function callback when the search input text changes, this will automatically disable the dropdown's interna search to be implemented manually outside the component */, + onlyDropdownIcon = false /*shows only drop down icon and ignores the text */, + textNumberOfLines = 1 /*Drop Down Button Text number of lines (numberOfLines prop for Text) */, + multipleSelect = false /*Select Multiple values from the Drop down List */, + searchKey /*search key if the data is object default searches all */, + emptyStyle /*Empty data style */, + allowSelectAll = false /*Allows user to select all data (works only if multiple select is true) */, + }, + ref, +) => { + const disabledInternalSearch = !!onChangeSearchInputText; + /* ******************* hooks ******************* */ + const {dropdownButtonRef, dropDownFlatlistRef} = useRefs(); + const { + dataArr, // + selectedItem, + selectedIndex, + selectItem, + reset, + searchTxt, + setSearchTxt, + selectAll, + toggleSeletAll, + } = useSelectDropdown(data, defaultValueByIndex, defaultValue, disabledInternalSearch, multipleSelect, searchKey); + const { + isVisible, // + setIsVisible, + buttonLayout, + onDropdownButtonLayout, + getItemLayout, + dropdownWindowStyle, + } = useLayoutDropdown(data, dropdownStyle, rowStyle, search); + useImperativeHandle(ref, () => ({ + reset: () => { + reset(); + }, + openDropdown: () => { + openDropdown(); + }, + closeDropdown: () => { + closeDropdown(); + }, + selectIndex: index => { + selectItem(index); + }, + })); + /* ******************* Methods ******************* */ + const openDropdown = () => { + dropdownButtonRef.current.measure((fx, fy, w, h, px, py) => { + onDropdownButtonLayout(w, h, px, py); + setIsVisible(true); + onFocus && onFocus(); + }); + }; + const closeDropdown = () => { + if (multipleSelect) { + onSelect && onSelect(selectedItem.map(d => d.item)); + } + setIsVisible(false); + setSearchTxt(''); + onBlur && onBlur(); + }; + const onLayout = () => { + if (disableAutoScroll) { + return; + } + if (selectedIndex >= 3 && dropDownFlatlistRef) { + dropDownFlatlistRef.current.scrollToOffset({ + offset: rowStyle && rowStyle.height ? rowStyle.height * selectedIndex : 50 * selectedIndex, + animated: true, + }); + } + }; + const onSelectItem = (item, index) => { + if (multipleSelect) { + selectItem(index); + toggleSeletAll(false); + return; + } + closeDropdown(); + onSelect && onSelect(item, index); + selectItem(index); + }; + /* ******************** Render Methods ******************** */ + const renderSearchView = () => { + return ( + search && ( + { + setSearchTxt(txt); + disabledInternalSearch && onChangeSearchInputText(txt); + }} + inputStyle={searchInputStyle} + inputTextStyle={searchInputTxtStyle} + renderLeft={renderSearchInputLeftIcon} + renderRight={renderSearchInputRightIcon} + /> + ) + ); + }; + const renderSelectAll = () => { + return ( + multipleSelect && + allowSelectAll && ( + + Select All + { + toggleSeletAll(); + }} + value={selectAll} + /> + + ) + ); + }; + const renderFlatlistItem = ({item, index}) => { + const isSelected = multipleSelect ? selectedIndex.filter(d => d == index).length > 0 : index == selectedIndex; + const disable = disabledIndexs?.includes(index); + return ( + isExist(item) && ( + onSelectItem(item, index)}> + {renderCustomizedRowChild ? ( + + {renderCustomizedRowChild(item, index, isSelected, disable)} + + ) : ( + + {rowTextForSelection ? rowTextForSelection(item, index) : item.toString()} + + )} + + ) + ); + }; + const renderDropdown = () => { + return ( + isVisible && ( + + + + {data.length > 0 && ( + + {renderSelectAll()} + {renderSearchView()} + + )} + index.toString()} + ref={dropDownFlatlistRef} + renderItem={renderFlatlistItem} + getItemLayout={getItemLayout} + onLayout={onLayout} + keyboardShouldPersistTaps="always" + onEndReached={() => onScrollEndReached && onScrollEndReached()} + onEndReachedThreshold={0.5} + ListEmptyComponent={ + + List Empty + + } + /> + + + ) + ); + }; + /////////////////////////////////////////////////////// + return ( + + {renderDropdown()} + {renderDropdownIcon && renderDropdownIcon(isVisible)} + {!onlyDropdownIcon && + (renderCustomizedButtonChild ? ( + + {renderCustomizedButtonChild(selectedItem, selectedIndex)} + + ) : ( + + {multipleSelect + ? selectedItem.length > 0 + ? buttonTextAfterSelection + : defaultButtonText + : isExist(selectedItem) + ? buttonTextAfterSelection + ? buttonTextAfterSelection(selectedItem, selectedIndex) + : selectedItem.toString() + : defaultButtonText || 'Select an option.'} + + ))} + + ); +}; + +export default forwardRef((props, ref) => FlashSelectDropdown(props, ref)); diff --git a/src/SelectDropdown.js b/src/SelectDropdown.js index 4f61bdf..357b403 100644 --- a/src/SelectDropdown.js +++ b/src/SelectDropdown.js @@ -1,5 +1,5 @@ -import React, {forwardRef, useImperativeHandle} from 'react'; -import {View, Text, TouchableOpacity, FlatList} from 'react-native'; +import React, {forwardRef, useImperativeHandle, useState} from 'react'; +import {View, Text, TouchableOpacity, FlatList, Switch} from 'react-native'; import styles from './styles'; import {isExist} from './helpers/isExist'; import Input from './components/Input'; @@ -15,7 +15,7 @@ const SelectDropdown = ( data /* array */, onSelect /* function */, defaultButtonText /* String */, - buttonTextAfterSelection /* function */, + buttonTextAfterSelection /* function or string */, rowTextForSelection /* function */, defaultValue /* any */, defaultValueByIndex /* integer */, @@ -39,6 +39,7 @@ const SelectDropdown = ( rowStyle /* style object for row */, rowTextStyle /* style object for row text */, selectedRowStyle /* style object for selected row */, + disabledStyle, selectedRowTextStyle /* style object for selected row text */, renderCustomizedRowChild /* function returns React component for customized row */, ///////////////////////////// @@ -51,6 +52,12 @@ const SelectDropdown = ( renderSearchInputLeftIcon /* function returns React component for search input icon */, renderSearchInputRightIcon /* function returns React component for search input icon */, onChangeSearchInputText /* function callback when the search input text changes, this will automatically disable the dropdown's interna search to be implemented manually outside the component */, + onlyDropdownIcon = false /*shows only drop down icon and ignores the text */, + textNumberOfLines = 1 /*Drop Down Button Text number of lines (numberOfLines prop for Text) */, + multipleSelect = false /*Select Multiple values from the Drop down List */, + searchKey /*search key if the data is object default searches all */, + emptyStyle /*Empty data style */, + allowSelectAll = false /*Allows user to select all data (works only if multiple select is true) */, }, ref, ) => { @@ -65,7 +72,9 @@ const SelectDropdown = ( reset, searchTxt, setSearchTxt, - } = useSelectDropdown(data, defaultValueByIndex, defaultValue, disabledInternalSearch); + selectAll, + toggleSeletAll, + } = useSelectDropdown(data, defaultValueByIndex, defaultValue, disabledInternalSearch, multipleSelect, searchKey); const { isVisible, // setIsVisible, @@ -97,6 +106,9 @@ const SelectDropdown = ( }); }; const closeDropdown = () => { + if (multipleSelect) { + onSelect && onSelect(selectedItem.map(d => d.item)); + } setIsVisible(false); setSearchTxt(''); onBlur && onBlur(); @@ -113,6 +125,11 @@ const SelectDropdown = ( } }; const onSelectItem = (item, index) => { + if (multipleSelect) { + selectItem(index); + toggleSeletAll(false); + return; + } closeDropdown(); onSelect && onSelect(item, index); selectItem(index); @@ -139,17 +156,41 @@ const SelectDropdown = ( ) ); }; + const renderSelectAll = () => { + return ( + multipleSelect && + allowSelectAll && ( + + Select All + { + toggleSeletAll(); + }} + value={selectAll} + /> + + ) + ); + }; const renderFlatlistItem = ({item, index}) => { - const isSelected = index == selectedIndex; + const isSelected = multipleSelect ? selectedIndex.filter(d => d == index).length > 0 : index == selectedIndex; + const disable = disabledIndexs?.includes(index); return ( isExist(item) && ( onSelectItem(item, index)}> {renderCustomizedRowChild ? ( - {renderCustomizedRowChild(item, index, isSelected)} + + {renderCustomizedRowChild(item, index, isSelected, disable)} + ) : ( + {data.length > 0 && ( + + {renderSelectAll()} + {renderSearchView()} + + )} index.toString()} ref={dropDownFlatlistRef} renderItem={renderFlatlistItem} getItemLayout={getItemLayout} onLayout={onLayout} - ListHeaderComponent={renderSearchView()} - stickyHeaderIndices={search && [0]} keyboardShouldPersistTaps="always" onEndReached={() => onScrollEndReached && onScrollEndReached()} onEndReachedThreshold={0.5} + ListEmptyComponent={ + + List Empty + + } /> @@ -197,22 +250,31 @@ const SelectDropdown = ( ...styles.dropdownButton, ...(dropdownIconPosition == 'left' ? styles.row : styles.rowRevese), ...buttonStyle, + justifyContent: onlyDropdownIcon ? 'center' : 'center', }}> {renderDropdown()} {renderDropdownIcon && renderDropdownIcon(isVisible)} - {renderCustomizedButtonChild ? ( - - {renderCustomizedButtonChild(selectedItem, selectedIndex)} - - ) : ( - - {isExist(selectedItem) - ? buttonTextAfterSelection - ? buttonTextAfterSelection(selectedItem, selectedIndex) - : selectedItem.toString() - : defaultButtonText || 'Select an option.'} - - )} + {!onlyDropdownIcon && + (renderCustomizedButtonChild ? ( + + {renderCustomizedButtonChild(selectedItem, selectedIndex)} + + ) : ( + + {multipleSelect + ? selectedItem.length > 0 + ? buttonTextAfterSelection + : defaultButtonText + : isExist(selectedItem) + ? buttonTextAfterSelection + ? buttonTextAfterSelection(selectedItem, selectedIndex) + : selectedItem.toString() + : defaultButtonText || 'Select an option.'} + + ))} ); }; diff --git a/src/hooks/useSelectDropdown.js b/src/hooks/useSelectDropdown.js index 879c685..ccea20b 100644 --- a/src/hooks/useSelectDropdown.js +++ b/src/hooks/useSelectDropdown.js @@ -3,9 +3,17 @@ import {deepSearchInArr} from '../helpers/deepSearchInArr'; import {findIndexInArr} from '../helpers/findIndexInArr'; import {isExist} from '../helpers/isExist'; -export const useSelectDropdown = (data, defaultValueByIndex, defaultValue, disabledInternalSearch) => { - const [selectedItem, setSelectedItem] = useState(null); // selected item from dropdown - const [selectedIndex, setSelectedIndex] = useState(-1); // index of selected item from dropdown +export const useSelectDropdown = ( + data, + defaultValueByIndex, + defaultValue, + disabledInternalSearch, + multipleSelect, + searchKey, +) => { + const [selectedItem, setSelectedItem] = useState(multipleSelect ? [] : null); // selected item from dropdown + const [selectedIndex, setSelectedIndex] = useState(multipleSelect ? [-1] : -1); // index of selected item from dropdown + const [selectAll, setSelectAll] = useState(false); // index of selected item from dropdown const [searchTxt, setSearchTxt] = useState(''); // data array changes @@ -19,6 +27,21 @@ export const useSelectDropdown = (data, defaultValueByIndex, defaultValue, disab useEffect(() => { // defaultValueByIndex may be equals zero if (isExist(defaultValueByIndex)) { + if (multipleSelect) { + let tmp = []; + + defaultValueByIndex.map((d, i) => { + let exist = isExist(data[d]); + if (data && exist) { + let index = findIndexInArr(data[d], data); + tmp.push({item: data[index], index}); + } + }); + setSelectedItem(tmp); + setSelectedIndex(tmp.map(d => d.index)); + return; + } + if (data && isExist(data[defaultValueByIndex])) { selectItem(defaultValueByIndex); } @@ -28,6 +51,20 @@ export const useSelectDropdown = (data, defaultValueByIndex, defaultValue, disab useEffect(() => { // defaultValue may be equals zero if (isExist(defaultValue)) { + if (multipleSelect) { + let tmp = []; + + defaultValue.map((d, i) => { + let index = findIndexInArr(d, data); + if (data && index >= 0) { + tmp.push({item: data[index], index}); + } + }); + setSelectedItem(tmp); + setSelectedIndex(tmp.map(d => d.index)); + return; + } + if (data && findIndexInArr(defaultValue, data) >= 0) { selectItem(findIndexInArr(defaultValue, data)); } @@ -38,17 +75,47 @@ export const useSelectDropdown = (data, defaultValueByIndex, defaultValue, disab if (disabledInternalSearch) { return data; } - return searchTxt ? deepSearchInArr(searchTxt, data) : data; + return searchTxt ? deepSearchInArr(searchTxt, data, searchKey) : data; }, [data, searchTxt]); const selectItem = index => { + if (multipleSelect) { + let tmp = selectedItem; + tmp = + tmp.filter(d => d?.index == index).length > 0 + ? tmp.filter(d => d.index !== index) + : [...tmp, {item: data[index], index}]; + setSelectedItem(tmp); + setSelectedIndex(tmp.map(d => d.index)); + return; + } + setSelectedItem(data[index]); setSelectedIndex(index); }; const reset = () => { - setSelectedItem(null); - setSelectedIndex(-1); + setSelectedItem(multipleSelect ? [] : null); + setSelectedIndex(multipleSelect ? [-1] : -1); + }; + + const toggleSeletAll = (cond = true) => { + if (cond) { + if (!selectAll) { + let tmp = []; + data.map((d, i) => { + tmp.push({item: d, index: i}); + }); + setSelectedItem(tmp); + setSelectedIndex(tmp.map(d => d.index)); + } else { + setSelectedItem([]); + setSelectedIndex([-1]); + } + setSelectAll(!selectAll); + return; + } + setSelectAll(false); }; return { @@ -59,5 +126,7 @@ export const useSelectDropdown = (data, defaultValueByIndex, defaultValue, disab reset, searchTxt, setSearchTxt, + selectAll, + toggleSeletAll, }; }; diff --git a/src/styles.js b/src/styles.js index 4115f96..1ebbd77 100644 --- a/src/styles.js +++ b/src/styles.js @@ -49,6 +49,16 @@ const styles = StyleSheet.create({ flex: 1, overflow: 'hidden', }, + allowAllStyle: { + justifyContent: 'center', + alignItems: 'center', + flexDirection: 'row', + position: 'absolute', + top: 0, + right: 0, + zIndex: 9999, + height: 50, + }, }); export default styles; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..fb57ccd --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + From a0df3996e4ca0660ce271d1f048eb45949336991 Mon Sep 17 00:00:00 2001 From: rohan km Date: Tue, 21 Feb 2023 18:59:45 +0530 Subject: [PATCH 2/5] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c7efd51..1d319a7 100644 --- a/README.md +++ b/README.md @@ -262,7 +262,7 @@ default selected item in dropdown ( check examples in Demo1). If multiple select ### defaultValueByIndex -default selected item index. If multipleSelect is true then pass the array of default indices (check Demo2). +default selected item index. If multipleSelect is true then pass the array of default indices. | Type | Required | | ---------------- | -------- | From 2355299dffc4bad104e1d62ebf3f32cdd811fab7 Mon Sep 17 00:00:00 2001 From: rohan km Date: Tue, 21 Feb 2023 19:09:21 +0530 Subject: [PATCH 3/5] deepSearchInArr updated with searchKey --- src/helpers/deepSearchInArr.js | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/helpers/deepSearchInArr.js b/src/helpers/deepSearchInArr.js index 39a8f1b..57ae221 100644 --- a/src/helpers/deepSearchInArr.js +++ b/src/helpers/deepSearchInArr.js @@ -1,10 +1,24 @@ -const contains = (item, searchTxt) => { +const decycle = (obj, stack = []) => { + if (!obj || typeof obj !== 'object') return obj; + if (stack.includes(obj)) return null; + if (obj._raw) { + return obj._raw; + } + let s = stack.concat([obj]); + + return Array.isArray(obj) + ? obj.map(x => decycle(x, s)) + : Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, decycle(v, s)])); +}; +const contains = (item, searchTxt, searchKey) => { // item is an object if (typeof item == 'object' && item != null) { for (let key in item) { - const value = item[key]; - if (contains(value, searchTxt)) { - return true; + if (searchKey ? searchKey.includes(key) : true) { + const value = item[key]; + if (contains(value, searchTxt)) { + return true; + } } } } @@ -19,10 +33,10 @@ const contains = (item, searchTxt) => { return false; }; -export const deepSearchInArr = (query, arr) => { +export const deepSearchInArr = (query, arr, searchKey) => { let array = []; for (let i = 0; i <= arr.length - 1; i++) { - if (contains(arr[i], query)) { + if (contains(arr[i], query, searchKey)) { array.push(arr[i]); } else { array.push(null); From 07bfd04800c7890d9c785eebb2a4c38c42f15375 Mon Sep 17 00:00:00 2001 From: rohan km Date: Tue, 21 Feb 2023 19:40:29 +0530 Subject: [PATCH 4/5] defauly export SelectDropdown --- index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 63f041a..1140548 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,5 @@ import SelectDropdown from './src/SelectDropdown'; import FlashSelectDropdown from './src/FlashSelectDropdown'; -export {SelectDropdown, FlashSelectDropdown}; +export default SelectDropdown; +export {FlashSelectDropdown}; From ed65ec8bb76b8864c7dded400ba9a06f29add2f8 Mon Sep 17 00:00:00 2001 From: rohan km Date: Tue, 21 Feb 2023 20:41:17 +0530 Subject: [PATCH 5/5] added index on select multiple values --- README.md | 4 ++-- src/FlashSelectDropdown.js | 6 +++++- src/SelectDropdown.js | 6 +++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1d319a7..4ba85e9 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ const [data,setData]=useState() ); }} - onSelect={async (selectedItem) => { + onSelect={async (selectedItem,index) => { setData(selectedItem); }} buttonTextAfterSelection={"Selected"} @@ -210,7 +210,7 @@ array of data that will be represented in dropdown 'can be array of objects function recieves selected item and its index in data array -if multipleSelect is true then recives only array of item. +if multipleSelect is true then recives array of items and arrat if selected index. | Type | Required | | -------- | -------- | diff --git a/src/FlashSelectDropdown.js b/src/FlashSelectDropdown.js index f8eb6c7..63e8987 100644 --- a/src/FlashSelectDropdown.js +++ b/src/FlashSelectDropdown.js @@ -108,7 +108,11 @@ const FlashSelectDropdown = ( }; const closeDropdown = () => { if (multipleSelect) { - onSelect && onSelect(selectedItem.map(d => d.item)); + onSelect && + onSelect( + selectedItem.map(d => d.item), + selectedIndex, + ); } setIsVisible(false); setSearchTxt(''); diff --git a/src/SelectDropdown.js b/src/SelectDropdown.js index 357b403..48d1823 100644 --- a/src/SelectDropdown.js +++ b/src/SelectDropdown.js @@ -107,7 +107,11 @@ const SelectDropdown = ( }; const closeDropdown = () => { if (multipleSelect) { - onSelect && onSelect(selectedItem.map(d => d.item)); + onSelect && + onSelect( + selectedItem.map(d => d.item), + selectedIndex, + ); } setIsVisible(false); setSearchTxt('');